首页 > 解决方案 > 初学者需要简单解释评估顺序和优先级/关联性之间的区别

问题描述

我正在阅读 K&R 第 2 章的结尾,我在理解两个特定的不相关的示例代码行(随后)以及书中对它们的评论时遇到了一些困难:

x = f() + g();
a[i] = i++;

第一行 - 我毫不费力地理解该标准没有指定+操作员的评估顺序,因此未指定是否先评估f()g()先评估(这就是为什么我认为这个问题不是重复的)。我的困惑源于这样一个事实,如果我们查看C 运算符优先级图表,它会将函数调用列为具有从左到右关联性的最高优先级。现在这不意味着f() 必须在之前调用/评估它g()吗?显然不是,但我不知道我错过了什么。

第二行 - 关于数组是索引到初始值i还是增量值的类似难题。但是,运算符优先级图表再次将数组下标引用为具有从左到右关联性的最高优先级。因此,数组下标不是要评估的第一件事,导致数组下标为初始值i并消除任何明确性吗?显然不是,我错过了一些东西。

我确实理解编译器可以自由决定何时在表达式中发生副作用(当然是在序列点之间),并且如果在同一个表达式中再次使用所讨论的变量,这可能会导致未定义的行为,但是在上面的示例中似乎任何歧义都被具有最高优先级的函数调用和数组下标清除并定义了从左到右的关联性,所以我看不到歧义。

我有一种感觉,我对关联性、运算符优先级和评估顺序的概念有一些基本的误解,但我无法指出它是什么,并且关于这个主题的类似问题/答案超出了我的范围至此彻底明白。

标签: c

解决方案


第一行

从左到右的关联性意味着诸如 的表达式f()()()被评估为((f())())()。函数调用运算符的关联性并()没有说明它与其他运算符的关系,例如+.

(请注意,关联性仅对可嵌套的中缀运算符(例如二元+%,

第二行

运算符优先级影响解析,而不是评估顺序[]具有更高优先级的事实=意味着表达式被解析为(a[i]) = (i++). 它很少提及评估顺序;a[i]并且i++必须在分配之前对其进行评估,但没有说明它们相对于彼此的顺序。

希望消除混乱:

关联性控制解析并告诉您a + b + c是解析为(a + b) + c(left-to-right) 还是a + (b + c)(right-to-left)。

Precedence还控制解析并告诉您是a + b * c被解析为(a + b) * c(+的优先级高于*) 还是a + (b * c)(*的优先级高于+)。

评估顺序控制需要以何种顺序评估哪些值。它的一部分可以遵循关联性或优先级(操作数必须在使用之前进行评估),但很少完全由它们定义。


推荐阅读