我想问一个关于下面代码的问题。
int a=1, b=3, c=1;
if((a||c--)&&(c&&b--)) printf("%d",b);
printf("%d %d %d",a,b,c);
为什么代码打印"21 21 1"而不是"1 20 ">
?谢谢你的帮助。
由于在(a||c——)中or立即被求值为true,因此c——永远不会被求值。编译器会这样做。如果一个语句马上为真,它就不会计算剩下的语句。因此,c永远不会被减,因为or的右侧永远不会被求值。
||
和&&
都强制从左到右求值——首先求LHS,然后应用所有副作用,然后根据结果求RHS
两个操作符都短路:
- 对于
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
。
你可以想象一下这个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与按位的|运算符不同,||运算符保证从左到右的评价;如果对第二个操作数求值,则有在第一个和第二个求值之间的一个序列点操作数。如果第一个操作数比较不等于0,则第二个操作数操作数未求值.