исключения случаев, когда это операнд из sizeof
или одинарных &
операторов, выражения типа «N
-элементного массива T
» будет преобразован («распад») к выражению типа «указатель на T
» , а значение выражения будет адресом первого элемента массива.
В строке
int *ptr=arr;
экспрессииarr
имеет тип "2-элемент массива 2-элемента массива int
" (IOW, T
"2-элемент массива int
"). Так как выражение arr
не является операндом либо sizeof
, либо унарных операторов &
, оно преобразуется («распады») в выражение типа «указатель на 2-элементный массив int
» или int (*)[2]
, а значение выражения является адресом первого элемента массива.
Вот почему вы получили предупреждение за выше линии, но не для
int (*ptr)[2]=arr;
, так как в этом случае типы совпадают правильно.
Учитывая заявление
int arr[2][2]={{6,2},{3,4}};
следующие все верно:
Expression Type Decays To Equivalent Value
---------- ---- --------- ----------------
arr int [2][2] int (*)[2] &arr[0][0]
&arr int (*)[2][2] &arr[0][0]
*arr int [2] int * &arr[0][0]
arr[i] int [2] int * &arr[i][0]
&arr[i] int (*)[2] &arr[i][0]
*arr[i] int arr[i][0]
arr[i][j] int
&arr[i][j] int *
Так arr
, &arr
, arr[0]
, &arr[0]
и &arr[0][0]
все оценки одной и той же значения (адрес первый элемент массива совпадает с адресом самого массива), но типов все разные.
Очень важный момент, который я хочу получить (особенно потому, что он показан в нескольких других ответах) состоит в том, что объекты массива не хранить любые значения указателя. Если посмотреть на содержимое arr
в памяти, вы увидите что-то вроде следующего:
+---+
arr: | 6 | arr[0][0]
+---+
| 2 | arr[0][1]
+---+
| 3 | arr[1][0]
+---+
| 4 | arr[1][1]
+---+
Нет хранения не установлен в стороне в любом месте для любых указателей. Когда ваш код скомпилирован, любые выражения, относящиеся к массивам, - , заменяют указателями на первый элемент массива.
Это то же самое, что разница между домом и кухней или между человеком и пальцем. –
Вот предупреждение для строки 'printf' во втором фрагменте, если вы его пропустили: **" check.c: 8: 17: warning: format указывает тип 'int', но аргумент имеет тип 'int *' [ -Wformat] "** – user3386109