Почему указатель int '++' увеличивается на 4, а не на 1? - PullRequest
40 голосов
/ 10 апреля 2011

Значение указателя является адресом переменной.Почему значение 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 занимает один за другим?

Ответы [ 6 ]

97 голосов
/ 10 апреля 2011

Когда вы увеличиваете 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 является неполным типом.

8 голосов
/ 10 апреля 2011

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

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

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

2 голосов
/ 10 апреля 2011

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

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

1 голос
/ 10 апреля 2011

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

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

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

1 голос
/ 10 апреля 2011

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

0 голосов
/ 14 марта 2019

Указатель указывает на НАЧАЛО чего-то в памяти.INT занимает 4 байта (32 бита), а DOUBLE занимает 8 байтов (64 бита) в памяти.Так что, если у вас есть номер DOUBLE, и вы хотите на очень низком уровне указывать на следующую доступную ячейку памяти, указатель может быть увеличен на 8 байт.Если по какой-то причине вы указали +4 байта от начала значения DOUBLE, вы бы испортили его значение.Память - это очень большое плоское поле, которое не имеет совести само по себе, поэтому программное обеспечение должно правильно разделить его и «уважать границы» элементов, расположенных в этом поле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...