ループ処理

 ループ処理とは,同じ処理を繰り返して実行させることをいいます。Java言語ではfor文,while文,do-while文でループ処理を実行することができます。

for文

 for文は,決まった数だけループする場合によく使われます。次のサンプルコードを見てください。

public class MyFor {
  public static void main(String[] args) {
    int a;
    for(a = 0;a < 5; a++){
      System.out.println("変数aは = " + a); 
    }
  }
}

実行すると,

のように表示されます。このことからこのプログラムでは,System.out.println("変数aは = " + a);の部分が5回実行されていることがわかります。つまり同じコードが繰り返し実行されているのです。

 for文は以下のような構文になっています。

for(初期化処理;条件判断;次の処理){
  繰り返される処理
} 

for文では,次のように

初期化処理
  ↓
条件判断
  ↓
条件がtrueのとき繰り返される処理
  ↓
次の処理
  ↓
条件判断
  ↓
条件が真(true)のとき繰り返される処理・・・

の順番で繰り返し実行されていきます。初期化処理の部分だけ最初の一度しか実行されない点に注意してください。

 では,以下のサンプルコードではどうでしょうか。

public class MyFor{
  public static void main(String[] args) {
    int a;
    for(a = 10;a > 5; a--){
      System.out.println("変数aは = " + a); 
    }
  }
}

実行すると,

のようになります。まず変数aは,for文の初期化処理の部分で10に初期化されます。次に条件判断の部分で5と比較されます。この場合5よりも変数aは大きいので,for文の中身の処理が1回実行され,画面に「変数aは = 10」と表示されます。中身の処理が終わると,aはデクリメントされて9になります。次に条件判断で5と比較され,変数aの方が大きいのでfor文の中身が実行されます。この繰り返しを変数aが6になるまで繰り返します。ただし変数aが5になると,条件判断はfalseになるので,for文の中身は実行されずに,for文は終了します。

 注意する点は,以下のようにfor文の初期化処理の中で変数の宣言と初期化が同時に記述できる点です。

public class MyFor {
  public static void main(String[] args) {
    for(int a = 10;a > 5; a--){
      System.out.println("変数aは = " + a); 
    }
    System.out.println("変数aは = " + a); 
  }
}

この場合,変数aの有効範囲はfor文の { から } までになります。したがって,for文の次にあるSystem.out.println("変数aは = " + a);の部分では宣言されてない変数aを使うことになるのでコンパイルエラーになります。変数の有効範囲については後で詳しく紹介します。

for文の( )内を省略

 for文では( ) 内を省略できます(ただし,セミコロンは省略できません)。そのため 以下のコードは正常に動作します。

public class MyFor {
  public static void main(String[] args) {
    int a = 0;
    for(;;){
     if(a >= 5) break; 
     System.out.println("変数aは = " + a); 
     a++;
    }
  }
}

 このサンプルでは,for文の初期化処理,条件判断,次の処理がすべて省略されて,( )の外部で同じ処理を行っています。最初の変数aの初期化はfor文の前で行っています。for文の ( ) 中には何の記述もないのでそのままfor文の中に入っていきます。次にif文で変数aと5が比較され,もし5と等しいか大きければbreak文が実行されます。break文が実行されるとfor文の { } から抜けます。もし5以下なら画面にメッセージが表示され,変数aはインクリメントされます。次にfor分の先頭に戻りますが, ( ) 内には何も記述されていないので,すぐにfor文の中に入ります。次にif文の条件判断が実行されて,変数aが5になるまで繰り返されます。

for文の( )内に複数処理を定義

 for文の ( ) の中には,カンマで区切ることで,複数の処理が書けます。

public class MyFor {
  public static void main(String[] args) {
    for(int a = 0,b = 1;a < 5;a++,b++){
     System.out.println(b + "行目-変数aは = " + a); 
    }
  }
}

実行結果

 このサンプルでは,初期化処理の部分で変数aと変数bの宣言と初期化を同時に行っています。また,次の処理の部分でも,変数aと変数bのインクリメントを同時に行っています。

while文

 for文が決まった回数ループするのに適しているのに対して,while文は,条件を満たしている間中処理を繰り返すのに適しています。

public class MyWhile {
  public static void main(String[] args) {
    int a = 0;
    while(a < 5){
      System.out.println("変数aは = " + a);
      a++; 
    }
  }
}

実行結果

 while文では,( ) の中には,条件判断しか記述することができません。そのためもしfor文と同じ処理をする場合,変数の初期化やインクリメントはwhile文の外や中で記述する必要があります。while文の構文は以下のようになります。

while(条件) {
  条件がtrueのとき、繰り返される処理
}

 このようにwhile文は,for文よりも構造が単純です。もちろんwhile文のループ処理をfor文で書くこともできますが,処理の性質や見易さを考えて適材適所で使っていきましょう。

do...while文

 while文の仲間に,do...while 文があります。do...whileは,while文の条件判断が,{から}までの処理が終了した後に実行されます。

do{
  処理
} while(条件式)

 注意する点は,while文は最初から条件判断がfalseになった場合,一度も{から}の間の処理が実行されない場合があるのに対して,do...while 文は,必ず一度は実行される点です。

ループのネスト

 ループの中にループを書くことができます。このようにある構造構文の中に同じ構造を持つことを「ネスト」といいます。たとえばfor文のネストは以下のようになります。

public class MyFor2 {
  public static void main(String[] args) {
    for(int a = 1;a < 10;a++){
      for(int b = 1;b < 10; b++) {
        System.out.print(a * b + "\t");
      }
      System.out.println("");
    }
  }
}

実行結果

 このプログラムでは,外側のfor文で,変数aを1~9まで変化させている中で,さらに内側のfor文で変数bを1~9へ変化させています。この2つの変数を掛け合せることで,九九と同じ計算結果を作り出して表示させています。プログラムの中で"\t"という記述がありますが,これはタブコードを表します。また,System.out.printメソッドは,改行をしない文字出力メソッドです。

break文

 break文は,自分を含んでいる一番近い { } から外に抜けます。そのためループ文をネストしているような場合,すべてのループから抜けるためには,すべてのループにbreak文が必要になります。

public class MyBreak {
  public static void main(String[] args) {
    int a = 1;
    int b;
    while(true){
      if(a > 9) break;
       b = 1;
      while(true) {
        if(b > 9) break;
        System.out.print(a * b + "\t"); b++;
      }
      a++;
      System.out.println("");
    }
  }
}

実行結果

 このプログラムでは,while文の条件判断にtrueが直接記述されています。そのためこのままではループは終了することがありません。このようなループを「無限ループ」といいます。さらにこの無限ループはネスト構造になっています。処理は外側のwhile文で,変数aを1~9まで変化させている中で,さらに内側の ループでは変数bを1~9へ変化させています。各ループを抜ける方法としてif文とbreak文が組み合わされて使われています。どちらのbreak文も自分が所属する一番近い { } から抜けるだけだということに注意してください。

continue文

 ループ処理の中でcontinue文を使って強制的にループの先頭に処理を戻すことができます。

public class MyContinue {
  public static void main(String[] args) {
    for(int a = 0; a < 5; a++){
      if(a == 2) continue;
      System.out.println(a);
    }
  }
}

実行結果

 このプログラムでは,aが0,1,3,4の時はそのまま表示されるが,2のときだけはcontinueされるため,for文の頭に戻りSystem.out.println()は実行されません。

 次回は,Javaの大きな特徴の1つであるオブジェクト指向という考え方について解説します。