Многомерный массив и указатель на указатели - PullRequest
6 голосов
/ 06 апреля 2011

Когда вы создаете многомерный массив char a[10][10], согласно моей книге говорится, что вы должны использовать параметр, аналогичный char a[][10], для передачи массива в функцию.

Почему вы должны указать длину как таковую?Разве вы не просто передаете двойной указатель на то, чтобы быть с, и разве этот двойной указатель уже не указывает на выделенную память?Так почему же параметр не может быть char **a?Вы перераспределяете любую новую память, предоставляя вторую 10.

Ответы [ 2 ]

13 голосов
/ 06 апреля 2011

Указатели не являются массивами

Разыменованный char ** является объектом типа char *.

Разыменованным char (*)[10] является объектом типа char [10].

Массивы не являются указателями

См. Запись c-faq об этом же предмете .


Предположим, у вас есть

char **pp;
char (*pa)[10];

и, ради аргумента, оба указывают на одно и то же место: 0x420000.

pp == 0x420000; /* true */
(pp + 1) == 0x420000 + sizeof(char*); /* true */

pa == 0x420000; /* true */
(pa + 1) == 0x420000 + sizeof(char[10]); /* true */

(pp + 1) != (pa + 1) /* true (very very likely true) */

, и именно поэтому аргумент не может иметь тип char**.Также char** и char (*)[10] не являются совместимыми типами, поэтому типы аргументов (разрушенный массив) должны соответствовать параметрам (тип в прототипе функции)

1 голос
/ 06 апреля 2011

C языковой стандарт, черновик n1256 :

6.3.2.1 L-значения, массивы и обозначения функций
...
3 За исключением случаев, когдаэто операнд оператора sizeof или унарный оператор &, или строковый литерал, используемый для инициализации массива; выражение, имеющее тип '' массив из тип '', преобразуется ввыражение с указателем типа '' на тип '', которое указывает на начальный элемент объекта массива и не является lvalue.Если объект массива имеет класс хранения регистров, поведение не определено.

При объявлении

char a[10][10];

тип выражения массива a - это "10-элементный массив из 10-элементного массива char".В соответствии с вышеприведенным правилом это распространяется на тип "указатель на массив из 10 элементов char" или char (*)[10].

Помните, что в контексте объявления параметров функции T a[N] и T a[] идентичны T *a;таким образом, T a[][10] идентичен T (*a)[10].

...