C语言中逻辑运算符的优先级

4
如果您查看C的优先级表,您会发现&&的优先级高于||。
但是请看以下代码:
a=b=c=1;

++a || ++b && ++c;

printf("%d %d %d\n",a,b,c);

它打印出"2 1 1",意味着"++a"首先被评估,一旦程序在那里看到一个TRUE,它就停止了,因为||另一边的内容不重要。
但是由于&&比||优先级更高,所以"++b && ++c"应该首先被评估,然后结果插入到"++a || result"中吗?(在这种情况下,程序将打印"1 2 2")。

是的,我没听清。谢谢你提醒我。 - Daniel Scocco
5个回答

13

试着用括号想象一下:

++a || ++b && ++c;

相等

(++a) || (++b && ++c);

操作符的结合顺序是从左到右。

如果 && 和 || 的优先级相同,它们将看起来像

(++a || ++b) && (++c);

6
优先级规则仅说明它将按照以下方式进行评估:
++a || (++b && ++c);

现在谈到逻辑运算符的短路行为,它要求你从左到右评估术语,并在结果已知时停止。右侧的部分永远不会被执行。

明白了。你能给我一个例子,说明在逻辑运算中 && 的优先级高于 || 会有影响吗?谢谢。 - Daniel Scocco
这里很重要。如果它们具有相等的优先级或者||的优先级更高,那么它将被计算为(++a || ++b) && ++c,因此++a++c都将被计算。 - R.. GitHub STOP HELPING ICE

2

优先级和运算顺序是两个完全不同的概念。对于逻辑运算符表达式,计算总是从左到右进行。表达式++a || ++b && ++c被解释为:

  1. 计算++a
  2. 如果第1步的结果为0,则计算++b && ++c

该表达式被解析++a || (++b && ++c);只要子表达式++a++b && ++c中有一个为true,整个表达式就为true。


明白了,是的,我的困惑在于假设优先级也影响了评估顺序。 - Daniel Scocco

0

&&在语法树中具有更高的优先级,但编译器会对代码进行优化。

if( !++a ) {
    ++b && ++c;
}

你更喜欢怎么称呼它,无所谓。 - artyom.stv
短路运算是一种"优化"的想法是一个经常在SO上出现的误解。在许多情况下,不进行短路计算可能是最佳选择。例如,++a|++b (无分支)几乎肯定比++a||++b (条件分支)更便宜。重要的是要认识到短路运算是不可选的行为,结果也是不同的。 - R.. GitHub STOP HELPING ICE
谢谢,很高兴知道这种行为不是可选的。我太懒了,没去查看标准来解决这个小问题。无论如何,我认为在条件语句中编写“赋值”运算符(任何类型的赋值)是一种不好的做法 - 新的编译器可以生成非常优化的代码(不需要自己进行此类优化,如在条件中进行赋值)。 - artyom.stv
即使您在条件或逻辑与/或中没有编写赋值语句,也有很多地方会出现具有副作用的表达式。函数调用将是一个明显的例子。 - R.. GitHub STOP HELPING ICE

0

你的例子 ++a || ++b && ++c++a || (++b && ++c) 是一样的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接