Если у вас есть массив в main()
, то есть int a[3][3];
, и вы хотите передать этот массив в вашу функцию, чтобы его можно было изменить внутри функции и увидеть изменения в вызывающей функции (main()
здесь ), вы должны передать адрес массива в качестве параметра. Если вы просто передадите сам массив по значению , то функция получит массив copy-of , и любые изменения, внесенные в массив в функции, будут потеряны при возврате функции - - так же, как любой другой локально объявленный массив будет.
Когда вы берете address-of массив, у вас есть указатель на массив. В вашем случае указатель на 2D массив. Синтаксис для типа выше будет int (*a)[3][3]
. (например, указатель на массив из int[3][3]
) Таким образом, чтобы передать address-of массив (он все еще передает адрес по значению, C не имеет ссылок), объявление вашей функции будет выглядеть следующим образом:
void mod_arr (int (*a)[ROWS][COLS])
{
for (int i = 0; i < ROWS; i++)
for (int j = 0; j < COLS; j++)
(*a)[i][j] = (i + 1) * (j + 1);
}
Чтобы работать с исходным массивом в функции и назначать / изменять значения элементов, необходимо разыменовать указатель на массив . Если вы посмотрите выше, это будет:
(*a)[i][j] = (i + 1) * (j + 1);
Если скобки вокруг (*a)
требуются из-за C приоритета оператора .
Объявление короткого prn_arr
Функция для вывода результатов вы можете сделать что-то вроде следующего:
#include <stdio.h>
#define ROWS 3
#define COLS ROWS
void mod_arr (int (*a)[ROWS][COLS])
{
for (int i = 0; i < ROWS; i++)
for (int j = 0; j < COLS; j++)
(*a)[i][j] = (i + 1) * (j + 1);
}
void prn_arr (int a[ROWS][COLS])
{
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++)
printf (" %2d", a[i][j]);
putchar ('\n');
}
}
int main (void) {
int a[ROWS][COLS] = {{0}};
mod_arr (&a);
prn_arr (a);
}
Где в main()
выше, вы просто объявляете массив и инициализируете все значения нулями, а затем передаете адрес в mod_arr
для манипулирования массивом, а затем вызовите prn_arr
для вывода результатов - нужно только передать сам массив (он является указателем на первый ряд значений).
Однако следует помнить, что для больших массивов более эффективно передавать указатель на массив в качестве параметра, а не передавать полную копию массива (например, указатель на x86_64 равен 8 байтам независимо от того, размера массива, в то время как, например, массив 1000x1000, для копирования которого потребуется 1 000 000 раз больше байтов элемента)
Пример использования / Вывод
$ ./bin/modarr
1 2 3
2 4 6
3 6 9
Таким образом, вы можете видеть, что, передавая адрес функции в массив, функция получает исходный адрес для массива (а не просто копию массива в качестве какого-то нового адреса), поэтому изменения, внесенные в mod_arr
- это изменения, внесенные в адреса в самом исходном массиве, и они будут видны в вызывающей функции.
Просмотрите все, и если у вас есть дополнительные вопросы, дайте мне знать. Это своего рода основная проблема при работе с указателями и массивами - понимание задействованных типов и синтаксиса для тех типов, которые позволяют вам заставить все это работать.