逻辑 AND OR 和递增优先级
Logical AND OR and increment precedence
我想问一个关于下面代码的问题。
int a=1, b=3, c=1;
if((a||c--)&&(c&&b--)) printf("%d",b);
printf("%d %d %d",a,b,c);
为什么代码打印的是“21 2 1”而不是“1 2 0”?
感谢您的帮助。
由于 or 在 (a||c--) 中立即被评估为真,因此 c-- 永远不会被评估。编译器执行此操作。如果一个陈述立即为真,它就不会费心去评估其余的。因此,c 永远不会递减,因为 or 的右侧永远不会被求值。
你可以想象这个if语句
if((a||c--)&&(c&&b--)) printf("%d",b);
以下方式
if ( a )
{
if ( c )
{
if ( b-- )
{
printf("%d",b);
}
}
}
else if ( c-- )
{
if ( c )
{
if ( b-- )
{
printf("%d",b);
}
}
}
所以如果第一个if语句中的表达式
if ( a )
评估为逻辑真则此 if 语句
else if ( c-- )
永远无法控制。
来自 C 标准(6.5.14 逻辑或运算符)
4 Unlike the bitwise | operator, the || operator guarantees
left-to-right evaluation; if the second operand is evaluated, there is
a sequence point between the evaluations of the first and second
operands. If the first operand compares unequal to 0, the second
operand is not evaluated.
||
和 &&
都强制从左到右评估 - 首先评估 LHS 并应用所有副作用,然后基于结果 RHS 被评估。
两个运营商短路:
- for
a || b
,如果a
非零,那么无论b
的值如何,表达式的结果都是1
,所以b
未评估;
- 对于
a && b
,如果a
为零,则无论b
的值如何,表达式的结果都是0
,所以b
未评估。
&&
的优先级高于||
,所以a || b && c
被解析为a || (b && c)
.
将所有这些放在一起,(a||c--)&&(c&&b--)
的计算结果如下:
a || c--
计算如下:
a
被评估 - 它的结果是 1
,所以
c--
未 评估;因此 c
的值没有改变,并且
- 表达式的结果是
1
c && b--
计算如下:
c
被评估 - 它的结果是 1
,所以
b--
被评估 - 它的结果是 3
;作为 副作用 b
递减,并且
- 表达式的结果是
1
a || c--
和 c && b--
的计算结果都是 1
a
和c
的值不变(分别为1
和1
),而b
已经递减,其值是现在 2
.
我想问一个关于下面代码的问题。
int a=1, b=3, c=1;
if((a||c--)&&(c&&b--)) printf("%d",b);
printf("%d %d %d",a,b,c);
为什么代码打印的是“21 2 1”而不是“1 2 0”?
感谢您的帮助。
由于 or 在 (a||c--) 中立即被评估为真,因此 c-- 永远不会被评估。编译器执行此操作。如果一个陈述立即为真,它就不会费心去评估其余的。因此,c 永远不会递减,因为 or 的右侧永远不会被求值。
你可以想象这个if语句
if((a||c--)&&(c&&b--)) printf("%d",b);
以下方式
if ( a )
{
if ( c )
{
if ( b-- )
{
printf("%d",b);
}
}
}
else if ( c-- )
{
if ( c )
{
if ( b-- )
{
printf("%d",b);
}
}
}
所以如果第一个if语句中的表达式
if ( a )
评估为逻辑真则此 if 语句
else if ( c-- )
永远无法控制。
来自 C 标准(6.5.14 逻辑或运算符)
4 Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares unequal to 0, the second operand is not evaluated.
||
和 &&
都强制从左到右评估 - 首先评估 LHS 并应用所有副作用,然后基于结果 RHS 被评估。
两个运营商短路:
- for
a || b
,如果a
非零,那么无论b
的值如何,表达式的结果都是1
,所以b
未评估; - 对于
a && b
,如果a
为零,则无论b
的值如何,表达式的结果都是0
,所以b
未评估。
&&
的优先级高于||
,所以a || b && c
被解析为a || (b && c)
.
将所有这些放在一起,(a||c--)&&(c&&b--)
的计算结果如下:
a || c--
计算如下:a
被评估 - 它的结果是1
,所以c--
未 评估;因此c
的值没有改变,并且- 表达式的结果是
1
c && b--
计算如下:c
被评估 - 它的结果是1
,所以b--
被评估 - 它的结果是3
;作为 副作用b
递减,并且- 表达式的结果是
1
a || c--
和c && b--
的计算结果都是1
a
和c
的值不变(分别为1
和1
),而b
已经递减,其值是现在 2
.