Подтвердить что ты не робот

Различные арифметические значения указателя при приеме адреса массива

Программа:

#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. Почему?

4b9b3361

Ответ 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, не говоря уже о попытке разыменовать его.