Различные арифметические значения указателя при приеме адреса массива
Программа:
#include<stdio.h>
int main(void) {
int x[4];
printf("%p\n", x);
printf("%p\n", x + 1);
printf("%p\n", &x);
printf("%p\n", &x + 1);
}
Вывод:
$ ./a.out
0xbff93510
0xbff93514
0xbff93510
0xbff93520
$
Я ожидаю, что выйдет следующая версия программы. Например:
x // 0x100
x+1 // 0x104 Because x is an integer array
&x // 0x100 Address of array
&x+1 // 0x104
Но результат последнего утверждения отличается от ожидаемого. &x
также является адресом массива. Таким образом, увеличивая 1 на этом
будет печатать адрес, увеличенный на 4. Но &x+1
указывает адрес, увеличиваемый на 10. Почему?
Ответы
Ответ 1
x -> Points to the first element of the array.
&x ->Points to the entire array.
Набросилось на описательное объяснение здесь: http://arjunsreedharan.org/post/69303442896/the-difference-between-arr-and-arr-how-to-find
Ссылка SO: Почему arr и & arr то же самое?
Ответ 2
В случае 4 вы получаете 0x100 + sizeof x
и sizeof x
равно 4 * sizeof int
= 4 * 4 = 16 = 0x10.
(В вашей системе sizeof int
равно 4).
Ответ 3
Легкий thumbrule для оценки:
Любой указатель на приращение указывает на следующее расположение памяти своего базового типа .
Базовый тип & x здесь int (* p) [4], который является указателем на массив из 4 целых чисел.
Итак, следующий указатель этого типа будет указывать на 16 байтов (предполагая, что int будет 4 байта) из исходного массива.
Ответ 4
Даже если x
и &x
оценивают одно и то же значение указателя, это разные типы. Тип x
после того, как он распадается на указатель, равен int*
, тогда как тип &x
равен int (*)[4]
.
sizeof(x)
sizeof(int)*4
.
Следовательно, численное различие между &x
и &x + 1
составляет sizeof(int)*4
.
Его можно лучше визуализировать с помощью 2D-массива. Скажем, у вас есть:
int array[2][4];
Макет памяти для array
:
array
|
+---+---+---+---+---+---+---+---+
| | | | | | | | |
+---+---+---+---+---+---+---+---+
array[0] array[1]
| |
+---+---+---+---+---+---+---+---+
| | | | | | | | |
+---+---+---+---+---+---+---+---+
Если вы используете указатель на такой массив,
int (*ptr)[4] = array;
и посмотрите на память через указатель, это выглядит так:
ptr ptr+1
| |
+---+---+---+---+---+---+---+---+
| | | | | | | | |
+---+---+---+---+---+---+---+---+
Как вы можете видеть, разница между ptr
и ptr+1
равна sizeof(int)*4
. Эта аналогия применяется к разнице между &x
и &x + 1
в вашем коде.
Ответ 5
Верьте или нет, поведение вашей программы undefined!
&x + 1
на самом деле указывает только на массив, так как @i486 ответ искусно указывает. Вы не владеете этой памятью. Даже попытка назначить указатель на него - это поведение undefined, не говоря уже о попытке разыменовать его.