C 按位优先级和结合性

C bitwise precedence and associativity

#include <stdio.h>

int main() {
    int a = 1;
    int b = a || (a | a) && a++;
    printf("%d %d\n", a, b);
    return 0;
}

当我 运行 这段代码时,结果是 11

根据 C 语言运算符优先级,操作 && 应该在操作 || 之前发生。那么结果不应该是 2 1 吗? (a = 2, b = 1)

在 C 中对表达式进行 OR 运算时,采用了一种快捷方式,即 I.E.一旦表达式被评估为 TRUE,其余的 OR 表达式就不会被评估

第一个表达式 a 的计算结果为 TRUE,因此所有其余表达式都不会计算,因此 a 永远不会递增

当我尝试将 a || (a | a) 放入括号中时。结果如你所料。

所以我猜想当 C 编译器执行一个 OR 运算符并且它得到一个 True 值给 OR 时,执行将立即完成。

在你的例子中,当编译器执行 a || (a | a) (1 || something) 操作时。 b 的值将立即声明为 1,并且不会执行 ++ 运算符。

应用运算符优先级规则时,表达式等同于:

int b = a || ((a | a) && a++);

||&& 的计算或操作数是从左到右执行的,如果左操作数可以确定结果,则快捷计算会阻止计算右操作数:因为 a 非零,a || anything 计算结果为 1 而不计算右操作数,因此绕过了 a++ 副作用。

因此 ab 都具有值 1 并且程序打印 1 1.

相反,如果您写了 int b = (a || ((a | a)) && a++;&& 的左操作数将具有值 1,因此需要计算右操作数。 a++ 计算为 1 但递增 a,因此 b 具有最终值 1 并且 a 设置为 2,产生您的预期结果。

混淆来自将运算符优先级等同于评估顺序。这是两个不同的概念:运算符优先级决定应用 运算符 的顺序,但不决定其 操作数 的计算顺序。

只有四个运算符对其操作数有指定的求值顺序:&&||? :,,前两个可能会跳过其中一个的求值,取决于另一个操作数的值,第三个仅评估第二个和第三个操作数中的第一个也是唯一一个。对于其他运算符,操作数的求值顺序是未指定的,它可能因编译器而异,可能因一个表达式而异,甚至可能因 运行 而异,尽管不太可能。