do-while 文

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

do-while 文 とは

do-while 文を使って「最低 1 回は実行したい繰り返し」を書いてみよう。条件チェックのタイミングが while とどう違うのかを身体に染み込ませる回。

「とりあえず 1 回は走らせたい」ループの作り方

ここまでで while 文を使った繰り返しを学びました。while (条件) { ... } は、ブロックに入る 前に 条件をチェックし、条件が false ならブロックを 1 度も実行しません。これはこれで便利ですが、現実のプログラムを書いていると「とりあえず 1 回はやってみて、その結果を見てから続けるかどうか決めたい」という場面がたくさん出てきます。そんなときに登場するのが、今回のテーマである do-while 文です。

do-while は「後判定ループ」と呼ばれます。while (前判定ループ) と双子のような関係で、文法はそっくりなのに、条件チェックのタイミングだけが裏返しになっています。Java だけでなく C C++ JavaScript にも同じ do-while があり、いずれも「最低 1 回はブロックを実行する」という同じ性質を持っています。

do-while の文法

まずは do-while の基本形を確認します。

Java

do { // 繰り返したい処理 } while (条件);

while 文との違いは、次の 3 点に集約できます。

  • do というキーワードでブロックが始まる
  • ブロックの 後ろwhile (条件) が来る
  • 文の最後に 必ずセミコロン ; が要る

3 つ目の ; は要注意ポイントです。while 文や if 文ではブロックの } の後ろにセミコロンを書きませんが、do-while 文はあくまで while (条件); という 1 つの文 として完結する必要があるので、セミコロンを忘れるとコンパイルエラーになります。「do-while の末尾はセミコロン」と呪文のように唱えて覚えてしまいましょう。

whiledo-while の違いを図で見る

両者の違いはコードで眺めるよりフロー図のほうが圧倒的にわかりやすいです。条件チェックの位置が違うだけで、最低実行回数が変わるのがポイントです。

diagram (will load when visible)

左側の while は、条件チェックが 最初 に来るので、条件が最初から false だと本体は 0 回しか実行されません。右側の do-while は、本体が先に動いてから条件チェックに進むので、条件がどうであれ 本体は最低 1 回 実行されます。「ブロックに入る前にチェックするか、入った後にチェックするか」という小さな違いが、最低実行回数 0 回と 1 回の差を生む、と覚えてください。

「最低 1 回」というのは、見落としやすいけど決定的な違いです。while (false) { ... } は 0 回、do { ... } while (false); は 1 回。ループの最低回数を間違えると、ユーザーに何も表示されない画面ができたり、逆に余計な処理が 1 回走ったりするので、do-while を選ぶときは必ず「本当に最低 1 回でいいんだっけ?」と自問する癖をつけましょう。

典型的なユースケース

do-while が活きるのは、最初の 1 回を実行しないと条件の判断材料が手に入らない ような処理です。代表例を 3 つ紹介します。

  • 入力検証 — ユーザーから入力を受け取り、不正なら再入力させる。「まず 1 回入力させる → 不正なら繰り返す」という流れが do-while にぴったり
  • 初期化処理 — DB やファイルから値を 1 回読み込んで、足りなければ続きを読み込む
  • メニュー画面 — ゲームやコマンドラインツールで「メニューを表示 → 選択 → 終了でなければ再表示」を続ける

たとえば入力検証の擬似コードはこんな感じになります。

Java

int age; do { age = readAgeFromUser(); } while (age < 0 || age > 150);

「まず 1 回読む → 妥当な値なら抜ける、おかしければもう一度読む」という流れがそのままコードになっていて、while 文だと冗長になる処理 (int age = readAgeFromUser(); を先に書いて、その後 while (...) { age = readAgeFromUser(); } と二重に書く必要がある) が、do-while だとスッキリまとまります。

while で書き換えてみる

同じロジックを while 文で書くとどうなるかも見ておきましょう。今回の課題「start から +1 ずつ進めて最初の正の数を返す」を、2 通りで書き比べます。

Java

// do-while 版 (今回の主役) public class Solution { public static int firstPositive(int start) { int n = start; do { if (n > 0) { return n; } n++; } while (true); } }

Java

// while 版 (同じ動き) public class Solution { public static int firstPositive(int start) { int n = start; while (n <= 0) { n++; } return n; } }

while 版のほうが短く見えるかもしれません。たしかにこの問題に関しては while のほうが自然です。それでも do-while 版が読みやすいのは、「まず n を見る → 正なら即返す → ダメなら +1 して繰り返す」という思考の順番がコードの上から下にそのまま並んでいる点です。条件によってどちらが読みやすいかは変わるので、両方書けるようにしておくのがおすすめです。

do-while でしか書けない処理」はほぼ存在しません。while で書き換えはできます。ただし do-while を選ぶと、最初の 1 回を強調できる・初期化と更新を 1 箇所にまとめられる、というメリットがあります。コードを読む人への「最初の 1 回は無条件で走ります」というメッセージとして使うイメージです。

動きを追ってみる

今回の課題のテストケースで、do-while 版がどう動くかを手で追ってみましょう。

  • firstPositive(-3)n = -3do ブロックに入る
    • n > 0false なので n++n = -2
    • 条件 true で再ループ。同じ流れで -1, 0, 1 と進む
    • n = 1 のとき n > 0true になり return 1
  • firstPositive(5)n = 5do ブロックに入る
    • n > 0 が一発で true になり、即 return 5
    • while 文だと条件チェックを先にやるが、do-while ではブロックの中で if チェックしているので、結果は同じく 1 回で返る
  • firstPositive(0)n = 0do ブロックに入る
    • n > 0false (0 は正ではない) なので n++n = 1
    • 再ループして n > 0true になり return 1

0 は正ではありません。Java>厳密な大なり で、0 > 0false1 > 0true です。「正の数」と聞いたら自動的に n > 0 (>= ではない) を選べるようにしておきましょう。

よくある間違い

do-while で初心者がハマりやすい落とし穴を 3 つ紹介します。

  • do { ... } while (条件) の末尾セミコロン忘れdo { ... } while (n <= 0) で終わると「; expected」というコンパイルエラーになります。do-while は文の最後に 必ず ; を付けるのがルールです。while 文と違うところなので意識して書きましょう
  • 条件の方向を逆にする (上昇 vs 下降) — 「正の数を見つける」課題なのに while (n > 0); と書いてしまうと、最初から正の数だったときに即終わり、負だったときは無限ループになります。「ループを 続ける ための条件」を書く、という基本に立ち戻ってください。n を上昇させて正を探すなら、ループ継続条件は n <= 0 (まだ正でない間続ける) です
  • 更新を忘れて無限ループdo { ... } while (n <= 0); の中で n++ を書き忘れると、n がずっと初期値のままで条件が変わらず、永遠にループします。Java の Playground では実行が 5 秒で打ち切られますが、本番システムでこれをやると CPU 100% でサーバーが落ちます。ループ本体で必ず変数を更新する を呪文にしてください

もうひとつ、ベテランも油断するとやる失敗が do の直後に ; を書く ミスです。たとえば do; { ... } while (cond); と書くと、do; だけで「空文を 1 回実行する do-while」になり、{ ... } は普通のブロックとして扱われて、do のループに含まれません。エラーにならない分タチが悪いので、do の後ろは 絶対にスペースか改行 にしてください。

ループのバグは「無限ループ」「1 回多い / 少ない (Off-by-one)」「順番違い」の 3 種類が大半です。do-while を書くときは、まず手で 2〜3 周シミュレーションしてからテストを走らせるのがおすすめ。JavaSystem.out.println(n) を 1 行入れるだけでも、ループ内の動きが見えて一気にデバッグしやすくなります。

やってみよう

それでは課題に挑戦しましょう。Solution.firstPositive(int start)do-while 文を必ず使って 完成させてください。

  1. int n = start; で受け取った値を変数に入れる
  2. do { ... } while (true); の形で、ループ本体の中で判定する
  3. ブロック先頭で if (n > 0) { return n; } と書き、正の数なら即返す
  4. 正でなければ n++ で 1 進めてから次の周回へ進む

書けたらテストを走らせて、firstPositive(-3)1firstPositive(5)5firstPositive(0)1 になることを確認してください。さらに余裕があれば、while 文で同じロジックを書いてみて、行数や読みやすさを比較してみるのもよい練習になります。do-while の「最低 1 回」「後判定」という感覚を、ここでしっかり手に染み込ませておきましょう。

よくある質問

Q. while で無限ループを止めるには?

A. ループ内で必ずカウンタを更新するか、break で抜ける条件を書きます。たとえば i = 0; while i < 10: i += 1 のように i += 1 を忘れると永久に止まりません。Ctrl+C で強制終了できますが、デバッグ時はループの 1 周目で print(i) を入れて挙動を確認すると原因が見えます。

Q. while と for はどう違いますか?

A. 繰り返し回数が決まっていれば for、終了条件が動的なら while が向いています。リスト走査や range は for で書く方が安全で、ユーザー入力が来るまで・センサー値が閾値を超えるまで、のようなケースは while True + break が定石です。

Q. do-while のように最低 1 回は実行したい場合は?

A. Python には do-while がないため、while True: ... if cond: break のパターンで再現します。JavaScript なら do { ... } while (cond) と書けます。「最初の 1 回は条件を見ずに走らせる」処理(入力受付など)で有効です。

次のレッスン

次は 二重ループ で、二重ループ を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. do-while の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. do-while とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. クラス名は Solution、メソッド名は firstPositive にすること
  2. 引数は int start の 1 つ、戻り値の型は int
  3. do-while 文を必ず使って 繰り返しを書くこと (while 文や for 文だけで書くのは NG)

入出力例

test-cases.txt

firstPositive(-3)1 firstPositive(5)5 firstPositive(0)1 firstPositive(1)1 firstPositive(-100)1 firstPositive(42)42

ヒント

main.java
main.java
学習モード

メモ

do-while 文

⌘S で保存