Два имеют одинаковое значение, но разные типы.
Когда он используется сам по себе (не операнд &
или sizeof
), arr
вычисляет указатель на int
, содержащий адрес первого int
в массиве.
&arr
вычисляет указатель на массив из трех int
s, содержащий адрес массива. Поскольку первый int
в массиве должен находиться в самом начале массива, эти адреса должны быть равны.
Разница между ними становится очевидной, если вы подсчитаете результаты:
arr+1
будет равно arr + sizeof(int)
.
((&arr) + 1)
будет равен arr + sizeof(arr)
== arr + sizeof(int) * 3
Редактировать: Относительно того, как / почему это происходит, ответ довольно прост: потому что стандарт говорит так. В частности, говорится (§6.3.2.1 / 3):
За исключением случаев, когда он является операндом оператора sizeof или унарного оператора &, или является
строковый литерал, используемый для инициализации массива; выражение, имеющее тип '' массив типа '', преобразуется в выражение с типом '' указатель на тип '', которое указывает на начальный элемент объекта массива и не является lvalue.
[примечание: эта конкретная цитата взята из стандарта C99, но я считаю, что во всех версиях стандартов C и C ++ есть эквивалентный язык].
В первом случае (сам по себе * 1034) arr
не используется в качестве операнда sizeof, унарного & и т. Д., Поэтому он преобразуется (не повышается) в тип «указатель на тип» (в данном случае «указатель на int»).
Во втором случае (&arr
) очевидно, что имя является , используемым в качестве операнда унарного оператора &
- так что преобразование не имеет место .