所以,我正在编写一些代码,我在程序的一个部分中获得了意外的输出,这破坏了整个系统。
我设法将问题提取并简化为基本的逻辑表达式。让我们说:
int i = 1, j = 1, k = 0;
printf("%d\n", ++i || ++j && k);
printf("%d, %d, %d\n", i, j, k);
return 0;
该程序的输出是:
1
2
1
0
由于j
运营商的短路性质,我认为2
的值未增加到||
。但是我很困惑第一个"%d"
的值是1
。 k
语句返回&&
时,1
的值不应该为非零吗?或者根本没有执行此声明,因为++i || ++j
不是0
因此返回1
?
&&
是逻辑和, expr1 &&如果 expr1 &&的值为 expr2 ,则值为1 expr2 都非零。任何澄清都将不胜感激,请原谅这个问题的基本性质。
答案 0 :(得分:7)
&&
的优先级高于||
。
(见https://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B)
所以
++i || ++j && k
是
++i || (++j && k)
如果第一个运算符是真的,那么和||
短路,根据6.5.14p4。
如果您使用gcc
或clang
并使用-Wall
编译代码,编译器会轻推您将这些括号放在那里。听取这些建议可能是一个好主意,因为有些人会被优先级混淆(我听说)。
答案 1 :(得分:3)
来自C标准(6.5.14逻辑OR运算符)
3 ||如果任一操作数进行比较,则运算符应为1 不等于0;否则,它产生0.结果的类型为int。
此表达式
++i || ++j && k
相当于
++i || ( ++j && k )
并且根据标准的引用,表达式返回整数值1,因为++i
不等于零。未评估子表达式( ++j && k )
。
答案 2 :(得分:2)
++i || ++j && k
被评估为1(真),因为我等于2(++ 1),因为短路而没有评估(++ j&& k)。
答案 3 :(得分:1)
运营商优先权。 &&
的优先级高于||
。
您的表达式与:++i || (++j && k)
++i
为TRUE
,不再评估括号。