您現在的位置是:首頁 > 棋牌
6.5 運算子與表示式
- 由 IT老者 發表于 棋牌
- 2022-09-17
運算子號鍵有什麼
6。5 運算子與表示式
上一節詳細介紹了資料型別轉換的方法。本節主要講常用運算子及表示式,包括自加、自減、複合賦值、簡單條件、逗號運算子以及它們構成表示式。
運算子是具有特定計算功能的符號,是一種特殊的函式實現。運算子有單目運算子、雙目運算子等,前者需要一個運算物件或運算量,後者左右兩邊各需要一個運算物件或運算量。一般雙目運算左右兩個運算量的資料型別應該相同,如果資料型別不同,則自動進行型別轉換後進行計算。
表示式是帶有值的運算式,在參與運算中地位等同於一個數。所以變數、常量和函式等也是最簡單的表示式。我們可以用運算子連線表示式構成新的表示式,表示式的資料型別由運算量的型別的優先順序決定。
程式設計最常用的運算子有算術運算子、賦值運算子、複合賦值運算子、關係運算符、邏輯運算子、逗號運算子、簡單條件運算子、位運算子等。
算術運算子
分為單目運算子+(正)、-(負)、++(自增)、——(自減)運算子,及雙目運算子+(加)、-(減)、*(乘)、/(除)和%(取餘)。在書寫數學表示式時,*號不能省略,/的分子和分母是複雜表示式時都要分別加括號,%是隻針對整數的運算。要注意兩個整數相除的結果是整數,小數部分會被丟棄。
自增++和自減——運算子的運算量只能是變數,用來實現變數的值加1或減1。這兩個運算子可以用在變數之前或之後,其功能有所不同。如:
int i=10,j=10;i++;++i;——j;++j;
等都是正確的。但是如以下表達是錯誤的:
++(i++)、(i+10)++或 ——10、(x+5)——
當自加(減)運算子用在變數之前稱為前加(減),用在變數之後稱為後加(減)。無論運算子用在前還是用在後,如果是構成賦值語句,則兩者是等價的,都等價於x=x+1或x=x-1賦值語句。如:
int i=10,j=20;i++; //可替換++i;——j; //可替換j——;
但是,當前加或後加、前減或後減用作表示式時,情況卻不一樣。此時不僅完成的是變數的自加1或者自減1的功能。整個表示式取值的時機卻有所不同,前加或前減先完成變數賦值後,表示式再取變數的值(先加1或先減1後取值),設i=10,則表示式(++i)的值11、(——i)的值是9,表示式的值與運算後變數i的值一樣;
後加或後減
是先把變數的值給表示式,則完成變數的值增1或減1(先取值再加1或減1),如j=10,則表示式(j++)或(j——)的值都是10,但是j卻分別變成了11或9。
掌握前加(減)和後加(關係)的關鍵是要抓住兩個值,即
變數值
和
表示式值
。不管是前加(減)或後加(減),變數的結果是一樣的,不同的是表示式的值是加(減)後取值還加(減)前取值。通過幾個個例子辨析一下:
int n1,n2,m,k;n1=n2=2;m=++n1;k=n2++;printf(“%d,%d\n”,m,k);
以上程式碼輸出結果為:3,2。n1自加1後值為3,然後表過式(++n1)取n的值再賦給m。接下來表示式(n2++)先取n2的值(即2),然後n2自加1,所以表示式(n2++)賦給k,k的值為2。實際上以上程式碼段可近似寫為:
int n,m,k;
n1=n2=2;
n1=1+1;
m=n1;
k=n2;
n2=n2+1;
printf(“%d,%d\n”,m,k);
很容易發現,所謂
前加
指的是n1在使用前先自加1,後加指的是n2使用後再自加1。
由於前加(減)和後加(減)更像是程式設計中技巧性的東西,初學者不必在上面過度花時間。但是瞭解它們的區別對讀懂他們寫的程式可能是必要的。
賦值運算子
“=”是C語言特有運算子,作用是計算等號=右邊的表示式後再給左邊變數或左值(Lvalue)賦值,同時構成賦值表示式。賦值表示式的值取被賦值後變數的值,如賦值表示式a=10,表示給變數a賦整數10,同時表示式“a=10“也取值10,因此可以將該表示式的值又賦給另一個變數以實現連續賦值,如:
b=(a=10);
由於賦值運算子按照從右至左的順序結合,因此以上表達式可以寫成:
b=a=10;
以上表達式並不是把10分別賦給a和b兩個變數,而是把10先賦給a後,再把表示式(a=10)的值賦給b。
複合賦值運算子
指的是運算子與賦值號組合構成的運算子,基本形式為: op=,op表示運算子,可以是+、-、*、/、%及位運算子等,=號表示賦值,複合賦值運算連線變數與表示式構成複合賦值表示式。要注意複合賦值運算子左邊必須是變數或合法的左值(Lvalue),右邊可以是任何表示式。作用是把左邊變數的值與右邊表示式的值作op運算後,再賦給左邊變數,複合賦值表示式:
變數 op= 表示式
與賦值表示式
變數 = 變數 op 表示式
賦值號左右兩邊的“變數”是同一個變數。如前面學到的“sum=sum+資料項i”“f=f*i”可以分別寫成:
sum += 資料項i;f=f*i;
而x=x*(y-3)可以寫成 x *= y-3。
複合賦值運算也可以作為一個表示式用在其它表示式中,此時複合賦值表示式的值與左邊被賦值以後的變數相等。如以下程式碼:
int a,b;a=10;b=20;a+=b*=a-5;printf(”a=%d,b=%d\n“,a,b);
程式碼執行結果是:a=110,b=100。複合賦值也是按
從右至左的
順序結合的,所以先執行“b*=a-5”,結果b的值和表示式的值都為100,再做a+=100,所以a的值為110。如果程式碼中a-5變為a=5,則結果又是什麼呢?請您思考。
關係運算符
可以完成兩個運算量的比較,有大於>、小於<、大於或等於>=、小於或等於<=和等於==、不等於!=六種。關係運算符構成關係表示式,其值只能有0和1兩種結果,分別表示假和真。關係運算符按從左至右相結合,>、<、>=、<=優先順序相同,且比==和!=高。關係運算符的優先順序低於算術運算子,但高於賦值運算子。如以下兩個表示式是合法的,如:
(1)4 設x為3時,表示式(1)從左至右計算,4 邏輯運算子 可以連線各類表示式構造出較複雜的條件表示式。主要有邏輯與(&&)、邏輯或(||)與邏輯非(!)三種,前面兩種是雙目運算,後一種是單目運算。邏輯與(&&)的優先順序大於邏輯或(||),這種兩運算子的優先順序都低於關係運算符,但是比賦值運算子高。邏輯非(!)的優先順序比算術運算的優先順序高,如: 判斷x在區間[5,20]以內可以用 x>=5 && x<=20表示,判斷ch是大寫字母可以用 ch>=‘A’ && ch<=‘Z’表示,要判斷ch是數字字元可以有ch>=‘0’ && ch<=‘9’。 邏輯與 構成表示式的值只有運算子兩邊結果都為真(非0)時,結果才為1(真),只要有一個表示式為假,結果一定為假。因此表示式 4 && -1 的結果為1,但4 && 0的結果為0。 判斷x的值在區間[5,20]之外可以用x<5 || x>20表示。 如當x分別為1時,有x<5為真,所以表示式的值為1(真),當x為10時,運算子兩邊的表示式都為假,結果為0(假)。 邏輯或 運算只要兩邊的表示式有一個為真(非零)時,結果就為真,只有兩個同時為假時,結果才為假。 所以有5 || 0為真,0 || 0為假。 邏輯非 (!)是把真變假,假變真的運算子。如表示x在區間[5,20]之外的表示式,除了可用x<5||x>20之外。還可以用!(x>=5 && x<=20)表示,意味著x不在[5,20]區間內,事實上兩種表示法是等價的。!0的結果為1,!1的結果為0。 表示式: a>20 || 3 + 10 && 2 含有算術運算子、邏輯運算子和關係運算符,計算優先順序是什麼呢?首先計算算術運算3+10,結果為13。然後計算a>20結果為0或1,表示式化簡為 (0或1) || 13 && 2 因為&&高於||,所以計算13&&2,結果為1。再與前面的值進行 || 運算,結果為1。所以表示式無論a為多少,結果都是1。 邏輯運算最容易搞錯的是其“ 短路原理 ”。即A||B中,只要計算A為1,B不再計算。A && B中要計算A為零,B也不用再計算。如程式碼段: int a=3,b=5;int c,d;c= (a+=3) || (b+=5);d= (b-=5) && (a=10);printf(”a=%d,b=%d,c=%d,d=%d\n“,a,b,c,d); 在給c賦值時,由於複合賦值表示式a+=3的值為6且變數a也變成了6,根據“短路原理”,不再計算b+=5,所以b的值不變。在給d賦值時,複合賦值語句b-=5的值為0(假),b的值也為零,所以不再計算a=10,所以a的值保持不變。所以最後顯示結果為:a=6,b=0,c=1,d=0。注意的是賦值運算子的優先順序比邏輯運算子低,所以要先加上括號。 例2: 請寫出判斷x與y不能同時為零的表示式。 (1)最簡單的方法是先寫出同時為零的表示式 x==0 && y==0,然後加上!運算子,即!(x==0 && y==0); (2)不同時為零,就是至少有一個不為零,可以用邏輯或運算,即:x!=0 || y!=0; (3)由於表示式x!=0只有當x是非0時為真,是0為假,因此x!=0等價於x,所以(2)可以簡寫為:x || y。 簡單條件運算子 (?:)是根據一個條件表示式的值來確定表示式的取值。構成的表示式稱為簡條件表示式,基本格式如下: e1 ? e2 : e3 e1稱為條件表示式,先計算表示式e1的值,如果e1的結果為1(真),則選擇表示式e2的值,否則選擇表示式e3的值。簡單條件表示式常用來簡化某些if_else語句。如: if(x>=60) y=1;else y=0; 可以用簡單條件表示式寫成: y = (x>=60) ? 1: 0; 原來用幾行寫完的程式碼,現在一行就能寫完,程式碼更加簡潔易讀。 再來看一個判斷空間是否用完的程式,如果n表示當前已經使用空間,MAXSIZE表示最大申請空間。如果空間用完函式返回1(真),否則返回0(假)。用if_else語句是這樣寫的: if(n==MAXSIZE) return 1;else return 0; 用簡單條件表示式可簡寫為: return n==MAXSIZE ? 1 :0; 最後來看一下求三個變數最大值的簡單條件表示式如何寫?用兩個簡單條件表示式就可省掉兩個if_else語句的書寫。 max=( a > b) ? a : b;max= (c > max)? c : max; 逗號運算子 (,)是用來連線一系列表示式,逗號運算子連線的表示式系列稱為逗號表示式,其取值為最後一個表示式的值。用法如下: 表示式1,表示式2,。。。。,表示式n 如以下例子: int a, b, c;(a=2), (b=3), (c=a+b); 由於逗號運算子的優先順序最低,比賦值運算子還要低。所以,上面第二行括號可以省略如下: a=2, b=3, c=a+b; 注意,不要錯把2,b=3,c=a+b理解為逗號表示式。該表示式的第一個表示式是a=2。我們可以用逗號表示式把多條賦值語句或複合語句變成一條件語句,如上面的表示式對應的是以下三條語句。 a=2;b=3;c=a+b; 逗號表示式可以用在for語句中的e1和e3表示式中,如求累加和的程式原來為: sum=0;for(i=1;i<=n;i++) sum=sum+i; 可以把sum=0合到for的表示式e1中,可以把sum=sum+i合到表示式e3中,結果for語句變成了這樣: for( sum=0,i=1 ;i<=n; sum=sum+i,i++ ) ; 用一行for語句完成原來的功能,此時迴圈體只是一個分號而已。 最後講一下sizeof運算子。sizeof是一個運算子,不是一個函式,可以用來獲得 常量、變數、表示式 和 資料型別 等佔用記憶體空間的大小。 要檢視資料型別佔用空間的大小,直接在sizeof後面跟資料型別即可,如: sizeof(int),sizeof(long long)可分別獲得整型和長長整型應該佔空間的大小。 如果想檢視常量、變數或表示式應占用儲存空間的大小,可以如下使用sizeof運算子,如: int a;double b;printf(”%d,%d,%d,%d\n“,sizeof(a),sizeof(b),sizeof(4),sizeof(a+2。0)); 程式執行結果為: 4,8,4,8 說明了變數a與常量4都是int型的,變數b與表示式a+2。0都是雙精度型。 本節簡要介紹了算術運算子、關係運算符和邏輯運算子以及它們構成的表示式,深入介紹了自加、自減運算子、複合賦值運算子、簡單條件運算子等及其相應表示式的使用。本節就講到這裡,下一節再見!