在第 1 節 “if語句”講過,a<b<c
不表示b
既大於a
又小於c
,那麼如果想表示這個含義該怎麼寫呢?可以這樣:
if (a < b) { if (b < c) { printf("b is between a and c.\n"); } }
我們也可以用邏輯與(Logical AND)運算符表示這兩個條件同時成立。邏輯與運算符在C語言中寫成兩個&號(Ampersand),上面的語句可以改寫為:
if (a < b && b < c) { printf("b is between a and c.\n"); }
對於a < b && b < c
這個控製表達式,要求“a < b
的值非0”和“b < c
的值非0”這兩個條件同時成立整個表達式的值才為1,否則整個表達式的值為0。也就是只有兩個條件都為真,它們做邏輯與運算的結果才為真,有一個條件為假,則邏輯與運算的結果為假,如下表所示:
這種表稱為真值表(Truth Table)。注意邏輯與運算的操作數以非0表示真以0表示假,而運算結果以1表示真以0表示假(類型是int
),我們忽略這些細微的差別,在表中全部以1表示真以0表示假。C語言還提供了邏輯或(Logical OR)運算符,寫成兩個|綫(Pipe Sign),邏輯非(Logical NOT)運算符,寫成一個!號(Exclamation Mark),它們的真值表如下:
邏輯或表示兩個條件只要有一個為真,它們做邏輯或運算的結果就為真,只有兩個條件都為假,邏輯或運算的結果才為假。邏輯非的作用是對原來的邏輯值取反,原來是真的就是假,原來是假的就是真。邏輯非運算符只有一個操作數,稱為單目運算符(Unary Operator),以前講過的加減乘除、賦值、相等性、關係、邏輯與、邏輯或運算符都有兩個操作數,稱為雙目運算符(Binary Operator)。
關於邏輯運算的數學體系稱為布爾代數(Boolean Algebra),以它的創始人布爾命名。在編程語言中表示真和假的數據類型叫做布爾類型,在C語言中通常用int
型來表示,非0表示真,0表示假[6]。布爾邏輯是寫程序的基本功之一,程序中的很多錯誤都可以歸因于邏輯錯誤。以下是一些布爾代數的基本定理,為了簡潔易讀,真和假用1和0表示,AND用*號表示,OR用+號表示(從真值表可以看出AND和OR運算確實有點像乘法和加法運算),NOT用¬表示,變數x
、y
、z
的值可能是0也可能是1。
¬¬x=x
x*0=0
x+1=1
x*1=x
x+0=x
x*x=x
x+x=x
x*¬x=0
x+¬x=1
x*y=y*x
x+y=y+x
x*(y*z)=(x*y)*z
x+(y+z)=(x+y)+z
x*(y+z)=x*y+x*z
x+y*z=(x+y)*(x+z)
x+x*y=x
x*(x+y)=x
x*y+x*¬y=x
(x+y)*(x+¬y)=x
¬(x*y)=¬x+¬y
¬(x+y)=¬x*¬y
x+¬x*y=x+y
x*(¬x+y)=x*y
x*y+¬x*z+y*z=x*y+¬x*z
(x+y)*(¬x+z)*(y+z)=(x+y)*(¬x+z)
除了第1行之外,這些公式都是每兩行一組的,每組的兩個公式就像對聯一樣:把其中一個公式中的*換成+、+換成*、0換成1、1換成0,就變成了與它對稱的另一個公式。這些定理都可以通過真值表證明,更多細節可參考有關數字邏輯的教材,例如[數字邏輯基礎]。我們將在本節的練習題中強化訓練對這些定理的理解。
目前為止介紹的這些運算符的優先順序順序是:!高於* / %,高於+ -,高於> < >= <=,高於== !=,高於&&,高於||,高於=。寫一個控製表達式很可能同時用到這些運算符中的多個,如果記不清楚運算符的優先順序一定要多套括號。我們將在第 4 節 “運算符總結”總結C語言所有運算符的優先順序和結合性。
1、把代碼段
if (x > 0 && x < 10); else printf("x is out of range.\n");
改寫成下面這種形式:
if (____ || ____) printf("x is out of range.\n");
____應該怎麼填?
2、把代碼段:
if (x > 0) printf("Test OK!\n"); else if (x <= 0 && y > 0) printf("Test OK!\n"); else printf("Test failed!\n");
改寫成下面這種形式:
if (____ && ____) printf("Test failed!\n"); else printf("Test OK!\n");
____應該怎麼填?
3、有這樣一段代碼:
if (x > 1 && y != 1) { ... } else if (x < 1 && y != 1) { ... } else { ... }
要進入最後一個else
,x和y需要滿足條件____ || ____。這裡應該怎麼填?
4、以下哪一個if判斷條件是多餘的可以去掉?這裡所謂的“多餘”是指,某種情況下如果本來應該打印Test OK!
,去掉這個多餘條件後仍然打印Test OK!
,如果本來應該打印Test failed!
,去掉這個多餘條件後仍然打印Test failed!
。
if (x<3 && y>3) printf("Test OK!\n"); else if (x>=3 && y>=3) printf("Test OK!\n"); else if (z>3 && x>=3) printf("Test OK!\n"); else if (z<=3 && y>=3) printf("Test OK!\n"); else printf("Test failed!\n");