Как я могу изменить 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 операторы не передают правильный тип данных, но я не могу понять, что они следует быть.

Как я могу изменить его, чтобы он работал должным образом?

Это было полезно?

Решение

При этом объявляется массив MAXROWS массивы указателей на int.

int *data[MAXROWS][MAXCOLS];

Однако в определении функции массивы верхнего уровня (любого размера) эквивалентны указателям, потому что массивы всегда распадаются на указатели на тип элемента массива при передаче в функцию.

Таким образом, ваше определение функции эквивалентно:

void getInput (int *(*data)[MAXCOLS])

т. е.указатель на массив из MAXCOLS указатели на int.

В нынешнем виде вашего кода вы никогда не инициализируете ни один из int указатели в массиве, поскольку вы передаете 2d-массив ints как указатель на двумерный массив 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ы).

Если вы убедитесь, что изменились, обязательно изменитесь:

  scanf ("%d", data[curRow][curCol]);
  printf ("%d\n", *data[curRow][curCol]);

Для:

  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-массив, вы бы ввели размер последних 2-х измерений в функцию sig и оставили первое пустое.

foo(int threeD[][10][15]);

Во-вторых, scanf принимает адрес аргумента, который для вашего массива выглядит следующим образом

&data[curRow][curCol]

В-третьих, вы всегда должны проверять диапазон ваших входных данных, чтобы убедиться в их достоверности:

  if (rows > MAXROWS || cols > MAXCOLS) {
    printf("Bad array dimensions\n");
    return;
  }

В-четвертых, всегда компилируйте со всеми включенными предупреждениями - компилятор предупредит вас о выделении всего этого:

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