повышение :: григорианский :: даты

Я попробовал следующее объяснение, но не уверен, является ли это «правильным» объяснением.

Не совсем, но он несколько близок.

t содержит адрес A[0], но поскольку A является массивом, а A[0] является указателем на массив

A[0] является массивом , в частности, его тип - int[4].

(который является «не совсем» указателем), C не выделяет память для указателя A или A[0] специально НЕОБХОДИМО другие переменные указателя.

Массивы и указатели представляют собой принципиально разные типы объектов. Не путайте их.

Тот факт, что в большинстве случаев выражение типа array of T преобразуется в значение типа pointer to T (указывающее на первый элемент массива), несомненно, способствует путанице, но нельзя забывать, что это преобразование . В частности, для многомерных массивов или массивов массивов тип элемента массива сам по себе является типом массива, поэтому результат преобразования является указателем на массив.

It выделяет память только для массива в целом. Таким образом, адрес A[0] и A[0] (который является адресом A[0][0]), по сути, один и тот же,

Нет, они существенно отличаются друг от друга, один - A[0] - это массив, int[4], другой - &A[0] - указатель на массив из четырех int, int(*)[4]. Также &A[0][0].

Но когда A[0] преобразуется в указатель на его первый элемент, &A[0][0], результирующий адрес обычно совпадает с адресом A[0] (обычно, a указатель на объект содержит адрес байта с наименьшим адресом, принадлежащим этому объекту, и поскольку A[0] принадлежит (является частью) объекта A, тот, у которого самый младший адрес, первый байт, который является частью A[0] является первым байтом, который является частью A).

Итак, &A[0] и &A[0][0] обычно имеют одно и то же представление, но одно - int(*)[4], другое - [int*.

оба принадлежат под одной крышей и не являются «отдельными» сущностями. В результате t в свою очередь косвенно удерживает адрес A[0][0] и *t, дает значение A[0][0], которое равно 1.

Эта часть, кроме несоответствие типа, которое делает разыменование t неопределенным поведением более или менее правильным. Формально неопределенное поведение допускает что-либо.

На практике, если sizeof(int) == sizeof(int*), разыменование t интерпретирует int 1, который является A[0][0] в качестве адреса, и если вы печатаете это как int (еще одно неопределенное поведение), вы получите 1. Если sizeof(int*) == 2*sizeof(int), как это обычно бывает в 64-битных системах, разыменование t обычно интерпретирует два int s A[0][0] и A[0][1] вместе как адрес - 0x200000001 или 0x100000002 в зависимости от того, .

1
задан foke 14 September 2010 в 19:32
поделиться