该问题将从N1570草案中获取信息,因此基本上是C11。
通俗地说,取消引用指针意味着将一元*
运算符应用于指针。草案中只有一个地方存在“取消引用”一词(没有“取消引用”的实例),并在脚注中:
102)[...]
一元*
用于解引用指针的无效值中
运算符是空指针,地址不适当地对齐
指向的对象的类型,以及对象后的地址
生命的尽头
据我所知,一元*
运算符实际上称为“间接运算符”,如第6.5.3.2节所示:
6.5.3.2地址和间接运算符
4
一元*
运算符表示间接。 [...]
类似地,在附件§J.2中将其明确称为间接操作符:
—通过数组下标[]
访问对象的值,
成员访问.
或−>
,地址&
或间接*
运算符或
指针在创建地址常量(6.6)中进行强制转换。
因此,在C语言中谈论“取消引用指针”是正确的,还是过于腐?术语从何而来? (由于§6.5.2.1,我可以在[]
上给通行证称为“ deferencing”)
最佳答案
K&R v1
如果看第一版(1978年)中的C编程语言,则使用术语“间接”。
例子
2.12评估的顺序和顺序
[…]
第5章讨论*(间接)和&(的地址)。
,
7.2一元运算符
[…]
一元*运算符表示间接寻址:表达式必须是指针,并且
结果是一个左值,表示表达式所指向的对象。
它也列在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的指针。这个人工序列显示了如何声明一个指针以及如何使用&和*:
[…]
先前的用法
然而,该术语(例如,“很多”)较老,例如可以从例如“ A.S.”中看出。
A survey of some issues concerning abstract data types,1974年。例如pp24 / 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)通常也很有用。 An example from Peter Lamb at Melbourne Uni(11/28/83):
取消引用NULL指针是又一个白痴的例子
编写“便携式”代码,但是假设他们的机器是
它只能在其上运行:设计了相同种类的人
带有二进制标头的cpio。
即使在VAX上,取消引用NULL也会使您很垃圾:当然,*(char *)NULL
和*(short *)NULL返回0,但是*(int *)NULL将给您
1024528128 !!!!
[…]
版1。加成
没有提及“取消引用”,但仍然; Ritchie是一个有趣的读物:The Development of the C Language ✝
在这里,术语“间接”也被一贯使用-但是/和/等等。语言之间的联系有些详细。因此,考虑到例如,该术语的使用是有趣的。像上面提到的1974年这样的论文。
作为关于概念的间接寻址和语法的示例,例如pp 12ev。
语法的偶然性导致了语言的复杂性。与BCPL和B中一样,在C中用*拼写的间接运算符在语法上是一元前缀运算符。这在简单的表达式中效果很好,但是在更复杂的情况下,需要用括号括起来才能进行解析。
[…]
有两种影响发生。最重要的是,C有一组相对丰富的描述类型的方式(例如,与Pascal相比)。例如,用C–Algol 68等语言表达的声明描述了同样难以理解的对象,这仅仅是因为对象本身很复杂。第二个效果归因于语法的细节。 C语言中的声明必须以“由内而外”的方式阅读,许多人很难理解[Anderson 80]。
在这种结合中,可能还值得一提的是ANSI C89,并提及:
3.1.2.5类型
尽管可以将指向void的指针取消引用,但可以将其转换为可以取消引用的普通指针类型。
Draft ANSI C Standard (ANSI X3J11/88-090),(由Wikipedia提供)
Rationale for American National Standard for Information Systems – Programming Language – C
一元*运算符用于解引用指针的无效值包括:
空指针,即不适合于以下类型的地址
指向的对象或具有自动功能的对象的地址
执行对象所在的块时的存储持续时间
声明,并且所有封闭的块已终止。
(我现在必须重新阅读其中一些文件。)
关于c - “取消引用”一词从何而来?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29473557/