Почему p и * p дают тот же адрес, когда p указывает на массив?

Я писал эту программу –

#include void main() { int arr[20]; arr[0]=22; arr[1]=23; int (*p)[20]=&arr; printf("address in p :%u:\n",p); printf("address in *p:%u:\n",*p); } 

Вывод этого кода одинаковый для p и * p! Насколько я знаю, p держит базовый адрес arr, который является не чем иным, как arr [0] !!! Таким образом, * p должен дать результат 22! Но он показывает тот же адрес памяти, что и p. Скажите, пожалуйста, почему это произошло? В чем причина этого.
Ссылка сайта Codepad: http://codepad.org/LK7qXaqt

p – указатель на массив из 20 целых чисел. Адрес первого байта массива называется адресом массива. Разыменовывая это, он даст весь массив. Поэтому *p представляет массив arr , поэтому вы можете думать о *p как имя массива.
Поскольку имена массивов преобразуются в указатели на первый элемент при передаче функции, *p распадается на указатель на первый элемент arr . Следовательно

 printf("address in *p: %p:\n", (void*)*p); 

будет печатать адрес первого элемента массива arr while

 printf("address in p: %p:\n", (void*)p); 

будет печатать адрес всего массива (т.е. первый байт массива). Поскольку значение первого байта и первого элемента одинаково, поэтому оба печатают один и тот же адрес.

Подробное объяснение: переполнение стека http://cdn.sstatic.net/stackoverflow/img/favicon.ico Что такое имя массива в c?

Поскольку p и * p указывают на одно и то же место памяти, только типы различны

  +-+-+-+-+-+-+-+-+-+-+-+-+ | | | | | | | | | | | | | +-+-+-+-+-+-+-+-+-+-+-+-+ arr [ ] p [ ] (*p)[ ] 

Если вы печатаете p+1 и *p + 1 вы должны увидеть разницу

int (*p)[20] объявляет p как указатель на массив размера 20 типа int, поэтому в то же время *p является указателем на первый элемент массива.

Адрес первого элемента и целого массива будет таким же.

Да, можно применить оператор адреса к массиву, хотя он кажется излишним. Результат p является указателем на массив. Такая ситуация при обычных обстоятельствах редко встречается. Как правильно заметил @Mohit, объектом, на который он указывает, является весь массив, что означает, что sizeof (* p) должен быть размером массива (а не его первого элемента).

* p логически является массивом; как обычно, он распадается на указатель на его первый элемент (который является int) при передаче в качестве аргумента, например, printf. Поскольку это первый элемент, его расположение в памяти – это местоположение (начало) всего массива.