Как я могу изменить 2d массив, переданный в функцию? - PullRequest
1 голос
/ 16 сентября 2009

Почему следующий код дает мне ошибку сегментации?

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

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

Ответы [ 3 ]

4 голосов
/ 16 сентября 2009

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

int *data[MAXROWS][MAXCOLS];

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

То есть определение вашей функции эквивалентно:

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

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

Поскольку ваш код стоит, вы никогда не инициализируете ни один из int указателей в массиве, поскольку вы передаете 2d-массив int s в качестве указателя на 2d-массив 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]);

до:

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

Также проверьте свои параметры здесь:

scanf ("%d %d", &rows, &cols);

Вы должны передавать указатели на rows и cols.

Обязательно добавьте некоторую проверку границ в функцию ввода, чтобы не пытаться читать больше строк и столбцов, чем MAXROWS или MAXCOLS.

0 голосов
/ 16 сентября 2009

Было несколько разных проблем.

Во-первых, при передаче массивов в функции вам нужно только определить измерения N-1. Например, если вы передаете трехмерный массив, вы должны поместить размер двух последних измерений в функцию 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;
}
0 голосов
/ 16 сентября 2009

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]);
        }
    }
}
...