Skip to content

循環處理

在寫程式時,為了讓程式碼更簡練,我們會使用迴圈 (Loop) 來批量處理重複的數據或邏輯。

迴圈的類型

迴圈有三種類別:

  • for 迴圈:已知次數的重複(例如:印 100 次)。
  • while 迴圈:未知次數,直到條件不滿足為止(例如:讀取檔案直到 EOF)。
  • do-while:無論如何,先做一次再說。

多數時候不會使用到 do-while 語句

使用迴圈

其實電腦的世界裡,只要有 while 就夠了。但人類很懶,每次寫迴圈都要做四件事:

  • A 計數器 (int i = 0)
  • B 終止條件 (i < 5)
  • C 改變計數器 (i++)
  • D 循環進行的任務 (printf())

while 迴圈

適合條件比較彈性的場景。

c
// 從零數到四
int j = 0; // A
while(j < 5) { // B
    printf("%d ", j); // D
    j++; // C
}

for 迴圈

將 A、B、C 全部打包在括號內,程式碼極其簡潔。

c
// A; B; C
for (int i = 0; i < 5; i++) {
    printf("%d ", i); // D
}
更多for 迴圈

for 的三個部分(A; B; C)都不是強制的,可以視需求留白:

c
int start = 0, end = 10;
for (; start < end; start += 2) { 
    // A 已在外面定義,所以留白
    printf("%d ", start);
}

避免死循環

在程式開發中最常遇到的問題之一,通常是因為沒有恰當的改變計數器或終止條件設置有誤,會導致程式卡死

c
// i >= 0 永遠為真,直到 overflow,循環不會停止
for (int i = 0; i >= 0; i++) {} // 死循環

迴圈操作

有時候單純的「終止條件」不夠用,我們需要更細緻的控制。

  • break: 直接跳出整個迴圈,通常用於比較複雜的中止判斷,讓判斷變得更優雅、明確。

break 只能跳出一層迴圈

  • continue: 跳過這次,直接進入下一次循環。

Eg-continue.
從一數到九,但四不吉利,不印出

c
int j = 0;
while(j < 10) {
    j++;
    if (j == 4) continue;
    printf("%d ", j);
}

請確保在任何情況都會更改計數器,避免死循環發生,尤其是使用 continue 語法的時候

Eg-break.

c
int numbers[5] = {0, 1, 2, 3, 4}; // 陣列,參見後面的章節
for (int i = 0; i < 5; i++) {
    if (number[i] == 3) {
        printf("3 exist\n");
        break;
    }
}

在部分時候可以選擇 return 直接返回值

多層迴圈跳出

在一些時候會使用到不止一層的迴圈,但也想在特定條件下可以直接結束,通常有兩個做法

  1. 立flag:
c
int terminate = 0; // flag
for (int i = 0; i < 5; i++) {
    for (int j = 0; j < 5; j++) {
        if (number[j] == 3) {
            terminate = 1;
            break;
        }
    }
    if (terminate) break;
}
  1. 使用不推薦的 goto 語法:
c
for (int i = 0; i < 5; i++) {
    for (int j = 0; j < 5; j++) {
        if (number[j] == 3) 
            goto outside;
    }
}
outside: 
printf("end\n");