2011-06-27 3 views
5

Что это значит: что приращение указателя указывает на адрес следующего базового типа указателя?
Например:Инкремент указателя в C++

p1++; // p1 is a pointer to an int 

Означает ли это утверждение о том, что адрес, на который указывает p1 следует изменить на адрес следующего int или оно должно быть просто увеличивается на 2 (предполагая int 2 байта), в в каком случае конкретный адрес может не содержать int?
Я имею в виду, если p1 есть, скажем, 0x442012, будет p1++ be 0x442014 (который может быть частью адреса двойного) или он будет указывать на следующий int, который находится по адресу 0x44201F?

Благодаря

ответ

10

Арифметика указателя не заботится о содержании - или действительности - о точке зрения. Это будет просто увеличивать адрес указателя, используя следующую формулу: (. Предполагая, что указатель на непредставленных const - в противном случае бросок не будет работать)

new_value = reinterpret_cast<char*>(p) + sizeof(*p); 

То есть, это увеличит указатель на количество sizeof(*p) байт, независимо от того, как значение pointee и выравнивание памяти.

3

p1 ++ приводит к инструкции ассемблере которые прибавка p1 по размеру, что он указывает. Таким образом, вы получите

(char *)p1 = (char *)p1 + sizeof (object pointed to by p1)

(Когда этот вопрос был дан ответ) Типично ИНТ 4 байта, поэтому он будет увеличиваться на 4, но это зависит от SizeOf() на вашей машине.

Это не перейти к следующему int.

Пример: предположим, что 4-байтовый адрес и p1 = 0x20424 (где p1 - это int *). Тогда

p1++

бы установить новое значение p1 до 0x20428. НЕ 0x20425.

+1

p ++ означает p + = 1 –

+0

№ 'p1 ++' означает 'p1 + = 1', ничего больше. –

+0

@ Konrad: Ну, если вы не перегрузите оператор ++. Ах, радости переопределяют смысл операторов (и отличный способ сделать врагов) ;-) – Skizz

3

Компилятор добавит sizeof(int) (обычно 4) к числовому значению указателя. Если p1 равно 0x442012 до приращения, то после приращения будет 0x442012 + 4 = 0x442016.

Помните, что 0x442012 не является кратным 4, поэтому он вряд ли будет адресом действительного четырехбайтового int, хотя это было бы хорошо для двухбайтовых int.

Это, конечно же, не будет искать следующее целое число. Это потребует магии.

0

Арифметика указателя выполняется в sizoeof(*pointer) кратных - то есть для указателя на int приращение переходит к следующему целому числу (или 4 байтам для 32-битных целых чисел).

+0

«4 байта для 32-битного целого», ну, это не всегда так. Лучше сказать «(32/CHAR_BIT) байты в 32-битном целом» (с использованием определения байта на C++, конечно). Но опять же, кто говорит, что целые числа - 32 бит? – Skizz

+0

Вряд ли есть архитектуры с размером байта, отличным от 8 бит. Тип 'int' не обязательно 32 бита, но« 32-битное целое ». Я не вижу, чтобы вы указывали ... –

+0

Существует множество микроконтроллеров и DSP, которые имеют странные конфигурации (есть чип TI, где все типы - 16 бит). – Skizz

1

Если p1 указывает на элемент индекса n массива объектов типа int (объект не-массив имеет значение как массив длины 1 для этой цели), то после того, как p1++, p1 либо:

  • Указывает на элемент индекса n+1, если массив имеет длину больше n+1.
  • «Прошедший конец» адреса массива, если массив имеет длину точно n+1.

p1++ вызывает неопределенное поведение, если p1 не указывает на элемент массива объектов типа int.

Единственное значение, которое языки C и C++ дают понятию «адрес», - это значение объекта-указателя.

Любые отношения, которые понятие адреса C/C++ относится к понятию числовых адресов, которые вы рассмотрели на языке ассемблера, является чисто детальностью реализации (хотя и чрезвычайно общей деталью реализации).

Смежные вопросы