上一篇 <一起學習C語言:C語言基本語法(一)> 中,我們瞭解if語句的語法和不同的應用場景,以及語句塊的使用方式。本篇文章中,我們分析邏輯運算符的用法,並通過幾個示例分析邏輯運算符之間的執行順序。
章節預覽:
2. 邏輯運算符
2.1 邏輯運算符用法
2.2 布爾型變量
2.3 邏輯表達式
2.4 邏輯運算符的優先級
目錄預覽
章節內容:
2. 邏輯運算符
部分場景下,一個簡單條件已無法滿足判斷需求時,可以通過對多個簡單條件優化,組成複合條件。
【例2.1】 如果今天不上班,並且健身房照常營業,那麼我會去健身房鍛鍊。
這個示例是由兩個簡單條件組成的複合條件:1. 今天是否上班;2. 健身房是否營業。只有這兩個條件都滿足時,纔去健身房。
2.1 邏輯運算符用法
邏輯運算符分爲三種:與(&&)、或(||)、非(!)。參考圖2.1-1 邏輯運算符表:
邏輯運算符 | 英文名 | 含義 | 相近含義 | 舉例 | 說明 |
---|---|---|---|---|---|
&& | AND | 邏輯與 | 且/而且 | a && b | 如果a和b都爲真,則表達式成立,否則表達式不成立 |
|| | OR | 邏輯或 | 或者 | a || b | 如果a或b其中一個爲真,則表達式成立,否則表達式不成立 |
! | NOR | 邏輯非 | 不等於 | !a | 如果a爲假,則!a爲真,表達式成立,如果a爲真,則!a爲假,表達式不成立 |
現在我們分析 【例2.1】:
根據這個例子,我們選擇使用“&&”,表示式爲:if (今天不上班 && 健身房照常營業)。
表達式成立代碼:
int a = 1, b = 1;
if (a == 1 && b == 1)
{
printf(“表達式成立。”);
}
else
{
printf(“表達式不成立。”);
}
【例2.2】 班主任在同學們的提議下組織一次春遊活動。如果參團人數達到50人,使用班級費用報銷活動費用。如果參團人數少於50人,則由每位參團同學交納20元錢用於活動費用,如果同學們不願交納活動費用,則取消春遊活動。
根據這個例子,我們選擇使用“||”,表示式爲:if (參團人數大於等於50人 || 每位參團同學交納20元錢)。
表達式不成立代碼:
int a = 49, b = 0;
if (a >= 50 || b == 20)
{
printf(“本次春遊活動組織成功,同學們可以玩耍一天了。”);
}
else
{
printf(“本次春遊組活動織失敗,同學們繼續上課。”);
}
程序分析:
【例2.1】 和 【例2.2】 實現代碼中,我們分別使用了與、或運算符,並通過對變量值修改,製造出表達式成立和表達值不成立兩種情況。在實際編程中,我們需要考慮更多的因素,比如:數據是否異常、數據值範圍不明確、運算符的優先級等問題。
邏輯與、或運算符分析:
“&&”、“||”屬於雙目運算符,它需要有兩個運算對象,比如: (a != 0) && (b != 0) ,(a != 0) || (a > b)。“&&”和“||”的執行順序都是從左向右,即先判斷左側條件,然後判斷右側條件。
現在,我們還沒有講述“!”運算符,彆着急!我們先了解一個新的變量,參考這個變量更容易理解。
2.2 布爾型變量
在C99標準中,增加了一種稱作“邏輯型”的單字節數據類型,一般叫做布爾型。布爾型的原型是_Bool關鍵字,定義在<stdbool.h>文件中,程序中一般使用它的宏定義bool。bool類型擁有兩個符號常量true和false,true代表1,false代表0,程序中用它們表示真和假。
布爾型在程序可以這麼用:
int a = 1, b = 2;
bool c = a < b; //關係賦值
或 bool a = true, b = false; //直接賦值
【2.3】 班主任在同學們的提議下組織一次春遊活動。如果參團人數少於50人,使用班級費用報銷活動費用。如果參團人數達到50人,則由每位參團同學交納20元錢用於活動費用,如果同學們不願交納活動費用,則取消春遊活動。
(1) 根據這個例子,我們選擇使用“!”,表示式爲:if (!(參團人數大於等於50人 || 每位參團同學交納20元錢))。
表達式成立代碼:
int a = 20, b = 0;
if (!(a >= 50 || b == 20))
{
printf(“本次春遊活動組織成功,同學們可以玩耍一天了。”);
}
else
{
printf(“本次春遊組活動織失敗,同學們繼續上課。”);
}
(2) 現在使用bool對象編寫if語句,表示式爲:if (!c)。
表達式不成立代碼:
int a = 50, b = 0;
bool c = a >= 50 || b == 20;
if (!c)
{
printf(“本次春遊活動組織成功,同學們可以玩耍一天了。”);
}
else
{
printf(“本次春遊組活動織失敗,同學們繼續上課。”);
}
程序分析:
【例2.3】 我們編寫兩種實現代碼:(1)採用“!”和“||”兩種邏輯運算符組合編寫,這種方式需要我們理解不同邏輯運算符之間的優先級關係,稍有不慎就會得到意料之外的結果。(2)採用“!”和布爾型對象組合編寫,這種方式可以讓我們更容易分析判斷邏輯,但在實際編程中,使用第一種(1)方式更直觀一些。
實現代碼(1)和(2)表達的意思相同,首先運算出邏輯或表達的值,然後通過“!”運算取反結果,即1取反爲0,0取反爲1。
邏輯非運算符分析:
“!”屬於單目運算符,它要求有一個運算對象,比如:!a,!(a > b)。“!”的執行順序是從右向做,即先判斷右側條件,然後結果取反,即“真”爲“假”,“假”爲“真”。
2.3 邏輯表達式
由邏輯運算符“控制”運算結果的表達式,稱爲邏輯表達式。邏輯表達式的結果由數字1或數字0,即“真”或“假”表示,結果爲“真”時,即表達式成立,結果爲“假”時,即表達式不成立。而在一個條件中,“假”由0表示,而“真”由非0值表示,比如:
- !(條件):
形式 | 描述 | 非運算形式 | 結果 |
---|---|---|---|
!-2,!2,!(a = -2) | 條件得到的都是非0值,由“真”表示。 | !真 | “假”,即0。 |
!0,!(a = 0) | 條件得到的值都爲0,由“假”表示。 | !假 | “真”,即1。 |
- 條件1 && 條件2:
形式 | 描述 | 與運算形式 | 結果 |
---|---|---|---|
0 && (a = -2) | 它的條件1得到的值爲0,即“假”,直接可以得出“&&”運算結果。 | 假 && 不需要運算 | “假”,即0。 |
(a = 2) && 0 | 它的條件1中,首先變量a賦值爲2,得到條件值爲2,即“真”。它的條件2得到的值爲0,即“假”。 | 真 && 假 | “假”,即0。 |
(a = 2) && (b = -2) | 它的條件1中,首先變量a賦值爲2,得到條件值爲2,即“真”。它的條件2中,首先變量b賦值爲-2,得到條件值爲-2,即“真”。 | 真 && 真 | “真”,即1。 |
- 條件1 || 條件2
形式 | 描述 | 或運算形式 | 結果 |
---|---|---|---|
2 || (a = 0) | 它的條件1得到的值爲2,即“真”,直接可以得出“||”運算結果。 | 真 || 不需要運算 | “真”,即1。 |
0 && (a = -2) | 它的條件1得到的值爲0,即“假”。它的條件2中,首先變量a賦值爲-2,得到條件值爲-2,即“真”。 | 假 && 真 | “真”,即1。 |
0 && 0 | 它的條件1和條件2得到的值都爲0,即都爲“假”。 | 假 && 假 | “假”,即0。 |
2.4 邏輯運算符的優先級
在一個邏輯表達式中,可以包含多個邏輯運算符,比如:!(a != 0) && (a > 2) || (b == 0)。這時候,需要我們瞭解每個邏輯運算符的優先順序,才能設計出我們需要的表達式。下面我們編寫個示例,分析出它們之間的執行順序。
【例2.4】 通過“!(a != 0) && (a > 2) || (b == 0)”表達式分析出“!”、“&&”和“||”之間的執行順序。
根據不同邏輯運算符的特性,我們可以把示例中的表達式分成多個部分單獨運算:
【部分1】 通過“&&”運算符編寫出結果爲“真”的表達式:
int a = 20;
if ((a != 0) && (a > 2))
{
printf(“表達式成立。”);
}
else
{
printf(“表達式不成立。”);
}
【部分1】 執行結果:
輸出:“表達式成立。”。
【部分2】 在部分1的實現代碼中,分別在表達式左側和右側判斷條件前增加“!”運算符,並輸出結果:
【部分2.1】 左側增加“!”運算符:
int a = 20;
if (!(a != 0) && (a > 2))
{
printf(“表達式成立。”);
}
else
{
printf(“表達式不成立。”);
}
【部分2.1】 執行結果:
輸出結果爲:“表達式不成立。”。
【部分2.2】 右側增加“!”運算符:
int a = 20;
if ((a != 0) && !(a > 2))
{
printf(“表達式成立。”);
}
else
{
printf(“表達式不成立。”);
}
【部分2.2】 執行結果:
輸出結果爲:“表達式不成立。”。
【部分2】 執行分析:
示例原型 | 運算表達式 | 結果 |
---|---|---|
(a != 0) && (a > 2) | 真 && 真 | “真”,即1。 |
!(a != 0) && (a > 2) | 假 && 真 | “假”,即0。 |
(a != 0) && !(a > 2) | 真 && 假 | “假”,即0。 |
【部分2】 實現代碼,在“與”表達式成立的基礎上,分別在左側和右側條件前增加“非”運算符,值都爲“假”。可以推算出“與”的優先級低於“非”,即“!”->“&&”。
接下來計算“與”和“或”之間的執行順序,如果“與”的優先級高於“或”,那麼不用再繼續判斷,即可得出結論。
【部分3】 在部分1的實現代碼中,分別在表達式左側和右側判斷條件增加“||”運算符和條件,並輸出結果:
【部分3.1】 左側增加“||”運算符和條件:
int a = 20, b = 0;
if ((b == 0) || (a != 0) && (a < 20))
{
printf(“表達式成立。”);
}
else
{
printf(“表達式不成立。”);
}
【部分3.1】 執行結果:
輸出結果爲:“表達式成立。”。
【部分3.1】 執行分析:
這個示例比較燒腦,我們分析一下它的執行思路。
如果程序先執行“(b == 0) || (a != 0)”這部分,得到結果爲“真”, (a < 20)得到的結果爲“假”,可以得到“與”表達式“真 && 假”,示例結果爲“假”,表達式不成立。
但實際結果爲“真”,只能先執行“與”表達式,得到結果爲“假”,然後執行“或”表達式“真 || 假”,示例結果爲“真”,表達式成立。
【部分3.2】 右側增加“||”運算符和條件:
int a = 20, b = 0;
if ((a < 0) && (a > 2) || (b == 0))
{
printf(“表達式成立。”);
}
else
{
printf(“表達式不成立。”);
}
【部分3.2】 執行結果:
輸出結果爲:“表達式成立。”。
【部分3.2】 執行分析:
如果程序先執行“(a > 2) || (b == 0)”這部分,得到結果爲“真”,(a < 0)得到的結果爲“假”,可以得到“與”表達式“假 && 真”,示例結果爲“假”,表達式不成立。
但這裏的實際結果也爲“真”,只能先執行“與”表達式,得到結果爲“假”,然後執行“或”表達式“假 || 真”,示例結果爲“真”,表達式成立。
【部分3】 執行分析:
示例原型 | 運算表達式 | 結果 |
---|---|---|
(a != 0) && (a > 2) | 真 && 真 | “真”,即1。 |
(b == 0) || (a != 0) && (a < 20) | 真 || (真 && 假) | “真”,即1。 |
(a < 0) && (a > 2) || (b == 0) | (假 && 真) || 真 | “真”,即1。 |
部分3實現代碼,在“與”表達式成立的基礎上,分別在左側和右側條件增加“或”運算符和條件,值都爲“真”。可以推算出“與”的優先級高於“或”,即“&&”->“||”。
程序分析:
【例2.4】 我們通過三部分表達出了邏輯運算符之間的關係,首先通過“與”運算符和“非”運算符比較,得出“非”的優先級高於“與”,然後通過“與”運算符和“或”運算符比較,得出“與”的優先級高於“或”的結論。
“與”、“或”、“非”,之間的優先級關係爲:“非”高於“與”,“與”高於“或”,即“!” ->“&&” ->“||”。
實際編程中,在我們不清楚運算符之間的優先級時,可以通過小括號進行代碼保護,比如:!( (a < 0) && ( (a > 2) || (b == 0) ) )。
目錄預覽
<一起學習C語言:C語言發展歷程以及定製學習計劃>
<一起學習C語言:初步進入編程世界(一)>
<一起學習C語言:初步進入編程世界(二)>
<一起學習C語言:初步進入編程世界(三)>
<一起學習C語言:C語言數據類型(一)>
<一起學習C語言:C語言數據類型(二)>
<一起學習C語言:C語言數據類型(三)>
<一起學習C語言:C語言基本語法(一)>