2016-10-04 2 views
-5

Почему мы можем использовать только четыре оператора (+, -, ++, --) в указателе арифметики? Имеет ли он какое-либо отношение к встроенному оборудованию, поскольку он имеет дело с адресами?Почему мы можем использовать только четыре оператора (+, -, ++, -) в арифметике указателя?

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

+8

Какие другие операторы вы считаете имеющими смысл? – John3136

+0

@ John3136: честно говоря, что-то вроде 'ptr% 8' может быть действительно полезным. –

+0

@KeithThompson: Если вы знаете, что работает, 'int * p; ... uintptr_t boff = ((uintptr_t) p% 8); '. 'p% 8' может не иметь особого смысла для всех архитектур для всех делителей (например, сегмент: офсетные носители, такие как x86-16bit). – Olaf

ответ

1

Почему мы можем использовать только четыре оператора (+, -, ++, -) в арифметике указателя?

Потому что язык был построен таким образом. Наиболее распространенной операцией является итерация, которая, вероятно, является причиной того, что эти операторы разрешены.

Что касается обоснований того, почему язык C был разработан таким образом, его не так много найти. Я проверил обоснование C99 относительно арифметики указателя, но в основном он обеспокоен результатом переполнения арифметики указателя и не упоминает, почему/когда арифметика указателя имеет смысл.

Имеет ли какое-либо отношение к встроенному оборудованию, так как он имеет дело с адресами?

Нет, это не имеет никакого отношения к этому. Адреса - это просто цифры. Вы всегда можете указать любой указатель на uintptr_t, а затем использовать его как любое другое целое число.

+0

Адреса - это не просто цифры. Они могут быть реализованы таким образом в аппаратном обеспечении, но значение указателя C является значением указателя; указатели не являются арифметическими типами. Что касается обоснования, мне кажется достаточно ясным; это единственные операции, которые имеют смысл. –

+0

Для 'uintptr_t' гарантируется только кастинг от указателя и обратно ** к тому же типу **. Также гарантируется, что это целочисленный тип (без знака), поэтому он также может хранить целочисленное значение. Но если вы измените сохраненное значение указателя и преобразуете его обратно, ничто не будет определено стандартом. Это - строго говоря - неопределенное поведение. – Olaf

+0

@KeithThompson Существует множество операторов, которые имели бы смысл использовать адреса. '& | ~ 'для манипулирования или маскировки бит. '%' для проверки выравнивания указателя. И т. Д. Но из-за системы типов эти операторы должны иметь целые операнды, тип указателя не может быть использован. Единственное, что они достигли с этим ограничением, - сделать C менее полезным. – Lundin

-2

Вы можете использовать любой оператор, если результатом будет int. Например:

int A[10], i=5; 
int *p; 
p = A + (i/2); 
+0

'(1/2)' просто '0'. Вы не указали разделение указателей, вы просто добавили '0' к указателю. –

+0

@ Keith-Thompson, 1/2 ?? Я написал 'i/2', с' i', инициализированным до 5, давая 2, следовательно '& A [2]'. –

+0

Моя ошибка, я неправильно ее понял. Но моя точка зрения. '(i/2)' все еще просто целочисленное выражение, и все, что вы сделали, это добавить целое число в указатель, и результат не является 'int', что противоречит вашему первому предложению. Речь идет не об арифметических операциях с целыми числами, а о арифметических операциях над указателями. –

-2

Просто потому, что C был спроектирован таким образом. +, - может быть просто использован для добавления или вычитания двух указателей соответственно (значение только по адресу). Однако, с другой стороны, операторы увеличения и уменьшения, т.е. ++ и -, могут использоваться для увеличения или уменьшения указателя. Помните данные тип указателя играет важную роль в этих двух (++, -) операторах. Например, если вы задаете указатель типа * int, то ++ увеличит адрес памяти на 2 (поскольку размер int в большинстве компиляторов равно 2), и так же имеет место с оператором -, поскольку он уменьшит его на 2.

+1

'+' не может использоваться для добавления двух указателей. Вы можете добавить указатель на целое число или целое число на указатель. Добавление двух указателей не имеет смысла. Кроме того, вычитание двух указателей дает целое число, а не указатель. И тип указателя также влияет на поведение '+' и '-'. –

+0

Я хочу сказать, что переменную указателя можно использовать для добавления значений по этому адресу ... Например, можно добавить * p + * q, а это значит, что значения по адресам p и q могут быть добавлены + –

+0

. Это не относится к вопрос. '* p + * q' не является добавлением указателя; это просто целочисленное добавление (предполагая, что 'p' и' q' являются указателями на целые числа); аналогично, '* p/* q' не является делением указателя. –