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;
}
当我 运行 这段代码时,结果是 1
和 1
。
根据 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++
副作用。
因此 a
和 b
都具有值 1
并且程序打印 1 1
.
相反,如果您写了 int b = (a || ((a | a)) && a++;
,&&
的左操作数将具有值 1
,因此需要计算右操作数。 a++
计算为 1
但递增 a
,因此 b
具有最终值 1
并且 a
设置为 2
,产生您的预期结果。
混淆来自将运算符优先级等同于评估顺序。这是两个不同的概念:运算符优先级决定应用 运算符 的顺序,但不决定其 操作数 的计算顺序。
只有四个运算符对其操作数有指定的求值顺序:&&
、||
、? :
和 ,
,前两个可能会跳过其中一个的求值,取决于另一个操作数的值,第三个仅评估第二个和第三个操作数中的第一个也是唯一一个。对于其他运算符,操作数的求值顺序是未指定的,它可能因编译器而异,可能因一个表达式而异,甚至可能因 运行 而异,尽管不太可能。
#include <stdio.h>
int main() {
int a = 1;
int b = a || (a | a) && a++;
printf("%d %d\n", a, b);
return 0;
}
当我 运行 这段代码时,结果是 1
和 1
。
根据 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++
副作用。
因此 a
和 b
都具有值 1
并且程序打印 1 1
.
相反,如果您写了 int b = (a || ((a | a)) && a++;
,&&
的左操作数将具有值 1
,因此需要计算右操作数。 a++
计算为 1
但递增 a
,因此 b
具有最终值 1
并且 a
设置为 2
,产生您的预期结果。
混淆来自将运算符优先级等同于评估顺序。这是两个不同的概念:运算符优先级决定应用 运算符 的顺序,但不决定其 操作数 的计算顺序。
只有四个运算符对其操作数有指定的求值顺序:&&
、||
、? :
和 ,
,前两个可能会跳过其中一个的求值,取决于另一个操作数的值,第三个仅评估第二个和第三个操作数中的第一个也是唯一一个。对于其他运算符,操作数的求值顺序是未指定的,它可能因编译器而异,可能因一个表达式而异,甚至可能因 运行 而异,尽管不太可能。