C言語のwhile文は、条件を満たすあいだ同じ処理を繰り返すための基本構文です。
プログラムの多くは、同じ処理を何度も実行する「ループ」で成り立っていますが、その中でもwhile文は条件を柔軟に記述できるループとしてよく使われます。
本記事では、while文の基本構文から、無限ループ、break・continueの使い方、さらに典型的な例やバグを防ぐコツまで、ていねいに解説していきます。
C言語のwhile文とは
while文の基本構文と書き方

while文は、「条件が真(0以外)である限り、ブロックの中身を繰り返し実行する」構文です。
基本的な書き方は次のとおりです。
#include <stdio.h>
int main(void) {
int i = 0; // カウンタ変数を0で初期化
// i が 5 未満のあいだ、このブロックを繰り返します
while (i < 5) {
printf("i = %d\n", i); // 現在の i を表示
i++; // i を 1 増やす (更新しないと無限ループの原因)
}
printf("ループ終了後の i = %d\n", i);
return 0;
}
i = 0
i = 1
i = 2
i = 3
i = 4
ループ終了後の i = 5
while文では、while (条件式)の条件式が0以外ならブロックが実行され、0ならループを終了します。
for文との違いと使い分け

C言語にはfor文もあり、同じように繰り返し処理ができます。
代表的な違いを、まず簡単な表で整理します。
| 項目 | for文 | while文 |
|---|---|---|
| 初期化 | ヘッダ内に書くことが多い | ループの前に書く |
| 条件式 | ヘッダ内の2番目 | whileの()内 |
| 変数更新 | ヘッダ内の3番目 | ブロック内部で行う |
| 主な用途 | 回数がはっきりしている繰り返し | 条件が変わるまで続けたい処理 |
for文の典型例は次のようになります。
// 0 〜 4 の5回ループする for文
for (int i = 0; i < 5; i++) {
printf("%d\n", i);
}
同じ処理をwhile文で書き直すと、次のようになります。
// 0 〜 4 の5回ループする while文
int i = 0; // 初期化
while (i < 5) { // 条件
printf("%d\n", i);
i++; // 更新 (ブロック内で書く)
}
for文は「何回繰り返すかを、カウンタで管理する」ときに読みやすく、while文は「いつ終わるかが事前にははっきりしない処理」で使いやすいという違いがあります。
ループ処理にwhile文を使うメリット

while文を使う大きなメリットは、終了条件を柔軟に書けることです。
具体的には次のような場面で力を発揮します。
1つ目はユーザー入力を処理し続ける場面です。
ユーザーが「終了」と入力したら終わる、といった処理は、何回で終わるか事前には分かりません。
2つ目はファイルやネットワークのデータを読み続ける場面です。
データがなくなるまで、あるいはエラーになるまで読み続ける処理は、条件表現が重要になります。
このように、while文は「条件が成り立つ間だけ処理する」という発想に素直に書けるため、コードを読む人に意図が伝わりやすくなります。
while文の条件式と評価タイミング
真偽値と0/0以外の扱い

C言語では専用の真偽値型(bool)が標準で導入されたのはC99以降ですが、while文などの条件式では整数値を「0か0以外か」で真偽として扱うのが基本です。
| 値 | 条件としての意味 |
|---|---|
| 0 | 偽(false) |
| 1 | 真(true) |
| -1 | 真(true) |
| 100 | 真(true) |
つまり、次のような書き方はどちらも有効です。
int flag = 1; // 1 は真とみなされる
while (flag) { // flag が 0 でないかぎりループ
printf("ループ中です\n");
flag = 0; // 0 を代入すると次からはループしない
}
「0が偽、それ以外はすべて真」というルールをしっかり覚えておくと、while文だけでなく、if文やfor文でも混乱しにくくなります。
条件式が評価されるタイミング

while文では、ループのたびに最初に条件式が評価されます。
具体的な流れは次のとおりです。
- まず
while (条件式)の条件式を評価する - 条件式が真(0以外)なら、ブロックの中身を1回実行する
- ブロックの最後まで実行したら、再び条件式の評価に戻る
- 条件式が偽(0)になったら、ループを抜ける
つまり、while文は「最低1回は必ず実行される」わけではないことに注意が必要です。
最初から条件式が偽なら、1回もブロックは実行されません。
#include <stdio.h>
int main(void) {
int x = 10;
// 最初の時点で x < 5 は偽(0)なので、1回も実行されません
while (x < 5) {
printf("このメッセージは表示されません\n");
}
printf("プログラム終了\n");
return 0;
}
プログラム終了
複数条件を使う場合の論理演算子

複数の条件を組み合わせたい場合は、論理演算子を用います。
代表的なのは&&(かつ)、||(または)、!(否定)です。
| 演算子 | 読み方 | 意味のイメージ |
|---|---|---|
&& | かつ(AND) | 両方が真なら真 |
|| | または(OR) | どちらかが真なら真 |
! | 否定(NOT) | 真偽を反転する |
例として、0〜100の範囲にある入力だけを受け付けるループを書いてみます。
#include <stdio.h>
int main(void) {
int score;
printf("0〜100の点数を入力してください(それ以外で終了):\n");
while (1) { // とりあえず無限ループにしておく
printf("score = ");
if (scanf("%d", &score) != 1) {
// 数値以外が入力された場合など
printf("数値の読み取りに失敗したので終了します。\n");
break;
}
// 0 <= score && score <= 100 のときだけ有効な点数とする
if (0 <= score && score <= 100) {
printf("有効な点数です: %d\n", score);
} else {
printf("0〜100の範囲外なので、ループを終了します。\n");
break; // 範囲外ならループを抜ける
}
}
return 0;
}
複雑な条件式は、かっこ()でグループ化して読みやすくすると、バグを減らしやすくなります。
無限ループとbreak・continueの使い方
whileによる無限ループの書き方(while(1))

while文で意図的に無限ループを作りたい場合、典型的には次のように書きます。
while (1) {
// ここに処理を書く
}
1は0以外なので真と判定され、条件が変わらない限り無限に繰り返されます。
別の書き方としてwhile (true)のように書く例もありますが、その場合はstdbool.hをインクルードし、trueを使えるようにしておく必要があります。
無限ループはメインループ(ゲームのループやサーバーの待ち受け処理など)に便利ですが、必ずどこかでループを抜ける仕組みを用意しなければなりません。
そのために使うのがbreakです。
無限ループから抜けるbreakの基本

breakは、現在のループ(while, for, do-while, switch)から即座に抜けるための文です。
無限ループと組み合わせることで、条件によってループを終了できます。
#include <stdio.h>
int main(void) {
int num;
printf("負の値が入力されるまで整数を入力してください。\n");
while (1) { // 無限ループ
printf("num = ");
if (scanf("%d", &num) != 1) {
printf("入力エラーのため終了します。\n");
break;
}
if (num < 0) {
printf("負の値が入力されたのでループを終了します。\n");
break; // while(1) から抜ける
}
printf("入力された値は %d です。\n", num);
}
printf("ループを抜けました。\n");
return 0;
}
負の値が入力されるまで整数を入力してください。
num = 3
入力された値は 3 です。
num = 10
入力された値は 10 です。
num = -1
負の値が入力されたのでループを終了します。
ループを抜けました。
「終了条件が複雑」「途中でいろいろな理由で抜ける可能性がある」ような処理では、breakをうまく使うことでコードを読みやすくできます。
一部だけスキップするcontinueの基本

continueは、その回の残りの処理をスキップし、すぐに次の繰り返しに進むための文です。
ループ自体を抜けるわけではありません。
#include <stdio.h>
int main(void) {
int i = 0;
while (i < 10) {
i++; // まず i を 1 増やす
if (i % 2 == 0) {
// i が偶数なら、以下の処理をスキップして次のループへ
continue;
}
// ここに来るのは i が奇数のときだけ
printf("奇数: %d\n", i);
}
return 0;
}
奇数: 1
奇数: 3
奇数: 5
奇数: 7
奇数: 9
この例では、偶数のときの処理をスキップし、奇数の場合だけ処理を行っています。
continueを使うと「この条件なら何もせず次へ進む」という意図を簡潔に書くことができます。
breakとcontinueの使い分け例

breakとcontinueは似ていますが、動作がまったく異なります。
| 文 | 動作 |
|---|---|
break | ループ(while, forなど)そのものを抜ける |
continue | その周回の残りをスキップし、次の周回に進む |
次のサンプルでは、負の数が来たらループを終了( break )し、0が来たときは「何もしないで次へ」( continue )、正の数なら合計を計算します。
#include <stdio.h>
int main(void) {
int num;
int sum = 0;
printf("正の整数を足し算します。0はスキップ、負の値で終了します。\n");
while (1) {
printf("num = ");
if (scanf("%d", &num) != 1) {
printf("入力エラーのため終了します。\n");
break;
}
if (num < 0) {
// 負の値ならループから完全に抜ける
printf("負の値が入力されたので終了します。\n");
break;
}
if (num == 0) {
// 0なら合計には加えず、次の入力へ進む
printf("0は合計に含めません。(スキップ)\n");
continue;
}
// ここに来るのは正の整数のときだけ
sum += num;
printf("現在の合計 = %d\n", sum);
}
printf("最終的な合計 = %d\n", sum);
return 0;
}
このように、「ループを終わらせたいのか」「その回だけ飛ばしたいのか」を意識してbreakとcontinueを使い分けることが大切です。
while文の典型例と注意点
カウンタ変数を使った繰り返し処理

while文でも、for文と同じようにカウンタ変数を使った単純な繰り返し処理がよく使われます。
#include <stdio.h>
int main(void) {
int i = 1; // 1からスタート
int n = 5; // 5回繰り返す
while (i <= n) { // i が n 以下のあいだ繰り返す
printf("%d 回目の処理です。\n", i);
i++; // カウンタを更新しないと無限ループになる
}
printf("ループが完了しました。\n");
return 0;
}
1 回目の処理です。
2 回目の処理です。
3 回目の処理です。
4 回目の処理です。
5 回目の処理です。
ループが完了しました。
このような「回数が決まっている繰り返し」は、for文で書くことも多いですが、初心者がwhile文の動作を理解するための練習としても役立ちます。
標準入力を読み続けるループ処理

while文の典型的な使い方の1つに、標準入力を読み続けるループがあります。
例えば、入力された数値を合計し、EOF(入力の終わり)で止めるコードは次のように書けます。
#include <stdio.h>
int main(void) {
int x;
int sum = 0;
printf("整数を入力してください(EOFで終了)。\n");
printf("例: 1 2 3 Ctrl+D(Linux/mac) または Ctrl+Z + Enter(Windows)\n");
// scanf が 1 (成功) を返すあいだループを続ける
while (scanf("%d", &x) == 1) {
sum += x;
}
printf("合計 = %d\n", sum);
return 0;
}
整数を入力してください(EOFで終了)。
例: 1 2 3 Ctrl+D(Linux/mac) または Ctrl+Z + Enter(Windows)
1 2 3
合計 = 6
ここでは「読み取りが成功しているかどうか」を条件式にしている点が重要です。
scanfは、読み取った項目数を返すので、成功している間(戻り値が1の間)だけループを続けることができます。
条件式の書き間違いによる無限ループを防ぐコツ

while文でよくあるミスが、条件式の書き間違いによる意図しない無限ループです。
特に、==(等しい)と=(代入)を混同してしまうと危険です。
int i = 0;
// 誤った例 (i = 10 と書いてしまう)
while (i = 10) {
// ...
}
この場合、i = 10は代入であり、その式全体の値は10です。
10は0以外なので真と判定され、このwhile文は無限ループになります。
無限ループを防ぐためのコツとして、次のようなポイントを意識するとよいです。
1つ目は「条件式の中では、代入演算子=と比較演算子==をよく確認する」ことです。
多くのエディタやIDEは、構文ハイライトで違いを色分けしてくれます。
2つ目はカウンタ変数の更新を必ず確認することです。
増減し忘れると、条件がいつまでも変わらず無限ループになります。
#include <stdio.h>
int main(void) {
int i = 0;
// 誤りの例: i++ を忘れているため、i はずっと 0 のまま
while (i < 5) {
printf("i = %d\n", i);
// i++; // これを書き忘れると無限ループ
break; // ここでは無限ループ防止のため break を入れている
}
return 0;
}
現実のコードではテスト用に一時的なbreakを入れて動きを確認するなど、段階的に動作を確かめながら実装すると安全です。
while文でバグを起こしやすいポイントと対策

while文でバグを起こしやすい典型的なポイントと、その対策を整理します。
1つ目は条件が変化しないケースです。
カウンタ変数を更新していなかったり、更新のロジックが条件式と矛盾していると、ループが終わりません。
対策としてはループ変数のライフサイクル(初期化→更新→終了)を紙に書き出すなどして、頭の中だけで考えないようにすることが有効です。
2つ目は入力エラーやEOFを考慮していないケースです。
scanfの戻り値を無視していると、思わぬところで無限ループになります。
#include <stdio.h>
int main(void) {
int x;
printf("整数を入力してください:\n");
while (1) {
printf("x = ");
if (scanf("%d", &x) != 1) {
// 戻り値をチェックしないと、このケースに気づかない
printf("数値の読み取りに失敗したので終了します。\n");
break;
}
printf("入力された値は %d です。\n", x);
}
return 0;
}
3つ目は条件式が複雑になりすぎて、自分でも理解しづらくなるケースです。
その場合は次のように条件そのものを別の変数にして可読性を上げるとよいです。
#include <stdio.h>
int main(void) {
int x = 0;
int y = 0;
while (1) {
int condition = (x < 10 && y < 5); // 条件式を変数にまとめる
if (!condition) {
break; // 条件を満たさなくなったら抜ける
}
printf("x = %d, y = %d\n", x, y);
x++;
y++;
}
return 0;
}
このように、「条件を分かりやすく書く」「更新を忘れない」「入力エラーを想定する」という3点を意識すると、while文まわりのバグを大幅に減らすことができます。
まとめ
while文は、C言語における最も基本的で、かつ強力なループ構文です。
本記事では、while文の基本構文、for文との違い、条件式と評価タイミング、無限ループとbreak・continueの使い方、さらに典型例やバグを防ぐコツまで解説しました。
「条件が真のあいだ処理を繰り返す」というシンプルな発想を軸に、少しずつサンプルコードを書いて試してみることで、while文の動作と注意点が自然と身についていきます。
