为啥 printf 不在这里打印?

Posted

技术标签:

【中文标题】为啥 printf 不在这里打印?【英文标题】:why printf is not printing here?为什么 printf 不在这里打印? 【发布时间】:2013-10-19 07:39:09 【问题描述】:

我知道 printf 执行后返回一些非零值 EDIT:returns no. of charecters 现在在这个例子中我使用了多个 printf 和现在。,

 /* As far as i was cocerned Precedence of && is more than ||,
  *and these logical operators check from left to right  
  *So compiler should come to hello and print "hello" then "nice to see you" then "hie" 
  *as all are true it should print "hola" 
  *but i wonder, why here the output is only "hie" and "hola"?
  */  

 #include<stdio.h>
 main()
 
    if(printf("hie")|| printf("hello")&& printf("nice to see you"))
    printf("\thola\n");
 

【问题讨论】:

你为什么要写这样(直言不讳)的废话 我知道,我只是为了好玩而已 :) 【参考方案1】:

成功时printf() 返回写入的字符总数。 因此printf("hie") 返回 3,这足以对逻辑“或”条件进行惰性求值。

printf("hie")|| printf("hello") 
// --> 3 || whatever --> 
// true || whatever --> 
// true

因此,根本不需要评估printf("hello")

【讨论】:

老兄,我的意思是“真实”不是单词;我的意思是它返回一个非零值:) 不!这里我想知道的是,&& 有更多的精确度,所以编译器应该首先检查“你好”,对吧?然后如果它是假的,它会转到||;所以我的问题是为什么不打印你好、很高兴看到你等? #include main() int x=1,y=2; if(x==1 && y>100) printf("你是真的"); else printf("你错了"); 【参考方案2】:

printf("hie") 返回 3,在 C 中任何非零值都表示 true。休息应该简单易懂。

如果遇到这种情况,请注意:

Condition1 || Condition2 || Condition3  || Condition4

在 Condition2 为 false 且 Condition1 也为 false 时评估 Condition3。否则,如果 Condition1 为假,则仅检查 Condition2,如果 Condition2 为假,则检查 Condition3,依此类推。

将不会评估后面的条件(在 Condition1 之后),因为如果 Condition1 已经为真,则尝试评估 Condition2、Condition3 和 Condition4 没有意义。由于控件无论如何都会进入if 块,无论其他条件如何计算。

对于以下情况:

Condition1 && Condition2 && Condition3 && Condition4

当任何条件评估为假时,其他条件的进一步评估不会完成(实际上不需要)。

个别条件可以是更复杂的条件,比如Condition2也可以是形式的表达式——

Condition2 -->   ( SubCondition1 || SubCondition2 )

等等

理解这种情况的一个很好的例子是假设您测试一个对象 NULL,然后您才想测试其他条件:

int *p =NULL;
if( p != NULL && *p < 100)  // -->  *p < 100 Should only checked if p is NOT NULL else Undefined Behavior

^现在想象一下,如果允许这样做,那么我们将取消引用指向 NULL 的指针。这是此类评估的最佳示例/用途之一。

在您的一个 cmets 中,您说 &amp;&amp; has more precidence - 您混淆了运算符优先级和评估顺序。

评估顺序不依赖于优先级、关联性或(必然)依赖于明显的依赖关系。

【讨论】:

老兄,我的意思是“真实”不是单词;我的意思是它返回一个非零值:) 当然,我认为你对我的帖子读得太多了。我知道你很清楚真假是一个词。 好的,我明白,但是这里所有的条件都是真实的,所以,我要问的是为什么不打印“你好”“很高兴见到你”等 它不会被评估,因为如果 Condition1 已经为真,那么尝试评估 Condition2、Condition3 和 Condition4 是没有意义的。不管其他条件如何计算,控件都会进入if 块。 你好,请编译这段代码并注释 #include main() int x=1,y=2; if(x==1 && y>100) printf("你是真的"); else printf("你错了"); 【参考方案3】:

为什么这里的输出只有“hie”和“hola”?

逻辑与 (&amp;&amp;) 的优先顺序大于逻辑或 (||)。同意。但是,这并不意味着程序必须按该顺序进行评估。它只是说将表达式组合在一起。因此,

if(printf("hie")|| printf("hello")&& printf("nice to see you"))

等价于,

 if(printf("hie")  ||  (printf("hello")&& printf("nice to see you")) )

||”运算符发生短路评估:

[C11: §6.5.14/4] 不同于按位 |运算符,||运算符保证从左到右的评估;如果计算第二个操作数,则在第一个和第二个操作数的计算之间存在一个序列点。 如果第一个操作数比较不等于 0,则不计算第二个操作数。

所以,hie 首先打印并返回 non-zero-value,满足 || 条件,然后是 if 条件返回 true


更多关于优先顺序和评估顺序:

其中一个答案指出

评估顺序不依赖于优先级、关联性或(必然)依赖于明显的依赖关系。

虽然这更接近,但这并不完全正确。虽然优先级与评估顺序不同。在某些情况下,优先级间接影响评估顺序。

考虑一下,

1 + 2 * 3

很明显,* 的优先顺序高于+。当两个运算符共享一个操作数时,优先级会深入到图片中,并且操作数与具有最高优先级的运算符分组。在上面的语句*+ 共享相同的操作数2,优先级告诉乘法运算符应用于23+ 应用于1 和乘法的结果。因此,编译器将上述语句解析为,

1 + (2 *3)

上述表达式求值顺序的约束是,没有乘法的结果就不能完成加法。因此,在这种情况下,乘法(较高优先级)在加法(较低优先级)之前进行评估


在你的if() 语句中,优先级告诉编译器以这样一种方式解析语句,即它有一个包含第二和第三printf() 的隐式括号。这并不意味着必须先评估这些内容,如前所述。

所以,我们已经看到了两个案例。一方面,优先级不控制/影响评估顺序,另一方面,优先级具有间接影响。

__

总之

“虽然优先级可能影响评估顺序,但它不决定评估顺序”

【讨论】:

详细解释:阅读 this 以及 this @Srinadh:更新了答案以澄清您在其中一个答案中发布的评论。 @smRaj - 你的报价 While precedence may influence the order of evaluation, it doesn't determine the order of evaluation 是错误的。请阅读 Jerry 的答案 - ***.com/questions/5473107/… @Acme:你能准确地说出它在什么意义上是错误的吗?而且,您真的阅读了我的全部答案吗?特别是1+2*3 部分,如果是,你能说优先级没有影响这个例子中的评估吗? 您采用了单个值而不是表达式,因此该示例并未阐明我的观点。 While precedence may influence the order of evaluation - 优先级与评估顺序有任何关系 - 完全没有影响。评估顺序不依赖于优先级、关联性或(必然)依赖于明显的依赖关系。【参考方案4】:

printf() 不返回 truefalse

它返回写入的字符总数 -- if 语句没有按照您的想法执行。

【讨论】:

老兄,我的意思是“真实”不是单词;我的意思是它返回一个非零值:)【参考方案5】:

首先 Printf() 返回打印的字符数,如果出错则返回负值。

 Secondly,  boolean works as follows
 TRUE || x ==TRUE here compiler wont check x. 
 FALSE && x==FALSE here compiler wont check x.

在其余情况下,编译器将检查 x,即将处理 x。

 In your case 
          printf("hie") gives TRUE hence TRUE ||x ==TRUE case
          i.e. x=printf("hello")&& printf("nice to see you") will not process.

现在为真 ||x==真 将结束 printf("\thola\n");

【讨论】:

好的,但据我所知 && i 的优先级超过 ||所以我认为编译器应该首先检查 && 然后自然它应该打印你好,很高兴见到你等等这就是我的问题:) (如果我错了,请纠正我) ||运算符进行短路评估,这意味着它总是首先评估其左边的参数,只有这样,如果左边的参数为假,它才会评估右边的参数。运算符优先级决定了表达式的分组方式,但是一旦解析,表达式总是从左到右进行计算。换句话说,一个 || b && c 表示 a || (b && c) 由于运算符优先级,但是因为“||”是第一个,它的参数首先被评估。【参考方案6】:

OR 运算符是左关联的,即其左侧的整个表达式被视为其左操作数。在您的情况下,AND 运算符属于 OR 运算符的右操作数。当您不确定一个的关联性时运算符,使用括号。

【讨论】:

以上是关于为啥 printf 不在这里打印?的主要内容,如果未能解决你的问题,请参考以下文章

STM32为啥要用重定向printf来打印串口数据?直接用串口发送函数不行吗

为啥使用 C printf 格式“%#x”打印 0(零)而没有前导“0x”?

了解汇编、nasm、x86 中的 printf 函数。我不知道为啥这段代码没有打印出任何东西

在 Julia 中,为啥 @printf 是宏而不是函数?

任何人都知道为啥以及如何工作?将打印啥[重复]

为啥 printf() 可以在内核中工作,但使用 std::cout 不能?