跳轉到內容

迴圈塊

100% developed
來自華夏公益教科書,開放的書籍,為開放的世界


導航 語言基礎 主題: v  d  e )


迴圈是一種便捷的工具,使程式設計師能夠以最少的努力完成重複的任務。假設我們想要一個可以從 1 到 10 計數的程式,我們可以編寫 以下程式

Computer code 程式碼清單 3.4:Count.java
class Count {
    public static void main(String[] args) {
        System.out.println("1 ");
        System.out.println("2 ");
        System.out.println("3 ");
        System.out.println("4 ");
        System.out.println("5 ");
        System.out.println("6 ");
        System.out.println("7 ");
        System.out.println("8 ");
        System.out.println("9 ");
        System.out.println("10 ");
    }
}
Standard input or output 程式碼清單 3.4 的輸出
1
2
3
4
5
6
7
8
9
10


任務將順利完成,數字 1 到 10 將在輸出中列印,但此解決方案存在一些問題。

  • 靈活性:如果我們想更改起始數字或結束數字怎麼辦?我們必須遍歷並更改它們,在需要的地方新增額外的程式碼行。
  • 可擴充套件性:10 次重複是微不足道的,但如果我們想要 100 次甚至 1000 次重複怎麼辦?對於大量迭代,所需的程式碼行數將非常多。
  • 維護性:程式碼量大時,更容易出錯。
  • 特性:任務數量是固定的,不會在每次執行時改變。

使用迴圈,我們可以解決所有這些問題。一旦你掌握了它們,它們將成為解決程式設計中許多問題的寶貴工具。

開啟你的編輯程式,建立一個名為 Loop.java 的新檔案。現在輸入或複製 以下程式碼

Computer code 程式碼清單 3.5:Loop.java
class Loop {
    public static void main(String[] args) {
        int i;
        for (i = 1; i <= 10; i++) {
            System.out.println(i + " ");
        }
    }
}
Standard input or output 程式碼清單 3.5 的輸出
1
2
3
4
5
6
7
8
9
10

如果我們執行該程式,將產生相同的結果,但檢視程式碼,我們立即看到了迴圈的優勢。而不是執行十行不同的程式碼,第 5 行執行十次。十行程式碼已經減少到只有四行。此外,我們可以將數字 10 更改為我們喜歡的任何數字。自己試試,將 10 替換為你自己的數字。

while 迴圈是最簡單的迴圈形式。while 迴圈重複執行程式碼塊,直到指定的條件為真。以下是一個 while 迴圈的結構。

while (布林表示式1) {
語句1
語句2
...
語句n

}

在每次迴圈迭代之前,都會檢查迴圈的條件。如果在迴圈開始時條件為假,則迴圈將不會執行。在 程式碼部分 3.28 中,squareHigherThan200 設定了平方大於 200 的最小整數。

Example 程式碼部分 3.28:平方大於 200 的最小整數。
int squareHigherThan200 = 0;

while (squareHigherThan200 * squareHigherThan200 < 200) {
  squareHigherThan200 = squareHigherThan200 + 1;
}
Note 如果迴圈的條件永遠不會變為假,例如,如果使用 true 常量作為條件,則該迴圈被稱為無限迴圈。這樣的迴圈會無限期地重複,除非它被 break 語句中斷。無限迴圈可以用來執行需要不斷重複而不確定停止點的任務,例如更新圖形顯示。

Do... while

[編輯 | 編輯原始碼]

do-while 迴圈的功能類似於 while 迴圈,只是條件是在語句執行之後才評估的。當我們嘗試透過隨機瀏覽一組資料來查詢起作用的資料時,它非常有用。

do {
語句1
語句2
...
語句n

} while (布林表示式1);

for 迴圈是一個專門的 while 迴圈,其語法旨在方便地遍歷數字序列。它由關鍵字 for 以及括號中包含的三個額外語句組成。第一個語句是變數宣告語句,它允許你宣告一個或多個整型變數。第二個是條件,其檢查方式與 while 迴圈相同。最後一個是迭代語句,用於遞增或遞減變數,儘管任何語句都是允許的。

這是一個 for 迴圈的結構。

for (變數宣告; 條件; 迭代語句) {
語句1
語句2
...
語句n

}

為了說明如何使用 for 迴圈,以下是一個示例。

Example 程式碼部分 3.29:一個 for 迴圈。
for (int i = 1; i <= 10; i++) {
    System.out.println(i);
}
Standard input or output 程式碼清單 3.29 的輸出
1
2
3
4
5
6
7
8
9
10

for 迴圈就像 while 迴圈的模板版本。使用 while 迴圈的替代程式碼如下:

Example 程式碼部分 3.30:使用 while 迴圈的迭代。
int i = 1;
while (i <= 10) {
  System.out.println(i);
  i++;
}

程式碼部分 3.31 中,展示瞭如何使用多個變數使用 for 迴圈進行迭代,而 程式碼部分 3.32 展示瞭如何跳過 for 迴圈的任何引數。跳過所有引數,你就會得到一個無限迴圈。

Example 程式碼部分 3.31:使用多個變數的 for 迴圈。
for (int i = 1, j = 10; i <= 10; i++, j--) {
  System.out.print(i + " ");
  System.out.println(j);
}
Example 程式碼部分 3.32:沒有引數的 for 迴圈。
for (;;) {
  // Some code
}

陣列 還沒有講到,但你會想知道如何使用增強 for 迴圈,稱為 for-each 迴圈。for-each 迴圈會自動遍歷列表或陣列,並將每個索引的值分配給一個變數。

要了解 for-each 迴圈的結構,請檢視以下示例。

Example 程式碼部分 3.33:一個 for-each 迴圈。
String[] sentence = {"I", "am", "a", "Java", "program."};
for (String word : sentence) {
    System.out.print(word + " ");
}
Standard input or output 程式碼部分 3.33 的輸出
I am a Java program.

該示例遍歷了一個單詞陣列,並將它們像句子一樣打印出來。迴圈所做的事情是遍歷 sentence,並將每個索引的值分配給 word,然後執行程式碼塊。

以下是 for-each 迴圈的一般約定。

for (變數宣告 : 陣列或列表) {
語句1
語句2
...
語句n

}

確保陣列或列表的型別可以分配給宣告的變數,否則你會遇到編譯錯誤。注意,迴圈會在檢查完集合中的最後一個專案後自動退出語句塊。

雖然增強 for 迴圈可以使程式碼更清晰,但它不能用於一些常見情況。

  • 只能訪問。 元素不能被賦值,例如,不能遞增集合中的每個元素。
  • 只能單個結構。 無法同時遍歷兩個結構,例如,比較兩個陣列。
  • 只能單個元素。 僅用於訪問單個元素,例如,不能比較連續的元素。
  • 只能向前。 只能按單步向前迭代。
  • 至少 Java 5。 如果需要與 Java 5 之前的版本相容,請不要使用它。

Break 和 continue 關鍵字

[編輯 | 編輯原始碼]

break 關鍵字退出流程控制迴圈,例如 for 迴圈。它基本上是中斷迴圈。

程式碼部分 3.34 中,迴圈將打印出從 1 到 10 的所有數字,但我們有一個檢查,當 i 等於 5 時會執行。當迴圈到達第五次迭代時,它將被 break 語句中斷,此時它將退出迴圈。

Example 程式碼部分 3.34:一個被中斷的 for 迴圈。
for (int i = 1; i <= 10; i++) {
    System.out.println(i);
    if (i == 5) {
       System.out.println("STOP!");
       break;
    }
}
Standard input or output 程式碼部分 3.34 的輸出
1
2
3
4
5
STOP!

continue 關鍵字直接跳轉到迴圈的下一個迭代,並評估控制迴圈的布林表示式。 程式碼部分 3.35continue 語句在實際應用中的示例

Example 程式碼部分 3.35:帶有跳過迭代的 for 迴圈。
for (int i = 1; i <= 10; i++) {
    if (i == 5) {
        System.out.println("Caught i == 5");
        continue;
    }
    System.out.println(i);
}
Standard input or output 程式碼部分 3.35 的輸出
1
2
3
4
Caught i == 5
6
7
8
9
10

由於 breakcontinue 語句會降低程式碼的可讀性,建議減少使用它們,或用 ifwhile 塊替換它們。由於這些語句的存在,一些 IDE 重構操作可能會失敗。

測試你的知識

問題 3.2:考慮以下程式碼

Example 問題 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);

標準輸出中將列印什麼?

答案
Standard input or output 問題 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 開始的每個正整數

Example 答案 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);

對於每一次迭代,當前數字要麼是質數,要麼不是。如果是質數,則執行左側的程式碼。如果不是質數,則執行右側的程式碼。

Example 答案 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);
Example 答案 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 個質數

Example 答案 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]

標籤可用於為迴圈命名。這樣做的原因是,我們可以從巢狀迴圈中退出或繼續上級迴圈。

以下是為迴圈新增標籤的方法

標籤名稱:迴圈

要退出或繼續迴圈,請使用 breakcontinue 關鍵字,後面跟著迴圈的名稱。

例如

Example 程式碼部分 3.36:一個雙重 for 迴圈。
int i, j;
int[][] nums = {
    {1, 2, 5},
    {6, 9, 7},
    {8, 3, 4}
};

Outer:
for (i = 0; i < nums.length; i++) {
    for (j = 0; j < nums[i].length; j++) {
        if (nums[i][j] == 9) {
            System.out.println("Found number 9 at (" + i + ", " + j + ")");
            break Outer;
        }
    }
}
Standard input or output 程式碼部分 3.36 的輸出
Found number 9 at (1, 1)

如果你不理解所有程式碼,也不用擔心,但請注意標籤是如何用於從內迴圈退出外迴圈的。但是,由於這種程式碼難以閱讀和維護,強烈建議不要使用標籤。

嘗試... 捕獲塊

[edit | edit source]
另請參閱 丟擲和捕獲異常

try-catch 塊用於捕獲程式碼中的任何異常或其他可丟擲物件。

以下是 try-catch 塊的樣子

try {
statement1.1
statement1.2
...
statement1.n

} catch (exception1) {

statement2.1
...
statement2.n

}

程式碼清單 3.6 嘗試列印傳遞給程式的所有引數。但是,如果引數不足,它將丟擲異常。

Computer code 程式碼清單 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 {
statement1.1
statement1.2
...
statement1.n

} catch (exception1) {

statement2.1
...
statement2.n

} finally {

statement3.1
...
statement3.n

}

示例

[edit | edit source]

程式碼清單 3.7 接收一個數字作為引數,並列印它的二進位制表示。

Computer code 程式碼清單 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 美元。這個遊戲展示瞭如何在程式中使用控制流以及賭博的徒勞無益。

Computer code 程式碼清單 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.");
        }
    }
}


華夏公益教科書