Как компилятор знает, как увеличивать разные указатели?

Я понимаю, что в целом указатели на любой тип данных будут иметь одинаковый размер. В 16-битной системе обычно 2 байта, а в 32-битной системе - 4 байта.

В зависимости от того, на что указывает этот указатель, если он увеличивается, он будет увеличиваться на другое количество байтов в зависимости от того, является ли это указателем char, длинным указателем и т. Д.

Мой вопрос заключается в том, как компилятор узнает, на сколько байтов нужно увеличить этот указатель. Разве это не просто переменная, хранящаяся в памяти, как и любая другая? Хранятся ли указатели в какой-либо таблице символов с информацией о том, на сколько они должны быть увеличены? Спасибо


person Engineer999    schedule 22.04.2016    source источник
comment
C строго типизирован, размер типа должен быть известен во время компиляции. Когда размер известен, компилятор знает, как это сделать.   -  person user3528438    schedule 22.04.2016
comment
РЖУ НЕ МОГУ! 'C строго типизирован'   -  person Martin James    schedule 22.04.2016
comment
@MartinJames Что? Что ты хочешь сказать? Вы хоть представляете, сколько клавиатур (клавиш) я потерял при написании кода C? :П   -  person Sourav Ghosh    schedule 22.04.2016
comment
Вот почему у вас есть разные типы указателей int *, char * и так далее, а не один тип pointer или что-то в этом роде.   -  person farhanhubble    schedule 22.04.2016
comment
@MartinJames stackoverflow.com/questions/430182/is-c-strongly-typed   -  person M.M    schedule 24.11.2016


Ответы (3)


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

Чтобы добавить к этому, чтобы арифметические операции с указателями выполнялись, указатели должны быть (цитируются из стандарта c11)

указатель на полный тип объекта

Итак, размер «объекта», на который указывает указатель, известен и определен.

Сноска: FWIW, поэтому арифметика указателей на недействительные указатели (неполный тип) не разрешена / не определена в стандарте. (Хотя GCC поддерживает арифметику с недействительными указателями через расширение .)

person Sourav Ghosh    schedule 22.04.2016

Re

Я понимаю, что в целом указатели на любой тип данных будут иметь одинаковый размер.

Нет. Различные размеры указателей необычны для простых указателей на объекты, но могут встречаться на машинах с адресной адресацией слов. Тогда char* - самый большой указатель, а void* - того же размера.

C++14 §3.9.2/4

Объект типа cv void* должен иметь те же требования к представлению и выравниванию, что и cv char*.

Однако все указатели на объект типа класса имеют одинаковый размер. Например, вы не смогли бы использовать массив указателей на базовый тип, если бы это было не так.


Re

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

Он знает размер указанного типа объекта.

Если ему неизвестен размер указанного объекта, т.е. этот тип неполный, вы не можете увеличить указатель.

Например, если p - это void*, то вы не можете сделать ++p.

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

person Cheers and hth. - Alf    schedule 22.04.2016

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

например: 1) при увеличении указателя символа указатель увеличивается на 1 байт. 2) Аналогично, для целочисленного указателя указатель увеличивается на 4 байта (для 32-разрядной системы) и 8 байтов (для 64-разрядной системы).

person Rjain    schedule 22.04.2016
comment
Поскольку данные (char или int) будут храниться в другом сегменте памяти по сравнению с кодом, как код узнает, каким образом увеличивать переменную или указатель? Хранятся ли переменные в таблице символов? - person Engineer999; 22.04.2016
comment
Переменные сохраняются либо в стеке (локальные переменные), либо в сегменте данных (глобальные переменные), тип данных не имеет ничего общего с сегментом, в котором они должны быть сохранены 2) Таблица символов содержит только ссылки на функцию, а не переменные - person Rjain; 22.04.2016
comment
Когда мы говорим об указателях, мы имеем в виду адреса в памяти. когда вы объявляете указатель на переменную, ваш указатель теперь указывает на эту ячейку памяти. Всякий раз, когда вы увеличиваете или уменьшаете указатель, он будет выполнять операции с этой ячейкой памяти. - person Rjain; 22.04.2016