运算符优先级

  优先级层次的结合性影响到最普通的使用情况。例如,

if(i <= 0 || max < i) // ...

的意思是“如果i小于等于0或者max小于i”。也就是说,它等价于

if((i <= 0) || (max < i)) // ...

而不是下面这个虽然是合法的,但却是一派胡言的

if(i <= (0||max) < i) // ...

然而,如果程序员对某些规则不很清楚,他就应该使用括号。在子表达式变得更加复杂时,使用括号会变得很普遍,但是复杂的子表达式总是错误的一个根源。因此,如果你开始感到需要括号的时候,你或许就应该考虑通过额外的变量将表达式分解开。

  确实存在一些情况,其中运算符的优先级造成的结果不符合“最明显的”解释。例如,

if(i & mask == 0)     // 呜呼! == 表达式被作为 & 的运算对象

这并不是将mask(掩码)作用于i而后检测结果是否为0。因为 == 具有比 & 更高的优先级,表达式将被解释为 i & (mask == 0)。幸运的是,编译器要想对大部分这类情况给出警告不是很难的事情。对于这个情况,加上括号是至关重要的:

if((i & mask) == 0) // ...

值得注意的是,下面的代码不会向数学家们希望的那样工作:

if(0 <= x <= 99) // ...

这是合法的,但却将被解释为(0 <= x) <= 99。由于第一个比较的结果是true或者false,这个布尔值将被隐式地转换到1或0,而后用于与99比较并产生出true。如果真的想检测x是否在0..99的范围内,我们就应该写:

if(0 <= x && x <= 99)    // ...

对于新手,一个最常见的错误就是在条件中将 =(赋值)当做 ==(相等):

if(a = 7) // 呜呼!条件中的常量赋值

这也很自然,因为在许多语言中确实用 = 作为“相等”。再提一句,让编译器对大部分这类错误提出警告也很容易---大部分编译器都会这样做。

🔚