
C言語基礎|do文とwhile文の違い
はじめに:do文とwhile文は「似てるけど性格が違う」ループ仲間
C言語の繰り返し処理で、まず混乱しやすいのが do文 と while文 です。
どっちもキーワードに while が出てくるので、ぱっと見で「あれ、これ do-while?普通の while?」ってなりがちなんですよね。
でも安心してください。コツさえ押さえれば、見分けも使い分けもスッキリします。
- do文:まず1回やってから判定(後判定)
- while文:まず判定してから実行(前判定)
そして読みやすさを上げる最大のコツは、do文の本体を必ず { } で囲むことです。

サンプル:正の整数だけ受け付けて、入力した数を逆順に表示する
「正の整数だけ受け付けて、入力した数を逆順に表示する」プログラムを例に解説をします。
- do文:入力を正の整数に制限する。
- while文:桁を取り出して逆順表示する。
プロジェクト名:chap4-11-1 ソースファイル名:chap4-11-1.c
Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。
// 正の整数だけ受け付けて、桁を逆順に表示
#include <stdio.h>
int main(void)
{
int n;
do {
printf("正の整数を入力してください:");
scanf("%d", &n);
if (n <= 0)
puts("0以下は受け付けません。もう一度入力してください。");
} while (n <= 0);
printf("逆順にすると:");
while (n > 0) {
printf("%d", n % 10);
n /= 10;
}
puts(" です。");
return 0;
}実行例
正の整数を入力してください:-3
0以下は受け付けません。もう一度入力してください。
正の整数を入力してください:1963
逆順にすると:3691 です。do文とwhile文の書式(見た目の違いをまず固定)
構文の違い
| 種類 | 書式 | 特徴 |
|---|---|---|
| do文 | do 文 while (式); | 文を実行してから判定(後判定) |
| while文 | while (式) 文 | 判定してから実行(前判定) |
do文は最後に ;(セミコロン) が必要なのも、見分けポイントです。
プログラムの流れの違い(前判定 vs 後判定)
while文の基本フロー(日本語)
制御式を評価
↓
真(非0) → ループ本体を実行 → 制御式へ戻る
↓
偽(0) → ループ終了
do文の基本フロー
ループ本体を実行(必ず1回)
↓
制御式を評価
↓
真(非0) → ループ本体へ戻る
↓
偽(0) → ループ終了
ここが本質です。
- while文:条件がダメなら 1回も実行されないことがある。
- do文:条件がどうあれ 最低1回は実行される。
見分けにくい問題:do文にもwhileが出る
do文とwhile文の両方に while が出てくるので、こういうコードは目が滑りやすいです。
例:見分けにくい書き方(イメージ)
x = 0;
do
x++;
while (x < 5);
while (x >= 0)
printf("%d ", --x);
「whileが2つある!」となった瞬間に、どっちがどっちか迷います。
読みやすさの鉄則:do文の本体は { } で囲む
do文は、ループ本体が1文でも 必ず複合文(ブロック)にすると読みやすくなります。
読みやすい形(do文の終わりが } で分かる)
x = 0;
do {
x++;
} while (x < 5);
while (x >= 0)
printf("%d ", --x);
見分けのコツ
| その行の先頭 | 何が分かる? |
|---|---|
| } while (式); | do文の一部(do-whileの末尾) |
| while (式) | while文の開始 |
} が見えたら do文の終端、これだけでも相当ラクになります。
サンプルの中での使い分け(doは入力チェック、whileは処理の繰り返し)
先ほどのサンプルでは、役割がきれいに分かれています。
do文:正の整数が入るまで入力を繰り返す
- 目的:入力制限(入力チェック)
- 理由:入力は最低1回は必要だから、do文と相性がいい
while文:n が 0 になるまで桁を取り出す
- 目的:処理の繰り返し
- 理由:n が最初から 0 なら繰り返し不要(前判定が自然)
while文のループ本体でやっていること(逆順表示の仕組み)
逆順表示は、毎回「一番下の桁」を取り出して捨てていく流れです。
ループ本体の2つの仕事
| やること | 式 | 意味 |
|---|---|---|
| 最下位桁を表示 | n % 10 | 10で割った余りが一番下の桁 |
| 右に1桁ずらす | n /= 10 | 10で割って下の桁を捨てる。 |
n = 1963 の変化
| 回 | 表示する n % 10 | n /= 10 後の n |
|---|---|---|
| 1 | 3 | 196 |
| 2 | 6 | 19 |
| 3 | 9 | 1 |
| 4 | 1 | 0 |
n が 0 になったら while が終わるので、逆順が完成します。
ここで登場した命令の書式まとめ
do文
| 書式 | 何をする? |
|---|---|
| do 文 while (式); | 文を実行してから式を評価し、真の間繰り返す。 |
while文
| 書式 | 何をする? |
|---|---|
| while (式) 文 | 式を評価して、真の間だけ文を繰り返す。 |
複合代入(ついでに復習)
| 書式 | 何をする? |
|---|---|
| a /= b | a を b で割って a に代入する。 |
演習問題
指定どおり、類似問題を3つ作ります(0以下なら何もしない系/繰り返し表示系/桁数系)。
演習4-7:正の整数の個数だけ A と B を交互に表示
正の整数 n を読み込み、n 個の文字を A と B で交互に表示せよ。
ただし、0 以下の整数が入力された場合は何も表示しない。
(例)
正の整数:7
ABABABA
解答例
#include <stdio.h>
int main(void)
{
int n;
printf("正の整数:");
scanf("%d", &n);
int i = 0;
while (i < n) {
putchar((i % 2 == 0) ? 'A' : 'B');
i++;
}
if (n > 0) putchar('\n');
return 0;
}演習4-8:入力した個数だけ @ を縦に表示
正の整数 n を読み込み、@ を n 行にわたって縦に表示せよ。
ただし、0 以下の整数が入力された場合は何も表示しない。
(例)
正の整数:3
@
@
@
解答例
#include <stdio.h>
int main(void)
{
int n;
printf("正の整数:");
scanf("%d", &n);
while (n-- > 0) {
putchar('@');
putchar('\n');
}
return 0;
}演習4-9:正の整数を読み込み、末尾の0の個数を表示
正の整数 n を読み込み、末尾に連続して付いている 0 の個数を表示せよ。
(例:12000 なら末尾の0は3個)
※ヒント:10で割り切れる間だけ繰り返す。
(例)
正の整数を入力してください:12000
末尾の0は3個です。
解答例
#include <stdio.h>
int main(void)
{
int n;
int cnt = 0;
printf("正の整数を入力してください:");
scanf("%d", &n);
if (n <= 0) {
puts("正の整数ではありません。");
return 0;
}
while (n % 10 == 0) {
cnt++;
n /= 10;
}
printf("末尾の0は%d個です。\n", cnt);
return 0;
}まとめ:迷ったら「最低1回必要か?」で選ぶとブレない
- 入力チェックみたいに、まず1回は実行したい → do文が自然
- 条件に合うときだけ処理したい → while文が自然
- 読みやすさは、do文の本体を { } にするだけで一気に上がる。
- do文にも while が出るので、終端の } while (式); を目印にする。
