C言語で繰り返し処理を書くようになると、「途中でループを抜けたい」「この回だけ処理を飛ばしたい」という場面が必ず出てきます。
そんな時に使うのがbreak文とcontinue文です。
本記事では、C言語初心者の方でも理解しやすいように、ループの基本から、break・continueの動き方、使い分けや注意点まで、サンプルコードを交えながら丁寧に解説します。
breakとcontinueとは何か
C言語のループ処理のおさらい
まず、breakとcontinueの理解を深めるために、ループ処理そのものを軽くおさらいします。
C言語の代表的なループ構文は次の3つです。
- for文
- while文
- do-while文
それぞれの基本形は次のようになります。
#include <stdio.h>
int main(void) {
int i;
/* for文の基本形 */
for (i = 0; i < 5; i++) {
printf("for: i = %d\n", i);
}
/* while文の基本形 */
i = 0;
while (i < 5) {
printf("while: i = %d\n", i);
i++;
}
/* do-while文の基本形 */
i = 0;
do {
printf("do-while: i = %d\n", i);
i++;
} while (i < 5);
return 0;
}
for: i = 0
for: i = 1
for: i = 2
for: i = 3
for: i = 4
while: i = 0
while: i = 1
while: i = 2
while: i = 3
while: i = 4
do-while: i = 0
do-while: i = 1
do-while: i = 2
do-while: i = 3
do-while: i = 4
このように、ループでは「条件を満たすあいだ、同じ処理を何度も繰り返す」ことが基本です。
しかし、実際のプログラムでは途中でループをやめたいことや、一部の繰り返しだけ処理を飛ばしたいことがあります。
そのときに使うのがbreakとcontinueです。
breakの基本的な意味と役割
break文は、「今いるループ(またはswitch文)を途中で完全に抜ける」ための文です。
ループの途中でbreakが実行されると、その瞬間にループを終了して、次の文へ進みます。
イメージとしては、ループの途中で非常停止ボタンを押して、強制的に繰り返しを止める感じです。
continueの基本的な意味と役割
continue文は、「今の周(1回分の繰り返し)の残りの処理をスキップして、次の周に進む」ための文です。
ループの途中でcontinueが実行されると、その後の文を実行せずに、次の繰り返しに移ります。
イメージとしては、「今回はここまででよし、次に進もう」と、残りを飛ばして先へ進めるボタンです。
breakとcontinueの違いを直感的に理解する
両者の違いを、短いコードで比較してみます。
#include <stdio.h>
int main(void) {
int i;
printf("=== breakの動き ===\n");
for (i = 1; i <= 5; i++) {
if (i == 3) {
printf("i == 3 なので break します\n");
break; /* ループ全体を終了 */
}
printf("i = %d\n", i);
}
printf("\n=== continueの動き ===\n");
for (i = 1; i <= 5; i++) {
if (i == 3) {
printf("i == 3 なので continue します\n");
continue; /* 今回だけ残りをスキップして次へ */
}
printf("i = %d\n", i);
}
return 0;
}
=== breakの動き ===
i = 1
i = 2
i == 3 なので break します
=== continueの動き ===
i = 1
i = 2
i == 3 なので continue します
i = 4
i = 5
この結果から、次の点が直感的にわかります。
- breakはループ自体をそこで終了させます。
- continueはその回だけ残りの処理をスキップして、次の周に進むだけです。
breakでループを途中で抜ける
for文でbreakを使う基本例
まず、for文におけるbreakの基本的な使い方を見ていきます。
#include <stdio.h>
int main(void) {
int i;
/* 1から10までカウントするが、5になったらループをやめる例 */
for (i = 1; i <= 10; i++) {
printf("i = %d\n", i);
if (i == 5) {
printf("i が 5 なのでループを終了します(break)\n");
break; /* for文から抜ける */
}
}
printf("ループの外に出ました\n");
return 0;
}
i = 1
i = 2
i = 3
i = 4
i = 5
i が 5 なのでループを終了します(break)
ループの外に出ました
このように、ループ条件(cst-code>i <= 10)を満たしていても、breakが実行されれば直ちにループを抜けることがわかります。
while文・do-while文でbreakを使う基本例
breakは、for文だけでなくwhile文・do-while文でも同じように使えます。
while文の例を見てみます。
#include <stdio.h>
int main(void) {
int i = 1;
/* while文での break の例 */
while (i <= 10) {
printf("i = %d\n", i);
if (i == 5) {
printf("i が 5 なのでループを終了します(break)\n");
break; /* while文から抜ける */
}
i++; /* カウンタを増やす */
}
printf("whileループの外に出ました\n");
return 0;
}
i = 1
i = 2
i = 3
i = 4
i = 5
i が 5 なのでループを終了します(break)
whileループの外に出ました
do-while文でも同様に使えます。
#include <stdio.h>
int main(void) {
int i = 1;
/* do-while文での break の例 */
do {
printf("i = %d\n", i);
if (i == 5) {
printf("i が 5 なのでループを終了します(break)\n");
break; /* do-whileループから抜ける */
}
i++; /* カウンタを増やす */
} while (i <= 10);
printf("do-whileループの外に出ました\n");
return 0;
}
i = 1
i = 2
i = 3
i = 4
i = 5
i が 5 なのでループを終了します(break)
do-whileループの外に出ました
while系のループでも、breakの動きはfor文と全く同じです。
多重ループ(入れ子ループ)でbreakが効く範囲
次に、多重ループ(入れ子ループ)でのbreakの挙動を確認しておきます。
C言語のbreakは「現在実行中の一番内側のループ」にだけ効きます。
#include <stdio.h>
int main(void) {
int i, j;
for (i = 1; i <= 3; i++) {
printf("外側ループ i = %d の開始\n", i);
for (j = 1; j <= 5; j++) {
printf(" 内側ループ j = %d\n", j);
if (j == 3) {
printf(" j が 3 なので内側ループを break します\n");
break; /* 内側 for だけを抜ける */
}
}
printf("外側ループ i = %d の終了\n\n", i);
}
printf("すべてのループを終了しました\n");
return 0;
}
外側ループ i = 1 の開始
内側ループ j = 1
内側ループ j = 2
内側ループ j = 3
j が 3 なので内側ループを break します
外側ループ i = 1 の終了
外側ループ i = 2 の開始
内側ループ j = 1
内側ループ j = 2
内側ループ j = 3
j が 3 なので内側ループを break します
外側ループ i = 2 の終了
外側ループ i = 3 の開始
内側ループ j = 1
内側ループ j = 2
内側ループ j = 3
j が 3 なので内側ループを break します
外側ループ i = 3 の終了
すべてのループを終了しました
この例では、breakは内側のfor文だけから抜けており、外側のfor文は継続していることが分かります。
一気に二重ループすべてを抜けるわけではない点に注意が必要です。
無限ループをbreakで抜ける書き方(while(1) / for(;;))
C言語では、条件式が常に真になるように書くことで、無限ループを書くことができます。
代表的な書き方は次の2つです。
while (1)for (;;)
これらは「終わらないループ」ですから、普通は内部でbreakして抜けるようにします。
#include <stdio.h>
int main(void) {
int n;
printf("0 が入力されるまで整数を読み続けます\n");
while (1) { /* 無限ループの開始 */
printf("整数を入力してください(0で終了): ");
scanf("%d", &n);
if (n == 0) {
printf("0 が入力されたのでループを終了します\n");
break; /* 無限ループから抜ける */
}
printf("入力された値は %d です\n", n);
}
printf("プログラムを終了します\n");
return 0;
}
0 が入力されるまで整数を読み続けます
整数を入力してください(0で終了): 3
入力された値は 3 です
整数を入力してください(0で終了): 8
入力された値は 8 です
整数を入力してください(0で終了): 0
0 が入力されたのでループを終了します
プログラムを終了します
同じことをfor (;;)で書くこともできます。
#include <stdio.h>
int main(void) {
int n;
printf("0 が入力されるまで整数を読み続けます(for版)\n");
for (;;) { /* 条件なしの for = 無限ループ */
printf("整数を入力してください(0で終了): ");
scanf("%d", &n);
if (n == 0) {
printf("0 が入力されたのでループを終了します\n");
break;
}
printf("入力された値は %d です\n", n);
}
printf("プログラムを終了します\n");
return 0;
}
実行結果もほぼ同様になります。
0 が入力されるまで整数を読み続けます(for版)
整数を入力してください(0で終了): 5
入力された値は 5 です
整数を入力してください(0で終了): 2
入力された値は 2 です
整数を入力してください(0で終了): 0
0 が入力されたのでループを終了します
プログラムを終了します
このように、無限ループ + breakは、ユーザー入力待ちなどで頻繁に使われるパターンです。
if文と組み合わせて条件付きでbreakする
これまでの例でも少し使いましたが、breakはほとんどの場合、if文と組み合わせて使います。
つまり、「ある条件を満たしたら、その時点でループをやめる」という形です。
次の例では、配列の中から特定の値を探し、見つかったらその時点でループを抜けます。
#include <stdio.h>
int main(void) {
int data[] = {10, 20, 30, 40, 50};
int size = sizeof(data) / sizeof(data[0]);
int key = 30; /* 探したい値 */
int i;
int found_index = -1; /* 見つからなかった場合は -1 のまま */
printf("配列の中から %d を探します\n", key);
for (i = 0; i < size; i++) {
if (data[i] == key) {
found_index = i;
break; /* 見つかったのでループを抜ける */
}
}
if (found_index != -1) {
printf("%d はインデックス %d に見つかりました\n", key, found_index);
} else {
printf("%d は配列の中に見つかりませんでした\n", key);
}
return 0;
}
配列の中から 30 を探します
30 はインデックス 2 に見つかりました
このように、「条件を満たした最初の位置だけ調べればよい」といった場合に、if + breakは非常に有効です。
continueで1回だけ処理をスキップする
for文でcontinueを使う基本例
次に、continue文を見ていきます。
continueは「今の周の残りをスキップして、次の周に進む」ためのものです。
まずはfor文での基本例です。
#include <stdio.h>
int main(void) {
int i;
/* 1〜10のうち、偶数だけを表示する例 */
for (i = 1; i <= 10; i++) {
if (i % 2 == 1) { /* i が奇数のとき */
continue; /* この回は残りをスキップして次へ */
}
printf("偶数: %d\n", i);
}
return 0;
}
偶数: 2
偶数: 4
偶数: 6
偶数: 8
偶数: 10
ここでは、iが奇数のときはcontinueによりprintfが実行されません。
その結果、偶数だけが表示されます。
while文・do-while文でcontinueを使う基本例
while文でもcontinueは同様に使えますが、カウンタの更新位置に注意する必要があります。
#include <stdio.h>
int main(void) {
int i = 0;
/* 1〜10のうち、偶数だけを表示する(while版) */
while (i < 10) {
i++; /* 先にインクリメントして 1 〜 10 にする */
if (i % 2 == 1) { /* i が奇数のとき */
continue; /* printf をスキップして次のループへ */
}
printf("偶数: %d\n", i);
}
return 0;
}
実行結果の例はfor文版と同じです。
偶数: 2
偶数: 4
偶数: 6
偶数: 8
偶数: 10
do-while文でも同様です。
#include <stdio.h>
int main(void) {
int i = 0;
/* 1〜10のうち、偶数だけを表示する(do-while版) */
do {
i++;
if (i % 2 == 1) {
continue; /* 奇数のときは printf を飛ばす */
}
printf("偶数: %d\n", i);
} while (i < 10);
return 0;
}
実行結果も同様になります。
偶数: 2
偶数: 4
偶数: 6
偶数: 8
偶数: 10
while系のループでは、continueで「カウンタを増やさないまま次へ進んでしまう」バグを起こしやすいので注意が必要です。
この点については後で詳しく触れます。
for文とwhile文でcontinueの動き方がどう違うか
for文とwhile文の大きな違いは、「カウンタの更新(増減)がどこに書かれているか」です。
- for文では、ヘッダ部分
(for (初期化; 条件; 更新))の「更新」の位置で毎回実行されます。 - while文では、自分でループ本体の中に更新を書く必要があります。
この違いは、continueの動きに影響します。
次の2つのコードを比較してみてください。
#include <stdio.h>
int main(void) {
int i;
printf("=== for文でのcontinue ===\n");
for (i = 1; i <= 5; i++) {
if (i == 3) {
printf("i == 3 で continue\n");
continue; /* ここで「更新 i++」の前に次の周へ */
}
printf("for: i = %d\n", i);
}
printf("\n=== while文でのcontinue ===\n");
i = 1;
while (i <= 5) {
if (i == 3) {
printf("i == 3 で continue\n");
i++; /* これを忘れると無限ループになる */
continue; /* whileの先頭へ戻る */
}
printf("while: i = %d\n", i);
i++;
}
return 0;
}
=== for文でのcontinue ===
for: i = 1
for: i = 2
i == 3 で continue
for: i = 4
for: i = 5
=== while文でのcontinue ===
while: i = 1
while: i = 2
i == 3 で continue
while: i = 4
while: i = 5
for文の場合、continueしてもヘッダの「更新部分(i++)」は毎回実行されるので、特別な配慮は要りません。
一方、while文では自分でi++を書く必要があり、continueの前に書くか後ろに書くかで挙動が変わります。
更新処理をcontinueより後ろに書いてしまうと、その行は実行されずにスキップされてしまい、無限ループの原因になります。
この点が、初心者が特に注意すべきポイントです。
if文と組み合わせて特定の条件だけcontinueする
continueも、breakと同様に、if文と組み合わせて特定の条件のときだけスキップするのが一般的です。
次の例では、1〜20までのうち、3の倍数だけを飛ばして表示しています。
#include <stdio.h>
int main(void) {
int i;
printf("1〜20のうち、3の倍数をスキップして表示します\n");
for (i = 1; i <= 20; i++) {
if (i % 3 == 0) { /* 3の倍数のとき */
continue; /* 残りを飛ばして次の i へ */
}
printf("%d ", i);
}
printf("\n終了しました\n");
return 0;
}
1〜20のうち、3の倍数をスキップして表示します
1 2 4 5 7 8 10 11 13 14 16 17 19 20
終了しました
このように、「特定の条件に当てはまるケースだけ処理を行わない」という場面でcontinueが役に立ちます。
breakとcontinueの使い分けと注意点
breakとcontinueを使う典型的なパターン
ここまでの内容をまとめると、breakとcontinueの典型的な使い方は次のようになります。
| 文 | 主な用途のイメージ |
|---|---|
| break | 検索などで目的のものを見つけたらループを終了する時、無限ループから抜ける時など |
| continue | 入力の検証などで条件を満たさないデータだけスキップして次へ進みたい時 |
具体的なパターンとしては、次のようなものがあります。
- 探索処理 + break
配列や文字列の中から最初に一致する要素を探し、見つかったらそこでループを抜ける。 - メニュー表示の無限ループ + break
繰り返しメニューを表示し、「終了」が選ばれたらbreakでループを抜ける。 - 入力チェック + continue
不正な入力や関係ないデータのときはcontinueでスキップし、有効なデータだけを処理する。
こうしたパターンを意識しておくと、どんな場面でどちらを使えばよいかが見えやすくなります。
breakやcontinueを多用しすぎるときのコードの読みづらさ
breakやcontinueは便利ですが、使いすぎるとコードが読みにくくなることがあります。
例えば、1つのループの中に複数のbreakとcontinueが散らばっていると、「どの条件でループが終わるのか」「どのケースがスキップされるのか」を把握するのが難しくなってしまいます。
読みやすさを保つためには、次のような工夫が有効です。
- 1つのループ内でのbreak/continueの数をできるだけ少なくする。
- 早期終了の条件(例: エラー検出時)だけにbreakを使い、それ以外は条件式を工夫する。
- 「continueしたケース」と「通常の処理」をコメントで明確に区別する。
例えば、continueを使わずに条件式で全体を囲む書き方もあります。
/* continue を使う場合 */
for (i = 0; i < n; i++) {
if (!条件を満たす) {
continue;
}
/* 条件を満たすときの処理 */
}
/* continue を使わずに書く場合 */
for (i = 0; i < n; i++) {
if (条件を満たす) {
/* 条件を満たすときの処理 */
}
}
どちらが読みやすいかは場合によりますが、「このループは何をしているのか」がすぐに分かる書き方を意識することが大切です。
switch文のbreakとループのbreakの違い
C言語にはswitch文にもbreakが登場します。
同じキーワードですが、意味と範囲が少し違うので整理しておきましょう。
- ループのbreak
今いるループ(for, while, do-while)全体から抜ける。 - switchのbreak
今いるswitch文の中から抜ける。ループが外側にあれば、ループ自体は続行される。
次のサンプルを見てください。
#include <stdio.h>
int main(void) {
int i;
for (i = 1; i <= 3; i++) {
int cmd;
printf("i = %d のときのメニュー: 1(続行), 2(スキップ), 3(ループ終了) >> ", i);
scanf("%d", &cmd);
switch (cmd) {
case 1:
printf(" case 1: 何もしないで次へ\n");
break; /* switch だけを抜ける */
case 2:
printf(" case 2: この i の残りをスキップ(continue)\n");
continue; /* for ループの次の周へ */
case 3:
printf(" case 3: ループ全体を終了(break)\n");
break; /* switch を抜けるだけなので、後で for からも抜ける必要がある */
default:
printf(" 不明なコマンドです\n");
break;
}
if (cmd == 3) {
printf("外側の for ループも break します\n");
break; /* for ループを終了 */
}
printf(" i = %d の処理が終わりました\n", i);
}
printf("プログラムを終了します\n");
return 0;
}
このように、switchの中でcontinueを書くと「外側のループに対するcontinue」になるなど、少しややこしく感じるかもしれません。
どのbreak/continueがどの構文に効くかを意識しながら書くことが重要です。
初心者がハマりやすいエラーとデバッグのコツ
最後に、breakとcontinueで初心者がハマりやすいポイントと、その対処方法をまとめておきます。
1. while文でcontinueを使って無限ループになる
更新処理(i++)をcontinueより後ろに書いてしまい、その行が実行されずに条件が変わらないままループが回り続けるパターンです。
対処法としては、「continueを使うときは更新処理を必ずそれより前に書く」か、for文を使って更新処理をヘッダにまとめるといった工夫が有効です。
2. どのループから抜けているのか分からなくなる 多重ループでbreak/continueを多用すると、どの階層のループに効いているのかが分かりづらくなります。
この場合は、次のような方法で解決を図るとよいです。
- ループを関数に分割し、
returnで抜ける。 - フラグ変数を使い、「外側ループを抜けるべきかどうか」を管理する。
- コメントで「このbreakは内側のforだけ」「このbreakはwhileから抜ける」などと明記する。
3. breakやcontinueの位置が1行違っていて意図しない動作になる
if文のブロック{}の付け忘れなどで、break/continueの適用範囲がずれるパターンです。
この問題を避けるコツとしては、ifの中に複数の文を書くときは必ずブロック{}で囲むことが挙げられます。
/* 悪い例: ブロックがない */
if (条件)
printf("メッセージ\n");
break; /* if とは無関係に毎回 break されてしまう */
/* 良い例: 必ずブロックで囲む */
if (条件) {
printf("メッセージ\n");
break; /* 条件が真のときだけ break される */
}
デバッグのコツとしては、printfで「今どこにいるのか」を細かく表示してみることが有効です。
ループの先頭・breakやcontinueの直前などにメッセージを入れると、処理の流れが追いやすくなります。
まとめ
本記事では、C言語のbreak文とcontinue文について、ループのおさらいから動作の違い、典型的な使い方や注意点まで詳しく解説しました。
breakはループを途中で完全に抜けるしくみであり、continueはその回だけ残りをスキップして次の繰り返しに進むしくみです。
どちらも便利な反面、使いすぎると処理の流れが見えにくくなります。
特にwhile文でのcontinueや多重ループでのbreakの範囲には注意しながら、「読みやすく、意図が伝わるコード」を書くことを心がけて練習してみてください。
