逻辑操作符和关系操作符

来源:互联网 发布:crm源码 编辑:程序博客网 时间:2024/05/19 16:19
!  逻辑非  !expr 
<  小于    expr < expr
<= 小于等于  expr <= expr
>  大于    expr > expr
>= 大于等于  expr >= expr
==  相等   expr == expr
!=  不等   expr != expr
&&  逻辑与 expr && expr
||  逻辑或 expr || expr

关系操作符和逻辑操作符使用算术或指针类型的操作数,并返回bool类型的值.

1.逻辑与、逻辑或操作符

逻辑操作符将其操作数视为条件表达式:首先对操作数求值;若结果为0,则条件为假(false),否则为真(true).仅当逻辑与(&&)操作符的两个操作数都为true,其结果才得true.对于逻辑或(||)操作符,只要两个操作符之一为true,它的值就为true.给定以下形式:

expr1 && expr2  //logical AND

expr1 || expr2    //logical OR

仅当由expr1不能确定表达式的值时,才会求解expr2.也就是说,当且仅当下列情况出现时,必须确保expr2是可以计算的.

a.在逻辑与表达式中,expr1的计算结果为true.如果expr1的值为false,则无论expr2的值是什么,逻辑与表达式的值都为false.当expr1的值为true时,只有expr2的值也是true,逻辑与表达式的值才为true.

b.在逻辑或表达式中,expr1的计算结果为false.如果expr1的值为false,则逻辑或表达式的值取决于expr2的值是否为true.

------------------------------------------------------------我是等待的分割线---------------------------------------------------

注解:逻辑与和逻辑或操作符总是先计算其左操作数,然后再计算其右操作数.只有在仅靠左操作数的值无法确定该逻辑表达式的结果时,才会求解其右操作数.我们常常称这种求职策略为"短路求值(short-circuit evaluation)".

------------------------------------------------------------我也是等待的分割线-----------------------------------------------

对于逻辑与操作符,一个很有价值的用法是:如果某边界条件使expr2的计算变的危险,则应在该条件出现之前,先让expr1的计算结果为false.例如,编写程序使用一个string类型的对象存储一个句子,然后将该句子的第一个单词的个字符全部变成大写,可如下实现:

string s("Expressions in C++ are conposed...");
string::iterator it=s.begin();
//convert first word in s to uppercase
while (it!=s.end()&&!isspace(*it))
{
 *it=toupper(*it);  //toupper covered in section 3.2.4(章节3.2.4)
 ++it;
}
在这个例子中,while循环判断了两个条件.首先检查it是否已经到达string类型对象的结尾,如果不是,则it指向s中的一个字符.只有当该检验条件成立时,系统才会计算逻辑与操作符的右操作数,即在保证it确实指向一个真正的字符之后,才检查该字符是否为空格.如果遇到空格,或者s中没有空格而已经到达s的结尾时,循环结束.

2.逻辑非操作符

逻辑非操作符(!)将其操作速汇视为条件表达式,产生与其操作数值相反的条件值.如果其操作数为非零值,则做!操作后的结果为false.例如,可如下在vector类型对象的empty成员函数上使用逻辑非操作符,根据函数返回值判断该对象是否为空:

//assign value of first element in vec to x if there is one
int x=0;
if (!vec.empty())
x=*vec.begin();

如果调用empty函数返回false,则子表达式!vec.empty()的值为true.

3.不应该串接使用关系操作符

关系操作符(<、<=、>、>=)具有左结合特性.事实上,由于关系操作符返回bool类型的结果,因此很少使用其左结合特性.如果把多个关系操作符串接起来使用,结果往往出乎预料:

// oops!this condition does not determine if the 3 values are unequal
if (i<j<k)
{
 /*...*/
}

这种写法只要K大于1,上述表达式的值就为true.这是因为第二个小于操作符的左操作数是第一个小于操作符的结果:true或false.也就是,该条件将K与整数0或1作比较.为了实现我们想要的条件检验,应重写上述表达式如下:

if(i<j && j<k){/*...*/}

4.相等测试与bool字面值.

bool类型可转换为任何算术类型-------bool值false用0表示,而true则用1表示.

----------------------------------------------------我是微困的分割线------------------------------------------------

小心:由于true转换为1,因此要检测某值是否与bool字面值true相等,其等效判断条件通常很难正确编写:

if(val==true){/*....*/}

---------------------------------------------------我是微困的分割线-------------------------------------------------

val本身是bool类型,或者val具有可转换为bool类型的数据类型.如果val是bool类型,则该判断条件等效于:

if(val){/*.....*/}

这样的代码更短而且更直接(尽管对初学者来说,这样的缩写可能会令人费解).

更重要的是,如果val不是bool值,val和true的比较等效于:

if(val==1){/*...*/}

这与下面的条件判断完全不同

//condition succeeds if val is any nonzero value
if(val) {/*...*/}

此时,只要val为任意非零值,条件判断都得true.如果显式地书写条件比较,则只有当val等于指定的1值时,条件才成立

 

习题 5.5  解释逻辑与操作符、逻辑或操作符以及相等操作符的操作数在什么时候计算.

逻辑与、逻辑或操作符采用称为"短路求值"的求值策略,即先计算左操作数,再计算右操作数,且只有当仅靠左操作数的值无法确定该逻辑运算的结果时,才会计算右操作数.
相等操作符的左右操作数均需进行计算

习题5.6  解释下列while循环条件的行为:

char *cp="Hello World";
while(cp && *cp)

该while循环的条件为:当指针cp为非空指针并且cp所指向的字符不为空字符null('.0')时执行循环体.即该循环可以对字符串"Hello World"中的字符进行逐个处理.

习题 5.7  编写while循环条件从标准输入设备读入整型(int)数据,当读入值为42时循环结束.

int val;
while (cin>>val && val!=42)
或者

int val;
cin>>val;
while(val!-42)

习题5.8  编写表达式判断四个值a、b、c和d是否满足a大于b,b大于c,而且c大于d的条件

a>b && b>c && c>d