2.19 逻辑运算符
前面只介绍了courter<=10、total>1000 和 number!=sentinel Value 之类的简单条件(simplecondition)。我们用关系运算符>、<、>=、<=和相等运算符==、!=表示这些条件。每个判断只测试一个条件。要在每个判断中测试多个条件,可以在不同语句中或嵌套if(if/else)结构中进行这些测试。
C++提供的逻辑运算符(logical operator)可以用简单条件组合成复杂条件。逻辑运算符有逻辑与(&&)、逻辑或(||)和逻辑非(!),下面将举例说明。
假设要保证两个条件均为true之后再选择某个执行路径,这时可以用&&逻辑运算符:
if ( gender == 1 && age>= 65 ) ++senior Females;
这个if语句包含两个简单条件。条件gender==1确定这个人是男是女,条件age>=65确定这个人是否为老年人。&&逻辑运算符左边的简单条件先求值,因为::的优先级高于&&。如果需要,再对&&逻辑运算符右边的简单条件求值,因为>=的优先级高级于&&(稍后将会介绍,&&逻辑运算符右边的条件只在左边为true时才求值)。然后if语句考虑下列组合条件:
gender==l&&age>=65
如果两边的简单条件均为true,则这个条件为true。最后.如果这个条件为true,则seniorFemales递增1。如果两边的简单条件有一个为false,则程序跳过该递增,处理if后面的语句。上述组合条件可以通过增加多余的括号而变得更加清楚:
(gender==1)&&(age>=65)
常见编程错误2.24
尽管3<x<7条件在数学上是正确的,但在C++中无法正确求值,应改成(3<x&&x<7)。
图2.28的表格总结了&&逻辑运算符。表中显示了表达式1和表达式2的四种false和true值组合,这种表称为真值表(truth table)。C++对所有包括逻辑运算符、相等运算符和关系运算符的所有表达式求值为false或true。
表达式1 | 表达式2 | 表达式1&&表达式2 |
false | false | false |
false | true | false |
true | false | false |
true | true | true |
图 2.28 逻辑与(&&)运算符真值表
可移植性提示2.5
为了与旧版C++标准兼容,bool值为true表示任何非0值,bool值为false表示0值。
下面考虑逻辑或运算符(||)。假设要保证两个条件至少有一个为true之后再选择某个执行路径,这时可以用逻辑或运算符,如下列程序段所示:
if(semesterAverage)>=90 ||finalExam>=90) cout<<"Student grade is A"<<endl;
上述条件也包含两个简单条件。条件semesterAverage>=90确定学生整个学期的表现是否为"A",条件finalExam>=90确定该生期末考试成绩是否优秀。然后if语句考虑下列组合条件:
semesterAverage>=90 || finalExam>=90
如果两个简单条件至少有一个为true,则该生评为“A”。注意只有在两个简单条件均为false时才不打印消息"Student grade is A"。图2.29是逻辑或(||)运算符的真值表。
&&逻辑运算符的优先级高于||运算符。这两个运算符都是从左向右结合。包含&&和||运算符的表达式只在知道真假值时才求值。这样,求值下列表达式:
gender==1 && age>=65
将在gender不等于1时立即停止(整个表达式为false),而gender等于1时则继续求值(整个表达式在age>=65为true时为true。
表达式1 | 表达式2 | 表达式1&&表达式2 |
false | false | false |
false | true | true |
true | false | true |
true | true | true |
图 2.29 逻辑或(||)运算符真值表
常见编程错误2.25
在使用&&逻辑运算符的表达式中,一个条件(称为相关备件)要在另一个条件为true时才有求值的必要。这时,相关条件应放在另一条件的后面,否则可能发生错误。
性能提示2.10
在使用&&逻辑运算符的表达式中,如果两个条件是相互独立的,则应把false可能性较大的条件放在左边;在使用||逻辑运算符的表达式中,应把true可能性较大的条件放在左边。这样可以减少程序执行时间。
C++提供了逻辑非(!)运算符,使程序员可以逆转条件的意义。与&&和||运算符不同的是,&&和||运算符组合两个条件(是二元运算符),而逻辑非(!)运算符只有一个操作数(是一元运算符)。逻辑非(!)运算符放在条件之前,在原条件(不带逻辑非运算符的条件)为false时选择执行路径,例如:
if(grade!=sentinelValue) cout<<"The next grade is"<<grade<<endl;
这种灵活性有助于程序员以更自然或更方便的方式表达条件。
图2.31显示了前面介绍的c++运算符的优先级和结合律。运算符优先级从上到下逐渐降低。
运算符 | 结合律 | 类型 |
() | 从左向右 | 括号 |
++ -- + - ! static_cast<type>() | 从右向左 | 一元 |
* / % | 从左向右 | 乘 |
+ - | 从左向右 | 加 |
<< >> | 从左向右 | 插入/读取 |
< <= > >= | 从左向右 | 关系 |
== != | 从左向右 | 相等 |
&& | 从左向右 | 逻辑与 |
|| | 从左向右 | 逻辑或 |
?: | 从右向左 | 条件 |
= += -= *= /= %= | 从右向左 | 赋值 |
, | 从左向右 | 逗号 |
图 2.31 运算符优先级和结合律