
🟢 はじめに
今回は、Java Silverなどの試験でも超頻出のテーマと言われる
に潜むひっかけポイントについて解説してみたいと思います。
🧭 今回のダンジョンコード
まずは、今回のコードを見てみましょう。
ある冒険者が、
を歩いているコードです。
public class Main { public static void main(String[] args) { // --- ステージ1:安全な結界の部屋 --- int hpA = 10; do { System.out.println("冒険者AのHP: " + hpA); hpA -= 3; // 💥 ダメージを受ける } while (hpA > 0); // 💀 HPが0より大きければループ System.out.println("\n---- ステージ2の入り口 ----"); // --- ステージ2:崩壊した結界の部屋 --- int hpB = 10; do System.out.println("冒険者BのHP: " + hpB); // hpB -= 3; // 👈 罠:コメントアウトで封印されている while ((hpB -= 3) > 0) ; // 👈 罠:こんなところで引き算が… } }
そう思われた方も多いかもしれません。
実はこのコード、
になります。
なぜそうなるのか、順番に見ていきたいと思います。
🛑 {}(波カッコ)がない時
ステージ2のコードをよく見てみましょう。
do System.out.println("冒険者BのHP: " + hpB); // hpB -= 3; while ((hpB -= 3) > 0) ;
綺麗にインデント(字下げ)されていて、いかにも
と、
の2つが do の中身に見えますよね。
ですが、Javaの世界にはこんなルールがあります。
つまり、コメントアウトを無視してコンピュータの視点で見ると、このコードの本当の姿はこうなっています。
do { System.out.println("冒険者BのHP: " + hpB); // 👈 doの仲間はこれだけ } while ((hpB -= 3) > 0);
🎯 条件チェックの「関所」でコッソリ計算
と思いますよね。
今回注目したいのは、
です。
なんと、
の中で、
という計算がコッソリ行われます。
この「冒険者B」の足跡を、1周ずつ追いかけてみましょう。
初期状態:hpB = 10
1回目(do)
画面に
と表示します。
判定(while):関所に到着。
ここで (hpB -= 3) が発動して、HPが 7 に減ります。
7 > 0 は正しい(true)ので、もう1周します。
2回目(do)
現在のHPは 7 なので、
画面に
と表示します。
判定(while):また関所でHPが減って 4 になります。
4 > 0 なので、もう1周します。
3回目(do)
現在のHPは 4 なので、
画面に
と表示します。
判定(while):また関所でHPが減って 1 になります。
1 > 0 なので、もう1周します。
4回目(do)
現在のHPは 1 なので、
画面に
と表示します。
判定(while):また関所でHPが減って -2 になります。
-2 > 0 は false なので、ここでループ終了です。
🏁 答え合わせ
それでは、
を並べてみましょう。
冒険者AのHP: 10 冒険者AのHP: 7 冒険者AのHP: 4 冒険者AのHP: 1 ---- ステージ2の入り口 ---- 冒険者BのHP: 10 冒険者BのHP: 7 冒険者BのHP: 4 冒険者BのHP: 1
のに、
しました。
Bは「部屋の中では何もせず、関所でダメージを受けてから判定する」
の違いだけで、
という全体の流れが全く同じだったため、こんな不思議な結果になりました。
📝 まとめ
今回のコードから学べるポイントは以下の2つです。
whileの中での計算は、その場で変数の値そのものが変わる
Java学習中の方の参考になれば幸いです🙌