330 likes | 456 Views
第四章 指定敘述. 指定敘述是指將等號右邊運算式的值指定給左邊變數的敘述。指定敘述的格式如下: 變數 = 運算式 ; 變數 變數名稱,為合乎 C 語言規定的識別字。 運算式 運算式為運算元與運算子以及小括號的結合,運算的結果只產生一個值,指定給左邊的變數。
E N D
第四章 指定敘述 • 指定敘述是指將等號右邊運算式的值指定給左邊變數的敘述。指定敘述的格式如下: • 變數 = 運算式 ; • 變數 • 變數名稱,為合乎 C 語言規定的識別字。 • 運算式 • 運算式為運算元與運算子以及小括號的結合,運算的結果只產生一個值,指定給左邊的變數。 • 例如下列的指定敘述: • y=x+6; • 變數為 y,運算式為「x+6」,若「x=3」則「x+6」運算式的值為 9,將 9 指定給 y 變數,因此 y 的值為 9。
4.1 運算元 • 運算式(expression)為運算元(operand)、運算子(operator)、及小括號的結合,運算的結果只產生一個值,指定給左邊的變數(variable),構成一個指定敘述(assignment statement)。運算元可為常數、變數、或另一個運算式。運算式執行運算的順序依運算子的優先順序。 • 常數運算元為一個常數,例如 123 表示整數常數,123.45 表示浮點數常數,'K' 表示字元常數,"How are you?" 表示字串常數等。
識別字運算元 • 識別字運算元一般為變數名稱,或函式名稱。例如下列的 i、f、d、ch、s、rnd 為識別字運算元,rnd() 函式也屬識別字運算元。 • int i; /*i表示一個整數的識別字*/ • float f; /*f表示一個浮點數的識別字*/ • double d; /*d表示一個倍精確浮點數的識別字*/ • char ch; /*ch表示一個字元的識別字*/ • char s[80]; /*s表示一個字串的識別字*/ • int rnd(); /*rnd表示一個傳回值為整數的函式*/
4.2 運算子 • 運算子若只處理一個運算元,稱為一元運算子,處理二個運算元稱為二元運算子,處理三個運算元為三元運算子,三元運算子只有一個,就是「?:」運算子。 • 運算子又可分為算術運算子、關係運算子、邏輯運算子、補數運算子、間接運算子、位址運算子、sizeof運算子、移位運算子、位元運算子、逗號運算子、條件運算子、指定運算子等等,說明如下。
4.2.1 算術運算子 • 算術運算子包括加「+」、減「-」、乘「*」、除「/」、餘數「%」等等。 • 表 4.1 算術運算子表 • 運算子 名稱 說明 • --------- ------ ------------------------------------------------ • + 相加 兩個運算元相加。 • - 相減 兩個運算元相減。; • * 相乘 兩個運算元相乘。 • / 相除 兩個運算元相除。 • % 餘數 第一運算元除於第二運算元之餘數。
/*********** arithmetic.c ************/ #include <stdio.h> int main() { int a=123, b=45; int add, sub, mul, div, remainder; add = a+b; sub = a-b; mul = a*b; div = a/b; remainder = a%b; printf("a=%d b=%d\n", a, b); printf("add=%d+%d=%d\n", a,b,add); printf("sub=%d-%d=%d\n", a,b,sub); printf("mul=%d*%d=%d\n", a,b,mul); printf("div=%d/%d=%d\n", a,b,div); printf("remainder=%d %% %d=%d\n", a,b,remainder); return 0; }
【執行結果】 a=123 b=45 add=123+45=168 sub=123-45=78 mul=123*45=5535 div=123/45=2 remainder=123 % 45=33
程式 arithmetic.c 說明整數的算術運算,其運算結果為整數,然後指定給左邊的整數變數。您有沒有注意到 123 除於 45 的結果,其商為整數 2,因為是整數除法的關係,其商也是只取整數部份而已。運算子「%」是取整數除法的餘數,您可看到「123%45」的餘數為 33。 浮點數的算術運算其結果為浮點數,然後指定給左邊的浮點數變數。但有時在一個算術式中會參雜著整數及浮點數,會將整數先轉型為浮點數後再行運算,運算結果再轉換為等號左邊變數的資料型態。
在 C 語言裡有許多運算子與等於符號「=」結合在一起,算術運算子與「=」結合的有「+=」、「-=」、「*=」、「/=」、「%=」等五種情形: a=a+1; 可寫成 a+=1; 也可以簡寫成 a++; 或 ++a; a=a+b; 可寫成 a+=b; a=a-1; 可寫成 a-=1; 也可以簡寫成 a--; 或 --a; a=a-b; 可寫成 a-=b; a=a%b; 可寫成 a%=b; a++ 與 ++a 對於 a 本身的值增加一,其結果是相同的,但在一個運算式中卻會影響運算式的值,++a 表示 a 值先加一後再與其他運算元運算,a++ 表示 a 值先與其他運算元運算後 a 值再行增加一。 如下例: int a,b=2,c=5; /*宣告a,b,c為整數變數,b初值2,c初值5*/ a=-c++; /*先取c的負數值指定給a後,c值再曾加1*/ /*即a為-5,c為6*/
【程式increment.c】 /*********** increment.c *********/ #include <stdio.h> int main() { int a,b=2,c=5; a=-c++; printf("a=%d c=%d\n", a,c); return 0; } 【執行結果】 a=-5 c=6
4.2.2 關係運算子 • 表 4.2 關係運算子表 • 符號 名 稱 說明 • ------ ----------- -------------------- • < 小於 例如 a<b • > 大於 例如 a>b • <= 小於等於 例如 a<=b • >= 大於等於 例如 a>=b • == 等於 例如 a==b • != 不等於 例如 a!=b • 這六個二元關係運算子測試第一運算元與第二運算元的關係,若關係成立,其值為真(整數值1),否則其值為假(整數值0)。這兩個運算元可為整數、浮點數、或指標。
【程式relation.c】 /************* relation.c *************/ #include <stdio.h> int main() { int a=123, b=456; printf("a=%d b=%d\n", a,b); printf("%d < %d = %d\n", a,b,a<b); printf("%d > %d = %d\n", a,b,a>b); printf("%d <= %d = %d\n", a,b,a<=b); printf("%d >= %d = %d\n", a,b,a>=b); printf("%d == %d = %d\n", a,b,a==b); printf("%d != %d = %d\n", a,b,a!=b); return 0; } 【執行結果】 a=123 b=456 123 < 456 = 1 123 > 456 = 0 123 <= 456 = 1 123 >= 456 = 0 123 == 456 = 0 123 != 456 = 1
4.2.3 邏輯運算子 • 表 4.3 邏輯運算子表 • 符號 名稱 說明 • ------- ------------ -------------- • && 邏輯 AND 例如 e1 && e2 • || 邏輯 OR 例如 e1 || e2 • ! 反 NOT 例如 !e1 • 邏輯運算子「&&」執行邏輯 AND(及)運算、「||」執行邏輯 OR(或)運算,兩個運算元必須為整數、浮點數、或指標。執行時由左至右,直到可判斷出結果為止。「!」執行邏輯 NOT(反)運算,只有一個運算元,若運算元之值非 0 則產生 0,若運算元之值為 0 則產生 1。
/********************* logic.c *****************/ #include <stdio.h> int main() { int a=123, b=456, c=789, e1, e2; e1 = a<b; e2 = a>c; printf("a=%d b=%d c=%d\n", a,b,c); printf("%d<%d=%d %d>%d=%d\n", a,b,e1,a,c,e2); printf("%d && %d = %d\n", e1,e2, e1&&e2); printf("%d || %d = %d\n", e1,e2, e1||e2); printf("!%d = %d\n", e1, !e1); printf("!%d = %d\n", e2, !e2); return 0; } 【執行結果】 a=123 b=456 c=789 123<456=1 123>789=0 1 && 0 = 0 1 || 0 = 1 !1 = 0 !0 = 1
4.2.4 補數運算子 • 表 4.4 補數運算子表 • 符號 名稱 說明 • ------ --------- ------------------------------------------------ • - 取負數 取緊跟在符號後運算元之負數。 • 例如 b=-a; 取 a 之負數值給予 b。 • ~ 逐位元 以逐位元方式取運算元之一系補數。 • 補數 例如 c=~b; 取 b 之一系補數。
b 值為 -1,在電腦記憶體裡以三十二位元表示如下: 1111 1111 1111 1111 1111 1111 1111 1111 取其逐位元一系補數,1 變 0,0 變 1,其結果如下: 0000 0000 0000 0000 0000 0000 0000 0000 其值為整數 0。 【程式complement.c】 /************ complement.c ***********/ #include <stdio.h> int main() { int a=1, b=-a, c=~b; printf("a=%d b=%d c=%d\n", a,b,c); return 0; } 【執行結果】 a=1 b=-1 c=0
4.2.5 間接運算子及位址運算子 • 表 4.5 間接運算子及位址運算子表 • 符號 名稱 說明 • ------ --------------- -------------------------------------- • * 間接運算子 取運算元所指位址的內含值。 • & 取位址 取得運算元之位址。
【程式indirect.c】 /************* indirect.c ***********/ #include <stdio.h> int main() { char ch='A'; char *p; p = &ch; printf("ch=%c p=0x%08p\n", ch,p); printf("*p='%c'", *p); return 0; } 【執行結果】 ch=A p=0x006dffdb *p='A'
4.2.6 sizeof 運算子 • /********************* sizeof.c ******************/ • #include <stdio.h> • int main() • { • printf("sizeof(char)=%d\n", sizeof(char)); • printf("sizeof(int)=%d\n", sizeof(int)); • printf("sizeof(float)=%d\n", sizeof(float)); • printf("sizeof(double)=%d\n", sizeof(double)); • return 0; • } • 【執行結果】 • sizeof(char)=1 • sizeof(int)=4 • sizeof(float)=4 • sizeof(double)=8
4.2.7 移位運算子 • 表 4.6 移位運算子表 • 符號 名稱 說 明 • ------ ------- ----------------------------------------------- • << 左移 將第一運算元左移第二運算元所指定 • 的位元數。 • 兩個運算元必須同為整數。 • >> 右移 將第一運算元右移第二運算元所指定 • 的位元數。 • 兩個運算元必須同為整數。
【程式shifttest.c】 /***************** shifttest.c ***************/ #include <stdio.h> int main() { int m=1, n=-1; printf("m=0x%08x m<<2=0x%08x\n", m, m<<2); printf("m=0x%08x m>>2=0x%08x\n", m, m>>2); printf("n=0x%08x n<<2=0x%08x\n", n, n<<2); printf("n=0x%08x n>>2=0x%08x\n", n, n>>2); return 0; } 【執行結果】 m=0x00000001 m<<2=0x00000004 m=0x00000001 m>>2=0x00000000 n=0xffffffff n<<2=0xfffffffc n=0xffffffff n>>2=0xffffffff
4.2.8 位元運算子 • 表 4.7 位元運算子表 • 符號 名稱 說明 • ----- ------------- ------------------------------------------------------------------- • & 位元AND 兩個算元每一相對應位元執行AND 運算,若為真值 • 則結果運算元相對位元設定為 1,否則為 0。 • | 位元OR 兩個運算元每一相對應位元執行 OR 運算,若為真 • 值則結果運算元相對位元設定為 1,否則為 0。 • ^ 位元XOR 兩個運算元每一相對應位元執行 XOR 運算,若為真 • 值則結果運算元相對位元設定為 1,否則為 0。
表 4.8 位元運算表 a位元值 b位元值 a&b a|b a^b ------------ ------------ ------ ------ ------ 0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 1 1 1 1 0
a = 0000 0000 1111 1111 0000 0000 1111 1111 b = 0000 0000 0000 1111 1111 1111 0000 1111 ───────────────────── c=a&b=0000 0000 0000 1111 0000 0000 0000 1111 d=a|b= 0000 0000 1111 1111 1111 1111 1111 1111
【程式bitoper.c】 /********************* bitoper.c *******************/ #include <stdio.h> int main() { int a=0x00ff00ff, b=0x000fff0f; printf("a=0x%08x b=0x%08x a&b=0x%08x\n", a,b,a&b); printf("a=0x%08x b=0x%08x a|b=0x%08x\n", a,b,a|b); return 0; } 【執行結果】 a=0x00ff00ff b=0x000fff0f a&b=0x000f000f a=0x00ff00ff b=0x000fff0f a|b=0x00ffffff
4.2.9 逗號運算子 • 表 4.9 逗號運算子表 • 符號 名 稱 說 明 • ------ ------------ ------------------------------------------ • , 循序計值 將數個運算元由左至右循序計 • 值,其值為右方運算元之型態。
使用逗號運算子將「i=i+j, j++」由左至右循序計值,先計算「i=i+j」,然後計算「j++」之值。執行時將 i 與 j 值輸出。 【程式comma.c】 /************* comma.c ***********/ #include <stdio.h> int main() { int i, j; for (i=j=1; i+j<12; i=i+j, j++) printf("%d:%d\n", i,j); return 0; } 【執行結果】 1:1 2:2 4:3 7:4
4.2.10 條件運算子 • 條件運算子「?:」為三元運算子,其語法如下: • 運算元1 ? 運算元2 : 運算元3 • 若「運算元1」非零值,則條件運算子執行的結果為「運算元2」之值,否則為「運算元3」之值。如下例: • int i=-5, a; • a = (i<0) ? (-i) : (i); • (i<0) 條件成立,故 a 為第一個運算元 -i 之值,為 5。
4.2.11 指定運算子 • 符號 名稱 說明 • ------- ------------------------- ----------------------------------- • ++ 一元遞增運算子 a++; 相當於 a=a+1; • -- 一元遞減運算子 a--; 相當於 a=a-1; • = 簡單指定運算子 a=2; 將2指定給a。 • *= 乘複合指定運算子 a*=2; 相當於 a=a*2; • /= 除複合指定運算子 a/=2; 相當於 a=a/2; • %= 餘數複合指定運算子 a%=2; 相當於 a=a%2; • += 加複合指定運算子 a+=2; 相當於 a=a+2; • -= 減複合指定運算子 a-=2; 相當於 a=a-2; • <<= 左移複合指定運算子 a<<=2; 相當於 a=a<<2; • >>= 右移複合指定運算子 a>>=2; 相當於 a=a>>2; • &= 位元AND 指定運算子 a&=2; 相當於 a=a&2; • |= 位元OR 指定運算子 a|=2; 相當於 a=a|2; • ^= 位元XOR 指定運算子 a^=2; 相當於 a=a^2;
表 4.11 運算子優先順序表 優先順序 符號 運算種類 順 序 ------------ ---------------------- ------------------ ------------ 1 ( ) [ ] -> . 運算式 左至右 2 ! ~ ++ -- - (運算元) 一元運算子 右至左 * & sizeof 3 * / % 乘法 左至右 4 + - 加法 左至右 5 << >> 移位 左至右 6 < <= > >= 關係運算子 左至右 7 == != 關係運算子 左至右
表 4.11 運算子優先順序表 (續) 優先順序 符號 運算種類 順 序 ------------ ------------------- ------------------ ------------ 8 & 位元 AND 左至右 9 ^ 位元 XOR 左至右 10 | 位元 OR 左至右 11 && 邏輯 AND 左至右 12 || 邏輯 OR 左至右 13 ?: 條件運算子 右至左 14 = += -= *= /= %= 指定運算子 右至左 <<= >>= &= |= ^= 15 , 循序計值運算子 左至右
4.4 資料型態轉換 • 運算元之前,小括號內標明資料型態可強迫該運算元轉換,如下例: • int a; • double d=12.345; • a=(int)d; /*將d強迫轉換為整數*/ • 其他在運算式計算過程當中也會自動做資料型態之轉換,一般算術運算式中若含有一個運算元為 double 型態,其他運算元都必須轉換為 double 型態,任何 char 字元型態之運算元均轉換為 int 整數型態。
程式 cast.c 宣告 d 為倍精確浮點數,初值為 12.345,將它強迫轉型為整數型態後存入整數變數 a,因此 a 值為 12,將 d 乘上 2 後將它強迫轉型為整數型態後存入整數變數 b,因此 b 值為 24。 【程式cast.c】 /**************** cast.c **************/ #include <stdio.h> int main() { int a, b; double d=12.345; a = (int)d; b = (int)(d*2); printf("d=%lf a=%d b=%d\n", d,a,b); return 0; } 【執行結果】 d=12.345 a=12 b=24