在 C(以及其他一些类似 C 的语言)中,我们有 2 个一元运算符用于处理指针:解引用运算符 (*
) 和“地址”运算符 (&
)。他们是left一元运算符,这会带来运算顺序的不确定性,例如:
*ptr->field
or
*arr[id]
操作顺序is标准严格定义,但从人的角度来看,却令人困惑。如果*
操作员是一个right一元运算符,顺序很明显并且不需要额外的括号:
ptr*->field vs ptr->field*
and
arr*[id] vs arr[id]*
那么运营商有充分的理由吗?left一元,而不是右。我想到的一件事是类型的声明。左运算符位于类型名称附近 (char *a
vs char a*
),但是有些类型声明已经违反了这条规则,所以为什么还要麻烦(char a[num]
, char (*a)(char)
, etc).
显然,这种方法也存在一些问题,例如
val*=2
这将是一个*=
简写为val = val * 2
或取消引用并分配val* = 2
。
然而,这可以通过要求之间有一个空格来轻松解决*
and =
取消引用时的令牌。再说一次,没有什么开创性的,因为有这样的规则的先例(- -a
vs --a
).
那么为什么他们是左操作员而不是右操作员呢?
编辑:
我想指出,我问这个问题是因为 C 的许多奇怪的方面都有有趣的解释,为什么它们是这样的,比如的存在->操作员 https://stackoverflow.com/questions/13366083/why-does-the-arrow-operator-in-c-exist或类型声明或从 0 开始的索引。等等。这些理由可能不再有效,但在我看来它们仍然很有趣。
确实有is权威来源:《C 语言的发展》,作者:C 语言创始人 Dennis M. Ritchie https://www.bell-labs.com/usr/dmr/www/chist.html:
语法上的意外导致了语言的复杂性。间接运算符,拼写为*
在 C 中,在语法上是一元前缀运算符,就像 BCPL 和 B 中一样。这在简单表达式中效果很好,但在更复杂的情况下,需要括号来指导解析。例如,为了通过函数返回的值来区分间接调用和调用由指针指定的函数,可以这样写:*fp()
and (*pf)()
分别。表达式中使用的样式会延续到声明中,因此可以声明名称
int *fp();
int (*pf)();
在更华丽但仍然现实的情况下,事情会变得更糟:
int *(*pfp)();
是一个指向返回整数指针的函数的指针。有两种效应发生。最重要的是,C 拥有一套相对丰富的描述类型的方法(例如与 Pascal 相比)。像 C 这样富有表现力的语言(例如 Algol 68)中的声明描述的对象同样难以理解,仅仅是因为对象本身很复杂。第二个效果归因于语法细节。 C 中的声明必须以“由内而外”的方式来阅读,许多人发现这很难理解 [安德森 80 https://dl.acm.org/citation.cfm?id=947627]. Sethi [Sethi 81 http://onlinelibrary.wiley.com/doi/10.1002/spe.4380110606/full] 观察到,如果间接运算符被视为后缀运算符而不是前缀,许多嵌套声明和表达式会变得更简单,但是到那时改变已经太晚了。
因此原因是*
位于左侧C是因为它是在左边B https://www.thinkage.ca/english/gcos/expl/b/manu/manu.html#Section6_3.
B部分基于BCPL https://www.lysator.liu.se/c/clive-on-bcpl.html,其中解引用运算符是!
。
这是在左边;二进制!
was an 数组索引操作员:
a!b
相当于!(a+b)
.
!a
是地址由 a 给出的单元格的内容;它可以出现在作业的左侧。
然而50岁的人BCPL https://www.bell-labs.com/usr/dmr/www/bcpl.html手册甚至没有提及!
运算符 - 相反,运算符是单词:一元lv
and rv
。由于它们被理解为函数,因此它们很自然地位于操作数之前;后来又长了rv a
然后可以用语法糖代替!a
.
当前的许多 C 操作符实践都可以通过这条路线进行追踪。 B同样有a[b]
相当于*(a + b)
to *(b + a)
to b[a]
就像在 BCPL 中一样可以使用a!b
b!a
.
请注意,B 中的变量是untyped,所以与声明的相似性当然不可能成为使用的原因*
在左边。
所以一元的原因*
在 C 语言中位于左边和“使用一元的更简单的程序没有任何问题*
在左边,每个人都习惯在其他语言中使用解引用运算符,没有人真正认为其他方式会更好,直到为时已晚,无法更改它”.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)