什么是 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。因此第二个操作数未计算,即变量 a
和 b
的值未更改。因此,根据该部分的第 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。因此不计算第二个操作数,即变量 a
和 b
的值未更改。因此变量 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
我正在学习 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。因此第二个操作数未计算,即变量 a
和 b
的值未更改。因此,根据该部分的第 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。因此不计算第二个操作数,即变量 a
和 b
的值未更改。因此变量 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