標籤:style blog http color os 使用 java ar 資料
1. 運算子和運算式-2
1.1. 賦值運算
1.1.1. 使用“=”進行賦值運算
“=”稱為賦值運算子,用於對變數賦值。關於賦值運算子,除了將右邊的運算式計算出來賦給左邊以外還具備如下特點:賦值運算式本身也有值,其本身之值即為所賦之值。範例程式碼如下所示:
int num = 18, index;System.out.println(index = num % 5); // 結果為:3,賦值運算式本身也有值System.out.println(index); // 結果為:3int a, b, c;a = b = c = 100; // c=100 整個運算式的值為100, 將其賦值給b,同樣b=(c=100)整個運算式的值也為100,然後有將這個值賦給了a,所以a 的值也是100。
1.1.2. 使用擴充賦值運算式
在賦值運算子”= ”前加上其它運算子,即為擴充賦值運算子,其效率高於賦值運算子,推薦使用,擴充賦值運算子如 - 5所示:
圖- 5
1.2. 字元串連運算
1.2.1. 使用“+”進行字串串連
“+”除了可以進行算術運算以外,還可以實現字串的串連,同時可以實現字串與其他資料類型的“相連”。
當 + 號作用於兩個數字類型變數時,是在進行算術運算。
當 + 號兩邊的變數有一個是字串類型,即””括起來的時候,則其進行的是字串的串連,串連後的結果為字串類型。範例程式碼如下所示:
int a = 100;String msg = "a=" + a;System.out.println(msg); //a=100,字串拼接msg = "" + 100 + 200;System.out.println(msg); //結果為: 100200,””+100,為字串100再拼上200為100200msg = 100 + 200 + "";System.out.println(msg); //結果為:300,100+200為算術運算結果為300,再加上””為300
1.3. 條件(三目)運算
1.3.1. 使用條件(三目)運算子
條件運算子又稱“三目”運算子,其結構為:boolean運算式 ? 運算式1:運算式2。
條件運算子的規則如下:
- 先計算boolean運算式;
- 如果boolean運算式的值為true,整個運算式的值為運算式1的值;
- 如果boolean運算式的值為false,整個運算式的值為運算式2的值。
範例程式碼如下:
int a = 100, b = 200;int flag = a > b ? 1 : -1; //因為a>b為false,所以整個運算式的值為-1,將其賦給flag,即:flag的值為-1。
1.3.2. 條件(三目)運算子的嵌套
條件運算子可以嵌套使用,所謂嵌套是指在條件(三目)運算式:“boolean運算式 ? 運算式1:運算式2”中的運算式1或運算式2也是條件(三目)運算式,相當於多重判斷,範例程式碼如下所示:
int a = -3;String r = a > 0 ? "正數" : (a == 0 ? "0":"負數");System.out.println(r); //結果為負數,因為 a 的值小於 0,即boolean 運算式的值為 false ,則取問號後第二個運算式的值作為運算式的結果。而問號後的第二個運算式也是一個三目運算子所構成的運算式。因為 a==0 運算式的值為 false,則取“負數”為運算式的結果。
2. 分支結構
2.1. 什麼是分支結構
首先,看一個需求,假設需要編寫一個收銀櫃檯收款程式,要求根據商品單價、購買數量以及收款金額,計算並輸出應收金額和找零。
通過分析可以想到,這個程式,需要定義三個輸入,即:單價、數量、金額。定義兩個輸出,即:應收金額、找零。因為金額有可能為小數類型,所以變數的資料結構定義為double類型。
此程式可以以如下方式解決,使用者由控制台輸入:商品單價、購買數量、收款金額;而後計算商品的總價及找零,並輸出。範例程式碼如下所示:
public static void main(String[] args) { //定義輸入 Scanner console = new Scanner(System.in); System.out.println("請輸入單價(¥):"); double unitPrice = console.nextDouble(); System.out.println("請輸入數量:"); double amount = console.nextDouble(); System.out.println("請輸入金額(¥):"); double money = console.nextDouble(); console.close(); //計算商品總價 double totalPrice = unitPrice * amount; //計算找零 double change = money - totalPrice; //輸出 System.out.println("應收金額為:" + totalPrice +",找零為:" + change); }
如上代碼,輸入資料後,可以正確輸出應收金額及找零,假設現在需求增加,當商品總價滿500時享受8折優惠, 如何解決?這種情況,在軟體應用中,需要使用分支結構來實現。
任何複雜的程式邏輯結構都可以通過“順序”,“分支”,“迴圈”這三種基本的程式結構實現。 – 1所示:
圖- 1
剛剛的案例即為順序結構,第一步A執行完執行第二步B,第二步執行完執行第三步,一步一步順序執行。分支結構即為根據一個條件做判斷,如果條件滿足則執行A,否則執行B。還有一種即為後面要介紹的迴圈結構。原則上,任何複雜的程式, 都可以通過這三種結構來解決。
當程式在運行過程中, 需要根據不同的條件而運行不同的語句時,即可以使用分支結構,Java中有專門的文法結構來實現分支:
- 當條件滿足時運行某些語句;當條件不滿足時則不運行這些語句——if結構。
- 當條件滿足時運行某些語句; 當條件不滿足時運行另外一些語句——if-else結構
2.2. if語句
2.2.1. if語句的執行邏輯
首先看下面if語句的文法:
語句0;if(邏輯運算式){ 語句1; 語句2;}語句3;
如上語句的執行步驟如下所示:
步驟一:執行語句0;
步驟二: 判斷邏輯運算式的值,此運算式的值結果為boolean類型,即true或者false。此處可以是關聯運算式也可以是邏輯運算式。
- 若值為true,則執行if語句塊中的語句;
- 若值為false,則跳過if語句塊;
步驟三:執行語句3語句。
2.2.2. if語句流程圖
if語句的執行邏輯如 - 2所示:
圖- 2
通過圖示得出結論:當條件滿足時,執行語句塊,然後執行if語句下面的語句;否則跳過語句塊,直接執行if語句下面的語句。
2.2.3. if語句用於處理分支邏輯
if語句是java中用於處理分支結構的語句,下面,通過if語句來實現剛剛的打折功能邏輯,再回顧一下新添的需求:如果商品總價大於等於500,則打8折。如– 3 紅色部分即為if的判斷邏輯:
圖- 3
可以看到,計算商品總價之後,進行了總價大於等於500的業務判斷,若判斷結果為true,則計算折扣後的應收金額,再計算找零後輸出。若判斷結果為false,則直接計算找零後輸出。如下即為實現代碼:
…… double totalPrice = ……; if (totalPrice >= 500) { totalPrice = totalPrice * 0.8; } ……
通過如上代碼可以看出: 當total>=500為true時, 總額乘以0.8, 即打8折。當total>=500為false時,不執行if語句塊的內容。
2.2.4. if語句塊不要省略“{}”
if語句塊在執行過程中,有一個問題是需要注意的,先看下面的兩段代碼:
代碼一:
int num = 5;if(num>2) System.out.print(num); System.out.println(“ 大於2 ”);
代碼二:
int num = 5;if(num>2){ System.out.print(num); System.out.println(“ 大於2 ”);}
分析如上兩個程式碼片段,得出的結論是:兩段代碼輸出結果一樣,即 “5 大於 2”。再看如下兩段代碼,輸出結果還一樣嗎?
代碼一:
int num = 5;if(num<2) System.out.println(num); System.out.println(“小於2”);
代碼二:
int num = 5;if(num<2){ System.out.print(num); System.out.println(“小於2”);}
分析如上兩個程式碼片段,可以得出,程式碼片段一的輸出結果是“大於2”,程式碼片段二沒有任何輸出。分析輸出結果可以看出,程式碼片段二的結果為正確結果,而程式碼片段一輸出的“小於2”是不應該存在的,出現這個問題的原因在於,在if語句之後沒有添加“{}”,而java文法規定,當if語句塊中只包含一條語句時,可以省略“{}”,但是if語句塊也只能作用於它下面的一條語句。
看如上程式碼片段一的if判斷,只作用於第一個輸出語句,因為num<2結果為false,所以第一個輸出語句並未執行,而第二個輸出語句“小於2”不屬於if作用範圍,所以無論條件滿足與否,都會執行。故而,輸出了“小於2”的結果。
所以,考慮到代碼的可讀性、擴充性,建議即便if語句塊中只有一條語句,也不要省略“{}”。
2.3. if-else語句
2.3.1. if-else語句的執行邏輯
分析上面的案例,當計算出最終(打折前、打折後)的應收金額後,直接計算找零,這
個時候就出現了一個問題,如果收款的金額小於應收的金額,那麼輸出的找零就會為負數結果,這顯然使用者體驗不好,下面對它做一下改進,要求考慮程式的異常情況,增加需求如下:
- 若收款金額大於等於應收金額,則計算找零後輸出;
- 若收款金額小於應收金額,則輸出錯誤提示資訊,如何處理?
這種情況,單單使用if語句顯然無法解決了,因為if語句用於解決的是,當某條件滿足時執行某段業務處理的邏輯,而現在的邏輯時,當條件滿足時執行某段商務邏輯,當條件不滿足時需要執行另一段商務邏輯。看如 – 4所示的紅色部分:
圖- 4
若想實現這樣的判斷邏輯,可以考慮if-else語句。看一下下面的文法:
語句0;if(邏輯運算式){ 語句塊1;} else { 語句塊2;}語句3;
如上語句的執行步驟如下所示:
步驟一:執行語句0;
步驟二:判斷if邏輯運算式的值:
- 若值為true,則執行語句塊1;
- 若值為false,則執行語句塊2;
步驟三:執行語句3語句。
2.3.2. if-else語句流程圖
if-else語句的執行邏輯如 - 5所示:
圖- 5
通過圖-5可以看到:當條件滿足時,執行語句塊1,然後執行if-else語句下面的語句;否則執行語句塊2,再執行if-else語句下面的語句。
2.3.3. if-else語句用於處理分支邏輯
通過下面的代碼,可以解決新增加的異常情況處理問題:
……if( money >= totalPrice ) { double change = money – totalPrice; System.out.println("應收金額為:" + totalPrice +",找零為:" + change);} else { System.out.println(“Error! 收款金額小於應收金額”);}
說明:money為收款金額,totalPrice為應收金額;當收款金額大於等於應收金額時,則計算找零並輸出,否則,提示錯誤資訊。
2.4. else if語句
2.4.1. if-else語句的嵌套
在日常生活中,很多情況並非進行一次邏輯判斷就可以擷取最終的結果, – 6所示:
圖 - 6
可以看出,實現製作沙拉的過程進行了兩次判斷,首先判斷是否有黃瓜,若有則直接製作黃瓜沙拉後結束,若沒有黃瓜則判斷是否有胡蘿蔔,若有則製作胡蘿蔔沙拉結束,沒有則不能上菜結束。這種情況,單單使用if-else還無法實現,因為if-else只是判斷了一次就結束了,而當前的情況需要判斷兩次。
在java程式中,當程式的分支數大於2時,可以用if-else嵌套的方式解決,即:else語句塊中又包含if語句(或if-else語句),下面看一個實際的需求:
根據學員的成績來輸出等級:
- A(成績大於等於90分);
- B(成績小於90分且大於等於80分);
- C(成績小於80分且大於等於60分);
- D(成績小於60)。
此程式即為多路判斷,– 7所示流程圖:
圖- 7
首先判斷分數是否大於等於90,若為真則輸出A終止,為假則再判斷分數是否大於等於80,若為真輸出B終止,為假則再判斷分數是否大於等於60,若為真輸出C終止,為假則輸出D。分析可以看出,該程式經過了3次判斷。需要在else中嵌套判斷。代碼如下所示:
2.4.2. else if語句執行邏輯
如 – 8所示,在else中再次進行if-else的判斷:
圖- 8
從中看出,當判斷層數比較多時,代碼清晰度不夠好,在實際開發中常常使用如- 9的方式來實現,事實上,else if結束就是if-else嵌套的簡便寫法:
圖 – 9
實現該程式碼如下所示:
… … ...if(score>=90) { System.out.println("A");} else if (score>=80) { System.out.println("B");} else if(score>=60) { System.out.println("C");} else { System.out.println("D");}
通過上面的代碼可以看出,使用else if方式,程式邏輯更清晰,可讀性更好。
2.5. switch-case語句
2.5.1. switch-case語句執行邏輯
switch-case是一種特殊的分支結構,與else if類似,但其應用面不如else if,只能用於特殊的情況之下, switch-case可以根據一個整數值的不同取值,從不同的程式入口開始執行。文法如下所示:
switch(整型運算式) { case 整型常量值1: //入口1 語句1; 語句2; case 整型常量值2: //入口2 語句3; …… default: //預設入口 語句n; }
switch-case流程圖見圖 – 10所示:
圖- 10
分析,可以看出其執行邏輯如下:
計算整型運算式的值:
- 若值等於整型常量值1,則從語句1開始執行,而後語句2、3,一直執行到語句n。
- 若值等於整型常量值2,則從語句3開始執行,一直執行到語句n。
- 若沒有找到匹配的值,則只執行語句n。
通過分析可以看出,switch是以case後的整型常量值作為入口的,若值相等,即開始執行其後面的語句。
使用switch時需要注意兩個問題,第一,case後面的常量值必須不同,第二,switch後面的整型運算式的值必須是整型或字元型。
2.5.2. switch-case和break聯合使用
前面的代碼中判斷整型運算式的值,若其值等於某個整型常量值,則會以此作為入口,依次執行其後面所有的語句。但是在實際應用中,通常case1、case2、…、caseN對應完全不同的操作,即: 若運算式的值等於case1,則只執行case1後的語句,不會再執行case2、caseN等後面的語句。這種情況下可以和break語句配合使用,執行完相應語句後即退出switch塊,不繼續執行下面的語句。文法如下所示:
switch(整型運算式) { case 整型常量值1: //入口1 語句1; 語句2; break ; case 整型常量值2: //入口2 語句3; break ; …… default: //預設入口 語句n;}
如上程式中的break語句的作用在於跳出switch結構,其執行邏輯如下:
- 計算整型運算式的值:
- 如果值等於整型常量值1,則執行語句1、語句2,跳出switch結構結束;
- 若值等於整型常量值2,則執行語句3,跳出switch結構結束;
- 如果沒有找到匹配的值,則執行語句n,結束。default後可以不寫break。
2.5.3. switch-case語句用於分支
在實際應用中,switch-case語句常常與break配合使用,參見下面的代碼:
int num = 2;switch(num) { case 1: System.out.println(“呼叫教學部”); break; case 2: System.out.println(“呼叫人事部”); break; default: System.out.println(“人工服務”);}
上面代碼的輸出結果為“呼叫人事部“,因為匹配case 2輸出後,即break跳出switch語句了。
2.5.4. switch-case的優勢
switch-case結構在實際應用中較廣泛, 常常和break語句結合使用實現分支的功能。
在很多情況下,switch-case可以代替else if結構,而switch-case實現分支功能的效率要高於else if結構,並且結構更清晰,所以推薦使用。從JDK 7.0開始,switch-case可以支援字串運算式,將更加方便程式的操作。
Day 3 : 運算子和運算式-2、分支結構