1. 程式人生 > >邏輯操作符和關係操作符

邏輯操作符和關係操作符

!  邏輯非  !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