Массив фактически является объемом памяти. Таким образом, адрес экстента - это адрес сохраненного массива в этом экстенте и его первого элемента.
В результате указатель массива, используемый в выражениях с редкими исключениями, преобразуется в указатель на его первый элемент.
Используя предоставленный вами пример
int arr[5] = { 1, 2, 3, 4, 5 };
эти выражения &arr
и &arr[0]
имеют одинаковые значения, но имеют разные типы.
Выражение &arr
имеет тип int( * )[5]
, в то время как выражение &a[0]
имеет тип int *
.
Вот демонстрационная программа.
#include <stdio.h>
int main(void)
{
int arr[5] = { 1, 2, 3, 4, 5 };
printf( "&arr == &arr[0] is %s\n",
( void * )&arr == ( void * )&arr[0] ? "true" : "false" );
printf( "sizeof( *&arr ) = %zu\n", sizeof( *&arr ) );
printf( "sizeof( *&arr[0] ) = %zu\n", sizeof( *&arr[0] ) );
return 0;
}
Его вывод
&arr == &arr[0] is true
sizeof( *&arr ) = 20
sizeof( *&arr[0] ) = 4