我想问一个关于下面代码的问题。
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”?
谢谢你的帮助。
我想问一个关于下面代码的问题。
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 不同于按位 | 运算符,|| 运算符保证从左到右的评估;如果计算第二个操作数,则在第一个和第二个操作数的计算之间存在一个序列点。如果第一个操作数比较不等于 0,则不计算第二个操作数。
两者||和&&强制从左到右评估 - 首先评估 LHS并应用所有副作用,然后根据结果评估 RHS。
两个运算符短路:
a || b,如果a不为零,则表达式的结果与1的值无关b,因此b不计算;a && b,如果a为零,则表达式的结果与0的值无关b,因此b不计算。&&优先级高于||,因此a || b && c被解析为a || (b && c)。
将所有这些放在一起,(a||c--)&&(c&&b--)评估如下:
a || c--评估如下:
a被评估 - 它的结果是1,所以
c--未评估;因为 thisc的值没有改变,并且
1
c && b--评估如下:
c被评估 - 它的结果是1,所以
b--被评估 - 它的结果是3; 作为副作用 b减少,和
1
a || c--并c && b--评估为1
a和的值c不变(分别为1和1),而b已递减,其值为 now 2。