为啥 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")
。
【讨论】:
老兄,我的意思是“真实”不是单词;我的意思是它返回一个非零值:) 不!这里我想知道的是,&& 有更多的精确度,所以编译器应该首先检查“你好”,对吧?然后如果它是假的,它会转到||;所以我的问题是为什么不打印你好、很高兴看到你等? #includeprintf("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 中,您说 && has more precidence
- 您混淆了运算符优先级和评估顺序。
评估顺序不依赖于优先级、关联性或(必然)依赖于明显的依赖关系。
【讨论】:
老兄,我的意思是“真实”不是单词;我的意思是它返回一个非零值:) 当然,我认为你对我的帖子读得太多了。我知道你很清楚真假是一个词。 好的,我明白,但是这里所有的条件都是真实的,所以,我要问的是为什么不打印“你好”“很高兴见到你”等 它不会被评估,因为如果 Condition1 已经为真,那么尝试评估 Condition2、Condition3 和 Condition4 是没有意义的。不管其他条件如何计算,控件都会进入if
块。
你好,请编译这段代码并注释 #include为什么这里的输出只有“hie”和“hola”?
逻辑与 (&&
) 的优先顺序大于逻辑或 (||
)。同意。但是,这并不意味着程序必须按该顺序进行评估。它只是说将表达式组合在一起。因此,
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
,优先级告诉乘法运算符应用于2
和3
。 +
应用于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()
不返回 true
或 false
。
它返回写入的字符总数 -- 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”?