Как я могу изменить 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
операторы не передают правильный тип данных, но я не могу понять, что они следует быть.
Как я могу изменить его, чтобы он работал должным образом?
Решение
При этом объявляется массив MAXROWS
массивы указателей на int
.
int *data[MAXROWS][MAXCOLS];
Однако в определении функции массивы верхнего уровня (любого размера) эквивалентны указателям, потому что массивы всегда распадаются на указатели на тип элемента массива при передаче в функцию.
Таким образом, ваше определение функции эквивалентно:
void getInput (int *(*data)[MAXCOLS])
т. е.указатель на массив из MAXCOLS
указатели на int
.
В нынешнем виде вашего кода вы никогда не инициализируете ни один из int
указатели в массиве, поскольку вы передаете 2d-массив int
s как указатель на двумерный массив 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;
}