为什么C使用星号作为指针?[关闭]


21

我现在正在学习C。

我感到奇怪的是,创建者选择星号(*)作为指针的符号,而不是实际上看起来像指针(->)的符号。

考虑到取消引用和函数指针可能会造成混淆,使用星号是否有历史或什至实际的原因?


10
请注意,->在C语言中,它被用作解除引用运算符-访问struct:中的字段时struct_pointer->field,这是的缩写(*struct_pointer).field
阿蒙2014年

@amon:它仅适用structs于取消引用,这对我来说很奇怪。是指针符号,对不对?为什么不使用(<-)取消引用?我真的是唯一一个这样思考的人吗?
Noob Saibot 2014年

1
给出了该问题的两个极好的答案,包括一个直接来自语言设计者的答案,因此很难以“基于观点”来证明结束是正确的。因此,我已提名重新开放。
Jules

恕我直言,帕斯卡风格更好。^使用,可以认为是旋转的箭头,读作“指向”,意思是相同->但较短。^integer表示用于类型声明的“指向整数的指针”,var^表示var用于解引用的“内存指向”。从左向右读取时,符号位置比C更具逻辑性,该位置始终放在类型之后和变量名之前。Pascal还@用于获取地址,该地址比更好&,因为它@var是“ var所在的地址”
phuclv

Answers:


59

为什么C使用星号作为指针?

很简单-因为B做到了。

由于内存是线性数组,因此可以将单元格中的值解释为该数组中的索引,并且BCPL为此提供了一个运算符。它的原始语言是拼写的rv,后来!B用一元的拼写*。因此,如果p一个单元格包含另一个单元格的索引(或该单元格的地址)或指向另一个单元格的指针,*p则将其指向所指向的单元格的内容,作为表达式中的值或作为赋值的目标。

C语言的发展

而已。在这一点上,问题就像“为什么python 3为什么要使用.一个方法?为什么不->呢?” 一样有趣。好吧……因为Python 2使用.了调用方法。

一种语言很少存在于无。它具有影响力,并且是基于以前发生的事情。


那么,为什么B !不像它的前身BCPL那样使用取消引用的指针呢?

好吧,BCPL有点罗word。代替&&||BCPL使用logandlogor。这是因为大多数键盘上没有不等于键实际上就是这个词NEQV(请参阅《 BCPL参考手册》)。

B似乎在某种程度上受到了启发,希望加强语法,而不是为程序员经常使用的所有这些逻辑运算符加长字。从而!为解引用成为*使!可用于逻辑否定。请注意,一元运算*符和二进制*运算符(乘法)之间存在差异。


好吧,其他选择->呢?

->被送往句法糖围绕场derefrences struct_pointer->field这是(*struct_pointer).field

其他类似的选项<-可能会导致模棱两可的解析。例如:

 foo <- bar

可以理解为:

(foo) <- (bar)

要么

(foo) < (-bar)

使一个由二元运算符和另一个一元运算符组成的一元运算符很可能会遇到问题,因为第二个一元运算符可能是另一个表达式的前缀。

此外,再次重要的是要尽量减少经常键入的内容。我不愿意写:

int main(int argc, char->-> argv, char->-> envp)

这也变得难以阅读。

可能还有其他字符(@直到Objective C才使用)。再说一次,这是“ C使用的核心,*因为B这样做了”。B为什么不使用@?好吧,B没有使用所有字符。B中没有bpp程序(比较cpp),其他字符可用(例如#cpp以后使用的字符)。

如果我可能会冒险猜一个原因-这是因为键在哪里。从B手册中

为了方便在可能的情况下操纵地址,B提供了两个一元地址运算符,*&&是地址运算符,假设&x的地址为1 x,那么它的地址也是如此。*是间接运算符;*x表示“将x的内容用作地址”。

请注意&是shift-7和*shift-8。它们彼此之间的接近性可能暗示了程序员所做的事情……但这只是一个猜测。有人会问肯·汤普森为什么要做出这种选择。


所以你有它。C之所以这样,是因为B是。B之所以这样,是因为它想改变BCPL的方式。


2
太棒了!@MichaelT,这是一个很好的答案!您向我展示了历史和实际原因,甚至还介绍了我不太了解但可以研究的内容。谢谢。+1
Noob Saibot 2014年

@NoobSaibot字符的选择并不重要,因为运算符是前置运算符而不是后置运算符。这需要大量的额外费用(尽管->语法糖会有所帮助),即使对于有经验的C ++程序员,这也可能导致愚蠢而令人烦恼的错误。
Trixie Wolf 2014年

1
您可能还提到C在几乎所有的Ascii标点字符中都有用。没有太多的备件。我想那@是另一种可能性。
david.pfx 2014年

1
@ david.pfx我已经对此进行了扩展-尽管不是C做出了选择...而是B。而且,我猜了为什么(键盘接近&*)。B也没有使用,#所以那时还有更多备用零件$

1
@ david.pfx 我发现的B教程是由BW Kernighan编写的。不幸的是,丹尼斯·里奇Dennis Ritchie)不再被问到(他于11年10月去世),而克尼根(Kernighan)显然仍是普林斯顿大学CS系的教授。肯·汤普森(B的另一位创建者)在Google工作。。。也许有些键盘也有问题(由C的三音符号表示,我们认为这是通用键),提示并非所有键盘都可用(我不确定'@'是否是)。

55

我被学生问&*(这是我以前从来没有注意到)被选中,因为他们是彼此相邻键盘上。大量的搜索使我想到了B和BCPL文档以及该线程。但是,我什么也找不到。*B中似乎有很多原因,但是我没有找到任何理由&

因此,按照@MichaelT的建议,我问肯·汤普森:

发件人:肯·汤普森<ken@google.com>

键盘附近:否。
从b复制的c,所以&和*在那里相同。
b从较早的语言中获得*-一些程序集,
bcpl和我认为pl / 1。
我认为我使用了&,因为名称(“&”号)
听起来像“地址”。b设计为与
33型电传打字机一起使用。(5位波特-o码),
因此限制了符号的使用。


19
+1以联系Ken Thompson并在此处报告。
stakx
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.