Java 入門指南
單元 7 - 迴圈
程式 (program) 中的迴圈 (loop) 就是在特定程式區塊 (block) 中,重複執行相同的工作
Java 中有兩種迴圈,一種是 while 迴圈 (while loop) ,另一種則是 for 迴圈 (for loop) ,兩種迴圈可以互相替代,端視自己喜歡用哪一種囉!我們先來看看 while 迴圈的寫法
int i = 10; // 設定控制變數
while (i > 0) { // 測試結束條件
// 迴圈工作區
System.out.println(i);
i--; // 調整控制變數值
}
這個迴圈所進行的工作很簡單,先在命令列上印出 10 ,然後一路倒數到 1 為止。迴圈有三個地方要注意
- 設定控制變數
- 測試結束條件
- 調整控制變數
while 迴圈的控制變數 (control variable) 必須在 while 之前就先設定好,此例中將控制變數 i 設定為 10 。然後進入 while 的地方,條件 (condition) 就在 while 之後的小括弧中,此例的條件為當控制變數 i 大於 0 時,迴圈便會重複執行。迴圈工作區,也就是 while 之後用大括弧圍住的程式區塊,這裡,我們只有簡單的印出控制變數 i 的值,另外,最後需要有調整控制變數值的地方。
我們先寫成完整的範例如下
/*
* 檔名:WhileDemo.java
* 作者:張凱慶
* 網站:http://kaiching.org
*/
package whiledemo;
public class WhileDemo {
public static void main(String[] args) {
int i = 10; // 設定控制變數
while (i > 0) { // 測試結束條件
// 迴圈工作區
System.out.println(i);
i--; // 調整控制變數值
}
}
}
執行結果如下
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
do {
statement(s)
} while (expression);
也就是說, do-while 迴圈至少會進行迴圈的第一次工作,然後才進行結束條件測試。當我們明確知道重複次數的時候,我們得利用控制變數來記錄 while 迴圈所進行次數,這樣 while 迴圈才會有結束的一天,不然若是漏了任一與控制變數相關的部份時,就有可能導致無窮迴圈 (infinite loop) 的發生,例如
int i = 10; // 設定控制變數
while (i > 0) {
// 迴圈工作區
System.out.println(i);
// 沒有調整控制變數值
}
這樣一來,控制變數 i 永遠大於 0 ,所以迴圈會一直重複執行,此例中會不斷的在命令列印出 10 ,直到強制結束程式執行為止。
以上的 while 迴圈是介紹有明確重複次數的用法,若是迴圈沒有明確重複次數,那就得另行設計結束迴圈的方式,例如控制變數等於某一個值之時,再利用 break 跳出迴圈。
另外一個 for 迴圈則是把控制變數的設定、迴圈結束條件、控制變數的調整全都寫在小括弧之中,如下
for (int i = 10; i > 0; i--) {
System.out.println(i);
}
for 之後的小括弧用兩個分號區隔三個項目,依序是控制變數的初值設定、迴圈結束條件、控制變數的調整。這個 for 迴圈與上面的 while 迴圈功能完全相同,寫成完整的範例程式,如下
/*
* 檔名:ForDemo.java
* 作者:張凱慶
* 網站:http://kaiching.org
*/
package whiledemo;
public class ForDemo {
public static void main(String[] args) {
for (int i = 10; i > 0; i--) {
System.out.println(i);
}
}
}
執行結果同樣是
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
小括弧中的兩個分號與條件是必須的,因此如果寫成
int i = 10;
for (; i > 0;) {
System.out.println(i);
}
這會使 for 迴圈變成一個無窮迴圈。
習慣上, for 迴圈通常用於具有明確重複次數的迴圈,因為全部的控制機制都放在 for 之後的小括弧中, while 迴圈用於沒有明確重複次數的迴圈,例如接收使用者輸入的迴圈,程式通常被設計成一直等待使用者輸入,當使用者輸入結束指令時,迴圈才會結束。
但是提醒一點, for 迴圈可以用 while 迴圈替代,反之亦然,自己偏好哪一種也就可以用哪一種囉!
JDK 1.5 之後, for 迴圈可以用來依序取得複合資料型態物件中的所有元素,例如
/*
* 檔名:ForeachDemo.java
* 作者:張凱慶
* 網站:http://kaiching.org
*/
package foreachdemo;
public class ForeachDemo {
public static void main(String[] args) {
// 建立含有 10 個整數的陣列
int[] a = new int[10];
// 初始化陣列元素
int v = 10;
for (int i = 0; i < 10; i++) {
a[i] = v--;
}
// 利用 for 迴圈印出每一個元素
for (int i : a) {
System.out.println(i);
}
}
}
這種迴圈又稱為 foreach 迴圈。
這個例子可以依單行註解,分成三個部分來看。首先,第一部分
// 建立含有 10 個整數的陣列
int[] a = new int[10];
這是宣告並建立整數陣列 (array) 的變數,注意宣告陣列變數要載明胎名稱後加上中括弧,例如 int[] 表示整數陣列。等候右側用關鍵字 new 加上型態名稱與中括弧,中括弧中需要指定陣列的元素個數。
陣列是長度限定、相同資料型態的資料結構,因此需要設定陣列的資料型態及元素個數。
其次,初始化陣列元素
// 初始化陣列元素
int v = 10;
for (int i = 0; i < 10; i++) {
a[i] = v--;
}
建立整數陣列後,整數陣列裡頭的每個元素值預設為整數 0 ,這裡是用 for 迴圈將陣列元素設定為從 10 到 1 的整數,由於陣列元素的索引值從 0 開始,因此 i 的初值設定為 0 。
留意這一行
a[i] = v--;
利用陣列變數 a 加上中括弧,中括弧裡面放索引值可以取得該索引值的元素,如果放在等號左邊,就可以設定該位置的元素值,像是這裡將 a[i] 設定為 v-- ,由於 i 從 0 開始, v 的初值為 10 ,因此 a[0] 會被設定為 10 ,遞減運算子會在指派完成後才計算,所以這一行結束, a[i] 會被設定為 v , v 會變成 v - 1 。
最後,利用 for 迴圈印出陣列中的每一個元素
// 利用 for 迴圈印出每一個元素
for (int i : a) {
System.out.println(i);
}
這裡整數型態的變數 i 會依序取得陣列變數 a 中的每一個元素
for (int i : a) {
由於陣列 a 是從 10 到 1 的正整數數列,因此執行結果同樣是
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
我們一路看了 SelectionDemo 、 SwitchDemo 、 WhileDemo 、 ForDemo 、 ForeachDemo 等等,這些都是類別 (class) , Java 中類別也就是檔案名稱,下面我們開始詳細討論類別的定義囉!
相關教學影片
中英文術語對照 | |
---|---|
array | 陣列 |
block | 程式區塊 |
class | 類別 |
condition | 條件 |
control variable | 控制變數 |
for loop | for 迴圈 |
infinite loop | 無窮迴圈 |
loop | 迴圈 |
program | 程式 |
while loop | while 迴圈 |
參考資料 | |
---|---|
1. The Java™ Tutorials: Control Flow Statements | |
2. The Java™ Tutorials: The while and do-while Statements | |
3. The Java™ Tutorials: The for Statement | |
4. The Java™ Tutorials: Branching Statements |
重點整理 |
---|
1. 迴圈是只在特定的程式區塊進行重複工作。 |
2. C# 中有四種迴圈,分別是 while 迴圈 、 for 迴圈、 do-while 迴圈、 foreach-in 迴圈。 |
3. 迴圈基本三要件:設定控制變數、結束條件測試、調整控制變數。 |
4. while 迴圈與 do-while 迴圈都需要設置迴圈三要素,兩者的差別是 while 迴圈是前測試迴圈, do-while 迴圈事後測試迴圈。 |
5. for 迴圈是把迴圈三要素寫在 for 之後的小括弧中,通常用於固定次數的迴圈。 |
6. foreach-in 迴圈用於複合資料型態的物件,逐一取得每一個元素。 |
7. 無窮迴圈是不會結束的迴圈,因此在無窮迴圈中要自行設定結束方式,通常是用 break 跳出迴圈。 |
問題與討論 |
---|
1. 很多情況都需要 while true 迴圈,這不是無窮迴圈嗎?那為什麼 還要 while true 迴圈呢? |
2. while 迴圈與 for 迴圈要如何互相替代? |
3. while 迴圈與 do-while 迴圈要如何互相替代? |
4. 遞迴是一種用於重複工作的演算法,遞迴跟迴圈有什麼不同呢? |
練習 |
---|
1. 建立一個新專案 Exercise0701 ,利用迴圈計算 1 到 1000 的總和。 |
2. 承上題,另建立一個專案 Exercise0702 ,改成接受使用者輸入,計算 1 到使用者輸入整數的總和。 |
3. 迴圈中若有其他迴圈稱之為巢狀迴圈,利用巢狀迴圈及 '*' 建立一個專案 Exercise0703,印出一個高 5 、底 5 的等腰直角三角形。 |
4. 承上題,另建立一個專案 Exercise0704 ,將三角形倒過來印。 |
5. 承上題,另建立一個專案 Exercise0705 ,改成接收使用者輸入邊長。 |
6. 建立一個專案 Exercise0706 ,利用巢狀迴圈印出九九乘法表。 |
7. 建立一個專案 Exercise0707 ,在 while true 迴圈中接受使用者的輸入,當使用者輸入 'e' 的時候利用 break 跳出迴圈,注意輸入字串要改用 Scanner 物件的 nextLine() 方法,比較字串相等要用 String 物件的 equals() 方法。 |
8. 建立一個專案 Exercise0708 ,計算 10 的階層,也就是從正整數 1 乘以正整數 2 ,一路乘到正整數 10 。 |
9. 承上題,另建立一個專案 Exercise0709 ,改成接受使用者輸入,計算使用者輸入的階層數。 |
10. 費氏數列為 0 、 1 、 1 、 2 、 3 、 5 、 8 、 13 .... ,也就是後面的數字為前兩個數字的總和,建立一個專案 Exercise0710 ,計算出第 20 個數字。 |
11. 承上題,建立一個專案 Exercise0711 ,改成接受使用者輸入,計算使用者輸入的第幾個費氏數。 |