Джон дал вам нужный ответ, но есть некоторые детали, о которых нужно знать.
Обработка
C массивов такова, что функция search
не получает массив 3x3 int
; скорее, он получает указатель на массив из 3 элементов int
. Из стандарта языка C, черновик n1256 :
6.3.2.1 L-значения, массивы и обозначения функций
...
3 За исключением случаев, когда это операнд оператора sizeof
или унарный оператор &
или строковый литерал, используемый для инициализации массива, выражение, имеющее тип '' массив типа '', преобразуется в выражение с type указатель на тип, который указывает на начальный элемент объекта массива и не является lvalue. Если объект массива имеет класс хранения регистров, поведение не определено.
Таким образом, когда вы вызываете result = search(Array, number);
, тип выражения Array
неявно преобразуется из 3-элементного массива из 3-элементных массивов int
(int [3][3]
) в указатель на 3- массив элементов int
(int (*)[3]
). В контексте объявления параметров функции T a[]
и T a[n]
являются синонимами T *a
. Вы можете изменить прототип функции на
int search(int (*a)[3], int x)
и он будет вести себя точно так же.
Одним из следствий этого является то, что search
может работать не только с массивами 3x3, но и с любым массивом Nx3. Вы написали свою функцию, предполагая, что a
всегда 3x3; если вы хотите иметь возможность обрабатывать массивы с разным количеством строк, вам нужно будет передать отдельный параметр, чтобы указать количество строк в массиве:
int search(int (*a)[3], size_t rows, int x)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < 3; j++)
if (a[i][j] == x)
return 1;
return 0;
}
int main(void)
{
int fiveRowArray[5][3] = {{ 1, 2, 3}, { 4, 5, 6}, { 7, 8, 9},
{10,11,12}, {13,14,15}};
int twoRowArray[2][3] = {{ 1, 2, 3}, { 4, 5, 6}};
int number;
printf("Gimme a number: ");
fflush(stdout);
scanf("%d", &number);
if (search(array, sizeof fiveRowArray / sizeof *fiveRowArray, number))
printf("Number exists in fiveRowArray\n");
else
printf("Number does not exist in fiveRowArray\n");
if (search(array, sizeof twoRowArray / sizeof *twoRowArray , number))
printf("Number exists in twoRowArray \n");
else
printf("Number does not exist in twoRowArray \n");
return 0;
}
Выражение sizeof arr / sizeof *arr
вычисляет количество элементов в массиве путем получения общего размера массива в байтах (sizeof arr
) и деления его на количество байтов в отдельном элементе массива (sizeof *arr
или sizeof arr[0]
). ). Обратите внимание, что это работает только для выражений типа массива; он не будет работать для указателей, которые обрабатываются как массивы (например, выражение a
в функции search
).
Если вы хотите обрабатывать различное количество строк и столбцов, вам придется использовать другой подход:
int search(int *a, size_t rows, size_t cols, int x)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
if (a[i * cols + j] == x)
return 1;
return 0;
}
int main(void)
{
int fiveByThree[5][3] = {...};
int twoByFour[2][4] = {...};
...
if (search(&fiveByThree[0][0],
sizeof fiveByThree / sizeof *fiveByThree,
sizeof fiveByThree[0] / sizeof *fiveByThree[0],
number))
...
if (search(&twoByFour[0][0],
sizeof twoByFour / sizeof *twoByFour,
sizeof twoByFour[0] / sizeof *twoByFour[0],
number))
...
}
В этом случае мы явно передаем указатель на первый элемент в каждом массиве, поэтому вместо получения указателя на массив int
, search
получает простой указатель на int
, который мы рассматриваем как 1D массив и вычислить смещение вручную как i * cols + j
. Этот код предполагает, что все элементы в массиве 2D являются смежными.
Редактировать
Обратите внимание, что в C99 вы можете иметь так называемые массивы переменной длины (VLA), где размерность массива может быть задана переменной времени выполнения, а не константным выражением; это позволяет нам написать прототип как
int search(size_t rows, size_t cols, int arr[rows][cols], int x)
и не связывайтесь с указателями.