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")
不會執行。