为什么左侧的"取消引用"和"运营商地址"?

RuR*_*uRo 5 c syntax pointers operator-precedence dereference

在C(以及一些其他类C语言)中,我们有2个一元运算符用于处理指针:dereference运算符(*)和'address of'运算符(&).他们留下一元运算符,它引入了一个不确定性的操作顺序,例如:

*ptr->field
Run Code Online (Sandbox Code Playgroud)

要么

*arr[id]
Run Code Online (Sandbox Code Playgroud)

操作的顺序严格标准定义的,而是从一个人的角度来看,这是令人困惑的.如果*操作员是一个正确的一元操作员,那么订单将是显而易见的,并且不需要额外的括号:

ptr*->field vs ptr->field*
Run Code Online (Sandbox Code Playgroud)

arr*[id] vs arr[id]*
Run Code Online (Sandbox Code Playgroud)

因此,运营商为什么要保持一元而不是正确,这是有充分理由的.想到的一件事是类型的声明.左运营附近逗留类型名称(char *aVS char a*),但也有类型声明,这已经打破了这一规则,何必(char a[num],char (*a)(char),等).

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

 val*=2
Run Code Online (Sandbox Code Playgroud)

这将是一个*=简短的手val = val * 2或取消引用和分配val* = 2.然而,这可以通过在解除引用的情况下在令牌*=令牌之间需要空白空间来容易地解决.再一次,没有任何开创性的,因为有这样一个规则的先例(- -avs --a).

那么为什么他们离开而不是正确的运营商?

编辑:我想指出,我问过这个问题,因为C的许多怪问题都有有趣的解释,为什么它们是这样的,就像运算符存在->或类型声明或索引从等等.原因可能不再有效,但我认为它们仍然很有趣.

Ant*_*ala 8

确实一个权威的来源:语言的创造者Dennis M. Ritchie的"C语言的发展":

语法意外导致了语言的复杂性.*在C语言中拼写的间接运算符在语法上是一元前缀运算符,就像在BCPL和B中一样.这在简单表达式中很有效,但在更复杂的情况下,需要括号来指导解析.例如,为了区分间接通过函数返回的值与调用指针指定的函数*fp(),(*pf)()分别写入和.表达式中使用的样式贯穿于声明,因此可以声明名称

int *fp();
int (*pf)();
Run Code Online (Sandbox Code Playgroud)

在更华丽但仍然现实的情况下,事情变得更糟:

int *(*pfp)();
Run Code Online (Sandbox Code Playgroud)

是一个指向函数的指针,该函数返回一个指向整数的指针.发生了两种效应.最重要的是,C有一套相对丰富的描述类型的方法(比如用Pascal比较).例如,像C-Algol 68那样富有表现力的语言中的声明描述同样难以理解的对象,仅仅因为对象本身很复杂.第二个效果归功于语法的细节.C中的声明必须以"由内而外"的方式阅读,许多人难以理解[ Anderson 80 ].Sethi [ Sethi 81 ]观察到,如果将间接运算符作为后缀运算符而不是前缀,许多嵌套的声明和表达式会变得更简单,但到那时为时已经太晚了.


因此,*C的左边是因为它B的左边.

B部分基于BCPL,其中解除引用运算符!.这是在左边; 二进制文件!是一个数组索引操作符:

a!b

相当于!(a+b).

!a

是地址由a给出的小区的内容; 它可以出现在作业的左侧.

然而,50年前的BCPL手册甚至没有提到!操作员 - 相反,操作员是单词:一元lvrv.由于这些被理解为它们是函数,因此它们在操作数之前是自然的; 之后rv a可以用句法糖代替长鱼!a.


许多当前的C操作员实践可以通过这条路线进行追踪.乙都必须a[b]等同于*(a + b)*(b + a)b[a]就像在BCPL一个可以使用a!b<=> b!a.

请注意,在B变量是无类型的,所以肯定与声明的相似性不能*成为左边那里使用的原因.

因此,*在C中左边一元一元的原因就像"在一个简单的程序中没有任何问题一样,*左边是一元的,在每个人习惯于在其他语言中使用解除引用算子的位置,没有人真的认为其他方式会更好,直到改变它为时已晚".

  • 请注意,"= +"和"=*"的语法已更改为"+ ="和"*=".在除数之后还需要空格来解除引用:"/*ptr2var"与"/*ptr2var"(这将是评论的开始). (3认同)