閉じる

【C言語】for文/while文で使うbreakとcontinueの挙動と使い分け

ループ処理を書いていると、条件に応じて途中で処理を止めたり、その周回だけ飛ばしたくなる場面が必ず出てきます。

C言語ではbreakcontinueという2つのキーワードでこれを実現します。

本記事では、for文とwhile文における挙動の違いと実行フローを、サンプルコードと実行結果を交えて丁寧に解説し、読みやすさを保つ使い分けの指針まで押さえます。

C言語のbreakとcontinueの基本

breakの役割(ループを終了)

breakは、今いる最も内側のループ全体を即座に終了します。

以降のループ周回は行われず、ループ直後の文に制御が移ります。

C言語
#include <stdio.h>

int main(void) {
    for (int i = 1; i <= 10; i++) {
        if (i == 5) {
            printf("i=%dでbreakします\n", i);  // 5に到達したらループを終了
            break;
        }
        printf("i=%d\n", i);  // 1,2,3,4まで出力される
    }
    printf("ループ後の処理\n");
    return 0;
}
実行結果
i=1
i=2
i=3
i=4
i=5でbreakします
ループ後の処理

ループ本体の残りや、それ以降の周回は実行されません。

continueの役割(周回をスキップ)

continueは、その周回の残りの処理だけをスキップし、次の周回へ進みます。

ループ自体は継続します。

C言語
#include <stdio.h>

int main(void) {
    for (int i = 1; i <= 10; i++) {
        if (i % 2 == 0) {
            // 偶数のときはこの周回の残りを飛ばして次へ
            continue;
        }
        printf("%d ", i);  // 奇数のみ出力
    }
    printf("\n");
    return 0;
}
実行結果
1 3 5 7 9

実行フローの違いと挙動

breakはループからの脱出、continueはループ継続という根本の違いに加え、forwhileでの「次にどこへ戻るか」が異なります。

  • forcontinueが発生すると、更新式(ヘッダの3つ目)が実行されてから条件判定に戻ります。
  • forbreakが発生すると、更新式は実行されず、ループ直後へ移ります。
  • whileでは更新式が別に書かれるため、continueを使う際はカウンタの更新忘れで無限ループを起こしやすい点に注意します。

下表に要点をまとめます。

振る舞いループ本体の残り次に実行される位置forの更新式脱出の範囲
break実行しないループ直後実行されない最も内側の1つのループ
continue実行しない次周回の先頭実行される(forのみ)脱出しない

特に「forの更新式が実行されるかどうか」は混乱しやすいため、次章で具体的に確かめます。

for文でのbreak/continueの挙動

break発生時のfor文の流れ

breakでは更新式が実行されないことを、変数の値で確認します。

C言語
#include <stdio.h>

int main(void) {
    int i;  // ループ外で宣言して後で値を観察する
    for (i = 0; i < 5; i++) {
        printf("本体: i=%d\n", i);
        if (i == 2) {
            printf("i==2でbreak\n");
            break;  // 更新式(i++)は実行されない
        }
    }
    printf("ループ直後: i=%d\n", i);  // 2のまま
    return 0;
}
実行結果
本体: i=0
本体: i=1
本体: i=2
i==2でbreak
ループ直後: i=2

breakでは「更新式がスキップされる」ため、iは2のままです。

continue後に更新式は実行される

continueでは更新式が実行されるため、次の周回ではインクリメント済みの値に進みます。

C言語
#include <stdio.h>

int main(void) {
    for (int i = 0; i < 5; i++) {
        if (i == 2) {
            printf("i==2でcontinue(この後に更新式のi++が動く)\n");
            continue;  // 更新式が動いて、次はi==3の周回へ
        }
        printf("印字: i=%d\n", i);
    }
    return 0;
}
実行結果
印字: i=0
印字: i=1
i==2でcontinue(この後に更新式のi++が動く)
印字: i=3
印字: i=4

i==2の周回では印字を飛ばし、更新式によりi==3へ進んでいることがわかります。

多重forでのbreakの効き方

break「最も内側のループ」だけを終了します。

外側のループは続行します。

C言語
#include <stdio.h>

int main(void) {
    for (int y = 1; y <= 2; y++) {          // 外側
        for (int x = 1; x <= 3; x++) {      // 内側
            if (x == 2) {
                printf("(y=%d)x==2で内側だけbreak\n", y);
                break;  // 内側のforからだけ脱出
            }
            printf("y=%d x=%d\n", y, x);
        }
        printf("外側は継続中 y=%d\n", y);
    }
    return 0;
}
実行結果
y=1 x=1
(y=1)x==2で内側だけbreak
外側は継続中 y=1
y=2 x=1
(y=2)x==2で内側だけbreak
外側は継続中 y=2

多重ループを一気に抜けたい場合、breakだけでは足りません

後述の「多重ループをまとめて抜ける考え方」で扱います。

for(;;)の無限ループをbreakで抜ける

for(;;)は条件なしの無限ループです。

終了条件を本体側で判定してbreakで抜けます。

C言語
#include <stdio.h>

int main(void) {
    int count = 0;
    for (;;) {  // 無限ループ
        printf("処理中... count=%d\n", count);
        if (count >= 3) {
            printf("条件達成でbreak\n");
            break;  // ループ終了
        }
        count++;  // 進捗を進める
    }
    printf("ループを抜けました\n");
    return 0;
}
実行結果
処理中... count=0
処理中... count=1
処理中... count=2
処理中... count=3
条件達成でbreak
ループを抜けました

while文でのbreak/continueの挙動

break発生時のwhile文の流れ

whileでもbreakはループを終了します。

forと同様に、以降の周回は行いません。

C言語
#include <stdio.h>

int main(void) {
    int i = 0;
    while (i < 5) {
        printf("i=%d\n", i);
        if (i == 3) {
            printf("i==3でbreak\n");
            break;
        }
        i++;  // 更新は自分で書く
    }
    printf("ループ後 i=%d\n", i);
    return 0;
}
実行結果
i=0
i=1
i=2
i=3
i==3でbreak
ループ後 i=3

continue後は条件判定へ戻る

whileではcontinueすると、ただちにループ先頭へ戻って条件判定が行われます。

更新は自分で記述する必要があるため、更新を飛ばすと無限ループになります。

C言語
#include <stdio.h>

int main(void) {
    int i = 0;
    while (i < 5) {
        if (i == 2) {
            printf("i==2でcontinue(更新i++を先に行う)\n");
            i++;           // 先に更新してからcontinue
            continue;      // 以降の本体処理をスキップ
        }
        printf("処理: i=%d\n", i);
        i++;               // 通常の更新
    }
    return 0;
}
実行結果
処理: i=0
処理: i=1
i==2でcontinue(更新i++を先に行う)
処理: i=3
処理: i=4

continueの前にカウンタ更新を行う配置が、安全な書き方です。

入力チェックでcontinueを使う例

ユーザー入力から正の整数だけを合計し、負や0は注意を出してスキップします。

continueで「その周回の残り」を飛ばします。

C言語
#include <stdio.h>

int main(void) {
    int sum = 0;
    int n;
    int count = 0;

    printf("正の整数を5回入力してください(負や0は無視します)\n");

    while (count < 5) {
        printf("%d回目: ", count + 1);
        if (scanf("%d", &n) != 1) {
            // 入力失敗時はバッファを捨てる簡易対応(実務ではより厳密に)
            int ch;
            while ((ch = getchar()) != '\n' && ch != EOF) { /* 破棄 */ }
            printf("数値を入力してください\n");
            continue;  // カウントを進めず再入力
        }
        if (n <= 0) {
            printf("正の整数ではありません。やり直してください\n");
            continue;  // 合計せず再入力
        }
        sum += n;
        count++;       // 有効入力のみ数える
    }

    printf("合計=%d\n", sum);
    return 0;
}
実行結果
正の整数を5回入力してください(負や0は無視します)
1回目: -2
正の整数ではありません。やり直してください
1回目: abc
数値を入力してください
1回目: 3
2回目: 5
3回目: 0
正の整数ではありません。やり直してください
3回目: 7
4回目: 10
5回目: 2
合計=27

無効入力の処理を短く切り上げて次の入力に進めるのがcontinueの得意分野です。

使い分けと注意点(C言語)

使い分けの指針(読みやすさ)

「読んだ人が一度で意図を理解できるか」を基準に選びます。

条件に合致したらループ全体を終わらせたいならbreak、処理対象外なのでその周回だけ飛ばしたいならcontinueです。

ネストが深い場所に複雑なbreak/continueが点在すると流れが追いにくくなるため、条件分岐の構造自体を見直す選択肢も検討します。

多重ループをまとめて抜ける考え方

breakは1段分しか抜けません。

2段以上を抜けたいときの代表的アプローチは次のとおりです。

  1. フラグ変数で外側のループも抜ける
C言語
#include <stdio.h>

int main(void) {
    int found = 0;
    for (int y = 0; y < 3 && !found; y++) {
        for (int x = 0; x < 3; x++) {
            if (x == 1 && y == 2) {
                printf("見つけたので二重ループを脱出\n");
                found = 1;   // フラグを立てる
                break;       // 内側を抜ける
            }
            printf("探索中 y=%d x=%d\n", y, x);
        }
        // foundが1なら外側の継続条件で抜ける
    }
    printf("終了 found=%d\n", found);
    return 0;
}
実行結果
探索中 y=0 x=0
探索中 y=0 x=1
探索中 y=0 x=2
探索中 y=1 x=0
探索中 y=1 x=1
探索中 y=1 x=2
探索中 y=2 x=0
見つけたので二重ループを脱出
終了 found=1
  1. ラベルとgotoで一気に脱出(用途限定で)
C言語
#include <stdio.h>

int main(void) {
    for (int y = 0; y < 3; y++) {
        for (int x = 0; x < 3; x++) {
            if (x == 2 && y == 1) {
                printf("ラベルへジャンプして全体を脱出\n");
                goto OUT;  // 多重ループを瞬時に抜ける
            }
            printf("走査 y=%d x=%d\n", y, x);
        }
    }
OUT:
    printf("OUTラベル後\n");
    return 0;
}
実行結果
走査 y=0 x=0
走査 y=0 x=1
走査 y=0 x=2
走査 y=1 x=0
走査 y=1 x=1
ラベルへジャンプして全体を脱出
OUTラベル後

gotoは可読性を損ねやすいため、例外処理的な早期脱出に限定し、可能なら関数分割やフラグ方式を優先します。

breakとreturnの違い

return関数からの復帰であり、breakのように「ループだけ」を抜けるわけではありません。

C言語
#include <stdio.h>

void demo_break(void) {
    for (int i = 0; i < 3; i++) {
        if (i == 1) {
            printf("breakでループだけ終了\n");
            break;               // 関数は続行する
        }
        printf("i=%d\n", i);
    }
    printf("demo_breakの後続処理\n");
}

void demo_return(void) {
    for (int i = 0; i < 3; i++) {
        if (i == 1) {
            printf("returnで関数を終了\n");
            return;              // 関数自体を抜ける
        }
        printf("i=%d\n", i);
    }
    printf("この行は実行されません\n");
}

int main(void) {
    demo_break();
    demo_return();
    printf("mainの終わり\n");
    return 0;
}
実行結果
i=0
breakでループだけ終了
demo_breakの後続処理
i=0
returnで関数を終了
mainの終わり

breakは制御の射程が「ループまで」、returnは「関数まで」と覚えると混同しません。

乱用を避けるコツ

  • 意図が単純なときに使うと読みやすく、複雑な分岐や多段ネストの中で多用すると読みにくくなります。条件を見直し、早期リターンや関数分割でネストを浅くする方が明確な場合があります。
  • whilecontinueを使う際は更新忘れの無限ループに注意し、continue前に更新するパターンを徹底します。
  • forではcontinue後に更新式が走る点を前提に、副作用のある更新式は簡潔に保つと誤解が減ります。

まとめ

breakはループからの脱出、continueは周回だけのスキップであり、forではcontinue後に更新式が実行され、break時は実行されないという違いが肝心です。

whileでは更新を自前で書くため、特にcontinueの位置に注意が必要です。

多重ループの脱出にはフラグや関数分割、場合によりgotoも選択肢ですが、可読性を最優先してください。

今回のポイントを押さえれば、意図どおりにループを制御でき、シンプルで保守しやすいコードに近づけます。

この記事を書いた人
エーテリア編集部
エーテリア編集部

プログラミングの基礎をしっかり学びたい方向けに、C言語の基本文法から解説しています。ポインタやメモリ管理も少しずつ理解できるよう工夫しています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!