dol*_*phy 31 c++ operator-precedence
我最近遇到了一些我认为我立即理解的东西,但是想更多关于它我想了解为什么它按照它的方式工作.
请考虑以下代码.该(x-- == 9)
显然得到评估,而(y++ == 11)
不是.我的第一个想法是,逻辑上的&&
启动,看到表达式已经变为假,并在评估表达式的第二部分之前开始.
我想的越多,我就越不明白为什么会这样做.据我了解,逻辑运算符按优先级顺序低于增量运算.不(y++ == 11)
应该评估,即使整体表达已经变为假?
换句话说,操作的顺序是否应该(y++ == 11)
在if
语句实现整个表达式之前进行评估将是错误的?
#include <iostream>
using namespace std;
int main( int argc, char** argv )
{
int x = 10;
int y = 10;
if( (x-- == 9) && (y++ == 11) )
{
cout << "I better not get here!" << endl;
}
cout << "Final X: " << x << endl;
cout << "Final Y: " << y << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
Final X: 9
Final Y: 10
Run Code Online (Sandbox Code Playgroud)
Ste*_*sop 49
逻辑运算符按优先级顺序低于增量运算.
优先顺序不是执行顺序.他们是完全不同的概念.优先顺序仅影响在操作符之前评估操作数的执行顺序,优先顺序有助于告诉您每个操作符的操作数.
短路运算符是一个部分例外甚至是操作符在操作符之前进行评估的规则,因为它们评估LHS,然后运算符有说明是否评估RHS,可能评估RHS,然后是结果算术运算符.
不要认为高优先级操作"先执行".想想他们"更紧密".++
的优先级高于&&
,而在表达x ++ && y ++
,运算符优先级指++
"结合更紧密地",以y
比&&
确实,因此表达整体相当于(x++) && (y++)
,不(x++ && y) ++
.
Jam*_*lis 45
不
(y++ == 11)
应该评估,即使整体表达已经成为false
?
否:&&
和||
运算符短路:它们从左到右进行评估,一旦表达式的结果已知,评估就会停止(也就是说,只要知道表达式就是false
一系列的情况的&&
,或true
在一系列的情况下||
)(*) .
做一些不需要做的额外工作是没有意义的.这种短路行为也非常有用,可以编写高级代码.例如,给定指向struct-type对象的指针,您可以测试指针是否为null,然后在后续子表达式中取消引用指针,例如: if (p && p->is_set) { /* ... */ }
.
(*)请注意,在C++中,你可以重载既&&
和||
类型操作数,如果你这样做,他们失去了短路特性(这是一般不宜过载&&
和||
这个原因).
caf*_*caf 13
优先级和关联性不指定实际执行操作的顺序.它们指定操作的分组方式:即,在以下表达式中:
x && y++
Run Code Online (Sandbox Code Playgroud)
......较低的优先级&&
表示它被分组为好像是:
x && (y++)
Run Code Online (Sandbox Code Playgroud)
而不是
(x && y)++
Run Code Online (Sandbox Code Playgroud)
在你的表达式中,相对优先级&&
和++
无关紧要,因为无论如何你已经用括号分隔了那些运算符.
分组(并且因此优先级和结合)指明什么每个操作者正在操作值; 但它没有具体说明何时这样做.
对于大多数运算符,未指定执行运算的顺序 - 但是,如果&&
指定首先计算左手操作数,则仅在左手操作数的结果为非时才计算右手操作数零.
不.优先顺序只是决定你是否得到这个:
A && B
Run Code Online (Sandbox Code Playgroud)
(有A
存在x-- == 9
和B
存在y++ == 11
)或
A == B == C
Run Code Online (Sandbox Code Playgroud)
(A
存在x--
,B
存在9 && y++
和C
存在).
显然,我们正在处理第一个案例.短路完全适用; if A
为true,B
则不进行评估.