C語 while 迴圈與條件式徹底解析|從基礎到應用、常見錯誤完整指南

目次

1. while語句的特點與使用時機

在 C 語言中,「while 語句」是用於在特定條件成立期間,重複相同處理的控制結構。程式中需要重複處理的情況很多,而 while 語句在「重複次數事先未決定」的情況下特別發揮作用。 while 語句的特點是「只要條件式成立,就可以無限次循環」這一點。當條件式變為偽(false)時,會立即跳出迴圈並進入下一個處理。正因為這種彈性,無論是等待使用者輸入、在檔案到達結尾前持續處理、或是監測感測器數值等外部變化,都能在各種情境中使用。 此外,C 語言中也有同樣執行重複處理的「for 語句」和「do-while 語句」,但 while 語句適合「在執行過程中需要變更重複次數或條件」的情況。例如「持續加總數值,直到使用者輸入 0 為止」的處理,就是 while 語句的拿手好戲。 如此一來,while 語句就是在 C 語言中實現彈性重複處理的基礎語法之一。接下來的章節將詳細說明 while 語句的基本語法與處理流程。

2. 基本語法與流程

while語句是 C 語言中迴圈處理的基本語法之一。用法非常簡單,只要「條件式」為真(true)時,就會不斷重複指定的處理區塊。此處將說明基本語法與其流程。

while語句的基本語法

while (條件式) {
    // 迴圈內想要重複的處理
}
  • while 後面的括號內(`())寫入「條件式」。
  • 條件式為「真(1)」時,波形大括號 {} 中的處理會重複執行。
  • 條件式變為「偽(0)」時,會跳出迴圈並進入下一個處理。

while語句的處理流程

  1. 首先,評估條件式。
  2. 若條件式為真(1),則區塊內的處理會執行一次。
  3. 處理結束後,會再次回到條件式的評估。
  4. 當條件式變為偽(0)時,迴圈結束,並繼續執行 while 語句之後的處理。
透過此流程,while語句能在「條件滿足的期間」持續重複相同的處理。

執行範例:條件從一開始即為偽的情況

如果 while 語句在最初的條件判斷就被判定為「偽」,則迴圈內的處理一次也不會執行就結束。例如,如下程式碼。
int n = 0;
while (n > 0) {
    printf("n是正數。n");
}
此時,變數n為 0,條件式n > 0從一開始就為偽。因此,printf 那一行一次也不會被執行。 如此,while語句是一種「只要條件式滿足就持續重複處理」的簡單且強大的控制結構。

3. 透過範例程式了解運作

while文的基本使用方式與流程已了解後,讓我們實際觀看具體的範例程式,確認其運作。這裡會介紹簡單的計數器迴圈、字串重複輸出等,適合初學者的範例。

範例1:使用計數器的基本 while 迴圈

#include <stdio.h>

int main() {
    int i = 1;
    while (i <= 5) {
        printf("i的值是 %d 。n", i);
        i = i + 1; // i 每次增加 1
    }
    return 0;
}
此程式碼中,變數i從 1 開始,只要i <= 5條件成立,迴圈內的printf就會執行。每次迴圈i會增加 1,直到 5 為止,重複輸出。 執行結果範例:
i的值是 1。
i的值是 2。
i的值是 3。
i的值是 4。
i的值是 5。

範例2:多次輸出「你好」

#include <stdio.h>

int main() {
    int count = 0;
    while (count < 3) {
        printf("你好n");
        count++;
    }
    return 0;
}
此例中,當count小於 3 時,會重複顯示「你好」的處理。 執行結果範例:
你好
你好
你好

範例3:根據使用者輸入值執行重複處理

#include <stdio.h>

int main() {
    int num;
    printf("輸入 0 即結束。n");
    while (1) {
        printf("請輸入數字:");
        scanf("%d", &num);
        if (num == 0) {
            break; // 輸入 0 時結束迴圈
        }
        printf("輸入的值是 %d 。n", num);
    }
    printf("結束。n");
    return 0;
}
此例中,使用者會持續輸入與顯示數字,直到輸入「0」為止。輸入 0 後,會以break語句跳出迴圈,程式結束。 這樣,while 迴圈可以以各種形式彈性運用。從簡單的計數迴圈到使用者輸入的處理,皆能廣泛應用。

4. do-while 的差異

C 語言中有一種與 while 迴圈非常相似的控制結構「do-while 迴圈」。兩者都在「條件成立時」執行重複處理,但執行順序與行為上有所不同。本章將說明 while 迴圈與 do-while 迴圈的差異以及何時使用它們。

while 迴圈與 do-while 迴圈的語法差異

  • while 迴圈
while (條件式) {
    // 想要重複的處理
}
- 首先判斷「條件式」,若為真(1)則執行區塊內的處理。
- 若條件式為偽(0),則一次也不執行,直接進入下一個處理。
  • do-while 迴圈
do {
    // 想要重複的處理
} while (條件式);
- 首先執行區塊內的處理一次,之後判斷「條件式」。
- 若條件式為真(1),則再次執行處理區塊;若為偽(0),則結束迴圈。

執行順序的差異與特點

  • while 迴圈是「前判定型」迴圈。因為先判斷條件式,某些情況下可能一次也不執行處理。
  • do-while 迴圈是「後判定型」迴圈。其特點是一定會先執行一次處理區塊。

範例:do-while 迴圈的範本

#include <stdio.h>

int main() {
    int n = 0;
    do {
        printf("n 的值是 %d", n);
        n++;
    } while (n < 3);
    return 0;
}
在此情況下,n 從 0 開始,當 n < 3 為真時會持續重複。 執行結果範例:
n 的值是 0。
n 的值是 1。
n 的值是 2。
即使 n 的初始值為 3,do-while 迴圈也只會顯示一次「n 的值是 3。」。

簡易比較表

while 迴圈do-while 迴圈
判定時機最初判斷條件最後判斷條件
執行次數0 次以上1 次以上
使用時機不一定需要執行的情況至少要執行一次的情況

使用分別的要點

  • 在需要驗證輸入值、顯示選單等「至少要執行一次」的情況下,適合使用 do-while 迴圈。
  • 若條件可能導致「一次也不執行」的情況,則使用 while 迴圈較安全。
透過了解兩者的特性並適當分別使用,即可實現更彈性的重複處理。

5. 透過 break·continue 的控制

在使用 while 迴圈進行重複處理時,常會出現「想在特定條件下中途結束迴圈」或「只想跳過某些條件」的情況。這時 break 陳述式與 continue 陳述式就很方便。本章將介紹它們各自的用法與實例。

break 陳述式:立即結束迴圈

break 陳述式用於在 while 等迴圈處理中,於符合條件的時機立即結束迴圈。例如「當輸入特定值時想跳出迴圈」的情況很有效。 範例:以特定值結束迴圈
#include <stdio.h>

int main() {
    int n;
    while (1) {  // 無限迴圈
        printf("請輸入整數(0 結束):");
        scanf("%d", &n);
        if (n == 0) {
            break;  // 0 被輸入時迴圈結束
        }
        printf("輸入的值是 %d。\n", n);
    }
    printf("程式結束。\n");
    return 0;
}

continue 陳述式:跳過一次處理

continue 陳述式在 while 迴圈內使用時,會「跳過該時點之後的處理,返回下一次迴圈條件判斷」的角色。例如「只想跳過偶數的處理」等情況很方便。 範例:僅在偶數時跳過處理
#include <stdio.h>

int main() {
    int i = 1;
    while (i <= 5) {
        if (i % 2 == 0) {
            i++;          // i 增加
            continue;     // 若為偶數則跳過以下
        }
        printf("奇數:%d\n", i);
        i++;
    }
    return 0;
}
執行結果範例:
奇數:1
奇數:3
奇數:5

總結

  • break 用於想強制結束迴圈時
  • continue 用於只想在特定條件下跳過該次處理時
結合這兩個控制語句,可更彈性且有效率地控制 while 迴圈的運作。

6. 使用多條件加強條件式

while 迴圈的條件式不僅可以使用單一比較,還可以結合「多個條件」來描述。藉此可以實現更彈性且實務的迴圈控制。本章將介紹使用多條件時的基本方法、邏輯運算子的用法以及具體範例。

邏輯運算子的基本

在 C 語言中,為了組合條件式,主要使用以下的邏輯運算子。
  • &&(AND):僅當兩個條件皆為真(true)時,整體才為真
  • ||(OR):只要其中一個條件為真,整體即為真
  • !(NOT):將條件的真假顛倒(真→偽、偽→真)

範例 1:使用 AND(&&)的多條件

在「a 大於等於 1 且 b 小於等於 10」的範圍內重複迴圈的況
#include <stdio.h>

int main() {
    int a = 1, b = 15;
    while (a < 5 && b > 10) {
        printf("a = %d, b = %dn", a, b);
        a++;
        b--;
    }
    return 0;
}
執行結果範例:
a = 1, b = 15
a = 2, b = 14
a = 3, b = 13
a = 4, b = 12

範例 2:使用 OR(||)的多條件

在「x 小於 5 或 y 小於 20」的範圍內重複迴圈的情況
#include <stdio.h>

int main() {
    int x = 3, y = 25;
    while (x < 5 || y < 20) {
        printf("x = %d, y = %dn", x, y);
        x++;
        y--;
    }
    return 0;
}
執行結果範例:
x = 3, y = 25
x = 4, y = 24
x = 5, y = 23
x = 6, y = 22
x = 7, y = 21
x = 8, y = 20
x = 9, y = 19
y 小於 20 為止)

範例 3:使用 NOT(!)的條件式

在「flg 為偽」時迴圈的情況
#include <stdio.h>

int main() {
    int flg = 0;
    while (!flg) {
        printf("因為 flg 為 0,正在迴圈中。n");
        flg = 1; // 將 flg 設為 1 以結束迴圈
    }
    return 0;
}

注意邏輯運算子的優先順序

同時使用多個邏輯運算子時,需要注意計算的順序(優先順序)。基本上,會依序優先評估 !&&||。必要時可使用 () 明確指定順序。 透過使用多條件,可以以更複雜的判斷標準來控制迴圈。

7. 輸入等待與 sentinel 控制的實踐範例

while語句在根據「外部輸入」持續或終止重複處理的情況下也非常常用。典型的例子是監視使用者輸入值或檔案結尾的「sentinel 控制」。本章將介紹實際的使用方法與要點。

什麼是 sentinel 控制?

sentinel(sentinel)指的是「守衛」或「哨兵」之類的意思,在程式設計的世界中指的是「作為迴圈結束標誌的值(結束條件的特定值)」。 例如,「0 被輸入時迴圈結束」等,使用特定的值作為「結束的訊號」。

範例1:使用者輸入值的迴圈控制

#include <stdio.h>

int main() {
    int value, sum = 0;
    printf("請輸入整數(0 結束):n");
    while (1) {
        scanf("%d", &value);
        if (value == 0) {
            break; // sentinel 值 0 結束
        }
        sum += value;
    }
    printf("總合為 %d。n", sum);
    return 0;
}
在此範例中,使用者在輸入 0 之前,系統會不斷接受值並計算總合。0 被輸入時,break 陳述式會結束迴圈。

範例2:文字輸入導致迴圈結束

#include <stdio.h>

int main() {
    char c;
    printf("請輸入文字(x 結束):n");
    while (1) {
        scanf(" %c", &c); // 在前面加入空格以跳過空白字元
        if (c == 'x') {
            break;
        }
        printf("輸入的文字:%cn", c);
    }
    printf("結束。n");
    return 0;
}

實用範例:重複處理至檔案結尾

在檔案處理中也常使用「sentinel 控制」。例如,逐行讀取檔案直到結尾(EOF)為止的情況:
#include <stdio.h>

int main() {
    FILE *fp = fopen("sample.txt", "r");
    char buf[100];
    if (fp == NULL) {
        printf("無法開啟檔案。n");
        return 1;
    }
    while (fgets(buf, sizeof(buf), fp) != NULL) {
        printf("%s", buf);
    }
    fclose(fp);
    return 0;
}
在此範例中,fgets 回傳 NULL 時即為 sentinel,迴圈結束。 這樣,while語句在監視與等待輸入或外部資料的處理上非常便利。

8. 無限迴圈與結束控制

C 語言在撰寫重複處理時,「無限迴圈」是常用的技巧之一。無限迴圈顧名思義是「刻意沒有結束」的迴圈,常用於希望程式持續運作,直到收到外部輸入或特定條件成立的情況。本章將說明無限迴圈的寫法,以及安全結束的方法。

無限迴圈的寫法

在 C 語言中,可透過將 while 陳述式的條件設為「永遠為真(1)」來實現無限迴圈,如下所示。
while (1) {
    // 這裡的處理會無限重複
}
或者,將條件式寫成永遠為真,也可以建立無限迴圈。
int flag = 0;
while (flag == 0) {
    // 只要 flag 保持為 0,就會無限執行
}

for 迴圈的無限迴圈

不僅是 while 陳述式,for 陳述式也可以寫成以下的無限迴圈。
for (;;) {
    // 無限迴圈
}

無限迴圈的應用範例

  • 持續等待使用者的輸入
  • 在遊戲或嵌入式程式中持續監測感測器數值
  • 伺服器等待外部連線

安全退出無限迴圈的方法

無限迴圈通常會使用 break 陳述式等,在「特定條件成立時」才結束迴圈。例如使用者輸入特定值,或發生錯誤時,就會跳出迴圈。 範例:使用者輸入以結束迴圈
#include <stdio.h>

int main() {
    char c;
    while (1) {
        printf("如果想結束,請輸入 q:");
        scanf(" %c", &c);
        if (c == 'q') {
            break; // 輸入 q 時結束無限迴圈
        }
        printf("仍在迴圈中。n");
    }
    printf("已跳出迴圈。n");
    return 0;
}

注意事項

無限迴圈很方便,但如果不小心沒有設計「退出路徑」,程式會無法停止。務必準備「結束條件」與「跳出迴圈的方法」,以確保程式安全運作。 掌握迴圈的使用方法,C 語言的應用能力將會更進一步提升。

9. 條件式的陷阱與注意事項

while文的條件式看起來很簡單,但在實際寫程式時,常會陷入「意想不到的陷阱」。本章將整理並介紹特別是初學者容易犯錯的重點與注意事項。

1. 變數未更新導致的無限迴圈

如果在 while 迴圈中未正確更新用於迴圈控制的變數,條件會一直為真,導致意外的無限迴圈。 範例:因未更新而產生的無限迴圈
int i = 0;
while (i < 5) {
    printf("i = %dn", i);
    // 由於缺少 i++ 的敘述,i 仍然是 0
}
在此情況下,i不會增加,i < 5會永遠為真,程式不會停止。

2. 比較運算子的錯誤(= 與 == 的混淆)

在 C 語言中,=是「賦值運算子」,==是「是否相等的比較運算子」。在條件式中搞錯會導致意外的行為或錯誤。 範例:賦值與比較的混淆
int n = 3;
while (n = 0) { // 應該寫成 while (n == 0)
    printf("n為0。n");
}
在此情況下,n = 0會把 n 賦值為 0,該值(0)作為條件式使用,導致「從一開始條件即為假」,迴圈本體一次也不會執行。

3. 條件式的評估規則(0 為假,非 0 為真)

在 C 語言中,條件式的值若為「0」則為假,「非 0」則為真。若不了解此規則,會導致意外的錯誤。 範例:直接使用數值作為條件式
int flag = -1;
while (flag) {
    // 當 flag 不為 0 時,迴圈持續
    flag = 0;
}
如此一來,負值或除 1 之外的數值也會被視為「真」。

4. 複雜的邏輯式中的優先順序錯誤

當結合多個邏輯運算子(&&、||、! 等)時,若搞錯優先順序會導致意外的條件判斷。若有疑慮,務必使用括號()明確表示。

5. 輸入值或外部資料的驗證不足

在使用使用者輸入值或檔案資料來控制 while 迴圈時,請注意即使出現「不正確的值」或「意外的輸入」能安全運作。

總結

  • 注意變數未更新、比較運算子的錯誤
  • 了解 0 與非 0 的真假判定規則
  • 邏輯運算子的優先順序與括號的使用也很重要
  • 熟悉條件式的設計後,while 迴圈的錯誤會大幅減少

10. 常見問題(FAQ)

C語言的 while 迴圈與條件式,彙整了學習者與初級程式設計師常見的疑問,以 Q&A 形式整理。釐清疑問點與容易卡住的重點,說明如何安心熟練使用 while 迴圈。

Q1. 如果 while 迴圈的條件式一開始就為假,迴圈內部會一次也不執行嗎?

A. 是的,正是如此。while 迴圈屬於「前判定型」,因此若最初的條件判斷為假(false、0),迴圈本體一次也不會執行,直接進入下一個處理。 ※若至少想執行一次,請使用 do-while 迴圈。

Q2. do-while 迴圈與 while 迴圈的差異是什麼?

A. 主要的差異在於「判斷條件式的時機」。
  • while 迴圈是「前判定型」,若條件式為假,則一次也不會執行。
  • do-while 迴圈是「後判定型」,不論條件式為何,都會至少執行一次。

Q3. 可以在 while 迴圈的條件式中結合多個條件嗎?

A. 可以。使用邏輯運算子(&&、||、!)即可自由組合多個條件。 例:while (a > 0 && b < 10) { ... }

Q4. 避免無限迴圈的技巧是什麼?

A. 請注意迴圈變數或控制變數的更新是否遺漏。另外,要意識「是否一定有跳出迴圈的條件」,正確設定 break 語句或結束條件非常重要。尤其是初學者,寫程式時要留意變數是否正確變化,以防錯誤。

Q5. 可以使用使用者輸入或外部資料來控制 while 迴圈嗎?

A. 當然可以。通常會以哨兵值(例如 0 或特定字元)或檔案結尾等方式,當輸入特定值時結束 while 迴圈,以此來控制迴圈。

Q6. if 語句與 while 語句的條件式有什麼差異嗎?

A. 條件式的寫法與評估規則相同,但
  • if 語句只會「判斷一次」條件並執行處理。
  • while 迴圈則會「只要條件成立,就會重複」執行處理。

Q7. 在 while 迴圈中大量使用 break 或 continue 會不會有問題?

A. 功能上沒問題,但若過於複雜,會讓人難以分辨「為何跳出迴圈」或「處理流程」是什麼。應注意可讀性,盡量保持控制簡潔。

Q8. 在 while 迴圈外定義的變數在迴圈內也能使用嗎?

A. 可以。於 while 迴圈外宣告與初始化的變數,可在迴圈內自由參照與更新。但需留意變數的作用域與值的初始化時機。 逐一解決這些疑問,能讓 while 迴圈的運用能力穩步提升。下一章將介紹全文的總結與未來的步驟。

11. 總結與下一步

C 語言中的 while 陳述式是「只要條件成立就重複執行」的,非常彈性且強大的控制結構。透過本文,從 while 陳述式的基本語法與用法、複數條件的應用、與 do-while 陳述式的差異、無限迴圈的控制、常見錯誤與 FAQ,廣泛地進行了解說。 while 陳述式的主要重點如下:
  • 前判定型的迴圈,若條件一開始為假,則一次也不會執行。
  • 了解 for 陳述式與 do-while 陳述式的差異,並在適當情境下加以區分使用是重要的。
  • 利用 邏輯運算子與哨兵值,即可彈性實作實務上的輸入監控與複雜控制。
  • 根據情況,可使用 無限迴圈與 break/continue 來退出或跳過。
  • 要注意 變數更新遺漏或比較運算子錯誤 等,這些是初學者容易卡住的陷阱。
若掌握 while 陳述式的使用,寫出「實際可執行的程式」的能力將大幅提升。對於程式設計初學者而言,最重要的是親自撰寫程式碼並不斷試驗,體驗「在什麼情境下 while 陳述式會很便利」。 未來,請以以下步驟提升技能:
  • 實作 for 陳述式、if 陳述式等其他控制結構的結合範例。
  • 挑戰結合 while 陳述式的實務程式,例如陣列、檔案 I/O、函式等。
  • 實作各種錯誤與例外處理,朝向更安全、穩固的程式碼邁進。
若能熟練運用 while 陳述式,C 語言的應用範圍將大幅擴展。請務必活用本次所學,挑戰更實務的程式設計吧。
侍エンジニア塾