问题描述
语言:C
根据上述声明,
案例 1:
输入
#include <stdio.h>
#include <stdbool.h>
main()
{
int a = 1,b = 2;
bool res = ((a == b) && ("your "));
printf("res = %d",res);
}
res = 0
案例 2:
输入
bool res = (!(a == b) && ("your "));
printf("res = %d",res);
res = 1
输入
bool res = ((a == b) && printf("your "));
printf("res = %d",res);
res = 0 //adding printf doesn't change the output
案例 4: 输入
bool res = (!(a == b) && printf("your "));
printf("res = %d",res);
your res = 1 // i expected just "res = 1" not "your res = 1"
打印功能如何在CASE 3中不执行而在CASE 4中执行?
解决方法
根据 C 标准(6.5.13 逻辑与运算符)
4 与按位二元 & 运算符不同,&& 运算符保证 从左到右评估;如果计算第二个操作数,则有 第一个和第二个评估之间的序列点 操作数。 如果第一个操作数比较等于 0,则第二个操作数 不计算操作数。
在此声明中用作初始值设定项的表达式中
bool res = ((a == b) && printf("your "));
逻辑 AND 运算符的第一个操作数 (a == b)
的计算结果为 0。因此不计算调用 printf
的第二个操作数,
另一方面,在这个表达式中用作声明中的初始化器
bool res = (!(a == b) && printf("your "));
第一个操作数 !(a == b)
的计算结果为 1。因此调用 printf
的第二个操作数也会计算。
逻辑和运算符 &&
的求值是短路求值。
考虑到A && B
,首先评估A
。当 A
为真时,A && B
可以变为真,并评估 B
。当 A
为 false 时,A && B
永远不会为 true 并且不评估 B
。
现在看看实际案例。
在情况 3 (a == b) && printf("your ")
中,(a == b)
为假,因为 a
(1) 不等于 b
(2)。因此,现在我们失去了表达式 (a == b) && printf("your ")
为真的所有机会,因此不计算 printf("your ")
。这意味着该函数没有被执行。
在情况 4 !(a == b) && printf("your ")
中,!(a == b)
为真,因为 (a == b)
为假。现在表达式 !(a == b) && printf("your ")
可能会根据 printf("your ")
的值变为真,因此 printf("your ")
被评估并执行函数。
情况 3:
这是由于编译器优化了语句。由于使用了括号,语句从左到右翻译和计算。第一个表达式是: (a == b) 由于 a 和 b 的值而为假。编译器发现 ((a == b) && printf("your")) 中的表达式的结果将始终为 false。所以优化要求不要为 printf("your") 生成代码。 我敢打赌,如果你在 demode 模式下编译它,你会看到预期的结果。
案例 4 的解释留给您自己。这很明显。 (提示注意运算符“!”、“&&”的优先级)
祝你好运。