dra*_*ine 3 c operators short-circuiting logical-operators
我正在从 Kelley-Pohl 的 A Book on 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);
Run Code Online (Sandbox Code Playgroud)
他们只是说想象输出并将其与真实输出进行比较。我以为输出会是
777 777 0
778 778 1
但它是
0 0 0
0 0 1
来自 C 标准(6.5.13 逻辑 AND 运算符)
3 && 运算符在其两个操作数比较不等于 0时应产生 1;否则,它产生 0。结果的类型为 int。
和
4 与按位二元 & 运算符不同,&& 运算符保证从左到右的计算;如果计算第二个操作数,则在第一个和第二个操作数的计算之间存在一个序列点。如果第一个操作数比较等于 0,则不计算第二个操作数。
在这个表达式语句中
x = 0 && (a = b = 777);
Run Code Online (Sandbox Code Playgroud)
第一个操作数比较等于 0。所以第二个操作数不会被评估,即变量的值a并且b不会改变。因此,变量x将0根据本节的第 3 段进行设置。
来自 C 标准(6.5.14 逻辑 OR 运算符)
3 || 如果其任一操作数比较不等于 0,则运算符应产生 1;否则,结果为 0。结果的类型为 int。
和
4 不同于按位 | 运算符 || 运算符保证从左到右的评估;如果计算第二个操作数,则在第一个和第二个操作数的计算之间存在一个序列点。如果第一个操作数比较不等于 0,则不计算第二个操作数。
在这个表达式语句中
x = 777 || (a = ++b);
Run Code Online (Sandbox Code Playgroud)
第一个操作数比较不等于 0。所以第二个操作数不会被评估,即变量的值a并且b不会改变..所以变量x将1根据本节的第 3 段设置。
如果您将更改表达式中操作数的顺序,例如
x = (a = b = 777) && 0;
x = (a = ++b) || 777;
Run Code Online (Sandbox Code Playgroud)
你得到了预期的结果。