Почему указатель 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.