Откуда происходит слово "разыменование"?
Этот вопрос будет черпать информацию из проекта N1570, поэтому C11 в основном.
В разговорной речи разыменование указателя означает применение одинарного *
оператор указателя. Есть только одно место, где слово "разыменование" существует в проекте документа (нет случая "разыменования"), и оно находится в сноске:
102) [...]
Среди недопустимых значений для разыменования указателя унарным
*
оператор - нулевой указатель, адрес неправильно выровнен для типа объекта, на который указывает объект, и адрес объекта после окончания срока его службы
Насколько я вижу, унарный *
оператор на самом деле называется "оператор косвенного обращения", что подтверждается §6.5.3.2:
6.5.3.2 Операторы адреса и косвенности
4
Одинарный*
Оператор обозначает косвенность. [...]
В то же время, он явно называется оператором косвенности в Приложении §J.2:
- Доступ к значению объекта осуществляется с помощью массива-индекса
[]
членский доступ.
или же−>
, адрес&
или косвенное*
оператор или указатель при создании адресной константы (6.6).
Так правильно ли говорить о "разыменовывающих указателях" в C или это чрезмерно педантично? Откуда взялась терминология? (Я могу дать проход []
будучи названным "уважением" из-за §6.5.2.1)
4 ответа
K&R v1
Если взглянуть на язык программирования C, в первом издании (1978) используется термин "косвенность".
Примеры
2.12 Приоритет и порядок оценки
[...]
В главе 5 обсуждаются * (косвенное направление) и & (адрес).
,
7.2 Унарные операторы
[...]
Унарный оператор * означает косвенность: выражение должно быть указателем, а результатом является l-значение, ссылающееся на объект, на который указывает выражение.
Он также указан в INDEX как, например,
* indirection operator 89, 187
Более длинный отрывок из раздела 5.1
5.1 Указатели и адреса
Поскольку указатель содержит адрес объекта, доступ к объекту возможен "косвенно" через указатель. Предположим, что
x
переменная, скажем,int
и чтоpx
это указатель, созданный каким-то еще неуказанным способом. Унарный оператор c дает адрес объекта, поэтому утверждениеpx = &x;
назначает адрес
x
к переменнойpx; px
теперь говорят "указать на"x
, Оператор & может применяться только к переменным и элементам массива; конструкции как&(x+1 )
а также&3
незаконны Также запрещено брать адрес регистровой переменной.Унарный оператор
*
обрабатывает свой операнд как адрес конечной цели и обращается к этому адресу для получения содержимого. Таким образом, еслиy
Алосint
,y = *px;
назначает
y
содержание чего угодноpx
указывает на. Итак, последовательностьpx = &x; y = *px;
присваивает y то же значение, что и
y = x;
K&R v2
Во втором издании термин разыменование вступает в силу.
5.1 Указатели и адреса
Унарный оператор * является оператором косвенного или разыменования; при применении к указателю он получает доступ к объекту, на который указывает указатель. Предположим, что x и y - целые числа, а ip - указатель на int. Эта искусственная последовательность показывает, как объявить указатель и как использовать & и *:
[...]
Предыдущее использование
Этот термин, однако ("намного") старше, как это видно, например, из
Обзор некоторых вопросов, касающихся абстрактных типов данных, 1974. Например, стр. 24/25. Здесь указано в связи с ALGOL 68, PASCAL, SIMULA 67.
Механизм, посредством которого указатели преобразуются в значения языком, известен как "разыменование", форма принуждения (будет обсуждаться позже). Рассмотрим утверждение
p := q;
В зависимости от типов p и q возможны несколько интерпретаций.
Пусть '@' - оператор разыменования (т. Е. Если p указывает на j, то @p совпадает с j), а '#' - ссылочная операция (т. Е. Если p указывает на j, то p совпадает с #j), В следующей таблице указаны возможные действия, которые может выполнить язык для выполнения назначения:
| | type of p | | t ref t ref ref t . . . | --------------------------------------------------------- | t | p←q p←#q p←##q | @p←q @p←#q | @@p←q type | of | q ref t | p←@q p←q p←#q | @p←@q @p←q | @@p←@q | | ref ref t | p←@@q p←@q p←q . | @p←@@q @p←@q . | @@p←@@q . | | |
[...]
Чеканка
Есть несколько других примеров его использования. Точно, где и когда это было придумано, я не могу найти, хотя (по крайней мере, пока). (Статья 1974 года, по крайней мере, интересна.)
Для удовольствия также часто бывает полезно посмотреть списки рассылки, такие как net.unix-wizards. Пример от Питера Лэмба из Мельбурнского университета (28.11.83):
Разыменование указателей NULL - это еще один пример идиотов, которые пишут "переносимый" код, предполагая, однако, что ИХ машина - единственная, на которой она когда-либо будет работать: те же самые люди, которые разработали cpio с двоичными заголовками. Даже на VAX разыменование NULL приведет к мусору: конечно, *(char *)NULL и *(short *)NULL вернут вам 0, но *(int *)NULL даст вам 1024528128!!!!.
[...]
Ed1. прибавление
Не упоминая "разыменование", но все же; Интересное чтение - Ричи: развитие языка Си ✝
Здесь также используется термин "косвенность" - но / и / и т.д. связь между языками несколько детальна. Таким образом, использование этого термина интересно, например, в работах, подобных упомянутой выше, 1974 года.
В качестве примера косвенного обращения как понятия и синтаксиса читайте, например, стр. 12 ev.
Случайность синтаксиса способствовала воспринимаемой сложности языка. Оператор косвенного обращения, записанный * в C, является синтаксически унарным префиксным оператором, так же как и в BCPL и B. Это хорошо работает в простых выражениях, но в более сложных случаях для управления синтаксическим анализом требуются скобки.
[...]
Есть два эффекта. Что наиболее важно, C имеет относительно богатый набор способов описания типов (по сравнению, скажем, с Pascal). Объявления на языках, таких же выразительных, как C - Algol 68, например, - описывают объекты, одинаково трудные для понимания, просто потому, что сами объекты являются сложными. Второй эффект обязан деталям синтаксиса. Объявления на С должны читаться в стиле "наизнанку", который многим трудно понять [Anderson 80].
В этом сочетании, вероятно, также стоит упомянуть ANSI C89 и упомянуть:
3.1.2.5 Типы
Указатель на void не может быть разыменован, хотя такой указатель может быть преобразован в обычный тип указателя, который может быть разыменован.
- Проект стандарта ANSI C (ANSI X3J11 / 88-090), (предоставлено Wikipedia)
- Обоснование американского национального стандарта для информационных систем - язык программирования - C
Среди недопустимых значений для разыменования указателя с помощью унарного оператора * есть нулевой указатель, адрес, неправильно выровненный для типа объекта, на который указывает объект, или адрес объекта, который имеет автоматическую продолжительность хранения при выполнении блока, в котором объект объявляется и всех вложенных блоков прекращается.
(Я должен перечитать некоторые из этих документов сейчас.)
Потому что в старые добрые времена K&R C язык передавал параметры только по значению. Таким образом, указатели использовались для имитации параметров передачи по ссылке. И люди (неправильно) говорили о получении ссылки на переменную для создания указателя на переменную.
И разыменование указателя было противоположной операцией.
Теперь C++ использует настоящие ссылки, отличные от указателей, но слово разыменование все еще используется (даже если оно не совсем правильно).
Керниган и Ричи, язык программирования Си, 2-е изд., 5.1:
Унарный оператор * является оператором косвенного или разыменования; [...] 'pointer to void''используется для хранения любого типа указателя, но не может быть разыменована сама.
Я не знаю точную этимологию, но можно рассматривать значение указателя (в общем смысле, а не специфичное для C/C++ значение) как "ссылку" на другой объект в памяти; то есть, p
относится к x
, Когда мы используем p
чтобы получить значение, хранящееся в x
, мы обходим эту ссылку или разыменование p
,