布尔表达式中打印函数的行为

问题描述

语言:C

如果输入 0,则布尔表达式输出 0,否则输出 1。

根据上述声明,

案例 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

案例 3: 现在我将 prinf 函数添加到(“你的”)

输入

    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 的解释留给您自己。这很明显。 (提示注意运算符“!”、“&&”的优先级)

祝你好运。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...