添加文字有關運算符和表達式的知識。
4.1 算術運算符與表達式
什麼是算術運算符?簡單的說就是加、減、乘、除。這些大家應該小學,不,幼兒園就開始學習了。算術運算符就是這些符號的名稱,而算術表達式則是對這些名稱的使用。比如算術運算符“+”。算術表達式就是“a+b”了。是不是很簡單,其實編程本來就是一件簡單的事情。
在C語言有很多算術表達式,表4.1列舉了部分關係表達式。
運算符 |
描述 |
結合性 |
例子 |
優先級 |
+ |
加法運算符 |
從左向右 |
a+b |
12 |
- |
減法運算符 |
從左向右 |
a-b |
12 |
* |
乘法運算符 |
從左向右 |
a*b |
13 |
/ |
除法運算符 |
從左向右 |
a/b |
13 |
% |
取模運算符 |
從左向右 |
a%b |
13 |
+ |
取正數(單目加) |
從右向左 |
+a |
15 |
- |
取負數(單目減) |
從右向左 |
-b |
15 |
注:更詳細的信息,請參考附錄B。
算術運算符類似於數學中的四則運算。但是又與四則運算有些不同,這與C語言本身的性質有關。C語言變量的定義需要指明數據類型,也就是說在程序運行前和運行後都是同一種類型(其他情況暫不考慮,如強制類型轉換),指定類型的目的就是說明要分配的存儲空間的大小。比如:
int a = 5,b=2,c;
c = 5/2;
那麼此時c的值是多少呢?答案是2。在數學中毫無疑問5除以2結果是2.5。而此處結果是2,是因爲c的類型是int,只接受整數2,後面的0.5自動被去掉。類似於數學中的取整運算。
【例4.1】 算術運算符與算術表達式
解題思路:我們只是用簡單的算術運算符和算術表達式來進行簡要的說明。程序中都是基本的加減乘除運算。由於學過上一章的scanf函數,我們可以嘗試做一個簡單計算器。
編寫代碼:
#include <stdio.h>
int main()
{
int a=7, b=3;
printf("a+b=%d\n", a+b);/*加法運算符*/
printf("a-b=%d\n", a-b);/*減法運算符*/
printf("a*b=%d\n", a*b);/*乘法運算符*/
printf("a/b=%d\n", a/b);/*除法運算符*/
printf("a%%b=%d\n", a%b);/*取模運算符,%號的輸出需要多添加一個%*/
printf("+a=%d, +b=%d\n", +a, +b);/*取正運算符*/
printf("-a=%d, -b=%d\n", -a, -b);/*取負運算符*/
return 0;
}
運行結果:
a+b=10
a-b=4
a*b=21
a/b=2
a%b=1
+a=7, +b=3
-a=-7, -b=-3
Press any key to continue
程序分析:這是一個很簡單的程序。程序第9行多使用了一個“%”,因爲要輸出一個百分號需要多寫一個“%”,即“%%”就會輸出一個“%”。那爲什麼“/”,不可以呢?因爲“/”是編譯器級別的轉義,“%”是printf()函數內部解析符號,所以不能用“/”。變量前面加一個‘-’表示負數。
注:
“%”號的作用:(1)“%”用於整數求餘。(2)“%”號放在特定的大小寫字母前表示控制輸入輸出格式。如%d、%x、%X等。
4.2 關係運算符與關係表達式
關係運算符是什麼?就是我們小學裏面學習的大於、小於、大於等於、小於等於、等於、不等於這些符號。而關係表達式就是對這些名稱的具體使用罷了!在C語言中一共提供了6中關係運算符,如表4.2所示,第1列就是關係運算符,第4列就是關係表達式的具體使用。
運算符 |
描述 |
結合性 |
例子 |
優先級 |
縮寫 |
< |
小於 |
從左向右 |
a<b |
10 |
LT |
<= |
小於或等於 |
從左向右 |
a<=b |
10 |
LE |
> |
大於 |
從左向右 |
a>b |
10 |
GT |
>= |
大於或等於 |
從左向右 |
a>=b |
10 |
GE |
== |
等於 |
從左向右 |
a==b |
9 |
EQ |
!= |
不等於 |
從左向右 |
a!=b |
9 |
NE |
注:優先級數字越大,優先級越高。詳見附錄B。
關係運算符的結果值只能是0或1。當關系運算符的值爲真時,結果值爲1。當關系運算符的值爲假時,結果值爲0。
除了關係運算符外,還有算術運算符,賦值運算符等。他們運算符的優先級如圖4.1所示:
例如:
a > b + c; 先進行算術運算b+c,然後再進行關係運算a>(b+c)。算符運算符優先級大於關係運算符優先級。值得注意的是“>”和“>=”類似。
a = b < c; 先進行關係運算b<c,然後再進行賦值運算a=(b<c)。關係運算符優先級大於賦值運算符優先級。值得注意的是“<”和“<=”類似。
a = b + c; 先進行算術運算b+c,然後再進行賦值運算a=(b+c)。算術運算符優先級大於賦值運算符優先級。
a!=b+c;先進行算術運算b+c,然後再進行關係運算a!=(b+c)。算術運算符優先級大於關係運算符優先級。
【例4.2】關係運算符與關係表達式
程序分析:我們使用基本的關係運算符與關係表達式進行編程,程序中提供了小於、小於等於、大於、大於等於、等於不等於以及把關係運算計算過的結果賦值給另一個變量,或者進行比較等。
編寫代碼:
#include <stdio.h>
int main()
{
int a=2, b=3, c=4;
printf("a<b+c的值:%d\n", a<b+c);/*<*/
printf("a<=b+c的值:%d\n", a<=b+c);/*<=*/
printf("a>b+c的值:%d\n", a>b+c);/*>*/
printf("a>=b+c的值:%d\n", a>=b+c);/*>=*/
printf("a=b<c的值:%d\n", a=b<c);/*=*/
printf("a=b+c的值:%d\n", a=b+c);/*=*/
printf("a==b+c的值:%d\n", a==b+c);/*==*/
printf("a!=b+c的值:%d\n", a!=b+c);/*!=*/
return 0;
}
運行結果:
a<b+c的值:1
a<=b+c的值:1
a>b+c的值:0
a>=b+c的值:0
a=b<c的值:1
a=b+c的值:7
a==b+c的值:1
a!=b+c的值:0
Press any key to continue
程序分析:由圖4.1我們知道了三種運算符的優先級。算術運算符大於關係運算符,關係運算符大於賦值運算符。程序第5行在“a<b+c”中,a<
b爲關係運算符,b+c爲算術運算符。由於算術運算符的優先級大於關係運算符,所以先計算b+c的結果爲7,然後在判斷a是否小於7。a爲2,即a<7。關係成立,結果爲1。程序往下分析同理。
4.3 邏輯運算符與邏輯表達式
在C語言中提供了三種邏輯運算符。他們分別是“!”,“&&”,“||”。事實上邏輯雲算符與變量結合運算,並不改變變量的值,而是影響運算結果。它們的具體解釋如表4.3所示。
運算符 |
描述 |
結合性 |
例子 |
優先級 |
|||||||||||||||
! |
邏輯非 |
從右向左 |
|
15 |
|||||||||||||||
&& |
邏輯與 |
從左向右 |
|
5 |
|||||||||||||||
|| |
邏輯或 |
從左向右 |
|
4 |
注:通常0表示假,非0表示真。
邏輯運算符的結果只能是0或1。當邏輯運算符的值爲真時,結果值爲1。當邏輯運算符的值爲假時,結果值爲0。
【例4.3】邏輯運算符與邏輯表達式
解題思路:我們編程程序實現基本的邏輯運算,有取非、邏輯與(&&)、邏輯或(||)以及這三種的各種組合。
編寫代碼:
#include <stdio.h>
int main()
{
int a=1,b=2;
printf("a=%d,b=%d\n", a, b);//輸出a,b的值
printf("!a=%d,!b=%d\n", !a, !b);//輸出非a,非b的值
printf("a&&b=%d\n", a&&b);//輸出a與b的邏輯與
printf("!a&&b=%d\n", !a&&b);//輸出非a與b的邏輯與
printf("a&&!b=%d\n", a&&!b);//輸出a與非b的邏輯與
printf("!a&&!b=%d\n", !a&&!b);//輸出非a與非b的邏輯與
printf("a||b=%d\n", a||b);//輸出a與b的邏輯或
printf("!a||b=%d\n", !a||b);//輸出非a與b的邏輯或
printf("a||!b=%d\n", a||!b);//輸出a與非b的邏輯或
printf("!a||!b=%d\n", !a||!b);//輸出非a與非b的邏輯或
return 0;
}
運行結果:
a=1,b=2
!a=0,!b=0
a&&b=1
!a&&b=0
a&&!b=0
!a&&!b=0
a||b=1
!a||b=1
a||!b=1
!a||!b=0
Press any key to continue
程序分析:當a=1,b=2時,!a,!b的結果值就是0。a&&b的結果值是1。!a&&b與a&&!b的結果值爲0,因爲“!”的優先級(15)大於“&&”的優先級(5)。!a&&!b的結果值爲0。a||b的結果值也是1!a||b與a||!b的結果值爲1。!a||!b的結果值爲0。所以就有了運行結果中的值。
4.4 條件運算符與條件表達式
條件運算符就是當你滿足某種條件時去執行一種情況,不滿足條件時去執行另一種情況。在C語言中存在一個唯一的三目條件運算符。三目運算符的優先級大於賦值運算符。
條件表達式的一般形式:
表達式1 ? 表達式2 : 表達式3
其中:“?”,“:”都是條件運算符。
該條件表達式的含義:經過運算,如果“表達式1”成立則執行“表達式2”。否則執行“表達式3”。通過圖4.2我們可以直觀的瞭解這樣一個三目條件運算符。
通過圖4.2我們會發現它和我們將要講的if語句很相似,如下。
if(表達式1)
{
表達式2;
}
else
{
表達式3;
}
如果表達式1爲真,則執行表達式2。如果表達式1爲假(不爲真),則執行表達式3。另外if-else我們將在後面介紹。
比如:
c=a>b?5:6;表示如果a大於b,就把5賦值給c。如果a不大於b,就把6賦值給c。當a等於2,b等於3時,判斷知a不大於b,所以把6賦值給c。
c=a>b?b+1:6;由於算術運算符的優先級大於關係運算符大於條件運算符,所以先執行b+1,然後再執行關係運算符,最後執行條件運算符。當a等於5,b等於4時,首先執行b+1後值爲5,接着判斷知a大於b,所以把b+1的值賦值給c,所以c等於5。
c=a>=b?’A’:’Z’;表示如果a大於等於b,就把字符’A’的ASCII碼值賦值給c。如果a小於b,就把’Z’的ASCII碼值賦值給c。
c=a==b?a>b:a<b;由於關係運算符大於條件運算符,所以先進行關係運算符的運算然後進行條件運算符的運算。假設a等於1,b等於2的時,先執行a==b、a>b與a<b,它們執行後的結果分別爲0、0和1,然後在執行三目運算符c=0?0:1,所以最終結果爲c的值爲1。具體實現請看代碼例4.4。
【例4.4】三目運算符與三目表達式
解題思路:同樣我們也是提供三目運算符與三目表達式相應代碼,使用三目結構,在大於、小於、大於等於、小於等於不等於、相等等幾種情況下的編碼。
編寫代碼:
#include <stdio.h>
int main()
{
int a=1,b=2,c;
printf("a=%d, b=%d\n", a,b);
c = a>b?5:6;//如果a大於b,則5賦值給變量c,否則6賦值給變量c
printf("a>b?5:6的結果:%d\n", c);//輸出三目運算之後的結果,無特殊說明以後同理
c = a<b?b+1:6;//如果a小於b,則b+1賦值給變量c,否則6賦值給變量c
printf("a<b?b+1:6的結果:%d\n", c);
c = a>=b?'A':'Z';//如果a大於等於b,則字符‘A’賦值給變量c,否則‘Z’賦值給變量c
printf("a>=b?'A':'Z'的結果:%d\n", c);
c = a<=b?'a':'z';//如果a小於等於b,則字符‘a’賦值給變量c,否則‘z’賦值給變量c
printf("a<=b?'a':'z'的結果:%d\n", c);
c = a!=b?a+b:a-b;//如果a不等於b,則a+b的值賦值給變量c,否則a-b的值賦值給變量c
printf("a!=b?a+b:a-b的結果:%d\n", c);
c = a==b?a>b:a<b;//如果a等於b,則a>b的關係運算結果賦值給變量c,否則a>b的關係運算結果賦值給變量c
printf("a==b?a>b:a<b的結果:%d\n", c);
printf("a==b?\"bad\":\"Good\"的結果:%s\n", a==b?"bad":"Good");//如果a等於b輸出字符串bad,否則輸出Good
return 0;
}
運行結果:
a=1, b=2
a>b?5:6的結果:6
a<b?b+1:6的結果:3
a>=b?'A':'Z'的結果:90
a<=b?'a':'z'的結果:97
a!=b?a+b:a-b的結果:3
a==b?a>b:a<b的結果:1
a==b?"bad":"Good"的結果:Good
Press any key to continue
程序分析:此處是三目運算的運行結果。我們只需要記住三目運算符的使用規則就行了。形如1?2:3,如果公式1成立,執行2。否則執行公式3。所以按照此思想進行判斷即可。程序第6行,首先判斷a是否大於b,因爲a爲1,b爲2,所以a>b不成立,即三目運算符最後的結果爲6。最後把6賦值給c,所以程序第7行輸出結果爲6。以下的判斷方式相同。
【例4.5】三目運算實現判斷閏年
解題思路:這是一個三目運算的實際應用,我們採用三目運算符計算某一年是否是閏年。我們都知道閏年可以4整除且不可被100整除,或者被400整除。基於此思想我們使用兩個三目運算符,第一個三目運算符先拿年份對100取餘,如果餘數爲0,一定不是閏年。如果餘數不爲0,則說明有可能是閏年。然後我們再讓年份取4的餘數,判斷餘數是否爲0,爲0是閏年。否則不是閏年。
編寫程序:
#include <stdio.h>
int main()
{
int num;
printf("請輸入一個年份:");
scanf("%d", &num);
printf("%s\n", num%(num%100?4:400)?"No":"Yes");//判斷年份是否是閏年
return 0;
}
第一次運行結果:
請輸入一個年份:2008
Yes
Press any key to continue
第二次運行結果:
請輸入一個年份:2010
No
Press any key to continue
程序分析:在printf()函數中我們發現,它是兩個三目條件運算符的結合。我們首先根據運算符的優先級,然後再進行運算。由於括號的優先級大於三目運算符的優先級,所有我們會先計算num%100?4:400,假設我們輸入的年份是閏年2008年,則num值爲2008,num%100的值爲8,不等於0爲真(即2008不能被100整除),所以括號內的計算結果爲4。然後再運算num%4?”No”:”Yes”,由於2008%4的值爲0,所以就有0?”No”:”Yes”表達式,所以最終結果值爲“Yes”。平年就算過程一樣,這裏就不再贅述。