Когда массив передается функции, он «распадается» на указатель на свой первый элемент. Итак, учитывая:
T a[10];
f(a);
В вызове f(a)
, a
фактически является &a[0]
, то есть указателем, а тип является T *
(тип &a[0]
).
Когда у вас есть массив массивов, применяется то же правило:
T a[10][5];
f(a);
a
снова распадается на указатель, равный &a[0]
. a[0]
имеет тип "массив [5] из T
". Таким образом, &a[0]
имеет тип «указатель на массив [5] из T
», то есть, если бы вы объявили указатель p
для установки равным &a[0]
, вы должны сделать:
T (*p)[5]; /* parentheses because [] binds tighter than * */
p = &a[0];
Учитывая вышеизложенное и предполагая, что ваш массив объявлен в вызывающем коде как int a[10][10];
, вы должны объявить свою функцию как:
function_name(int (*a)[10]);
Подробнее см. this .
Синтаксическая ошибка в function_name(int[10][10] a)
- вам необходимо указать размер массива после имени «переменной»: function_name(int a[10][10])
. Фактически, вышесказанное эквивалентно function_name(int (*a)[10])
из-за упомянутого выше «распада».
Редактировать : ах, думаю, теперь я понимаю. Вы не можете объявить функцию, которая принимает как «двумерный» массив, так и указатель на указатель по причинам, указанным выше («распад» на указатель происходит только один раз). Указатель на указатель может не указывать на смежные данные и может иметь разное количество элементов в каждой «строке». Массив массивов не может иметь эти свойства. Они принципиально разные.