Code Fix

中級

ループが終わらない・空回りする原因

カウンタ更新の忘れ、更新方向の誤り、forの直後のセミコロンという3パターンを扱います。

なぜエラーが出ないのか

出力: 0 が無限に続く
(エラーなし)
javacは何も報告しません。文法として正しいためです
出力: 0 が無限に続く
実際の挙動 — 期待した結果と食い違っている箇所
見つけ方
エラーが出ないので、出力を目で確かめるしかありません。この種の誤りが最も発見が遅れます

このエラーが出る典型パターン

パターン1

 1  public class Main {
 2      public static void main(String[] args) {
 3          int i = 0;
 4          while (i < 3) {
 5              System.out.println(i);
 6                  
                  ^
 7          }
 8      }
 9  }
出力: 0 が無限に続く(プロセスが終わりません)

whileは条件を変える処理を自分で書きます。カウンタの更新を忘れると止まりません。

直し方: (空) を i++; にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  public class Main {
 2      public static void main(String[] args) {
 3          for (int i = 0; i < 3; i-- ) {
                                     ^
 4              System.out.println(i);
 5          }
 6      }
 7  }
出力: 0 -1 -2 ... が無限に続く(プロセスが終わりません)

更新式が条件を満たす方向に動いていないと終わりません。増加か減少かを条件と合わせます。

直し方: -- を ++ にします。

この問題を解いてみる →

パターン3

 1  public class Main {
 2      public static void main(String[] args) {
 3          int count = 0;
 4          for (int i = 0; i < 3; i++); 
                                        ^
 5              count++;
 6          System.out.println(count);
 7      }
 8  }
出力: 1期待: 3 (コンパイルは通っています)

forの直後のセミコロンは「本体が空」を意味します。ループが空回りし、次の行は1回だけ実行されます。

直し方: ; を (空) にします。

この問題を解いてみる →

パターン4

 1  public class Main {
 2      public static void main(String[] args) {
 3          int i = 0;
 4          do {
 5              System.out.println(i);
 6                  
                  ^
 7          } while (i < 3);
 8      }
 9  }
出力: 0 が無限に続く(プロセスが終わりません)

do-whileも条件を変える処理は自分で書く必要があります。カウンタの更新を忘れると止まりません。

直し方: (空) を i++; にします。

この問題を解いてみる →

パターン5

 1  public class Main {
 2      public static void main(String[] args) {
 3          int i = 0;
 4          boolean cont = true;
 5          while (cont =  true) {
                         ^
 6              System.out.println(i);
 7              i++;
 8              if (i >= 3) cont = false;
 9          }
10      }
11  }
出力: 0 1 2 3 4 ... が無限に続く(プロセスが終わりません)

whileの条件で = を書くと、毎回contにtrueを代入してしまいます。ループ内でfalseにしても次の判定で上書きされ、条件は常にtrueのままです。

直し方: = を == にします。

この問題を解いてみる →

よくある誤解

forの直後のセミコロンはエラーになりません。文法上は正しい「空の本体」だからです。

実務での勘所

無限ループはコンパイルエラーにも警告にもならないことがほとんどです。停止するかどうかを一般的に判定することは理論的に不可能(停止性問題)なので、javacやIDEがこれを検出して教えてくれることは期待できません。一方でwhile (true) { ... break; }のように、意図的に無限ループとbreakを組み合わせる書き方は、サーバーのリクエスト待ちやゲームのメインループなどで実務でも普通に使われる正当なパターンです。「無限ループ=バグ」ではなく、終了条件を書き忘れたものだけがバグです。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)