Почему ошибка компиляции присваивает адрес массива указателю "my_pointer = & my_array"?
int my_array[5] = {0};
int *my_pointer = 0;
my_pointer = &my_array // compiler error
my_pointer = my_array // ok
Если my_array
- адрес массива, то что мне дает &my_array
?
Ответы
Ответ 1
my_array
- это имя массива из 5 целых чисел. Компилятор с радостью преобразует его в указатель на одно целое.
&my_array
- это указатель на массив из 5 целых чисел. Компилятор не будет рассматривать массив целых чисел как одно целое, поэтому он отказывается делать преобразование.
Ответ 2
&my_array
- это адрес, в котором хранится значение my_array
, то есть оно является адресом адреса массива и имеет тип int**
.
Ответ 3
Это была бы увлекательная тема для исследований нейронауки, семантики и разработки программного обеспечения. Хотя мы можем объяснить разницу между my_array и my_array, и хотя мы можем повторять мантру, что "массивы являются (или нет) указателями", это различие все еще запутывается.
Обычно, когда мы берем адрес чего-то с "&" мы получаем совершенно другое значение.
int x;
x=5;
cout <<x << " "<<&x<<endl;
Прежде всего, бросьте вызов этой интуиции. Указатель может быть случайно равен значению, на которое он указывает:
int* x;
x=(int*)(&x);
cout <<"same: "<<x << " "<<&x<<endl;
Поэтому в некоторых контекстах семантически разные вещи могут оценивать одно и то же. Но только потому, что два выражения равны в текущем контексте, это не означает, что они взаимозаменяемы.
int w=3;
int* ip=&w;
void* vp=&w;
cout <<"Equal: "<<ip<<" "<<vp<<" "<<(ip==vp)<<endl;
cout <<"But not interchangeable: "<<ip+1<<" "<<vp+1<<" "<<(ip+1==vp+1)<<endl;
То же самое происходит с указателями на массивы. Указатель на массив часто технически "равен" самому массиву, но поскольку они имеют разную семантику, бывают ситуации, когда они не взаимозаменяемы. Попробуйте следующее:
int my_array[5] = {5,6,7,8,9};
cout <<my_array[0]<<endl; // output 5
cout <<(&my_array)[0]<<endl; // outputs the address of the first element
cout <<sizeof my_array[0]<<endl; // outputs 4
cout <<sizeof (&my_array)[0]<<endl; // outputs 20