関数に渡された2D配列を変更するにはどうすればよいですか?
質問
次のコードでセグメンテーションエラーが発生するのはなぜですか?
#define MAXROWS 10
#define MAXCOLS 10
void getInput (int *data[MAXROWS][MAXCOLS]) {
int rows, cols;
int curRow, curCol;
printf ("How many rows and cols?");
scanf ("%d %d", rows, cols);
for (curRow = 0; curRow < rows; curRow++) {
for (curCol = 0; curCol < cols; curCol++) {
scanf ("%d", data[curRow][curCol]);
printf ("%d\n", *data[curRow][curCol]);
}
}
}
void main () {
int data[MAXROWS][MAXCOLS];
getInput (data);
}
scanf
および printf
ステートメントは、渡された正しいデータ型を取得していないようですが、 する必要があります。
正しく動作するように変更するにはどうすればよいですか?
解決
これは、 int
へのポインターの MAXROWS
配列の配列を宣言します。
int *data[MAXROWS][MAXCOLS];
ただし、関数定義では、配列は関数に渡されると常に配列メンバーの型へのポインターに減衰するため、最上位の配列(任意のサイズ)はポインターと同等です。
つまり、関数定義は次と同等です:
void getInput (int *(*data)[MAXCOLS])
i.e。 int
への MAXCOLS
ポインターの配列へのポインター。
コードが立っているとき、2dへのポインターとして int
sの2d配列を渡すため、配列内の int
ポインターを初期化することはありません。 int *
の配列。
おそらく渡したいのは、 MAXCOLS
int
の配列へのポインタです:
void getInput (int (*data)[MAXCOLS])
または同等:
void getInput (int data[][MAXCOLS])
次に、次のことを行います。
int main(void)
{
int data[MAXROWS][MAXCOLS];
getInput(data);
return 0;
}
次に、2D配列を最初の要素へのポインタ(行または MAXCOLS
int
sの配列へのポインタ)として渡します。
変更を確認する場合は、必ず変更してください:
scanf ("%d", data[curRow][curCol]);
printf ("%d\n", *data[curRow][curCol]);
to:
scanf ("%d", &data[curRow][curCol]);
printf ("%d\n", data[curRow][curCol]);
また、ここでパラメータを確認してください:
scanf ("%d %d", &rows, &cols);
rows
および cols
へのポインタを渡す必要があります。
MAXROWS
または MAXCOLS
を超える行と列を読み取らないように、入力関数に境界チェックを追加してください。
他のヒント
scanfは、変数の内容ではなく変数のアドレスを受け入れます:
void getInput (int data[][MAXCOLS]) {
int rows, cols;
int curRow, curCol;
printf ("How many rows and cols?");
scanf ("%d %d", &rows, &cols);
//scanf ("%d %d", &rows, &cols);
for (curRow = 0; curRow < rows; curRow++) {
for (curCol = 0; curCol < cols; curCol++) {
scanf ("%d", &data[curRow][curCol]);
printf ("%d\n", data[curRow][curCol]);
}
}
}
いくつかの異なる問題がありました。
まず、配列を関数に渡すとき、N-1次元の定義のみが必要です。たとえば、3D配列を渡す場合、関数sigに最後の2次元のサイズを入れ、最初の次元を空のままにします。
foo(int threeD[][10][15]);
次に、scanfは引数のアドレスを取得します。これは、配列では次のようになります
&data[curRow][curCol]
第三に、入力範囲を常にチェックして、有効であることを確認する必要があります。
if (rows > MAXROWS || cols > MAXCOLS) {
printf("Bad array dimensions\n");
return;
}
第4に、常にすべての警告をオンにしてコンパイルします。コンパイラは、これらのすべてについて警告します。
gcc -Wall pass_array.c -o pass_array
。
#include <stdio.h>
#define MAXROWS 10
#define MAXCOLS 10
void getInput (int data[][MAXCOLS]) {
int rows, cols;
int curRow, curCol;
printf ("How many rows and cols?");
scanf ("%d %d", &rows, &cols);
if (rows > MAXROWS || cols > MAXCOLS) {
printf("Bad array dimensions\n");
return;
}
for (curRow = 0; curRow < rows; curRow++) {
for (curCol = 0; curCol < cols; curCol++) {
scanf ("%d", &data[curRow][curCol]);
printf ("%d\n", data[curRow][curCol]);
}
}
}
int main () {
int data[MAXROWS][MAXCOLS];
getInput (data);
return 0;
}