2.4.12 运算符的优先级和结合性

    实际在书写程序的时候,一个表达式中往往会有多个运算符,这时的运算顺序主要由以下两种因素决定。

    (1)运算符的优先级:程序总是先执行优先级较高的运算符;

    (2)运算符的结合性:当同优先级的操作符并列时,运算符的结合性决定运行顺序。对从左到右的运算符,先执行左侧的部分,对从右向左的运算符,则先执行右侧的部分。

    表2.9给出了C++中的运算符的优先级和结合性,从上到下,优先级依次降低。

    2.4.12 运算符的优先级和结合性 - 图1

    总地来说,有以下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);

    注意

    为避免出错,请尽量写出简单的代码,不要在一个语句中进行太多的处理,做到一行语句只做一件事情。