1

私の行サイズは固定ですが、列サイズは常に変化し続けます。そのため、列レベルにポインターを使用することを考えています。しかし、Cでこの機能を使用する方法がわかりません。親切に助けてください。

int array[rows][columns]; //row size fixed but column size is not fixed.
4

6 に答える 6

0

各行が異なる数の列を持つことができる場合、一般的なアプローチはポインターの配列を宣言し、各行に対してその行の要素数を動的に割り当てることです。

int *array[ROWS];

array[i] = malloc(sizeof *array[i] * number_of_columns_for_row_i);

完了したら、各行を個別に解放する必要があることに注意してください。

for (i = 0; i < ROWS; i++)
  free(array[i]);

すべての行の列数が同じで、その数が配列のインスタンスごとに変わる可能性がある場合は、いくつかの選択肢があります。C99 準拠のコンパイラを使用している場合は、実行時まで配列の次元が不明な可変長配列を使用できます。

int columns;

// get number of columns somehow

int array[ROWS][columns];

VLA は便利ですが、制限があります。のメンバーstructまたはunion型にすることはできず、宣言しstaticたり、ファイル スコープで使用したりすることはできません。このアプローチの大きな利点は、完了時に何かを解放することを心配する必要がないことです。このアプローチの大きな欠点は、要求を満たすのに十分なメモリがない可能性があることです。変数に使用できるメモリ スペースautoは、動的に割り当てられたオブジェクトのメモリに比べて、通常は非常に限られています。また、言語標準の最新リビジョン (C11) では VLA がオプションになっているため、今後のすべての実装で使用できるとは限りません。

または、次のように配列を動的に割り当てることもできます。

int (*array)[ROWS];
int columns;

// get number of columns somehow

array = malloc(sizeof *array * columns);

今回arrayは、へのポインターの配列でintはなく、 の配列へのポインターであることに注意してくださいint。このアプローチの利点は、配列メモリが連続して割り当てられfree、メモリの書き込みが書き込みと同じくらい簡単であることです。

free(array);

欠点は、配列が非常に大きい場合、または動的メモリ プールが非常に断片化されている場合、要求を満たすのに十分な大きさのメモリ チャンクを使用できない可能性があることです。

すべての行を連続して割り当てる必要がない場合は、各行を個別に割り当てる最初の方法を使用します。列数に同じ値を使用するだけです。

int *array[ROWS];
int columns;

// get number of columns

for (i = 0; i < ROWS; i++)
  array[i] = malloc(sizeof *array[i] * columns);
于 2012-04-30T14:20:05.357 に答える
0

ポインターの配列を宣言する必要があります。このような:

int *array[rows]; 

後で、必要に応じて、各行にメモリを割り当てます。これには、malloc または calloc 関数を使用できます。

for(int i=0; i<rows; i++){
    array[i] = (int *) malloc(columns * sizeof(int));
}

この方法では、さまざまなサイズの行を持つこともできます。

于 2012-04-30T13:48:55.887 に答える
0

配列の 1 つを除くすべての次元が固定されている場合 (これは、説明した状況です)、ポインターの配列の使用を避けることができます。行を として型定義しint[rows]、次のように行の配列を作成できます。

typedef int row_t[rows];

row_tこれで、配列で構成される 2D 配列を次のように渡すことができます。

int total(row_t array[], int len) {
    int res = 0;
    for (int c = 0 ; c != len ; c++) {
        for (int r = 0 ; r != rows ; r++) {
            res += array[r][c];
        }
    }
    return res;
}

int main() {
    row_t *matrix = malloc(columns*sizeof(row_t));
    for (int c = 0 ; c != columns ; c++) {
        for (int r = 0 ; r != rows ; r++) {
            matrix[r][c] = r*r+c*c;
        }
    }
    printf("%d\n", total(matrix, columns));
    free(matrix);
    return 0;
}
于 2012-04-30T13:49:11.843 に答える
0

配列次元では変数を使用できないため、ポインターへのポインターを使用します

int **array;

array = (int **)malloc(sizeof(int *) * rows);
for (int i = 0; i < rows; ++i) {
    array[i] = (int *)malloc(sizeof(int) * columns); 
    for (int j = 0; j < columns; j++) {
       array[i][j] = value;
    }
}

もちろん、すべてを解放することを忘れないでください

于 2012-04-30T13:49:20.300 に答える
0

int* の配列を使用してこれを行います。

int* array[row];
for (int i = 0; i < row; ++i)
    array[i] = (int*)malloc(i * sizeof(int));

そして、静的であるかのようにデータにアクセスできます。

int val = array[myRow][myColumn];

割り当てたときと同じパターンでメモリを解放する必要があります。

于 2012-04-30T13:51:14.467 に答える
0

13 年前から、C では配列の宣言で動的サイズが許可されています。これを可変長配列 VLA と呼びます。

本当に大きな配列がある場合、これによりスタックが爆発する可能性があります。mallocしかし、2D 配列のすべての単純さを使用して、そのような野獣を割り当てることもできます。

size_t n = SOME_COMPLICATED_VALUE;
size_t m = ANOTHER_ONE;
double (*A)[n] = malloc(double[m][n]);
于 2012-04-30T13:57:43.950 に答える