“解除引用”这个词来自哪里?
这个问题将从N1570草案中提取信息 ,所以基本上是C11。
通俗地说,取消引用指针意味着将一元*
运算符应用于指针。 草案文件中只有一个“解除引用”一词的地方(没有“解除引用”的例子),它在脚注中:
102)[…]
用于通过一元
*
运算符解除引用指针的无效值包括空指针,为指向的对象类型不恰当地对齐的地址,以及对象在其生命周期结束后的地址
据我所知,一元*
运算符实际上被称为“间接运算符”,如§6.5.3.2所示:
6.5.3.2地址和间接运营商
4
一元*
运算符表示间接。 […]
同时,它在附件§J.2中被明确地称为间接运算符:
– 对象的值由array-subscript
[]
,member-access访问.
或−>
,地址&
或间接*
运算符或在创建地址常量(6.6)时强制转换的指针。
那么在C中谈论“解除引用指针”是否正确或者这是否过于迂腐? 术语来自哪里? (由于§6.5.2.1,我可以给[]
传递称为“引用”
K&R v1
如果看一下C编程语言 ,在第一版(1978)中,使用术语“间接” 。
例子
2.12优先顺序和评估顺序
[…]
第5章讨论*(间接)和&(地址)。
,
7.2一元运营商
[…]
一元*运算符意味着间接:表达式必须是指针,结果是一个左值,引用表达式指向的对象。
它也在INDEX中列为例如
* indirection operator 89, 187
5.1节的更长摘录
5.1指针和地址
由于指针包含对象的地址,因此可以通过指针“间接”访问对象。 假设
x
是一个变量,比如一个int
,并且px
是一个指针,以某种尚未指定的方式创建。 一元运算符c给出一个对象的地址 ,所以声明px = &x;
将
x
的地址分配给变量px; px
px; px
现在被称为“指向”x
。 &运算符只能应用于变量和数组元素; 像&(x+1 )
和&3
是非法的。 获取寄存器变量的地址也是非法的。一元运算符
*
将其操作数视为最终目标之外的地址,并访问该地址以获取内容。 因此,如果y
是alos一个int
,y = *px;
指定任何
px
指向的内容。 所以顺序px = &x; y = *px;
为y指定相同的值
y = x;
K&R v2
在第二版中, 解除引用一词就出现了。
5.1指针和地址
一元运算符*是间接或解除引用运算符 ; 当应用于指针时,它访问指针指向的对象。 假设x和y是整数,ip是指向int的指针。 这个人工序列显示了如何声明指针以及如何使用&和*:
[…]
事先使用
然而,该术语( “很多” )较旧,如在例如中可见
关于抽象数据类型的一些问题的调查 ,1974年。例如pp24 / 25。 这里与ALGOL 68,PASCAL,SIMULA 67有关。
通过语言将指针转换为值的机制称为“解除引用”,一种强制forms(稍后讨论)。 考虑一下这句话
p := q;
根据p和q的类型,有几种可能的解释。
设’@’为解除引用运算符(即如果p指向j,则@p与j相同),’#’为引用运算(即,如果p指向j,则p与#j相同) 。 下表显示了语言执行分配可能采取的操作:
| | type of p | | t ref t ref ref t . . . | --------------------------------------------------------- | t | p←qp←#qp←##q | @p←q @p←#q | @@p←q type | of | q ref t | p←@qp←qp←#q | @p←@q @p←q | @@p←@q | | ref ref t | p←@@qp←@qp←q . | @p←@@q @p←@q . | @@p←@@q . | | |
[…]
铸币
还有其他一些使用示例。 究竟在何时何地创造,我无法找到(至少还没有)。 (1974年的论文至少很有趣。)
为了它的乐趣,查看诸如net.unix-wizards之类的邮件列表通常也很有用。 墨尔本大学Peter Lamb的一个例子 (11/28/83) :
取消引用NULL指针是编写“可移植”代码的白痴的另一个例子,但是假设他们的机器是唯一可以运行的机器:使用二进制头设计cpio的同类人。 即使在VAX上,取消引用NULL也会让你变得垃圾:确定,*(char *)NULL和*(short *)NULL返回0,但是*(int *)NULL会给你1024528128 !!!!。
[…]
ED1。 加成
没有提到“解除引用”但仍然; 一个有趣的读物是里奇: C语言的发展✝
这里一直使用术语“间接” – 但/和/等。 语言之间的联系有点详细。 因此,鉴于例如上面提到的1974年的论文,该术语的使用是有趣的。
作为概念和语法的间接例子,例如pp 12 ev。
语法意外导致了语言的复杂性。 在C语言中拼写为*的间接运算符在语法上是一元前缀运算符,就像在BCPL和B中一样。这在简单表达式中很有效,但在更复杂的情况下,需要括号来指导解析。
[…]
发生了两种效应。 最重要的是,C有一套相对丰富的描述类型的方法(比如用Pascal比较)。 例如,像C-Algol 68那样表达语言的声明 – 描述同样难以理解的对象,仅仅因为对象本身是复杂的。 第二个效果归功于语法的细节。 C中的声明必须以“由内而外”的方式阅读,许多人难以理解[Anderson 80]。
在这种情况下,可能还值得一提的是ANSI C89,并提到:
3.1.2.5类型
尽管可以将这样的指针转换为可以被解除引用的正常指针类型,但是可以不取消引用指向void的指针。
- ANSI C标准草案(ANSI X3J11 / 88-090) ,(由维基百科提供 )
- 美国国家信息系统标准的基本原理 – 编程语言 – C.
用于通过一元*运算符解除引用指针的无效值是空指针,对于指向的对象类型不适当地对齐的地址,或者在执行对象的块时具有自动存储持续时间的对象的地址声明并且所有封闭的块都已终止。
(我现在必须重新阅读其中的一些文件。)
因为在K&R C过去的好时光,语言只按值传递参数。 所以指针用于通过引用来模拟传递参数 。 并且人们(错误地)提到了对变量的引用以构造指向变量的指针。
并且指针的解除引用是相反的操作。
现在C ++使用与指针不同的真正引用,但仍然使用了dereference一词(即使它不是真的正确)。
我不知道确切的词源,但是可以将指针值(在一般意义上,而不是C / C ++特定含义)视为“引用”内存中的另一个对象; 也就是说, p
指的是 x
。 当我们使用p
来获取存储在x
的值时,我们绕过该引用,或者取消引用 p
。
Kernighan和Ritchie, C编程语言 ,第2版,5.1:
一元运算符*是间接或解除引用运算符; […]”指向void’的指针用于保存任何类型的指针,但不能自行解除引用。