4.3 for 迴圈
for 迴圈特別適合有明確計數器的場景——你要跑固定圈數,或掃過一段範圍(例如 1 到 n)。它把「初始化、條件判斷、每次迴圈後的更新」都收在同一行,讓程式碼更緊湊,也不容易漏掉其中某一段。
for 迴圈的結構:
for (初始化; 條件式; 更新運算式) {
程式碼區塊
}
三個部分的意義:
- 初始化:迴圈開始前執行一次,通常宣告計數器
- 條件式:每次迴圈開始前都檢查,為 false 時停止
- 更新運算式:每次迴圈結束後執行,通常是計數器加 1
執行流程:
- 執行初始化(只一次)
- 檢查條件式
- 如果為 true,執行程式碼區塊,然後執行更新運算式,回到步驟 2
- 如果為 false,跳出迴圈
和 4.2 的 while 相比,for 多了藍色的兩塊:初始化在進迴圈前只做一次,更新運算式在每一圈結束後才執行——這正是 for 把「初始化、條件、更新」收在一行的原因。
¶範例程式碼
範例 1:印出 1 到 10(和 4.2 的 while 對照)
4.2 我們用 while 印出 1 到 10,計數器的「初始化、條件、更新」散在三個地方。改用 for,這三件事收進同一行:
#include<iostream>
using namespace std;
int main() {
// 初始化 i = 1;條件 i <= 10;每圈結束後 i++
for (int i = 1; i <= 10; i++) {
cout << i << "\n";
}
return 0;
}
執行結果:
1
2
3
...(中間略)
10
對照 4.2 的 while 版本,for 把 int i = 1;、i <= 10、i += 1 三段從三行收進括號裡,一眼就看出「這個迴圈讓 i 從 1 數到 10」。
for 的三段什麼時候跑? for 最容易搞混的是「三段各在什麼時機執行」。用範例 1 追蹤,重點看三段的觸發順序:
| 步驟 | 動作 | i |
|---|---|---|
| 進迴圈 | 初始化 int i = 1(只做這一次) |
1 |
| 第 1 圈 | 檢查 i <= 10?成立 → 印出 1 → 更新 i++ |
1 → 2 |
| 第 2 圈 | 檢查 2 <= 10?成立 → 印出 2 → 更新 i++ |
2 → 3 |
| … | … | … |
| 第 10 圈 | 檢查 10 <= 10?成立 → 印出 10 → 更新 i++ |
10 → 11 |
| 結束 | 檢查 11 <= 10?不成立 → 跳出 |
11 |
順序是:初始化一次 → (檢查 → 執行 → 更新)一直循環 → 檢查失敗才停。注意更新 i++ 是在印完之後才發生,所以最後一次真的印出的是 10、不是 11。
範例 2:印出一個數的所有因數
給一個正整數 n,印出它的所有因數(能整除 n 的數)。
因數一定落在 1 到 n 之間,所以讓計數器 i 掃過整個範圍 1 到 n,逐一檢查「i 能不能整除 n」——這種「掃過一段固定範圍」正是 for 最自然的場景。
#include<iostream>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) { // 掃過 1 到 n 每一個數
if (n % i == 0) { // i 能整除 n → i 是因數
cout << i << " ";
}
}
cout << "\n";
return 0;
}
執行結果:(假設輸入為 12)
1 2 3 4 6 12
i 從 1 一路走到 12,每一格都問一次「12 % i 是不是 0」,是就印出來。這裡的 i 同時扮演「掃到哪」和「要檢查的因數」,一個計數器兩用。
¶大括號可以省略嗎?
規則和 3.5 的 if 一模一樣:迴圈體只有「一個陳述式」時,可以省略大括號:
for (int i = 1; i <= n; i++)
cout << i << "\n"; // 迴圈體只有一句,可以省略 { }
但省略的陷阱也一樣:之後想在迴圈裡加第二句時,如果忘了補回大括號,第二句其實在迴圈外:
for (int i = 1; i <= n; i++)
cout << i << "\n";
sum += i; // ✗ 縮排看起來在迴圈裡,其實只執行一次!
¶變數宣告在迴圈內還是迴圈外?
宣告在迴圈大括號裡面的變數,每一圈都會重新誕生、重新初始化(複習 3.8 變數範圍的生命週期):
for (int i = 1; i <= n; i++) {
long long sum = 0; // ✗ 每一圈都被重設成 0
int x;
cin >> x;
sum += x; // 永遠只加到當圈讀入的 x
}
- 只在當圈使用的變數(例如每圈讀入的
x)→ 宣告在迴圈內,乾淨俐落。 - 要跨圈記住東西的變數(累加總和、目前最小值、答案)→ 一定宣告在迴圈外,否則每圈歸零。
¶迴圈的排版
延續 1.5 與 3.5 的排版習慣,while 和 for 迴圈也要排得層次分明。重點一樣是縮排和大括號的位置;另外 for 的括號裡有三段,也有一套好讀的寫法:
// ✓ 好的排版
for (int i = 0; i < n; i++) {
sum += i;
}
// ✗ 不好的排版:擠成一團、沒縮排
for(int i=0;i<n;i++){sum+=i;}
| 規則 | ✓ 好的做法 | ✗ 不好的做法 | 為什麼 |
|---|---|---|---|
| 關鍵字後空一格 | for (...)、while (...) |
for(...)、while(...) |
for/while 是關鍵字,和 ( 空一格,跟函式呼叫區別開 |
| 左大括號接行尾 | for (...) { |
{ 另起一行 |
{ 放在同一行行尾,省一行、更緊湊 |
| 迴圈體縮排一層 | { } 裡的語句往右縮 2~4 格 |
頂著最左邊寫 | 一眼看出「這些是迴圈裡重複做的事」 |
| 三段分號後空格 | for (int i = 0; i < n; i++) |
for (int i=0;i<n;i++) |
初始化/條件/更新三段用 ; 隔開更清楚 |
¶動手試試看
- (暖身) 用
for計算 1 + 2 + 3 + \dots + 100 並輸出。 - (範圍掃描) 讀入正整數 n,把 1 到 n 之間所有的偶數印出來。
- (累乘) 讀入正整數 n,計算 1 \times 2 \times \dots \times n(也就是 n 階乘)。想一想:累乘用的變數初始值該設 0 還是 1?為什麼?(提示:n 稍微大一點就會溢位,要用
long long,複習 2.9。)