関数に渡された2D配列を変更するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/1431500

  •  07-07-2019
  •  | 
  •  

質問

次のコードでセグメンテーションエラーが発生するのはなぜですか?

#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;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top