C语言 逻辑与或和自增优先级



我想问一个关于下面代码的问题。

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--)的求值如下:

  1. a || c--的评估如下:
    1. a被求值——它的结果是1,所以
    2. c--评估;因此,c的值不会改变,并且
    3. 表达式的结果是1
  2. c && b--的求值如下:对
    1. c求值,其结果为1,因此计算
    2. b--,其结果为3;作为副作用b递减,并且
    3. 表达式的结果是1
  3. a || c--c && b--都求值为1

ac的值保持不变(分别为11),而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,则第二个操作数操作数未求值.

相关内容

  • 没有找到相关文章

最新更新