C 运算符优先级:增量和逻辑运算符

C operator precendence: Increment and logical operators

这是我的代码。

#include <stdio.h>

#define PRINT3(x,y,z) printf("x=%d\ty=%d\tz=%d\n",x,y,z)

int main()
{
    int x,y,z;

    x = y = z = 1;
    ++x || ++y && ++z; PRINT3(x,y,z);

    return 0;
}

输出是,

x=2     y=1     z=1

我不明白这是怎么发生的。我期望的是,由于 ++ 的优先级高于 &&||,因此这里的前缀操作将首先被评估。也就是说,++x++y++z 将首先被评估。所以我期望的输出是,

x=2     y=2     z=2

有人能帮我理解一下吗?提前致谢。

我查看了 this 问题,但我仍然不明白为什么编译器决定在评估所有 ++s 之前评估 ||。这个编译器是依赖的​​,还是在标准中定义的,只要 || 的操作数是 1,就应该在评估另一个操作数中其他更高优先级的操作之前对其进行评估。

如果||的第一个操作数是真的。在 运行 时间,其余表达式未被计算。因为无论剩余部分的结果如何,答案都是正确的。因此,您将获得预期的结果。

运算符的更高优先级并不能保证它首先被评估,但它保证操作数将首先绑定(括号)到它。

++x || ++y && ++z;

将被括起来为

( (++x) || ( (++y) && (++z) ) );  

由于 || 运算符保证从左到右计算其操作数,因此 (++x) 将首先计算。由于其成为左操作数 true 时的短路行为,将不会评估右操作数。

这里,编译器做了一点优化。

任何与“1”进行“或”运算的结果都将始终为 1。 同样,任何与“1”进行“与”运算的结果都将为 0。

编译器将根据这些评估跳过代码块。

在你的情况下,

++x || ++y && ++z

这里 x > 0。所以无论你用什么或运算,结果 都会 为真。

因此,编译器直接跳过对其余部分的评估。

欲了解更多信息,Google for "short circuit evaluation."