C 中带有 ++ 运算符的语句的短路评估
Short circuit evaluation of a statement with ++ operator in C
我在 Code::Blocks 10.05 中 Windows 7 上执行了以下代码。
int a=0,b=0,c;
c=a++&&b++;
printf("\na=%d\nb=%d\nc=%d\n\n",a,b,c);
我得到的输出如下,
a=1
b=0
c=0
由于短路评估,这非常有意义。
表达式a++
是post递增,0
返回逻辑与(&&
)。因此 b++
部分不会被评估,因为 0 && 0
和
0 && 1
的计算结果为 0
。
但是这里出现了我的疑问。运算符的优先级值明确指出 ++
比 &&
具有更高的优先级。所以我的理解是这样的,a++
和 b++ 都被评估,然后 &&
只检查表达式 a++
的结果来做出决定。但这并没有发生,只有 a++
在这里被评估。
这种行为的原因是什么? &&
作为序列点是否与此行为有关?如果是这样,为什么我们说 &&
的优先级低于 ++
?
这里有两个概念——优先顺序和求值顺序。仅当对表达式(或子表达式)求值时,优先顺序才会产生影响。
一般来说,评价的顺序是不分先后的。给定一个运算符,它的操作数可以按任何顺序求值。函数的参数可以按任何顺序求值。
来自 C++ 标准:
1.9 Program execution
15 Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.
和
8.3.6 Default arguments
9 Default arguments are evaluated each time the function is called. The order of evaluation of function arguments is unspecified.
对于逻辑 AND 运算符 &&
,C++11 标准规定:
5.14 Logical AND operator
1 The &&
operator groups left-to-right. The operands are both contextually converted to type bool
(Clause 4). The result is true
if both operands are true
and false
otherwise. Unlike &
, &&
guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false
.
为逻辑 OR 运算符指定了类似的例外,||
。
由于 b++
由于 &&
运算符的表达式短路而未被评估,因此运算符的优先顺序在这种特殊情况下没有意义。
您对优先级和求值顺序感到困惑。
优先级定义运算符的分组方式,即
c = a++ && b++;
相当于:
c = ((a++) && (b++));
求值顺序定义了表达式的求值方式,&&
的短接表示a++
先求值,为0则结束;如果它不为零,则计算 b++
。
再举个例子:
c = (a++) + (b++);
a++
是否在 b++
之前评估?答案是我们不知道。大多数运算符不定义求值顺序。 &&
是为数不多的定义的运算符之一。 (其余为||
、,
和?:
)
我在 Code::Blocks 10.05 中 Windows 7 上执行了以下代码。
int a=0,b=0,c;
c=a++&&b++;
printf("\na=%d\nb=%d\nc=%d\n\n",a,b,c);
我得到的输出如下,
a=1
b=0
c=0
由于短路评估,这非常有意义。
表达式a++
是post递增,0
返回逻辑与(&&
)。因此 b++
部分不会被评估,因为 0 && 0
和
0 && 1
的计算结果为 0
。
但是这里出现了我的疑问。运算符的优先级值明确指出 ++
比 &&
具有更高的优先级。所以我的理解是这样的,a++
和 b++ 都被评估,然后 &&
只检查表达式 a++
的结果来做出决定。但这并没有发生,只有 a++
在这里被评估。
这种行为的原因是什么? &&
作为序列点是否与此行为有关?如果是这样,为什么我们说 &&
的优先级低于 ++
?
这里有两个概念——优先顺序和求值顺序。仅当对表达式(或子表达式)求值时,优先顺序才会产生影响。
一般来说,评价的顺序是不分先后的。给定一个运算符,它的操作数可以按任何顺序求值。函数的参数可以按任何顺序求值。
来自 C++ 标准:
1.9 Program execution
15 Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.
和
8.3.6 Default arguments
9 Default arguments are evaluated each time the function is called. The order of evaluation of function arguments is unspecified.
对于逻辑 AND 运算符 &&
,C++11 标准规定:
5.14 Logical AND operator
1 The
&&
operator groups left-to-right. The operands are both contextually converted to typebool
(Clause 4). The result istrue
if both operands aretrue
andfalse
otherwise. Unlike&
,&&
guarantees left-to-right evaluation: the second operand is not evaluated if the first operand isfalse
.
为逻辑 OR 运算符指定了类似的例外,||
。
由于 b++
由于 &&
运算符的表达式短路而未被评估,因此运算符的优先顺序在这种特殊情况下没有意义。
您对优先级和求值顺序感到困惑。
优先级定义运算符的分组方式,即
c = a++ && b++;
相当于:
c = ((a++) && (b++));
求值顺序定义了表达式的求值方式,&&
的短接表示a++
先求值,为0则结束;如果它不为零,则计算 b++
。
再举个例子:
c = (a++) + (b++);
a++
是否在 b++
之前评估?答案是我们不知道。大多数运算符不定义求值顺序。 &&
是为数不多的定义的运算符之一。 (其余为||
、,
和?:
)