2.4.12 运算符的优先级和结合性
实际在书写程序的时候,一个表达式中往往会有多个运算符,这时的运算顺序主要由以下两种因素决定。
(1)运算符的优先级:程序总是先执行优先级较高的运算符;
(2)运算符的结合性:当同优先级的操作符并列时,运算符的结合性决定运行顺序。对从左到右的运算符,先执行左侧的部分,对从右向左的运算符,则先执行右侧的部分。
表2.9给出了C++中的运算符的优先级和结合性,从上到下,优先级依次降低。
总地来说,有以下6点规律。
❑操作数多的运算符优先级别相对低一点,从高到低依次为单目→双目(不包含赋值运算符)→三目→赋值→逗号;
❑双目运算符个数最多,双目运算符优先级从高到低依次为算术运算符→比较运算符→位运算符→逻辑运算符;
❑算术运算符中,*、/和%的优先级高于+和-;
❑位运算符优先级从高到低依次为~→&→^→|;
❑逻辑运算符优先级从高到低依次为!→&&→||;
❑赋值运算具有相同的优先级。
运算符使用不当会给程序带来这样或那样的问题,除了前面所讲的短路表达式外,还会出现一些程序员经常疏忽或理解有误的地方。
1.二元操作符的潜在缺点
二元操作符左右操作数的计算顺序在C++的标准中并没有明确的规定,如下所示。
int A=5,B; B=(A=2)+(++A);
“A=2”和“++A”的执行顺序是不确定的,而这个顺序却关乎B的结果,先执行语句“A=2”的话,B=5,如先执行“++A”的话,B=8。
可通过分解表达式的方法解决这一问题,将语句“B=(A=2)+(++A);”分解如下。
A=2; ++A; B=A+A;//或B=2*A;
2.程序员对运算符的错误理解
错例1:如果A为0,则对A加1,否则,对A加10,下列语句能否达到目的。
A==0?A+=1:A+=10;上述写法是错误的,程序员的本意如下所示。 A==0?(A+=1):(A+=10);而编译器认为的结果如下所示。 (A==0?A+=1:A)+=10;
因为三目条件运算符的优先级高于赋值运算符。
错例2:判断A、B和C是否相等,下列语句能否达到目的。
A==B==C程序员可能认为:只有在A、B和C相等的时候,上述表达式才为真,而编译器所认为的结果如下。 A==(B==C);
因为赋值符的结合性是从右向左的,上述语句在“A为0、B不等于C”时恒为真。
加括号是个有效的途径,既能强调程序员的意图,提高程序的可读性,又能避免意想不到的错误,如错例1中的语句可写为如下形式。
A==0?(A+=1):(A+=10);而对错例2这种类型,要靠多用多练来克服,以深入理解操作符的含义。为了达到目的,错例2中的代码可改写为如下形式。 (A==B)&&(A==C)&&(B==C);
注意
为避免出错,请尽量写出简单的代码,不要在一个语句中进行太多的处理,做到一行语句只做一件事情。