迴圈塊
| 導航 語言基礎 主題: |
迴圈是一種便捷的工具,使程式設計師能夠以最少的努力完成重複的任務。假設我們想要一個可以從 1 到 10 計數的程式,我們可以編寫 以下程式。
|
|
任務將順利完成,數字 1 到 10 將在輸出中列印,但此解決方案存在一些問題。
- 靈活性:如果我們想更改起始數字或結束數字怎麼辦?我們必須遍歷並更改它們,在需要的地方新增額外的程式碼行。
- 可擴充套件性:10 次重複是微不足道的,但如果我們想要 100 次甚至 1000 次重複怎麼辦?對於大量迭代,所需的程式碼行數將非常多。
- 維護性:程式碼量大時,更容易出錯。
- 特性:任務數量是固定的,不會在每次執行時改變。
使用迴圈,我們可以解決所有這些問題。一旦你掌握了它們,它們將成為解決程式設計中許多問題的寶貴工具。
開啟你的編輯程式,建立一個名為 Loop.java 的新檔案。現在輸入或複製 以下程式碼
|
|
如果我們執行該程式,將產生相同的結果,但檢視程式碼,我們立即看到了迴圈的優勢。而不是執行十行不同的程式碼,第 5 行執行十次。十行程式碼已經減少到只有四行。此外,我們可以將數字 10 更改為我們喜歡的任何數字。自己試試,將 10 替換為你自己的數字。
while 迴圈是最簡單的迴圈形式。while 迴圈重複執行程式碼塊,直到指定的條件為真。以下是一個 while 迴圈的結構。
while (布林表示式1) {
} |
在每次迴圈迭代之前,都會檢查迴圈的條件。如果在迴圈開始時條件為假,則迴圈將不會執行。在 程式碼部分 3.28 中,squareHigherThan200 設定了平方大於 200 的最小整數。
程式碼部分 3.28:平方大於 200 的最小整數。
int squareHigherThan200 = 0;
while (squareHigherThan200 * squareHigherThan200 < 200) {
squareHigherThan200 = squareHigherThan200 + 1;
}
|
如果迴圈的條件永遠不會變為假,例如,如果使用 true 常量作為條件,則該迴圈被稱為無限迴圈。這樣的迴圈會無限期地重複,除非它被 break 語句中斷。無限迴圈可以用來執行需要不斷重複而不確定停止點的任務,例如更新圖形顯示。 |
do-while 迴圈的功能類似於 while 迴圈,只是條件是在語句執行之後才評估的。當我們嘗試透過隨機瀏覽一組資料來查詢起作用的資料時,它非常有用。
do {
} while (布林表示式1); |
for 迴圈是一個專門的 while 迴圈,其語法旨在方便地遍歷數字序列。它由關鍵字 for 以及括號中包含的三個額外語句組成。第一個語句是變數宣告語句,它允許你宣告一個或多個整型變數。第二個是條件,其檢查方式與 while 迴圈相同。最後一個是迭代語句,用於遞增或遞減變數,儘管任何語句都是允許的。
這是一個 for 迴圈的結構。
for (變數宣告; 條件; 迭代語句) {
} |
為了說明如何使用 for 迴圈,以下是一個示例。
|
|
for 迴圈就像 while 迴圈的模板版本。使用 while 迴圈的替代程式碼如下:
程式碼部分 3.30:使用 while 迴圈的迭代。
int i = 1;
while (i <= 10) {
System.out.println(i);
i++;
}
|
在 程式碼部分 3.31 中,展示瞭如何使用多個變數使用 for 迴圈進行迭代,而 程式碼部分 3.32 展示瞭如何跳過 for 迴圈的任何引數。跳過所有引數,你就會得到一個無限迴圈。
|
|
陣列 還沒有講到,但你會想知道如何使用增強 for 迴圈,稱為 for-each 迴圈。for-each 迴圈會自動遍歷列表或陣列,並將每個索引的值分配給一個變數。
要了解 for-each 迴圈的結構,請檢視以下示例。
程式碼部分 3.33:一個 for-each 迴圈。
String[] sentence = {"I", "am", "a", "Java", "program."};
for (String word : sentence) {
System.out.print(word + " ");
}
|
程式碼部分 3.33 的輸出
I am a Java program. |
該示例遍歷了一個單詞陣列,並將它們像句子一樣打印出來。迴圈所做的事情是遍歷 sentence,並將每個索引的值分配給 word,然後執行程式碼塊。
以下是 for-each 迴圈的一般約定。
for (變數宣告 : 陣列或列表) {
} |
確保陣列或列表的型別可以分配給宣告的變數,否則你會遇到編譯錯誤。注意,迴圈會在檢查完集合中的最後一個專案後自動退出語句塊。
雖然增強 for 迴圈可以使程式碼更清晰,但它不能用於一些常見情況。
- 只能訪問。 元素不能被賦值,例如,不能遞增集合中的每個元素。
- 只能單個結構。 無法同時遍歷兩個結構,例如,比較兩個陣列。
- 只能單個元素。 僅用於訪問單個元素,例如,不能比較連續的元素。
- 只能向前。 只能按單步向前迭代。
- 至少 Java 5。 如果需要與 Java 5 之前的版本相容,請不要使用它。
break 關鍵字退出流程控制迴圈,例如 for 迴圈。它基本上是中斷迴圈。
在 程式碼部分 3.34 中,迴圈將打印出從 1 到 10 的所有數字,但我們有一個檢查,當 i 等於 5 時會執行。當迴圈到達第五次迭代時,它將被 break 語句中斷,此時它將退出迴圈。
|
|
continue 關鍵字直接跳轉到迴圈的下一個迭代,並評估控制迴圈的布林表示式。 程式碼部分 3.35 是 continue 語句在實際應用中的示例
|
|
由於 break 和 continue 語句會降低程式碼的可讀性,建議減少使用它們,或用 if 和 while 塊替換它們。由於這些語句的存在,一些 IDE 重構操作可能會失敗。
問題 3.2:考慮以下程式碼
問題 3.2:迴圈和條件。
int numberOfItems = 5;
int currentItems = 0;
int currentCandidate = 1;
while (currentItems < numberOfItems) {
currentCandidate = currentCandidate + 1;
System.out.println("Test with integer: " + currentCandidate);
boolean found = true;
for (int i = currentCandidate - 1; i > 1; i--) {
// Test if i is a divisor of currentCandidate
if ((currentCandidate % i) == 0) {
System.out.println("Not matching...");
found = false;
break;
}
}
if (found) {
System.out.println("Matching!");
currentItems = currentItems + 1;
}
}
System.out.println("Find the value: " + currentCandidate);
|
標準輸出中將列印什麼?
問題 3.2 的輸出
Test with integer: 2 Matching! Test with integer: 3 Matching! Test with integer: 4 Not matching... Test with integer: 5 Matching! Test with integer: 6 Not matching... Test with integer: 7 Matching! Test with integer: 8 Not matching... Test with integer: 9 Not matching... Test with integer: 10 Not matching... Test with integer: 11 Matching! Find the value: 11 |
這段程式碼片段正在搜尋第 5 個 質數,也就是:11。它迭代從 2 開始的每個正整數(2、3、4、5、6、7、8、9、10、11...),其中,它統計質數(2、3、5、7、11)並在第 5 個質數處停止。
因此,程式碼片段首先使用 while 迴圈迭代從 2 開始的每個正整數
答案 3.2.1:while 迴圈。
int numberOfItems = 5;
int currentItems = 0;
int currentCandidate = 1;
while (currentItems < numberOfItems) {
currentCandidate = currentCandidate + 1;
System.out.println("Test with integer: " + currentCandidate);
boolean found = true;
for (int i = currentCandidate - 1; i > 1; i--) {
// Test if i is a divisor of currentCandidate
if ((currentCandidate % i) == 0) {
System.out.println("Not matching...");
found = false;
break;
}
}
if (found) {
System.out.println("Matching!");
currentItems = currentItems + 1;
}
}
System.out.println("Find the value: " + currentCandidate);
|
對於每一次迭代,當前數字要麼是質數,要麼不是。如果是質數,則執行左側的程式碼。如果不是質數,則執行右側的程式碼。
答案 3.2.2:一個質數。
int numberOfItems = 5;
int currentItems = 0;
int currentCandidate = 1;
while (currentItems < numberOfItems) {
currentCandidate = currentCandidate + 1;
System.out.println("Test with integer: " + currentCandidate);
boolean found = true;
for (int i = currentCandidate - 1; i > 1; i--) {
// Test if i is a divisor of currentCandidate
if ((currentCandidate % i) == 0) {
System.out.println("Not matching...");
found = false;
break;
}
}
if (found) {
System.out.println("Matching!");
currentItems = currentItems + 1;
}
}
System.out.println("Find the value: " + currentCandidate);
|
答案 3.2.3:不是一個質數。
int numberOfItems = 5;
int currentItems = 0;
int currentCandidate = 1;
while (currentItems < numberOfItems) {
currentCandidate = currentCandidate + 1;
System.out.println("Test with integer: " + currentCandidate);
boolean found = true;
for (int i = currentCandidate - 1; i > 1; i--) {
// Test if i is a divisor of currentCandidate
if ((currentCandidate % i) == 0) {
System.out.println("Not matching...");
found = false;
break;
}
}
if (found) {
System.out.println("Matching!");
currentItems = currentItems + 1;
}
}
System.out.println("Find the value: " + currentCandidate);
|
質數使用 currentItems 計數。當 currentItems 等於 numberOfItems(5)時,程式退出 while 迴圈。currentCandidate 包含最後一個數字,也就是第 5 個質數
答案 3.2.4:程式結束。
int numberOfItems = 5;
int currentItems = 0;
int currentCandidate = 1;
while (currentItems < numberOfItems) {
currentCandidate = currentCandidate + 1;
System.out.println("Test with integer: " + currentCandidate);
boolean found = true;
for (int i = currentCandidate - 1; i > 1; i--) {
// Test if i is a divisor of currentCandidate
if ((currentCandidate % i) == 0) {
System.out.println("Not matching...");
found = false;
break;
}
}
if (found) {
System.out.println("Matching!");
currentItems = currentItems + 1;
}
}
System.out.println("Find the value: " + currentCandidate);
|
標籤
[edit | edit source]標籤可用於為迴圈命名。這樣做的原因是,我們可以從巢狀迴圈中退出或繼續上級迴圈。
以下是為迴圈新增標籤的方法
| 標籤名稱:迴圈 |
要退出或繼續迴圈,請使用 break 或 continue 關鍵字,後面跟著迴圈的名稱。
例如
|
|
如果你不理解所有程式碼,也不用擔心,但請注意標籤是如何用於從內迴圈退出外迴圈的。但是,由於這種程式碼難以閱讀和維護,強烈建議不要使用標籤。
嘗試... 捕獲塊
[edit | edit source]- 另請參閱 丟擲和捕獲異常。
try-catch 塊用於捕獲程式碼中的任何異常或其他可丟擲物件。
以下是 try-catch 塊的樣子
try {
} catch (exception1) {
} |
程式碼清單 3.6 嘗試列印傳遞給程式的所有引數。但是,如果引數不足,它將丟擲異常。
程式碼清單 3.6:Attempt.java
public class Attempt {
public static void main(String[] args) {
try {
System.out.println(args[0]);
System.out.println(args[1]);
System.out.println(args[2]);
System.out.println(args[3]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Not enough arguments");
}
}
}
|
除了 try 和 catch 塊之外,還可以使用 finally 塊。無論是否丟擲異常,都會始終執行 finally 塊。它可以與 catch 塊一起出現,也可以不與 catch 塊一起出現,但始終與 try 塊一起出現。
以下是 finally 塊的樣子
try {
} catch (exception1) {
} finally {
} |
示例
[edit | edit source]程式碼清單 3.7 接收一個數字作為引數,並列印它的二進位制表示。
程式碼清單 3.7:GetBinary.java
public class GetBinary {
public static void main(String[] args) {
if (args.length == 0) {
// Print usage
System.out.println("Usage: java GetBinary <decimal integer>");
System.exit(0);
} else {
// Print arguments
System.out.println("Received " + args.length + " arguments.");
System.out.println("The arguments are:");
for (String arg : args) {
System.out.println("\t" + arg);
}
}
int number = 0;
String binary = "";
// Get the input number
try {
number = Integer.parseInt(args[0]);
} catch (NumberFormatException ex) {
System.out.println("Error: argument must be a base-10 integer.");
System.exit(0);
}
// Convert to a binary string
do {
switch (number % 2) {
case 0: binary = '0' + binary; break;
case 1: binary = '1' + binary; break;
}
number >>= 1;
} while (number > 0);
System.out.println("The binary representation of " + args[0] + " is " + binary);
}
}
|
程式碼清單 3.8 模擬玩一個名為幸運七的遊戲。這是一個骰子游戲,玩家擲兩個骰子。如果骰子上的數字加起來是七,他就贏了 4 美元。如果不是,他就輸了 1 美元。這個遊戲展示瞭如何在程式中使用控制流以及賭博的徒勞無益。
程式碼清單 3.8:LuckySevens.java
import java.util.*;
public class LuckySevens {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Random random = new Random();
String input;
int startingCash, cash, maxCash, rolls, roll;
// Loop until "quit" is input
while (true) {
System.out.print("Enter the amount of cash to start with (or \"quit\" to quit): ");
input = in.nextLine();
// Check if user wants to exit
if (input.toLowerCase().equals("quit")) {
System.out.println("\tGoodbye.");
System.exit(0);
}
// Get number
try {
startingCash = Integer.parseInt(input);
} catch (NumberFormatException ex) {
System.out.println("\tPlease enter a positive integer greater than 0.");
continue;
}
// You have to start with some money!
if (startingCash <= 0) {
System.out.println("\tPlease enter a positive integer greater than 0.");
continue;
}
cash = startingCash;
maxCash = cash;
rolls = 0;
roll = 0;
// Here is the game loop
for (; cash > 0; rolls++) {
roll = random.nextInt(6) + 1;
roll += random.nextInt(6) + 1;
if (roll == 7)
cash += 4;
else
cash -= 1;
if (cash > maxCash)
maxCash = cash;
}
System.out.println("\tYou start with $" + startingCash + ".\n"
+ "\tYou peak at $" + maxCash + ".\n"
+ "\tAfter " + rolls + " rolls, you run out of cash.");
}
}
}
|