逻辑&&
运算符执行左侧的表达式;并且只有它是真的,它才会在右侧执行表达式。
但在以下示例中,
![C短路和示例] [1]
如果LHS是假的并且RHS没有被执行则它违反了C中运算符的优先顺序,因为一元NOT优先于逻辑&&
:
![C运营商优先顺序] [2]
这背后的逻辑是什么?
答案 0 :(得分:3)
考虑这个表达式:
a*b + c*d
执行了哪个顺序?好吧,我们知道+
必须最后执行,但这里有没有信息关于哪个乘法首先发生。
它可以这样做:
t1 = a * b
t2 = c * d
result = t1 + t2
或者,它可以这样做:
t1 = c * d
t2 = a * b
result = t1 + t2
没有办法知道。
现在考虑一下这个表达式:
a>1 && b<2
逻辑说话,没有理由为什么这需要任何特定的评估顺序。它可能会以任何方式发生,而且没有任何区别。
但是,有时重要的是评估子表达式的顺序:
ptr != NULL && ptr->value == 1
因此,作为便利 C 定义,&&
运算符具有保证评估顺序的特殊行为。
如果C 不以这种方式定义,那么我们必须写下这样的一切:
if (ptr != NULL)
if (ptr->value == 1)
result = true
那就是PITA!
除了文本方便之外,还有另一个原因:优化。
当&&
表达式的一半评估为假时,没有理由检查另一半的结果:这只是浪费时间和电力。所以,编译器想要缩短它。
除非编译器无法删除任何可能具有用户可见(或程序员可见)副作用的内容,除非程序员知道它&#39将要发生。
所以,再一次,行为必须明确定义:左,右。如果不是那么它可能会在优化时改变行为,那将是不好的。
答案 1 :(得分:2)
当一个评估为假时,操作符从左到右操作并且短路操作的逻辑有几个原因,一个是在第一个评估为假之后评估第二个是浪费精力,因为整个条件将会在评估为假之后永远不会评估为True,这样你也可以做一些事情,例如以防止错误的方式命令你的条件,例如:(抱歉你的C问题中的python,但它是我想到的第一)
if 'parameter' in dictionary and dictionary['parameter']:
(do something with parameter that you are now confident exists AND has a value);
如果你颠倒了订单
if dictionary['parameter'] and 'parameter' in dictionary:
可能会引发错误,因为在不存在的字典中要求'parameter'的值是禁止的。
再一次,对于python感到抱歉,但我希望你能得到这个功能对你有利的原因并且可以被精明的编码器利用。