
C言語の基本|無限ループの使い方
終わらないように見えても、出口はきちんと用意する。無限ループとbreak文を組み合わせて、終了時期が変わる処理を自在に作ろう。
繰り返し処理の中には、何回実行すれば終わるのかを事前に決められないものがあります。
たとえば、次のような処理です。
- 正しい値が入力されるまで質問を続ける
- 終了番号が入力されるまでデータを受け付ける
- メニューで終了が選ばれるまで操作を繰り返す
- ゲームの正解が見つかるまで入力を続ける
このような場面で役立つのが無限ループです。
無限ループは、継続条件が常に真になるように作られた繰り返し処理です。そのままでは終了しませんが、一般的にはループの中で終了条件を判定し、break文で抜けます。
無限ループは、ただ処理を永遠に続けるためのものではありません。繰り返す回数ではなく、終了する条件をループの中で決めるための書き方だと考えると分かりやすいでしょう。
無限ループとは
通常のwhile文やfor文は、継続条件が偽になると終了します。
一方、無限ループでは、継続条件が常に真になる形を使います。
while (1) {
処理;
}このwhile文の条件式には1が指定されています。C言語では0が偽、0以外が真なので、1は常に真です。そのため、ループの外から終了させる仕組みがなければ、処理は繰り返され続けます。
実用的な無限ループでは、次のようにif文とbreak文を組み合わせます。
while (1) {
処理;
if (終了条件) {
break;
}
}処理の考え方はシンプルです。
- ループ内の処理を実行する
- 終了条件を判定する
- 条件が真ならbreak文で終了する
- 条件が偽なら次の繰り返しへ進む
図1:無限ループとbreak文による出口

この図から分かること
無限ループは、繰り返しを続けること自体が基本の動作です。
終了条件が成立しない間は、処理が何度でも繰り返されます。終了条件が成立するとbreak文が実行され、初めてループの外へ進みます。
無限ループを書くときは、次の2つをセットで考えることが大切です。
- 何を繰り返すのか
- どの条件で終了するのか
終了条件が書かれていても、その条件が絶対に成立しない場合はループが終わりません。実際にbreak文へ到達できる流れになっているかも確認しましょう。
無限ループが向いている場面
繰り返し回数が決まっているなら、通常のfor文で十分です。無限ループが向いているのは、処理を始める時点で終了回数が分からない場合です。
| 使用場面 | 無限ループが向いている理由 |
|---|---|
| 入力値の検査 | 何回目に正しい値が入力されるか分からない |
| 終了番号による受付 | 利用者がいつ終了番号を入力するか分からない |
| メニュー処理 | 終了項目が選ばれるまで操作を続けたい |
| 計算問題 | 何回目で正解するか分からない |
| 数当てゲーム | 正解するまで入力とヒント表示を続けたい |
共通しているのは、実行回数ではなく、途中で発生する出来事によって終了が決まることです。
while文で無限ループを作る
while文では、条件式に1を指定すると無限ループになります。
while (1) {
処理;
}while文はループ本体を実行する前に条件を判定します。しかし、while (1)では条件が常に真になるため、毎回ループ本体へ入ります。
break文を組み合わせる基本形は次のとおりです。
while (1) {
処理1;
if (終了条件) {
break;
}
処理2;
}終了条件が真になると、break文より後ろにある処理2は実行されません。制御はwhile文の直後へ移ります。
while (true)を使う書き方
C99以降では、stdbool.hをインクルードするとtrueとfalseを使えます。
#include <stdbool.h>
while (true) {
処理;
}trueは真を表すため、while (1)と同じように無限ループになります。
| 書き方 | 特徴 |
|---|---|
| while (1) | C言語で広く使われる分かりやすい書き方 |
| while (true) | 条件が真であることを言葉で表現できる |
| for (;;) | 条件式を省略した無限ループの定番表現 |
while (true)を使う場合は、stdbool.hが必要です。まずは教材や既存のコードでよく見かけるwhile (1)に慣れておくとよいでしょう。
while文で終了番号まで入力を受け付ける
ここでは、作業記録番号を何件でも入力できるプログラムを作ります。終了番号として0が入力されたら受付を終了します。
作業記録番号を0が入力されるまで受け付けるプログラム
ファイル名:9_12_1.c
#include <stdio.h>
int main(void)
{
int record_number;
int count = 0;
while (1) {
printf("作業記録番号を入力してください(0で終了)> ");
scanf("%d", &record_number);
/* 0が入力されたら無限ループを終了する */
if (record_number == 0) {
break;
}
count++;
}
printf("受け付けた作業記録は%d件です。\n", count);
return 0;
}実行結果の例
作業記録番号を入力してください(0で終了)> 412
作業記録番号を入力してください(0で終了)> 527
作業記録番号を入力してください(0で終了)> 684
作業記録番号を入力してください(0で終了)> 0
受け付けた作業記録は3件です。受付プログラムの処理を確認する
while (1)によって、入力処理は何度でも繰り返されます。
入力された値は、最初に終了番号かどうかを判定します。
if (record_number == 0) {
break;
}record_numberが0ならbreak文が実行され、while文を終了します。break文より後ろにあるcount++は実行されないため、終了番号の0は件数に含まれません。
0以外が入力された場合は、条件が偽になるのでbreak文は実行されません。そのままcount++へ進み、受付件数が1増えます。
処理の流れは次のようになります。
- 作業記録番号を入力する
- 入力値が0か判定する
- 0ならbreak文で終了する
- 0でなければcountを1増やす
- 次の入力へ進む
このプログラムでは、入力回数は決められていません。しかし、0が入力されたら終了するという条件は明確です。
for文で無限ループを作る
for文では、初期化式、継続条件式、更新式をすべて省略すると無限ループになります。
for (;;) {
処理;
}for文の基本形は次のようになっています。
for (初期化式; 継続条件式; 更新式) {
処理;
}for (;;)では、3つの式をすべて省略しています。継続条件式が省略されたfor文は、終了条件を持たないループとして動作します。
途中で終了する場合は、while (1)と同じようにbreak文を使います。
for (;;) {
処理;
if (終了条件) {
break;
}
}図2:while (1)とfor (;;)の無限ループ

この図から分かること
while (1)とfor (;;)は書き方が異なりますが、どちらもそのままでは終了しない無限ループです。
while (1)は、条件が常に真であることを直接表しています。for (;;)は、for文の3つの式を省略して終了条件を持たない形にしています。
どちらを使った場合でも、一般的にはループ内で終了条件を判定し、break文で終了します。
for (;;)で同じ受付処理を書く
先ほどの作業記録番号の受付処理を、for (;;)で書き直してみましょう。
for (;;)で作業記録番号を受け付けるプログラム
ファイル名:9_12_2.c
#include <stdio.h>
int main(void)
{
int record_number;
int count = 0;
for (;;) {
printf("作業記録番号を入力してください(0で終了)> ");
scanf("%d", &record_number);
/* 0が入力されたら無限ループを終了する */
if (record_number == 0) {
break;
}
count++;
}
printf("受け付けた作業記録は%d件です。\n", count);
return 0;
}実行結果の例
作業記録番号を入力してください(0で終了)> 731
作業記録番号を入力してください(0で終了)> 845
作業記録番号を入力してください(0で終了)> 0
受け付けた作業記録は2件です。while (1)をfor (;;)に変更しても、入力、終了判定、件数の加算という処理は変わりません。
| 比較項目 | while (1)版 | for (;;)版 |
|---|---|---|
| 無限ループの表現 | 条件式に1を指定する | 3つの式を省略する |
| 終了方法 | break文 | break文 |
| 受付件数の計算 | 同じ | 同じ |
| 実行結果 | 同じ | 同じ |
入力を条件が成立するまで繰り返すという意図を見せたい場合は、while (1)が分かりやすいでしょう。for (;;)もC言語で使われる定番の表現なので、読めるようにしておくことが大切です。
do~while文でも無限ループは作れる
do~while文でも、継続条件を常に真にすれば無限ループになります。
do {
処理;
} while (1);この書き方でも、break文が実行されない限り処理は続きます。
ただし、do~while文は継続条件がループの末尾にあります。コードを上から読んだとき、無限ループであることを把握するには末尾まで確認しなければなりません。
そのため、無限ループを明確に表現したい場合は、while (1)またはfor (;;)がよく使われます。
無限ループと通常のwhile文の違い
入力値によって終了する処理は、通常のwhile文でも書ける場合があります。
たとえば、ループに入る前に最初の入力を行えば、次のような形にできます。
入力処理;
while (入力値が終了値ではない) {
通常の処理;
次の入力処理;
}この書き方では、入力処理をループの前とループ内の2か所に書くことになります。
一方、無限ループとbreak文を使えば、入力処理を1か所にまとめられます。
while (1) {
入力処理;
if (入力値が終了値) {
break;
}
通常の処理;
}最初に入力し、その結果を見て終了するか決める処理では、無限ループの中で判定する形が自然なことがあります。
ただし、必ず無限ループを使わなければならないわけではありません。終了条件を通常のwhile文で明確に表せる場合は、そちらを選んでも構いません。
無限ループで大切なのは出口を作ること
無限ループを書くときは、終了条件とbreak文の位置を必ず確認します。
| 確認すること | 内容 |
|---|---|
| 終了条件 | 何が起きたらループを終えるのか |
| 条件の判定位置 | 必要な入力や計算の後で判定しているか |
| break文 | 条件が成立したときに確実に実行されるか |
| break後の処理 | その回で実行されなくなる処理は何か |
| ループ終了後 | どの処理へ進むのか |
終了条件を書いただけでは、無限ループは終わりません。条件が真になったときにbreak文を実行する必要があります。
また、break文が書かれていても、プログラムの流れによってそこへ到達できなければ終了できません。
回数制限がある場合は通常のfor文を使う
すべての繰り返しを無限ループにする必要はありません。
入力できる回数が最大5回と決まっているなら、通常のfor文が自然です。正しい値が入力された場合だけbreak文で早めに終了します。
最大5回まで認証番号を入力できるプログラム
ファイル名:9_12_3.c
#include <stdio.h>
int main(void)
{
const int correct_number = 24;
int input;
int attempt;
printf("認証を開始します。最大5回まで入力できます。\n");
for (attempt = 1; attempt <= 5; attempt++) {
printf("%d回目の入力> ", attempt);
scanf("%d", &input);
if (input == correct_number) {
break;
}
}
if (attempt <= 5) {
printf("%d回目で認証できました。\n", attempt);
} else {
printf("認証できませんでした。正しい番号は%dです。\n",
correct_number);
}
return 0;
}実行結果の例1:途中で認証できた場合
認証を開始します。最大5回まで入力できます。
1回目の入力> 10
2回目の入力> 18
3回目の入力> 24
3回目で認証できました。実行結果の例2:最後まで認証できなかった場合
認証を開始します。最大5回まで入力できます。
1回目の入力> 7
2回目の入力> 12
3回目の入力> 20
4回目の入力> 25
5回目の入力> 30
認証できませんでした。正しい番号は24です。このプログラムには最大5回という明確な上限があります。そのため、無限ループではなく通常のfor文を使っています。
正しい番号が入力されると、break文によって途中終了します。このとき、attemptには成功した回数が残っています。
正解せずに5回の繰り返しを終えた場合は、更新式attempt++によってattemptが6になり、継続条件attempt <= 5が偽になります。
| ループの終了方法 | 終了後のattempt |
|---|---|
| 1回目でbreak | 1 |
| 3回目でbreak | 3 |
| 5回目でbreak | 5 |
| 正解せず通常終了 | 6 |
そのため、ループ後にattempt <= 5を判定すれば、成功したかどうかを判断できます。
回数が分からない場合は無限ループを使う
正解するまで入力を続ける処理では、何回で終了するか分かりません。このような場合は、while (1)とbreak文の組み合わせが分かりやすくなります。
正しい引き算の答えが入力されるまで続けるプログラム
ファイル名:9_12_4.c
#include <stdio.h>
int main(void)
{
const int left = 615;
const int right = 278;
const int correct = left - right;
int answer;
while (1) {
printf("%d - %d の答えは?> ", left, right);
scanf("%d", &answer);
if (answer == correct) {
break;
}
printf("答えが違います。もう一度入力してください。\n");
}
printf("正しい答えです。\n");
return 0;
}実行結果の例
615 - 278 の答えは?> 347
答えが違います。もう一度入力してください。
615 - 278 の答えは?> 327
答えが違います。もう一度入力してください。
615 - 278 の答えは?> 337
正しい答えです。このプログラムでは、answerがcorrectと等しくなるまで入力を繰り返します。
正解が入力された場合は、次のbreak文が実行されます。
if (answer == correct) {
break;
}break文によってwhile文が終了するため、その後ろにある不正解メッセージは表示されません。
不正解の場合は条件が偽になるためbreak文を通らず、次のメッセージが表示されます。
printf("答えが違います。もう一度入力してください。\n");その後、while (1)の先頭へ戻って再び問題を表示します。
無限ループ内でbreak文とcontinue文を使い分ける
無限ループでは、break文だけでなくcontinue文も役立ちます。
| 文 | 動き |
|---|---|
| break | 無限ループそのものを終了する |
| continue | その回の残りを飛ばし、次の繰り返しへ進む |
正解した場合は、ゲームや入力処理を終えるためにbreak文を使います。
入力値が範囲外だった場合は、ループを終了する必要はありません。その回の残りだけを飛ばし、次の入力へ進みたいのでcontinue文が向いています。
図3:無限ループ内でのbreakとcontinue

この図から分かること
無限ループでは、入力結果に応じて次の動きを選べます。
- 範囲外ならcontinue文で次の入力へ進む
- 範囲内で不正解ならヒントを表示して繰り返す
- 正解ならbreak文でループを終了する
continue文は無限ループを終わらせません。その回の残りを飛ばし、再びループの先頭から処理を始めます。
break文は無限ループそのものを終了し、ループの直後へ進みます。
数当てゲームで無限ループを活用する
次のプログラムでは、1から60までの範囲にある正解27を当てます。
入力した値に応じて、正解候補の範囲を狭めて表示します。
ヒントを表示しながら正解を探す数当てゲーム
ファイル名:9_12_5.c
#include <stdio.h>
int main(void)
{
const int answer = 27;
int input;
int low = 1;
int high = 60;
int count = 0;
printf("1~60の範囲で正解の数を当ててください。\n");
while (1) {
printf("%d~%dの範囲で入力してください> ", low, high);
scanf("%d", &input);
count++;
/* 現在の候補範囲から外れていたら次の入力へ進む */
if (input < low || input > high) {
printf("現在の候補範囲から外れています。\n");
continue;
}
/* 正解なら無限ループを終了する */
if (input == answer) {
break;
}
/* 入力値に応じて候補範囲を狭める */
if (input < answer) {
low = input + 1;
} else {
high = input - 1;
}
printf("正解は%d~%dの範囲にあります。\n", low, high);
}
printf("%d回目で正解しました。\n", count);
return 0;
}実行結果の例
1~60の範囲で正解の数を当ててください。
1~60の範囲で入力してください> 40
正解は1~39の範囲にあります。
1~39の範囲で入力してください> 20
正解は21~39の範囲にあります。
21~39の範囲で入力してください> 50
現在の候補範囲から外れています。
21~39の範囲で入力してください> 27
4回目で正解しました。数当てゲームで使う変数
このプログラムでは、正解と現在の候補範囲を複数の変数で管理しています。
| 変数名 | 役割 |
|---|---|
| answer | 正解となる数 |
| input | 利用者が入力した数 |
| low | 現在の候補範囲の下限 |
| high | 現在の候補範囲の上限 |
| count | 入力した回数 |
最初の候補範囲は1から60です。
int low = 1;
int high = 60;入力値が正解より小さい場合、その入力値以下は候補から外れます。そのため、lowをinput + 1に更新します。
low = input + 1;入力値が正解より大きい場合、その入力値以上は候補から外れます。そのため、highをinput - 1に更新します。
high = input - 1;これによって、入力するたびに正解候補の範囲が狭くなります。
範囲外でcontinue文を使う理由
入力値が現在の候補範囲から外れていた場合は、次の処理を実行します。
if (input < low || input > high) {
printf("現在の候補範囲から外れています。\n");
continue;
}continue文が実行されると、その回の残りの処理を飛ばします。そのため、次の判定や範囲更新は行われません。
- 正解かどうかの判定
- lowの更新
- highの更新
- 次の候補範囲の表示
ループそのものは終わらないので、while (1)の先頭へ戻って次の入力を受け付けます。
正解でbreak文を使う理由
正解が入力された場合は、次の処理を実行します。
if (input == answer) {
break;
}正解した後は、入力やヒント表示を続ける必要がありません。そのため、break文で無限ループを終了します。
break文の後は、ループの外にある結果表示へ進みます。
printf("%d回目で正解しました。\n", count);continue文は次の入力を続けるために使い、break文はゲームを終了するために使っています。
無限ループで起こりやすい間違い
無限ループを書くときは、次のような間違いに注意しましょう。
| 間違い | 起こること |
|---|---|
| break文を書かない | 終了できずに処理が続く |
| 終了条件を間違える | 期待した値でもループが終わらない |
| break文へ到達できない | break文があっても終了しない |
| break文の位置が早すぎる | 必要な処理を行う前に終了する |
| continue文の位置を間違える | 必要な判定や更新を飛ばしてしまう |
| 終了値を通常データとして処理する | 件数や合計に終了値が含まれる |
終了用の値を通常のデータに含めたくない場合は、加算や集計よりも先に終了条件を判定します。
入力処理;
if (終了条件) {
break;
}
集計処理;この順番なら、終了用の値が集計される前にループから抜けられます。
無限ループを書くときの確認ポイント
無限ループを安全で読みやすくするには、終了条件がすぐに見つかるように書きます。
- 無限ループを使う理由を明確にする
- 終了条件をif文で分かりやすく表す
- 条件成立時にbreak文が実行されるようにする
- break文より後ろで実行されない処理を確認する
- 入力案内に終了用の値を表示する
- continue文で何が飛ばされるのか確認する
- 回数の上限があるなら通常のfor文も検討する
- while (1)とfor (;;)のどちらが意図を伝えやすいか考える
無限ループは、終了時期が事前に決まっていない処理を自然に表現できます。ただし、ループを作ることと同じくらい、どこで終了するのかを明確に書くことが大切です。
