什么是 C 中的短路评估?

What is short-circuit evaluation in C?

我正在学习 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);

他们只是说想象输出结果并将其与真实输出结果进行比较。我以为输出会是

777 777 0

778 778 1

但它是

0 0 0

0 0 1

&& 运算符使用 lazy evaluation。如果 && 运算符的任一侧是 false,则整个表达式是 false

C 检查运算符左侧的真值,在您的例子中是 0。由于 0 在 c 中为假,因此永远不会评估运算符右侧的表达式 (a = b = 777)

第二种情况类似,除了 || returns true 如果左侧表达式 returns true。还要记住,在 c 中,任何不是 0 的东西都被认为是 true.

希望对您有所帮助。

来自 C 标准(6.5.13 逻辑与运算符)

3 The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.

4 Unlike the bitwise binary & operator, the && operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares equal to 0, the second operand is not evaluated.

在这个表达式语句中

x = 0 && (a = b = 777);

第一个操作数比较等于 0。因此第二个操作数未计算,即变量 ab 的值未更改。因此,根据该部分的第 3 段,变量 x 将设置为 0

来自 C 标准(6.5.14 逻辑或运算符)

3 The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.

4 Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares unequal to 0, the second operand is not evaluated.

在这个表达式语句中

x = 777 || (a = ++b);

第一个操作数比较不等于 0。因此不计算第二个操作数,即变量 ab 的值未更改。因此变量 x 将根据本节的第 3 段设置为 1

如果你要改变像

这样的表达式中操作数的顺序
x = (a = b = 777) && 0;
x = (a = ++b) || 777;

你得到了你期望的结果。

这个表达式的另一个陷阱是;运算符的优先级。如&&、|| (逻辑与,逻辑或)运算符比赋值运算符(=)具有更高的优先级。

在这种情况下 x=(0&&(a=b=777)) 与 x=0&&(a=b=777) 相同,但是 x=(0&(a=b=777)) 更具可读性比上一个。

逻辑运算符 select 其操作数之一和 returns 相应的结果。 他们还强制其操作数为布尔值,如真或假。 在此表达式“x=0&&(a=b=777)”中,由于第一个操作数为假,结果将等于第一个 operand.Second 操作数被短路并且不会 executed.So 输出将是a=b=0, x=0.

x=777 || (a=++b) 在此表达式中,由于第一个操作数为真,结果将等于第一个操作数,逻辑运算符不会检查第二个操作数,逻辑或运算符将绕过第二个 operand.In 此表达式,因为第一个操作数为真(777 转换为真)结果为真意味着 x=1.Since 第二个操作数被跳过“a”和“b”值将保持与之前的值相同,在本例中为 0 ,0