continue文

continue文による処理のスキップ

ループ本体の実行途中に、それ以降の処理をスキップして、次の回の繰り返しに移りたいときがあります。そのためにはcontinue文を使います。

英語のcontinueには、「続ける」という意味があります。

構文 : continue文
continue;

ループ本体の中でcontinue文を実行すると、そのcontinue文を含む一番内側のループ本体の最後まで、処理がスキップされます。 continue文を実行するときの処理の流れは図 7-10のようになります。

図 7-10 : continue文を含むループのフローチャート

for文の中でcontinue文が実行された場合は、文2の処理は飛ばされ、次の回の繰り返しの準備ために、「更新部」が実行され、さらに「条件」が評価されます。

while文とdo〜while文の中でcontinue文が実行された場合は、文2が飛ばされ、次の回の繰り返しを実行するかどうかを判定するために、「条件」が評価されます。

それでは、サンプルプログラムを見てみましょう。 今回は1から入力された整数までのうち、奇数だけの和を求めるプログラムです。 これは、例えば次のように動作します。

  • 「5」を入力した場合、1+3+5を計算して、結果を表示します。
  • 「10」を入力した場合、1+3+5+7+9を計算して、結果を表示します。
ContinueSample01.java
import java.io.*;

class ContinueSample01 {
    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++){
            if(i % 2 == 0){ //偶数なら処理をスキップ
                continue;
            }
            sum += i; //奇数だけを足す。
        }
        
        System.out.println("1から" + num + "までの和(奇数のみ)は" + sum + "です。");
    }
}
ContinueSample01の実行結果 1
1からどの数までの和(奇数のみ)を求めますか。
5
1から5までの和(奇数のみ)は9です。
ContinueSample01の実行結果 2
1からどの数までの和(奇数のみ)を求めますか。
10
1から10までの和(奇数のみ)は25です。

for文は、iの値を1からnumまでインクリメントしながら実行されていきます。

        for(int i = 1; i <= num; i++){
            if(i % 2 == 0){ //偶数なら処理をスキップ
                continue;
            }
            sum += i; //奇数だけを足す。
        }

しかし、if文の条件が i % 2 == 0 となっているため、変数iが偶数の場合はcontinue文が実行されます。 すると、

            sum += i; //奇数だけを足す。

はスキップされ、次の回の繰り返しの準備のため、for文の「更新部」の i++ が実行され、さらに「条件」の i <= num が評価されます。 したがって、 sum += i; が実行されるのは、変数iの値が奇数の場合だけということになるのです。

表 7-10 : ContinueSample01でのfor文の流れ(1から5までの奇数の和)
繰り返し回数 iの値 i <= num i % 2 == 0 sum += i;
前のsumの値
sum += i;
後のsumの値
i++
後のiの値
1 1 true false 0 1 2
2 2 true true 1 3
3 3 true false 1 4 4
4 4 true true 4 5
5 5 true false 4 9 6
6 6 false

continue文を使えば、それ以降の処理をスキップして、次の回の繰り返し処理に移ることができる。

ラベル付きcontinue文で多重ループの処理をスキップする

既に述べましたように、continue文が実行されると、それを含む一番内側のループ本体の最後まで、処理がスキップされます。 したがって、二重ループの内側のループ本体でcontinue文が実行された場合、内側のループ本体の最後までの処理がスキップされるだけで、外側のループ本体の処理はスキップされません。 今回も、九九の表を作るプログラム(MultipleLoopSample01A)を少し作り替えて、このことを確認してみましょう。

ContinueSample02.java
class ContinueSample02 {
    public static void main(String[] args) {
        for(int i = 1; i <= 9; i++){
            for(int j = 1; j <= 9; j++){
                if(i * j % 2 == 0){
                    continue;
                }
                System.out.printf(" %2d", i * j);
            }
            System.out.println();
        }
    }
}

ContinueSample02の実行結果は図 7-11のようになります。

図 7-11 : ContinueSample02の実行結果

ContinueSample02の内側のループ(列ループ)の中には、

                if(i * j % 2 == 0){
                    continue;
                }

と記述されています。 九九の答えが偶数の場合は、continue文が実行されて、内側のループ本体のそれ以降の処理がスキップされます。 つまり、

                System.out.printf(" %2d", i * j);

という処理は飛ばされ、 j++ が実行され、次に j <= 9 が評価され、列ループは次の回の繰り返しへと移っていくのです。 しかし、外側のループ(行ループ)本体の処理はスキップされるわけではなく、相変わらず、現在の行の処理を続行します。

このように、continue文が実行されると、それを含む一番内側のループ本体の処理がスキップされるのであって、外側のループ本体の処理はスキップされないのです。

外側のループ本体の処理をスキップするためには、ラベル付きcontinue文を使います。

構文 : ラベル付きcontinue文
ラベル:
    for(初期化部1; 条件1; 更新部1){
        for(初期化部2; 条件2; 更新部2){
            if(条件3){
                ...
                continue ラベル;
            }
        }
    }

それでは、ContinueSample02を少しだけ作り替えたプログラムで、ラベル付きcontinue文のはたらきを確かめてみましょう。

ContinueSample03.java
class ContinueSample03 {
    public static void main(String[] args) {
    RowLoop:
        for(int i = 1; i <= 9; i++){
            for(int j = 1; j <= 9; j++){
                if(i * j % 2 == 0){
                    System.out.println();
                    continue RowLoop;
                }
                System.out.printf(" %2d", i * j);
            }
            System.out.println();
        }
    }
}
図 7-12 : ContinueSample03の実行結果

今回は、外側のループ(行ループ)の直前に RowLoop というラベルが付いています。 そして、九九の答えが偶数となる場合はラベル付きcontinue文が実行されます。

                if(i * j % 2 == 0){
                    System.out.println();
                    continue RowLoop;
                }

ラベル付きcontinue文が実行されると、行ループの次の回の繰り返しへと移ります。 したがって、その時点で現在の行(段)の表示は終了することになります。 この場合、内側のループ(列ループ)の後の改行の処理は行われないことになるので、ラベル付きcontinue文の実行前に、改行しておかなければなりません。

多重ループの外側のループの処理をスキップするには、外側のループの直前にラベルを付けて、ラベル付きcontinue文を実行する。