在 C99 标准中,表达式允许优先级和关联性。
优先级记录得非常好,因为运算符在文档中出现的顺序是降低优先级的,因此函数调用在乘法运算符之前,而乘法运算符又在加法运算符之前。
但是,我找不到对关联性的明确描述,无论是左还是右。这很重要,因为对于一个变体(35/5)*2
35/5*2
14
,而对于另一个变体35/(5*2)
3
。
第6.5 Expressions /3, footnote 74
节指出:
语法指定运算符在表达式求值中的优先级,这与该子句的主要子句的顺序相同,优先级最高。
在每个主要子条款中,运算符具有相同的优先级。左结合性或右结合性在每个子句中由其中讨论的表达式的语法表示。
但是,以乘法情况为例:
6.5.5 乘法运算符
语法
multiplicative-expression:
cast-expression
multiplicative-expression * cast-expression
multiplicative-expression / cast-expression
multiplicative-expression % cast-expression
约束
每个操作数应具有算术类型。%
操作人员的操作数应 具有整数类型。
语义学
通常的算术转换是在操作数上执行的。
二元*
运算符的结果是操作数的乘积。
/
运算符的结果是第一个操作数除以 第二;%
运算符的结果是余数。在这两个操作中,如果值 第二个操作数为零,行为未定义。
当整数被除以时,/
运算符的结果是代数商与任何 丢弃小数部分。如果商a/b
是可表示的,则表达式(a/b)*b + a%b
应等于a
。
我看不到任何提到关联性的内容,标准中的其他地方似乎也没有任何默认设置。
我在这里错过了什么吗?
运算符关联性未明确指定为"右关联"或"左关联"。 你从语法中推断出来。 在您的示例中,multiplicative-expression
项以递归方式引用自身,递归位于运算符的左侧。 这意味着遇到a * b * c
的解析器必须像(a * b) * c
一样解析a * b * c
,这是左关联的。
assignment-expression
术语 (6.5.16( 具有以下语法:
assignment-expression:
conditional-expression
unary-expression assignment-operator assignment-expression
所以遇到a = b = c
的解析器必须像a = (b = c)
一样解析它,这是右关联。
语法本身通过所使用的产品指定关联性:
multiplicative-expression:
cast-expression
multiplicative-expression * cast-expression
这意味着在a * b * c
中,在进一步解析a * b
本身之前,c
必须被解析为一个cast-expression
,并a * b
为一个multiplicative-expression
。因此,乘法的左结合性被解析规则强制到语法树中。