Вопрос: Мой компилятор ругается, когда я передаю двумерный массив функции, ожидающей указатель на указатель.

Ответ:

Правило, по которому массивы превращаются в указатели, не может применяться рекурсивно. Массив массивов (т.е. двумерный массив в С) превращается в указатель на массив, а не в указатель на указатель.
Указатели на массивы могут вводить в заблуждение и применять их нужно с осторожностью. (Путаница еще более усугубляется тем, что существуют некорректные компиляторы, включая некоторые версии pcc и полученные
на основе pcc программы lint, которые неверно вопринимают присваивание многоуровневым указателям многомерных массивов.)
Если вы передаете двумерный массив функции:
int array[NROWS][NCOLUMNS];
f(array);

описание функции должно соответствовать
  f(int a[][NCOLUMNS]) {...}

// или

  f(int (*ap)[NCOLUMNS]) {...}   // ap - указатель на массив

В случае, когда используется первое описание, компилятор неявно осуществляет обычное преобразование "массива массивов" в "указатель на массив"; во втором случае указатель на массив задается явно.
Так как вызываемая функция не выделяет место для массива, нет необходимости знать его размер, так что количество "строк" NROWS может быть опущено. "Форма" массива по-прежнему важна, так что размер "столбца" NCOLUMNS должен быть включен (а для массивов размерности 3 и больше, все промежуточные размеры).

Если формальный параметр функции описан как указатель на указатель, то передача функции в качестве параметра двумерного массива будет, видимо, некорректной.

Смотри:
K&R I Разд.5.10 c. 110;
K&R II Разд.5.9 c. 113.
Автор: Кодт    Оценить