【问题标题】:behavior of print function inside a Boolean expression [duplicate]布尔表达式中打印函数的行为[重复]
【发布时间】:2021-04-16 14:30:43
【问题描述】:

语言: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 boolean printf logical-and


【解决方案1】:

根据 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 的第二个操作数也被计算。

【讨论】:

  • 是在所有情况下都短路还是在某些情况下停止?或者如果我使用scanf(必须声明)而不是printf(已经声明)..
  • @neversettleevolve 这是逻辑与运算符的一般行为。 scanf 的返回类型为 int。所以它可以用在带有逻辑 AND 运算符的表达式中。
【解决方案2】:

逻辑和运算符&amp;&amp; 的评估是短路评估

考虑到A &amp;&amp; B,首先评估A。当A 为真时,A &amp;&amp; B 可以变为真并评估B。当A 为假时,A &amp;&amp; B 永远不会为真,B 不会被评估。

现在看看实际案例。

在案例 3 (a == b) &amp;&amp; printf("your ") 中,(a == b) 为假,因为 a (1) 不等于 b (2)。因此,现在我们失去了表达式 (a == b) &amp;&amp; printf("your ") 变为真的所有机会,因此不评估 printf("your ")。这意味着函数没有被执行。

在案例 4 !(a == b) &amp;&amp; printf("your ") 中,!(a == b) 为真,因为 (a == b) 为假。现在表达式!(a == b) &amp;&amp; printf("your ") 可能会根据printf("your ") 的值变为真,因此会评估printf("your ") 并执行函数。

【讨论】:

  • so 快捷方式也优化了代码,减少了运行时间。
【解决方案3】:

案例 3:

这是由于编译器优化了语句。由于使用了括号,语句从左到右翻译和评估。第一个表达式是: (a == b) 因为 a 和 b 的值而为假。编译器发现 ((a == b) && printf("your")) 中的表达式的结果总是会产生错误。因此优化要求不要为 printf("your") 生成代码。 我敢打赌,如果你在 demode 模式下编译它,你会看到预期的结果。

案例4的解释留给你自己。这很明显。 (提示注意运算符“!”、“&&”的优先级)

祝你好运。

【讨论】:

  • 不,这绝对与优化无关。这纯粹是由于短路评估
  • 优化不得改变可观察的行为。只有在 C++ 中可以优化出一些构造函数,但这个问题是关于 C
  • 而且和这段代码中的括号无关。
  • 短路评估不是优化方案的一部分吗?很明显,括号可能与行为无关,但它们使代码更容易理解。
  • 您能否解释和对比案例 4 和案例 3 中的差异,让他明白。就我而言,你的观点似乎没有为这家伙提出的问题带来任何亮点。
猜你喜欢
  • 2019-05-10
  • 2017-05-03
  • 2013-07-02
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多