我是在Kelley-Pohl的C书上学习C,而且这个练习我不明白:
int a = 0, b = 0, x;
x = 0 && (a = b = 777);
printf("%d %d %d\n", a, b, x);
x = 777 || (a = ++b);
printf("%d %d %d\n", a, b, x);
他们只是说想象输出并将其与真实的输出进行比较。我以为输出会是
777 777 0
778 778 1
但它是
0 0 0
0 0 1
答案 0 :(得分:4)
&&
运算符使用lazy evaluation。如果&&
运算符的任一侧为false
,则整个表达式为false
。
C检查运算符左侧的真值,在您的情况下为0
。由于0
在c中为false,因此操作的右侧表达式(a = b = 777)
永远不会被评估。
第二种情况类似,只是如果左侧表达式返回||
,则true
返回true
。另请注意,在c中,任何非0
的内容都被视为true
。
希望这有帮助。
答案 1 :(得分:4)
来自C标准(6.5.13逻辑AND运算符)
3&&如果两个操作数都比较,则运算符产生1 不等于0;否则,它会产生0 。结果的类型为int。
和
4与按位二进制&操作员,&&运营商保证 从左到右的评价;如果评估第二个操作数,则有 第一个和第二个的评估之间的序列点 操作数。 如果第一个操作数比较等于0,则第二个操作数 操作数未被评估。
在此表达式声明中
x = 0 && (a = b = 777);
第一个操作数比较等于0.因此,不计算第二个操作数,即变量a
和b
的值不会更改。因此,根据该部分的第3段,变量x
将设置为0
。
来自C标准(6.5.14逻辑OR运算符)
3 ||如果任一操作数进行比较,则运算符将产生1 不等于0;否则,它会产生0。结果的类型为int。
和
4与按位|不同运算符,||运营商保证 从左到右的评价;如果评估第二个操作数,则有 第一个和第二个的评估之间的序列点 操作数。我 f第一个操作数比较不等于0,第二个操作数 操作数未被评估。
在此表达式声明中
x = 777 || (a = ++b);
第一个操作数比较不等于0.所以不计算第二个操作数,即变量a
和b
的值没有改变。所以变量x
将根据本节第3段设置为1
。
如果要更改
等表达式中操作数的顺序x = (a = b = 777) && 0;
x = (a = ++b) || 777;
你得到了你期望的结果。