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

Почему int указатель "++" увеличивается на 4, а не на 1?

Значение указателя - это адрес переменной. Почему значение int pointer увеличилось на 4 байта после того, как указатель int увеличился на 1.

По-моему, я думаю, что значение указателя (адрес переменной) увеличивается только на 1 байт после приращения указателя.

Тестовый код:

int a = 1, *ptr;
ptr = &a;
printf("0x%X\n", ptr);
ptr++;
printf("0x%X\n", ptr);

Ожидаемый результат:

0xBF8D63B8
0xBF8D63B9

Фактически вывод:

0xBF8D63B8
0xBF8D63BC

ИЗМЕНИТЬ

Другой вопрос - как побывать 4 байта a int занимает один за другим?

4b9b3361

Ответ 1

Когда вы увеличиваете значение T*, он перемещает sizeof(T) bytes. Это потому, что не имеет смысла перемещать любое другое значение: если я указываю на int что размером 4 байта, например, что будет увеличиваться менее чем на 4 байта? Частичное int, смешанное с некоторыми другими данными: бессмысленно.


Рассмотрим это в памяти:

    [↓      ]
[...|0 1 2 3|0 1 2 3|...]
[...|int    |int    |...]

Что имеет смысл, когда я увеличиваю этот указатель? Это:

            [↓      ]
[...|0 1 2 3|0 1 2 3|...]
[...|int    |int    |...]

Или это:

      [↓      ]
[...|0 1 2 3|0 1 2 3|...]
[...|int    |int    |...]

Последнее на самом деле не указывает любой тип int. (Технически, используя этот указатель UB.)

Если вы действительно хотите переместить один байт, увеличьте a char*: размер char всегда один:

int i = 0;
int* p = &i;

char* c = (char*)p;
char x = c[1]; // one byte into an int

† Следствием этого является то, что вы не можете увеличивать void*, потому что void является неполным типом.

Ответ 2

Приращение указателя основывается на размере указанного типа. Если int равно 4 байтам, приращение int * на 1 увеличит его значение на 4.

Если короткий - 2 байта, приращение короткого * на 1 увеличит его значение на 2.

Это стандартное поведение для арифметики C-указателя.

Ответ 3

Указатели увеличены на размер типа, на который они указывают, если указатель указывает на char, pointer++ будет увеличивать указатель на 1, если он указывает на структуру 1234 байта, pointer++ будет увеличивать указатель на 1234.

Это может запутать первый раз, когда вы его встречаете, но на самом деле это имеет большой смысл, это не особая функция процессора, но компилятор вычисляет ее во время компиляции, поэтому, когда вы пишете pointer+1, компилятор компилирует ее как pointer + sizeof(*pointer)

Ответ 4

Идея заключается в том, что после инкремента указатель указывает на следующий int в памяти. Поскольку ints имеет ширину 4 байта, он увеличивается на 4 байта. В общем случае указатель на тип T будет увеличиваться на sizeof (T)

Ответ 5

Как вы сказали, int pointer указывает на int. int обычно занимает 4 байта, поэтому, когда вы увеличиваете указатель, он указывает на "следующий" int в памяти, то есть увеличивается на 4 байта. Он действует таким образом для любого размера. Если у вас есть указатель на тип A, то приращение a A* будет увеличиваться на sizeof(A).

Подумайте об этом - если вы только увеличиваете указатель на 1 байт, то он будет указывать на середину int, и я не могу придумать, где это желательно.

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