printf("%p\n", arr);
printf("%p\n",*arr);
В первом примере arr
распадается на указатель на первый элемент в первом измерении двумерного массива arr
(первый массив int
из 5 элементов - тип (* 1005) *)) который также распадается на указатель на свой первый элемент, который a[0][0]
.
. Во втором примере вы явно обращаетесь к первому элементу первого измерения (тип int[5]
- int
массив из 5 элементов), и этот также распадается на указатель на свой первый элемент, который снова равен a[0][0]
.
Таким образом, оба результата имеют одинаковый результат - доступ и печать адреса первого элемента первого массива в первом измерении arr
- arr[0][0]
.
Примечание то, что вам нужно привести указатель к void
, чтобы программа C -стандарт-соответствовала, поскольку стандарт подразумевает, что спецификатор формата %p
должен иметь связанный аргумент типа void*
:
printf("%p\n", (void*) arr);
printf("%p\n", (void*) *arr);
Цитата из ISO: IEC 9899: 2018 (C18), раздел 7.21.6.1/8:
"p - Аргумент должен быть указателем на void . Значение указателя преобразуется в последовательность печатных символов способом, определяемым реализацией. "