第五章 運算關係式(Expression)
5-1 簡介 電腦系統對我們人類之意義,可廣義歸納為:資料儲存(Store)、資料運算(Calculation)、與資料傳輸(Transmission)。可見運算是電腦系統之一個重要環節,本章將就Java之狹義運算式(Expressions) 作詳細探討。 於離散數學曾定義:設有元素值a與b,若兩者之間存在某種關係元R,即可以關係式 “aRb” 表示之。我們熟悉的關係元如:“等於(=)”、“大於(>)”、“因此(→)”、“加(+)”、“乘(×)” 等均屬之。 Java程式中之大部份敘述式(Statements),都是由運算關係式(Expressions) 所組成。運算關係式(Expressions) 包括 “運算值(Operands)” 與 “運算元(Operators)”,如2+3,運算值為2與3,運算元為+。
5-2 指定運算元(Assignment Operators) 指定運算元以等號 “=” 表示之,等號之左端為變數(Variable),右端為指定值(Assign Value)。系統將右端之指定值給予左端之變數,指定值可以是一個數值、可以是一個變數、亦可以是一個運算式。
範例25: 指定運算元之應用。 01 class Ex05_2 { 01 class Ex05_2 { 02 public static void main (String[] argv) { 03 int a, b, c, d; 04 a = 15; 05 b = 'A'; 06 System.out.println("數值 a = "+a); 07 System.out.println("字元值 b = "+b); 08 c = b; 09 System.out.println("變數值 c = "+c); 10 d = a + b; 11 System.out.println("運算式值 d = "+d); 12 } 13 }
5-3 算術運算元(Arithmetic Operators) 算術運算元包括:加、減、乘、除、餘數,分別以+、-、*、/、% 表示之,其運算值之資料型態必需為 { byte, int, short, long, float, double},否則無法計算,有關資料型態之轉換,將於爾後再詳述。
範例26: 算術運算元之應用。 01 class Ex05_3_1 { 02 public static void main (String[] argv) { 03 int a = 15, b = 2, c; 04 c = a + b; 05 System.out.println(“加法值 c = ”+c); 06 c = a - b; 07 System.out.println(“減法值 c = ”+c); 08 c = a * b; 09 System.out.println(“乘法值 c = ”+c); 10 c = a / b; 11 System.out.println(“除法值 c = ”+c); 12 c = a % b; 13 System.out.println("餘數值 c = "+c); 14 } 15 }
範例27: 算術運算元與複合等號之應用。 01 class Ex05_3_2 { 01 class Ex05_3_2 { 02 public static void main (String[] argv) { 03 int a, b = 2; 04 a = 15; 05 a += b; 06 System.out.println("加法值 a = "+a); 07 a = 15; 08 a -= b; 09 System.out.println("減法值 a = "+a);
範例27:續 10 a = 15; 11 a *= b; 12 System.out.println("乘法值 a = "+a); 13 a = 15; 14 a /= b; 15 System.out.println("除法值 a = "+a); 16 a = 15; 17 a %= b; 18 System.out.println("除法值 a = "+a); 19 } 20 }
5-4 遞增/遞減運算元 (Increment/Decrement Operators) 一般來言,遞增/遞減運算元(Increment/Decrement Operator) 用於迴圈(Loop),每迴圈一次,變數值加1、或減1。表示方式可分兩類:前置式(Prefix) 如++a、--a,與後置式(Postfix) 如a++、a--。
範例28遞增/遞減運算元之應用。 01 class Ex05_4 { 02 public static void main (String[] argv) { 03 int a; 04 a = 10; 05 System.out.println("前置遞增 a = "+ ++a); 06 a = 10; 07 System.out.println("後置遞增 a = "+ a++); 08 a = 10; 09 System.out.println("前置遞減 a = "+ --a); 10 a = 10; 11 System.out.println("後置遞減 a = "+ a--); 12 } 13 }
5-5 比較運算元(Compare Operators) 比較運算元(Compare Operators) 用於測試兩個運算值(Operands) 的大小關係,並回傳一個布林值(Boolean Value)。 常用的比較運算元(Compare Operators) 有:相等(= =)、不相等(! =)、大於(>)、小於(<)、大於等於(> =)、小於等於(< =)。
範例29: 比較運算元之應用。 01 class Ex05_5 { 01 class Ex05_5 { 02 public static void main (String[] argv) { 03 int a = 3, b = 2; 04 System.out.println("測試 (a == b) = "+ (a==b)); 05 System.out.println("測試 (a != b) = "+ (a!=b)); 06 System.out.println("測試 (a > b) = "+ (a>b)); 07 System.out.println("測試 (a < b) = "+ (a<b)); 08 System.out.println("測試 (a >= b) = "+ (a>=b)); 09 System.out.println("測試 (a <= b) = "+ (a<=b)); 10 } 11 }
5-6 邏輯運算元(Logical Operators)
範例30: 邏輯運算元之應用。 01 class Ex05_6_1 { 02 public static void main (String[] argv) { 03 System.out.println("測試 (false & true) = "+ (false & true)); 04 System.out.println("測試 (true | false) = "+ (true | false)); 05 System.out.println("測試 (!true) = "+ (! true)); 06 } 07 }
範例31: 短路(Short Circuit) 邏輯運算元之應用。 01 class Ex05_6_2 { 02 public static void main (String[] argv) { 03 int a; 04 a = 3; 05 System.out.println("測試 (true && (++a > 0)) = "+ (true && (++a > 0))); 06 System.out.println(“測試是否有執行 ++a: ”+ a); 07 a = 3; 08 System.out.println("測試 (false && (++a > 0)) = "+ (false && (++a > 0))); 09 System.out.println(“測試是否有執行 ++a: ”+ a); 10 a = 3; 11 System.out.println("測試 (true || (++a > 0)) = "+ (true || (++a > 0))); 12 System.out.println(“測試是否有執行 ++a: ”+ a); 13 a = 3; 14 System.out.println("測試 (false || (++a > 0)) = "+ (false || (++a > 0))); 15 System.out.println("測試是否有執行 ++a: "+ a); 16 } 17 }
5-7 位元運算元(Bitwise Operators) 數值以2進位表示時,每一個位置之0或1佔用一個位元(Bit),執行如此形態之運算元是謂 “位元運算元(Bitwise Operators)”。常用的位元運算元有 “補數運算元(Complement Bitwise Operators)”、“位移運算元(Shift Bitwise Operators)”、與 “位元邏輯運算元(Logical Bitwise Operators)”。
範例34: 補數運算元之應用。 01 class Ex05_7_1 { 02 public static void main (String[] argv) { 03 int a, b; 04 a = 3; 05 System.out.println("執行前之 a值: "+ a); 06 a = ~a; 07 System.out.println(“1的補數執行後之 a值: ”+ a); 08 a = -3; 09 System.out.println("執行前之 a值: "+ a); 10 a = ~a; 11 System.out.println(“1的補數執行後之 a值: ”+ a); 12 b = 3; 13 System.out.println("執行前之 b值: "+ b); 14 b = ~b+1; 15 System.out.println(“2的補數執行後之 b值: ”+ b); 16 b = -3; 17 System.out.println("執行前之 b值: "+ b); 18 b = ~b+1; 19 System.out.println("2的補數執行後之 b值: "+ b); 20 } 21 }
範例41: 位移運算元之應用。 01 class Ex05_7_2_1 { 01 class Ex05_7_2_1 { 02 public static void main (String[] argv) { 03 int a, b; 04 a = 4; 05 b = a>>1; 06 System.out.println("正數測試右移運算元 >>: "+ b); 07 a = -4; 08 b = a>>1; 09 System.out.println("負數測試右移運算元 >>: "+ b);
範例41:續 10 a = 4; 11 b = a<<1; 12 System.out.println("正數測試左移運算元 <<: "+ b); 13 a = -4; 14 b = a<<1; 15 System.out.println("負數測試左移運算元 <<: "+ b); 16 a = 4; 17 b = a>>>1; 18 System.out.println("正數測試0值右移運算元 >>>: "+ b); 19 a = -4; 20 b = a>>>1; 21 System.out.println("負數測試0值右移運算元 >>>: "+ b); 22 } 23 }
範例43: 大於32位元位移之應用。 01 class Ex05_7_2_2 { 01 class Ex05_7_2_2 { 02 public static void main (String[] argv) { 03 int a, b; 04 a = 4; 05 b = a>>1; 06 System.out.println("正數測試右移運算元 >>: "+ b); 07 a = 4; 08 b = a>>33; 09 System.out.println("測試大於32位元之位移: "+ b); 10 a = -4; 11 b = a>>1; 12 System.out.println("負數測試右移運算元 >>: "+ b); 13 a = -4; 14 b = a>>33; 15 System.out.println("測試大於32位元之位移: "+ b);
範例43:續 16 a = 4; 17 b = a<<1; 18 System.out.println("正數測試左移運算元 <<: "+ b); 19 a = 4; 20 b = a<<33; 21 System.out.println("測試大於32位元之位移: "+ b); 22 a = -4; 23 b = a<<1; 24 System.out.println("負數測試左移運算元 <<: "+ b); 25 a = -4; 26 b = a<<33; 27 System.out.println("測試大於32位元之位移: "+ b); 28 } 29 }
範例47: 位元邏輯運算元之應用。 01 class Ex05_7_3 { 01 class Ex05_7_3 { 02 public static void main (String[] argv) { 03 int a = 9, b = 10, c; 04 c = a & b; 05 System.out.println("測試運算元 &: "+ c); 06 c = a | b; 07 System.out.println("測試運算元 |: "+ c); 08 c = a ^ b; 09 System.out.println("測試運算元 ^: "+ c); 10 } 11 }
5-8 資料轉型(Type Conversion) 較小範圍資料型態之變數可自動轉換成較大範圍之資料型態,亦即小範圍之變數可輕易置入大範圍之容器內,是謂 “放大轉型(Widening Conversion)” 或稱 “隱性轉型(Implicit Casting)”。 較大範圍資料型態之變數需經過強迫手段,才可轉換成較小範圍之資料型態,如圖5-8-1之反箭頭方向,亦即大範圍之變數無法輕易置入小範圍之容器內,是謂 “縮小轉型(Narrowing Conversion)” 或稱 “顯性轉型(Explicit Casting)”。
範例49: 資料變數自動轉型之應用。 01 class Ex05_8_1 { 01 class Ex05_8_1 { 02 public static void main (String[] argv) { 03 byte bt; 04 short sh; 05 int in; 06 long lg; 07 float ft; 08 double db;
範例49:續 09 bt = 97; 10 sh = bt; 11 System.out.println("short<--byte:"+sh+"<--"+bt); 12 in = sh; 13 System.out.println("int<--short:"+in+"<--"+sh); 14 lg = in; 15 System.out.println("long<--int:"+lg+"<--"+in); 16 ft = lg; 17 System.out.println("float<--long:"+ft+"<--"+lg); 18 db = ft; 19 System.out.println("double<--float:"+db+"<--"+ft); 20 } 21 }
範例50: 資料變數強迫轉型之應用。 01 class Ex05_8_2 { 01 class Ex05_8_2 { 02 public static void main (String[] argv) { 03 byte bt; 04 short sh; 05 int in; 06 long lg; 07 float ft; 08 double db;
範例50:續 09 db = 97.0; 10 ft = (float)db; 11 System.out.println("float<--double:"+ft+"<--"+db); 12 lg = (long)ft; 13 System.out.println("long<--float:"+lg+"<--"+ft); 14 in = (int)lg; 15 System.out.println("int<--long:"+in+"<--"+lg); 16 sh = (short)in; 17 System.out.println("short<--int:"+sh+"<--"+in); 18 bt = (byte)sh; 19 System.out.println("bt<--short:"+bt+"<--"+sh); 20 } 20 }
5-9 條件運算元(Conditional Operators) 當Java程式執行到邏輯決策選擇時,我們使用條件運算式,條件運算式是由運算元符號 “問號(?) ”、與 “ 冒號(:) ” 組成,其格式為: Max = ( (a > b) ? a : b);
範例51: 條件式之應用。 01 class Ex05_9 { 02 public static void main (String[] argv) { 03 int a=3, b=2, M, N; 04 M = ((a>b) ? a : b); 05 System.out.println("M = "+M); 06 if (a>b) 07 N = a; 08 else 09 N = b; 10 System.out.println("N = "+N); 11 } 12 }