for文

for文による繰り返し

同じようなことを何度も正確に繰り返す処理は、コンピュータにとっては得意中の得意です。 このような処理は、プログラミングの世界では単に繰り返し(loop)と呼ばれることもありますが、実際にはループと呼ばれることが多いようです。 Javaには繰り返しの構文として、for文(for statement)、while文(while statement)、do〜while文(do statemet)があります。 では、for文から学習していきましょう。

英語のforには、「〜の間」という意味があります。

構文 : for文
for(初期化部; 条件; 更新部)
    文
構文 : 複数の文を実行するfor文
for(初期化部; 条件; 更新部){
    文1
    文2
    ...
}
図 7-1 : 複数の文を実行するfor文のフローチャート

if文のときと同様に、ブロックを使って複数の文を繰り返すことができるのは言うまでも有りません。

ブロックの中の文は1つだけでもかまいません。 実行したい文が1つだけの場合でも、ブロックを使った書き方をお薦めします。 一貫性のある書き方をした方が、コードが読みやすくなるからです。 ただし、本講座では、コードの行数を減らすために、文が1つだけの場合はブロックに入れないときもあります(while文、do〜while文についても同様)。

構文中の「文」や{文1 文2 ...}などのfor文が繰り返す部分をループ本体と呼びます(while文、do〜while文についても同様)。

肝心なのは「初期化部; 条件; 更新部」の部分です。 「初期化部」、「条件」、「更新部」はセミコロン(;)で区切られています。 ループの中で利用される変数の初期値を設定したりするのが「初期化部」です。 この「初期化部」は実際にループに入る前に、一回だけ実行されることになります。 「条件」はもちろんboolean型の式で、この値がtrueの間だけループ本体が実行され、falseになったときにループは終了します。 ループ本体が実行された後で、次の回の繰り返しに入る前に「更新部」が実行されます。 「更新部」では変数の値を新しいものに変えたりします。 さすがに今回は具体例を見ないと分かりにくいですね。

ForSample01.java
class ForSample01 {
    public static void main(String[] args) {
        int i;
        for(i = 1; i <= 3; i++)
            System.out.println(i + "回目です。");
        
        System.out.println("ループを抜けた後、iは" + i + "になっています。");
    }
}
ForSample01の実行結果
1回目です。
2回目です。
3回目です。
ループを抜けた後、iは4になっています。

ForSample01のfor文では、まず実際にループに入る前に一回だけ「初期化部」として i = 1 が実行されます。 次に「条件」である i <= 3 が評価されます。 最初はiの値が1になっていますので、trueとなり、

            System.out.println(i + "回目です。");

が実行され、「1回目です。」と表示されます。 そして、次の回の繰り返しに入る前に「更新部」として i++ が実行されます。 このとき、iの値は2になります。 ここでまた i <= 3 が評価され、...というように繰り返されていきます。 「3回目です。」と表示された後で i++ が実行されると、iの値は4になります。 そして、次に i <= 3 を評価するとfalseとなり、4回目はループ本体は実行されず、ループは終了することになります。 ForSample01でのfor文の流れを表 7-1にまとめておきます。

表 7-1 : ForSample01でのfor文の流れ
繰り返し回数 iの値 i <= 3 表示内容 i++後のiの値
1 1 true 1回目です。 2
2 2 true 2回目です。 3
3 3 true 3回目です。 4
4 4 false

for文の中で使う変数を「初期化部」の中で宣言することもできます。 ただし、この変数はfor文の外では使えません。

ForSample01A.java
class ForSample01A {
    public static void main(String[] args) {
        for(int i = 1; i <= 3; i++)
            System.out.println(i + "回目です。");
        
        //System.out.println("ループを抜けた後、iは" + i + "になっています。");
    }
}

for文の「初期化部」で宣言された変数を利用できる範囲(有効範囲)は、for文の中だけとなります。 for文を抜けた後で変数iを使おうとすると、コンパイルエラーになってしまうので、変数iを表示する部分を

        //System.out.println("ループを抜けた後、iは" + i + "になっています。");

のようにコメントアウトしてあるのです。

ForSample01Aの実行結果
1回目です。
2回目です。
3回目です。

for文を使ったいろいろなプログラム

指定された個数だけ*(アスタリスク)を表示するプログラムを作ってみましょう。

ForSample02.java
import java.io.*;

class ForSample02 {
    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        
        System.out.println("*を何個表示しますか。");
        int num = Integer.parseInt(br.readLine());
        
        for(int i = 1; i <= num; i++){
            System.out.print("*");//アスタリスクを表示するが、改行しない。
        }
        
        System.out.println();//最後に改行だけする。
    }
}

ForSample02では、まず*を何個表示するのかを訪ねてきます。 そして、入力された値は変数numに代入されます。 for文では「初期化部」が int i = 1 、「条件」が i <= num 、「更新部」が i++ となっているため、num回の繰り返しが実行されます。 println は表示した後で改行しますが、 print は改行しません。 そのため、num個の*がつながって表示されることになります。

ForSample02の実行結果
*を何個表示しますか。
4
****

次は1から入力された整数までの和を求めるプログラムを作ってみましょう。 例えば、「10」を入力した場合、1+2+3+...+9+10の計算をして、結果を表示します。

ForSample03.java
import java.io.*;

class ForSample03 {
    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        
        System.out.println("1からどの数までの和を求めますか。");
        int num = Integer.parseInt(br.readLine());
        
        int sum = 0;
        for(int i = 1; i <= num; i++){
            sum += i;
        }
        
        System.out.println("1から" + num + "までの和は" + sum + "です。");
    }
}

ForSample03では、まず1からどの数までの和求めるのかを訪ねてきます。 そして、入力された値は変数numに代入されます。 for文に入る前に変数sumの値は0に初期化されています。 このsumこそ、最終的に1からnumまでの和が格納される変数です。 for文では「初期化部」が int i = 1 、「条件」が i <= num 、「更新部」が i++ となっているため、num回の繰り返しが実行されます。 i回目の繰り返しでは、sumにiが加算されます。 その結果、sumの値は最終的に1からnumまでの和になります。

ForSample03の実行結果 1
1からどの数までの和を求めますか。
10
1から10までの和は55です。

0以下の数を入力した場合は、ループ本体は一度も実行されず、次のようなおかしな結果になってしまいます。 本来なら、0以下の数は入力できないようにしたいところです。 これについては後ほど改良したいと思います。

ForSample03の実行結果 2
1からどの数までの和を求めますか。
0
1から0までの和は0です。

ForSample03で「10」を入力した場合のfor文の流れを表 7-2にまとめておきます。

表 7-2 : ForSample03でのfor文の流れ(1から10までの和)
繰り返し回数 iの値 i <= num sum += i;
前のsumの値
sum += i;
後のsumの値
i++後のiの値
1 1 true 0 1 2
2 2 true 1 3 3
3 3 true 3 6 4
4 4 true 6 10 5
5 5 true 10 15 6
6 6 true 15 21 7
7 7 true 21 28 8
8 8 true 28 36 9
9 9 true 36 45 10
10 10 true 45 55 11
11 11 false

for文の「初期化部」と「更新部」では複数の変数を扱うこともできます。

ForSample04.java
import java.io.*;

class ForSample04 {
    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        
        System.out.println("何回繰り返しますか。");
        int num = Integer.parseInt(br.readLine());
        
        for(int i = 1, j = num-1; i <= num; i++, j--){
            System.out.println(i + "回目です。あと" + j + "回です。");
        }        
    }
}

「初期化部」は int i = 1, j = num-1 となっています。このように、複数の変数を初期化する場合は、カンマ(,)で区切ります。 「更新部」は i++, j-- となっています。やはり、カンマ(,)で区切っていますね。

ForSample04の実行結果
何回繰り返しますか。
4
1回目です。あと3回です。
2回目です。あと2回です。
3回目です。あと1回です。
4回目です。あと0回です。

for文の基本がお分かりいただけたでしょうか。

繰り返しの構文としては、while文do〜while文なども学習することになります。 for文の特長は、「初期化部」、「条件」、「更新部」というお決まりの処理がまとめて記述でき、直感的に分かりやすいということでしょう。

for文を使うと、直感的に分かりやすい繰り返し処理が記述できる。