do-while 文
do-while 文 とは
do-while文を使って「最低 1 回は実行したい繰り返し」を書いてみよう。条件チェックのタイミングがwhileとどう違うのかを身体に染み込ませる回。
「とりあえず 1 回は走らせたい」ループの作り方
ここまでで while 文を使った繰り返しを学びました。while (条件) { ... } は、ブロックに入る 前に 条件をチェックし、条件が false ならブロックを 1 度も実行しません。これはこれで便利ですが、現実のプログラムを書いていると「とりあえず 1 回はやってみて、その結果を見てから続けるかどうか決めたい」という場面がたくさん出てきます。そんなときに登場するのが、今回のテーマである do-while 文です。
do-whileは「後判定ループ」と呼ばれます。while(前判定ループ) と双子のような関係で、文法はそっくりなのに、条件チェックのタイミングだけが裏返しになっています。JavaだけでなくCC++JavaScriptにも同じdo-whileがあり、いずれも「最低 1 回はブロックを実行する」という同じ性質を持っています。
do-while の文法
まずは do-while の基本形を確認します。
Java
do {
// 繰り返したい処理
} while (条件);while 文との違いは、次の 3 点に集約できます。
doというキーワードでブロックが始まる- ブロックの 後ろ に
while (条件)が来る - 文の最後に 必ずセミコロン
;が要る
3 つ目の ; は要注意ポイントです。while 文や if 文ではブロックの } の後ろにセミコロンを書きませんが、do-while 文はあくまで while (条件); という 1 つの文 として完結する必要があるので、セミコロンを忘れるとコンパイルエラーになります。「do-while の末尾はセミコロン」と呪文のように唱えて覚えてしまいましょう。
while と do-while の違いを図で見る
両者の違いはコードで眺めるよりフロー図のほうが圧倒的にわかりやすいです。条件チェックの位置が違うだけで、最低実行回数が変わるのがポイントです。
左側の 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 = -3でdoブロックに入るn > 0はfalseなのでn++でn = -2- 条件
trueで再ループ。同じ流れで-1,0,1と進む n = 1のときn > 0がtrueになりreturn 1
firstPositive(5)→n = 5でdoブロックに入るn > 0が一発でtrueになり、即return 5while文だと条件チェックを先にやるが、do-whileではブロックの中でifチェックしているので、結果は同じく 1 回で返る
firstPositive(0)→n = 0でdoブロックに入るn > 0はfalse(0は正ではない) なのでn++でn = 1- 再ループして
n > 0がtrueになりreturn 1
0は正ではありません。Javaの>は 厳密な大なり で、0 > 0はfalse、1 > 0はtrueです。「正の数」と聞いたら自動的に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 周シミュレーションしてからテストを走らせるのがおすすめ。JavaのSystem.out.println(n)を 1 行入れるだけでも、ループ内の動きが見えて一気にデバッグしやすくなります。
やってみよう
それでは課題に挑戦しましょう。Solution.firstPositive(int start) を do-while 文を必ず使って 完成させてください。
int n = start;で受け取った値を変数に入れるdo { ... } while (true);の形で、ループ本体の中で判定する- ブロック先頭で
if (n > 0) { return n; }と書き、正の数なら即返す - 正でなければ
n++で 1 進めてから次の周回へ進む
書けたらテストを走らせて、firstPositive(-3) が 1、firstPositive(5) が 5、firstPositive(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 つができることを確認しましょう。
- do-while の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. do-while とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
- クラス名は
Solution、メソッド名はfirstPositiveにすること - 引数は
int startの 1 つ、戻り値の型はint 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