术语"运算符优先级"和"求值顺序"是编程中非常常用的术语,对于程序员来说非常重要.而且,据我所知,这两个概念是紧密联系在一起的,在谈到表达时,一个离不开另一个.
让我们举一个简单的例子:
int a=1; // Line 1
a = a++ + ++a; // Line 2
printf("%d",a); // Line 3
显然,Line 2
会导致未定义的行为,因为100包括:
在对&;和amp;的左操作数和右操作数求值之间(逻辑 AND)、||(逻辑或)和逗号 操作员.例如,在 表达式
*p++ != 0 && *q++ != 0
,全部 子表达式的副作用*p++ != 0
在任何try 访问q
之前完成.在三元数的第一个操作数的求值之间
在完整表达的结尾.这一类包括表达
在函数调用中输入函数之前.顺序
在函数返回时,将返回值复制到 调用上下文.(此序列点 仅在C++标准中指定; 它仅隐式存在于 (C.)
在初始值设定项结束时;例如,在求值为5之后 在第
int a = 5;
号声明中.
因此,通过第三点:
At the end of a full expression. This category includes expression statements (such as the assignment a=b;), return statements, the controlling expressions of if, switch, while, or do-while statements, and all three expressions in a for statement.
Line 2
显然会导致未定义的行为.这说明Undefined Behaviour和Sequence Points是如何紧密耦合的.
现在让我们再举一个例子:
int x=10,y=1,z=2; // Line 4
int result = x<y<z; // Line 5
现在很明显,Line 5
将使变量result
存储1
.
现在,Line 5
中的表达式x<y<z
可以求值为:
x<(y<z)
或(x<y)<z
.在第一种情况下,值result
将是0
,在第二种情况下,值result
将是1
.但我们知道,当Operator Precedence
是Equal/Same
-Associativity
开始发挥作用时,因此被评为(x<y)<z
.
这MSDN Article句话是这样说的:
The precedence and associativity of C operators affect the grouping and evaluation of operands in expressions. An operator's precedence is meaningful only if other operators with higher or lower precedence are present. Expressions with higher-precedence operators are evaluated first. Precedence can also be described by the word "binding." Operators with a higher precedence are said to have tighter binding.个
现在,关于上面的文章:
It mentions "Expressions with higher-precedence operators are evaluated first."个
这听起来可能不正确.但是,如果我们认为()
也是操作员的话,我认为这篇文章并不是说错了,x<y<z
与(x<y)<z
是一样的.我的推理是,如果结合性没有发挥作用,那么完整表达式的求值将变得不明确,因为<
不是Sequence Point.
另外,我在Operator Precedence and Associativity上找到的另一个链接是这样的:
This page lists C operators in order of precedence (highest to lowest). Their associativity indicates in what order operators of equal precedence in an expression are applied.个
以int result=x<y<z
的第二个例子为例,我们可以看到在所有3个表达式中,x
,y
和z
,因为最简单的表达式形式是由一个文本常量或对象组成的.因此,表达式x
、y
、z
的结果将为rvalues,即分别为10
、1
和2
.因此,现在我们可以将x<y<z
解释为10<1<2
.
现在,结合性不是开始发挥作用了吗,因为我们现在有两个表达式要计算,要么是10<1
,要么是1<2
,而且由于运算符的优先级是相同的,they are evaluated from left to right?
以最后这个例子作为我的论点:
int myval = ( printf("Operator\n"), printf("Precedence\n"), printf("vs\n"),
printf("Order of Evaluation\n") );
现在在上面的示例中,由于comma
运算符具有相同的优先级,因此表达式被求值left-to-right
,并且最后printf()
的返回值被存储在myval
中.
在SO/IEC 9899:201x岁以下的J.1 Unspecified behavior岁以下,它提到:
The order in which subexpressions are evaluated and the order in which side effects take place, except as specified for the function-call (), &&, ||, ?:, and comma operators (6.5).
现在我想知道,这样说是否不对:
Order of Evaluation depends on the precedence of operators, leaving cases of Unspecified Behavior.
如果我在问题中说的话有任何错误,我希望得到纠正. 我贴这个问题的原因是因为MSDN的文章在我的脑海里创造了一个念力.是不是Error美元?