Это:
int a[4][2];
определен a
массив из 4 элементов, каждый из которых представляет собой массив из 2 int
элементов. (2-мерный массив не больше или меньше массива массивов.)
Выражение массива в большинстве контекстов неявно преобразуется в указатель на исходный (нулевой) элемент объекта массива. (Обратите внимание на предположение о том, что существует массив объект, что вызвало некоторую тоску, но это не имеет значения здесь.)
случаев, когда выражение массива является не преобразуется в указатель является:
- Когда это операнд
sizeof
;
- Когда это операнд унарного
&
; и
- Когда это строковый литерал в инициализаторе, используемом для инициализации объекта массива.
(Compiler специфические расширения, такие как ССЗ typeof
может создать больше исключений.)
Таким образом, в выражении *a
, подвыражение a
(который имеет тип int[4][2]
) неявно преобразуется в указатель типа int(*)[2]
(указатель на массив из 2 int
s).Применяем унарные *
разыменования этого указателя, давая нам выражение типа int[2]
.
Но мы не довольно сделано еще. *a
также является выражением типа массива, что означает, что в зависимости от того, как он используется, он будет , вероятно, снова преобразован в указатель, на этот раз типа int*
.
Если записать sizeof *a
, Подвыражение a
преобразуется из int[4][2]
в int(*)[2]
, но Подвыражение *a
является не преобразуются из int[2]
в int*
, так что выражение дает размер типа int[2]
.
Если мы напишем **a
, произойдет преобразование . *a
имеет тип int[2]
, который преобразуется в int*
; разыменование, которое дает выражение типа int
.
Обратите внимание, что, несмотря на то, что мы можем законно сослаться на **a
, используя две операции указателя разыменования, нет указателя объектов. a
- объект массива, состоящий целиком из 8 int
объектов. Неявные преобразования дают указатель значения.
правило преобразования Неявного массив в-указателя в N1570 разделе пункта 6.3.2.1 3. (Этот пункт неправильно дает _Alignof
в качестве четвертого исключения, но _Alignof
не может быть применена к выражению. Опубликованная стандарт C11 исправлена ошибка .)
Рекомендуемое чтение: Раздел 6 раздела comp.lang.c FAQ.
Нет указателя на массив. Массив не является указателем. «Тогда' a' внутренне преобразован в указатель первого элемента массива из 4 элементов из 2-х целых чисел ». просто неправильно! – Olaf
@Olaf Что вы имеете в виду, нет указателя на массив? Разве это не означает (int (* x) [4] [2]), что x является указателем на массив из 4 элементов из 2 ints? – Jin
Где это появляется в вашем вопросе ?? Если вы прочтете комментарий до конца и поняли ответы, это должно быть ясно. 'a' - массив, а не указатель! И это само по себе «не превращается в указатель». Почему так сложно для новичков понять, что разные синтаксисы генерируют разные типы? – Olaf