2010-04-09 4 views
4

У меня есть два указателя,символов указателей и целых указателей (++)

char *str1; 
int *str2; 

Если я смотрю на размер обоих указателей давайте предположим

str1=4 bytes 
str2=4 bytes 

str1 ++ будет увеличиваться на 1 байт, но если str2 ++ будет увеличивать 4 байта.

Какова концепция этого?

+4

Если вы хотите узнать «размер шага» указателя, вы хотите сделать sizeof (* p), а не sizeof (p). –

+0

Ну, собственно, в моем ответе я рассказал вам всю концепцию, стоящую за ней, и вы приняли самый основной ответ ... xD – Cipi

+0

Шар занимает 1 байт в памяти, поэтому ptrchar ++ будет перемещать 1 память вперед. а целое число занимает 4 байта в памяти. поэтому следующий ptrinteger ++ будет перемещать 4 байта. Аналогично, скажем, float занимает 8 байтов, поэтому floatptr ++ wil перемещает float ptr в 8 байтов. – samprat

ответ

16

Простой, в предоставленном сценарию:

  • символ является 1 байт длиной
  • Int (в вашей платформы) имеет длину 4 байта

увеличивает Оператор ++ указатель по размеру остроконечного типа.

+1

Если int равно 4 байтам, то это просто происходит на его платформе/компиляторе. -1, потому что вы не прояснили платформу-зависимость от этого. –

+1

В сценарии, предоставляемом OP, можно четко видеть, что тип int имеет длину 4 байта. Я не счел нужным подробно останавливаться на том, имеют ли другие платформы/архитектуры по-разному размеры по определению, потому что он попросил объяснить инкрементный оператор, а не сам int. – jweyrich

+1

Просто добавил явное утверждение, что оно связано с предоставленным сценарием. Спасибо @ Джон. – jweyrich

1

Подсказка: p[i] является сокращением на *(p + i).

3

Указатель содержит адрес ячейки памяти, который равен 4 байтам. str1 указывает на местоположение, которое содержит 1 байт, поэтому, если вы увеличиваете адрес str1, он переходит к следующему адресу из 1 байта данных. Но в другом случае str2 указывает на данные в 4 байта, поэтому, если вы увеличиваете этот адрес, он должен перепрыгнуть через эти данные, чтобы перейти к следующим 4-байтным данным, поэтому он увеличивает на 4.

Это как 1 байтовая последовательность данные хранятся в Memmory:

ADDRESS:   FF334400 FF334401 FF334402 FF334403 
DATA (1BYTE):   1   2   3   4 

Так что, если str1 хочет, чтобы указать на номер 2, он должен иметь свой адрес, который FF334401. Если увеличить str1, он должен перепрыгнуть через 2s адрес и получить до 3, и делать, что он должен быть увеличен на 1.

В другом случае:

ADDRESS:   FF334400 FF334401 FF334402 FF334403 FF334404 ... FF334407 
DATA (4BYTE):   0   0   0   1  0   2 

Теперь если Str2 пунктов к числу 1, который является целым числом, и он действителен, это 4 байта данных, он указывает на начало этих данных, который является адресом FF334400. Когда вы увеличиваете его, он должен перепрыгнуть через все 4 байта данных 1s, чтобы получить данные 2s, поэтому он увеличивается на 4, а его адрес становится FF334404, который является первым байтом данных 4 байта номера 2.

9

При выполнении арифметики на указателе она всегда относится к объектам, на которые указывает, а не в байтах.

Значит, указатель, целевой объект которого является, например, четыре байта, увеличит его фактическое числовое значение на четыре, когда вы его добавите.

Это гораздо удобнее и имеет гораздо больший смысл, чем все арифметические указатели в байтах.

4

A char 1 байт, int (обычно) 4 байта. Когда вы увеличиваете указатель, вы увеличиваете размер указателей на данные. Итак, когда вы увеличиваете char*, вы увеличиваете на 1 байт, но когда вы увеличиваете int*, вы увеличиваете 4 байта.

+0

+1 для "int is (* обычно *) 4 байта" –

0

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

Рассмотрим массив и указатель на целое число в этом массиве:

int p[10]; 
int *q = p; 

Тогда * (д + 1) такая же, как р [1], то есть следующий int в памяти. Было бы гораздо менее полезно, если бы он просто указал один байт вперед.

0

Приращение указателя всегда увеличивает адрес, на который указывает его размер, представленный им. Таким образом, для указателя char он увеличивается на 1 и для целых чисел на 4. Но для самой переменной указателя потребуется 4 байта для хранения адреса.

Вы можете задуматься о том, как работает индексация массива. Инка целочисленного массива a [0] укажет на первый элемент, а [1] укажет на второй. В этом случае для приращения 1 он должен увеличиваться на 4 байта для доступа к следующему целому. В случае символов это должно быть 1. То же самое понятие работает для всех указателей арифметики.

0

Простой. Это зависит от компилятора.

Если int имеет 4 байта размера при добавлении 1 к его указателю, он добавит к нему свой размер, то есть для и если int имеет 2 байта, то он добавит 2, размер которого в указатель , Например, в Turbo C++

int *str = NULL; 
str + 1; //It will add 2 as Turbo C++ has int size 2 bytes 

В Visual C++, ул + 1; // Он добавит 4, поскольку Visual C++ имеет размер int 4 байта.

И то же самое имеет место с символом.

0

Это согласно указателю арифметики. Вот оно.

Как вы сказали, память, выделенная для всех указателей, одинакова. Но когда вы используете оператор инкремента с переменной-указателем, это означает, что указатель должен быть сделан, чтобы указать (приращение) на следующее место в памяти.

Итак, если вы используете указатель на символ, то если вы увеличиваете, вы должны указать на следующий символ шириной в один байт. Аналогичным образом, если вы хотите увеличить указатель целых чисел, то это похоже на то, что он указывает на следующее целое число, ширина которого составляет четыре байта.

Я думаю, что этого достаточно, чтобы уточнить ваш вопрос :)

0

Указателя является абстракцией, которая позволяет ссылаться на данные в памяти, так что сырьевая память доступна как атомная единица, чтобы убедиться, что он интерпретируется соответствующим образом для данного типа выбран.

Указатель сам по себе представляет собой размер машинного слова. В вашем примере у вас есть два указателя на разные типы, но они все еще являются указателями на адреса в памяти, и поэтому они одинакового размера. Как упоминалось в других ответах, чтобы получить размер типа данных, на который указывает указатель, вы должны разыменовать его в операции sizeof, например. SizeOf (* р).

Оператор ++ позволяет получить указатель, который ссылается на следующий адрес в памяти для соответствующего типа. Если он просто увеличил адрес на один байт для всех типов, вы могли бы получить адрес в памяти, который указывает на середину представления данных.

, например.для двух беззнаковых 4-байтовых целых чисел, представляющих десятичные значения 1 и 4 278 190 080 соответственно, начиная с адреса 0x00 в памяти (обратите внимание, что адрес здесь просто для иллюстрации и не представляет реальной системы, так как ОС резервирует их для своих целей)

address       0x00 0x01 0x02 0x03 | 0x04 0x05 0x06 0x07 
data value (4 byte integer)  0x00 0x00 0x00 0x01 | 0xFF 0x00 0x00 0x00 

Если указатель на целое число имеет ссылку для решения 0x00 и оператор ++ только увеличивается адрес указателя на 1 байт, то будет иметь указатель для решения 0x01, который, если вы тогда доступ этот адрес (плюс последующие 3 байты) в качестве целого числа вы получили бы целое число, представляемое байтами данных 0x00 0x00 0x01 плюс значение адреса 0x04, которое в этом случае является значением 0xFF. Это приведет к целому числу с десятичным значением 511, которое не представляет ни одно из двух целых чисел, хранящихся в памяти.

Для правильного доступа к следующему целому числу в памяти оператор ++ должен увеличивать байтовый адрес указателя на 4 байта.

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