Откуда происходит слово "разыменование"?

Этот вопрос будет черпать информацию из проекта 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 не может быть разыменован, хотя такой указатель может быть преобразован в обычный тип указателя, который может быть разыменован.

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

(Я должен перечитать некоторые из этих документов сейчас.)

Потому что в старые добрые времена K&R C язык передавал параметры только по значению. Таким образом, указатели использовались для имитации параметров передачи по ссылке. И люди (неправильно) говорили о получении ссылки на переменную для создания указателя на переменную.

И разыменование указателя было противоположной операцией.

Теперь C++ использует настоящие ссылки, отличные от указателей, но слово разыменование все еще используется (даже если оно не совсем правильно).

Керниган и Ричи, язык программирования Си, 2-е изд., 5.1:

Унарный оператор * является оператором косвенного или разыменования; [...] 'pointer to void''используется для хранения любого типа указателя, но не может быть разыменована сама.

Я не знаю точную этимологию, но можно рассматривать значение указателя (в общем смысле, а не специфичное для C/C++ значение) как "ссылку" на другой объект в памяти; то есть, p относится к x, Когда мы используем p чтобы получить значение, хранящееся в x, мы обходим эту ссылку или разыменование p,

Другие вопросы по тегам