for、while 迴圈
May 22, 2022如果要進行重複性指令執行,可以使用迴圈。
for 迴圈
for 迴圈的基本語法之一如下:
for(初始式; 執行結果必須是boolean的重複式; 重複式) {
陳述句;
}
for 迴圈語法的圓括號中,初始式只執行一次,通常用來宣告或初始變數,如果是宣告變數,結束 for 迴圈後變數就會消失。第一個分號後則是每次執行迴圈本體前會執行一次,必須是 true 或 false 的結果,true 就會執行迴圈本體,false 就會結束迴圈,第二個分號後,則是每次執行完迴圈本體後會執行一次。
實際來看個 for 迴圈範例,在文字模式下從 1 顯示到 10:
package cc.openhome;
public class OneToTen {
public static void main(String[] args) {
for(var i = 1; i <= 10; i++) {
System.out.println(i);
}
}
}
這個程式白話讀來,就是從 i 等於 1,只要 i 小於等於 10 就執行迴圈本體,然後遞增 i,這是 for 迴圈的常見的應用方式。
如果 for 本體只有一行陳述句,{ 與 } 可以省略,不過為了可讀性與可維護性而言,建議就算只有一行陳述句,也要撰寫 { 與 } 明確定義範圍。
for 迴圈圓括號中第二個複合陳述區塊若沒有撰寫,預設就是 true,偶而看到有人如下撰寫的話,表示無窮迴圈:
for(;;) {
...
}
當 for 中包括一個 if 陳述時:
while 迴圈
while 迴圈可根據指定條件式來判斷是否執行迴圈本體,語法如下所示:
while(條件式) {
陳述句;
}
如果迴圈本體只有一個陳述句,while 的 { 與 } 可以省略不寫,但為了可讀性,建議還是撰寫。
while 主要用於停止條件必須在執行時期判斷的重複性動作,例如在一個使用者輸入介面,使用者可能輸入的學生名稱個數未知,只知道要結束時會輸入 quit,就可以使用 while 迴圈。
底下是個很無聊的遊戲,看誰可以最久不撞到這個數字5:
package cc.openhome;
public class RandomStop {
public static void main(String[] args) {
while(true) {
var number = (int) (Math.random() * 10);
System.out.println(number);
if(number == 5) {
break;
}
}
System.out.println("I hit 5....Orz");
}
}
這個範例的 while 判斷式直接設為 true,表示每次 while 重來就直接執行迴圈本體,Math.random 會隨機產生 0.0 到小於 1.0 的值,乘上 10 再裁掉小數部份,表示產生 0 到 9 的數,在 while 迴圈中如果執行到 break,會離開迴圈本體。
while 迴圈有時稱為前測式迴圈,因為會在迴圈執行前就進行條件判斷,如果想先執行一些動作,再判斷要不要重複,則可以使用 do/while,又稱後測式迴圈,do/while 的語法如下所示:
do {
陳述句;
} while(條件式);
while 後面是以分號 ; 作為結束,這個很常被忽略;可以將上一個範例改為 do/while:
package cc.openhome;
public class RandomStop2 {
public static void main(String[] args) {
var number = -1;
do {
number = (int) (Math.random() * 10);
System.out.println(number);
} while(number != 5);
System.out.println("I hit 5....Orz");
}
}
break 與 continue
break 可以離開目前 switch、for、while、do/while 的區塊,並執行區塊後下一個陳述句,在 switch 主要用來中斷下個 case 比對,在 for、while 與 do/while,主要用於中斷目前迴圈。
continue 作用與 break 類似,不過使用於迴圈,break 會結束區塊執行,而 continue 只會略過之後陳述句,並回到迴圈區塊開頭進行下一次迴圈,而不是離開迴圈。例如:
for(var i = 1; i < 10; i++) {
if(i == 5) {
break;
}
System.out.printf("i = %d%n", i);
}
這段程式會顯示 i = 1 到 i = 4,因為在 i 等於 5 時就會執行 break 而離開迴圈。再看下面這個程式:
for(var i = 1; i < 10; i++) {
if(i == 5) {
continue;
}
System.out.printf("i = %d%n", i);
}
這段程式會顯示 i =1 到 4,以及 6 到 9,當 i 等於 5 時,會執行 continue 直接略過之後陳述句,也就是該次的 System.out.printf 該行並沒有被執行,直接從區塊開頭執行下一次迴圈,所以 i = 5 沒有被顯示。
break 與 continue 還可以配合標籤使用,例如本來 break 只會離開 for 迴圈,設定標籤與區塊,可以離開整個區塊。
back : {
for(var i = 0; i < 10; i++) {
if(i == 9) {
System.out.println("break");
break back;
}
}
System.out.println("test");
}
程式執行結果會顯示 break;back 是個標籤,當 break back 時,返回至 back 標籤處,之後整個 back 區塊不執行而跳過,所以 System.out.println("test") 該行不會執行。
continue 也有類似的用法,只不過標籤只能設定在 for 之前。例如:
back1:
for(int i = 0; i < 10; i++){
back2:
for(int j = 0; j < 10; j++) {
if(j == 9) {
continue back1;
}
}
System.out.println("test");
}
continue 配合標籤,可以自由地跳至任何一層 for 迴圈,可以試試 continue back1 與 continue back2 的不同,設定 back1 時,System.out.println("test") 不會執行。


