Почему указатель 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 байта int занимает один за другим?

5 ответов

Решение

Когда вы увеличиваете T*, он движется sizeof(T) байт. Это потому, что не имеет смысла перемещать любое другое значение: если я указываю на 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.)

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

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

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

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

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

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

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

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

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

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

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

Такое поведение очень удобно, например, при переборе массива.

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

A pointer points at the BEGINNING of something in memory. An INT occupies 4 bytes (32bit) and a DOUBLE occupies 8 bytes (64bit) in memory. So if you have a DOUBLE number stored, and you wish at a very low level pointing to the next available memory location, the pointer wooud be increased by 8 bytes. If for some reason you pointed at +4bytes from the start of a DOUBLE value, you would corrupt it's value. Memory is a very large flat field that has no conscience of itself, so it's up to the software to divides it properly and to "respect the borders" of items located in that field.

Другие вопросы по тегам