gpt4 book ai didi

c - 为什么 'dereference' 和 'address of' 运算符在左边?

转载 作者:太空狗 更新时间:2023-10-29 14:56:57 24 4
gpt4 key购买 nike

在 C(和其他一些类似 C 的语言)中,我们有 2 个用于处理指针的一元运算符:解引用运算符 (*) 和“地址”运算符 (&)。它们是一元运算符,这会在运算顺序中引入不确定性,例如:

*ptr->field

*arr[id]

操作顺序由标准严格定义的,但从人类的角度来看,这是令人困惑的。如果 * 运算符是一元运算符,则顺序将很明显并且不需要额外的括号:

ptr*->field vs ptr->field*

arr*[id] vs arr[id]*

那么,为什么运算符是一元运算符而不是右运算符,这有充分的理由吗?我想到的一件事是类型声明。左运算符留在类型名称附近(char *a vs char a*),但是有类型声明,这已经打破了这个规则,所以为什么还要麻烦 ( char a[num], char (*a)(char) 等)。

显然,这种方法也存在一些问题,比如

 val*=2

可以是 *= 的简写 val = val * 2 或取消引用并分配 val* = 2。然而,这可以通过在取消引用的情况下要求 *= 标记之间的空格来轻松解决。再一次,没有什么开创性的,因为有这样一个规则的先例(--a vs --a)。

那么为什么它们是左运算符而不是右运算符?

编辑:我想指出,我问了这个问题,因为 C 的许多更奇怪的方面都有有趣的解释,为什么它们是这样的,比如 existence of the -> operator或类型声明或从 0 开始的索引。等等。原因可能不再有效,但在我看来它们仍然很有趣。

最佳答案

确实有权威来源:"The Development of the C Language" by the creator of the language, Dennis M. Ritchie :

An accident of syntax contributed to the perceived complexity of the language. The indirection operator, spelled * in C, is syntactically a unary prefix operator, just as in BCPL and B. This works well in simple expressions, but in more complex cases, parentheses are required to direct the parsing. For example, to distinguish indirection through the value returned by a function from calling a function designated by a pointer, one writes *fp() and (*pf)() respectively. The style used in expressions carries through to declarations, so the names might be declared

int *fp();
int (*pf)();

In more ornate but still realistic cases, things become worse:

int *(*pfp)();

is a pointer to a function returning a pointer to an integer. There are two effects occurring. Most important, C has a relatively rich set of ways of describing types (compared, say, with Pascal). Declarations in languages as expressive as C—Algol 68, for example—describe objects equally hard to understand, simply because the objects themselves are complex. A second effect owes to details of the syntax. Declarations in C must be read in an `inside-out' style that many find difficult to grasp [Anderson 80]. Sethi [Sethi 81] observed that many of the nested declarations and expressions would become simpler if the indirection operator had been taken as a postfix operator instead of prefix, but by then it was too late to change.


因此 *C 中位于左侧的原因是因为它是 on the left in B .

B 部分基于 BCPL ,其中取消引用运算符是 !。这是在左边;二进制 ! 是一个数组索引运算符:

a!b

is equivalent to !(a+b).

!a

is the content of the cell whose address is given by a; it can appear on the left of an assignment.

还50岁BCPL手册甚至没有提及 ! 运算符 - 相反,运算符是单词:一元 lvrv。由于这些被理解为好像它们是函数,所以很自然地它们先于操作数;后来较长的 rv a 可以用语法糖 !a 代替。


许多当前的 C 运算符实践都可以通过这条路线进行追踪。 B 同样有 a[b] 等同于 *(a + b)*(b + a)b[ a] 就像在 BCPL 中一样,可以使用 a!b <=> b!a

请注意,在 B 中变量是未类型化的,因此与声明的相似性肯定不是在左侧使用 * 的原因。

所以一元 * 在 C 中位于左侧的原因和 一样无聊“在使用一元 * 的更简单的程序中没有任何问题> 在左边,在每个人都习惯于使用其他语言的解引用运算符的情况下,没有人真正认为其他方法会更好,直到为时已晚才改变它“

关于c - 为什么 'dereference' 和 'address of' 运算符在左边?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46759733/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com