未来エンジニア養成所Blog

プログラミングを皆に楽しんでもらうための情報をお届けします。

【Java】制御構造の応用 「二重ループ」「制御の中断」「制御の継続」

title


制御構造については下記のページで解説しましたが、ここでは、制御構造の応用的な使い方を取り上げます。

ですので事前に確認しておいて下さい。 phoeducation.work

phoeducation.work


具体的には次の3つです。

  • 二重ループ
  • 制御の中断
  • 制御の継続


二重ループ

二重ループとは、for文の中にさらにfor文があるような「入れ子」になった繰り返し制御のことです。

(入れ子のことを「ネスト」と表現する場合もあります)


二重ループにすることで外側の繰り返し処理が行われる度に、内側の繰り返し処理が実行されます。


多重配列の全要素にアクセスするループ文を書く際には、この二重ループなどが利用されます。


for文を用いた二重ループは次のように書くことができます。さらに、下の図で動作のイメージも確認しておきましょう。

二重ループ


フローチャートは以下の通りです。

二重ループ_フローチャート


【二重ループ】

public class DoubleLoop{
    public static void main(String[ ] args){
        for(int i = 1; i <= 3; i++){
            System.out.println("外側のループ処理のはじめ:" + i + "回目");
            for(int j = 1; j <= 2; j++) {
                System.out.println("\t内側のループ:" + j + "回目");
            }
            System.out.println("外側のループ処理の終わり");
        }
    }
}

実行結果

外側のループ処理のはじめ:1回目
  内側のループ:1回目
  内側のループ:2回目
外側のループ処理の終わり
外側のループ処理のはじめ:2回目
  内側のループ:1回目
  内側のループ:2回目
外側のループ処理の終わり
外側のループ処理のはじめ:2回目
  内側のループ:1回目
  内側のループ:2回目
外側のループ処理の終わり


ポイントは、外側のfor文によるループが1回行われるたびに、内側のfor文ループでは初期化処理が行われる点です。

4行目の処理の後、5行目にプログラムが移るときに、初期化の処理が行われ、カウンタjの値が1になります。

このような二重ループは、二次元配列の値を初期化したり、表示するときなどによく利用されます。


【九九表の作成】

public class Kuku{
    public static void main(String[ ] args){
        int[ ][ ] hyou = new int[9][9]; // 二次元配列で九九の表を表す。
        //表の作成
        for(int i = 1; i <= 9; i++){
            for(int j = 1; j <= 9; j++){
                hyou[i-1][j-1] = i * j;
            }
        }
        // 表の出力
        for(int i = 1; i <= 9; i++){
            for(int j = 1; j <= 9; j++) {
                System.out.print(hyou[i-1][j-1] + " "); 
            }
            System.out.println( );  // 改行
        }
    }
}


実行結果

1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81


外側のループは九九の段数を表すiを変更します。

1の段から9の段までループしているのがわかります。


内側のループは各段を表すiへ1から9の値を掛けて、二重配列に格納しています。


添え字が[i-1][j-1]のように、-1されているのは、配列が0から始まるためです。


制御の中断と継続

二重ループを何らかの条件が成り立った時に中断したり、ループの先頭に戻したりという事が出来ます。

この際に用いるのが、「break文」「continue文」です。この制御の中断と継続はループの中で使います。

各々の違いは以下の通りです。

  • break文 : ループを中断
  • continue文 : ループの先頭へ戻る


ポイント1 : break文とswitch文

break文の場合は条件分岐のswitch文でも登場しました。

これは中括弧”{…}”で囲まれた処理を中断する点で共通しています。


ポイント2 : break文で中断するブロック

break文でswitch文やループ(for文、while文)のループを中断することができます。

ただし、if文のブロックは中断することはできませんので注意してください。


【break 文】

public class Break{
    public static void main(String[ ] args){
        System.out.println("Start...");

        for(int i = 0; i < 3; i++){
            System.out.println("i : " + i );
            if(i == 1){      //iが1の時にループを中断する
                break;
            }
            System.out.println("ループの中身の処理");
        }
        System.out.println("終了");
    }
}


実行結果

Start...
i : 0
ループの中身の処理
i : 1
終了


プログラムの7〜9行目を見てください。

これはカウンタiの値が1の時、ループを中断するというものです。

本来はfor文によってiが2まで処理されるはずですが、iが1の時にbreak文が処理されるため、for文がその時点で中断されます。

if文が中断するのではなく、ループが中断している点に注意してください。


【break文と二重ループ】

public class Break2{
    public static void main(String[ ] args){
        System.out.println("Start...");

        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
                System.out.println("\ti : " + i + ", j : " + j);
                if(j == 1){      // j が1の時にループを中断する
                    break;
                }
                System.out.println("\t\t内側のループの処理");
            }
            System.out.println("外側のループの処理");
        }
        System.out.println("終了");
    }
}


実行結果

Start...
  i : 0, j : 0
    内側のループの処理
  i : 0, j : 1
外側のループの処理
  i : 1, j : 0
    内側のループの処理
  i : 1, j : 1
外側のループの処理
  i : 2, j : 0
    内側のループの処理
  i : 2, j : 1
外側のループの処理
終了


break文を使った場合に中断するブロックは、一番内側のブロックになります。

従って、今回のプログラムのように、内側のループでbreak文を記述しても、その外側にあるループまでは中断しません。


if文はbreakの対象とはなりませんので、注意してください。


ラベルを使ったbreak

二重ループの外側のループをbreak文で中断したい場合には”ラベル”を利用します。

ラベルとはループ(for文、while文など)のブロックに名前を付けるもので、break文を処理する際にラベル名を記述すると、内側のループの処理を抜けるのではなく、そのラベルのループの処理を抜けます。


ラベルを貼る際の書式は以下の通りです。ラベル名には好きな名前をアルファベットと数字でつけます。

ラベル:for(…){……………} ラベル:while(…){…………}


ラベルを貼ったループを中断するには以下のようにbreak文で貼り付けたラベルを指定します。

break ラベル名;


【break文とラベル】

public class Break3{
    public static void main(String[ ] args){
        System.out.println("Start...");

        break_point:
        for(int i = 0; i < 3; i++){     // 外側のループにラベルを貼る
            for(int j = 0; j < 3; j++){
                System.out.println("\ti : " + i + ", j : " + j);
                if(j == 1){      // j が1の時にループを中断する
                    break break_point;  // 抜けるループを指定して
                                        // break文を実行
                }
                System.out.println("\t\t内側ループの中身の処理");
            }
            System.out.println("外側のループの中身の処理");
        }
        System.out.println("終了");
    }
}


実行結果

Start...
  i : 0, j : 0
    内側のループの処理
  i : 0, j : 1
終了


5行目では”break_point:”を記述しています。

これは6行目のfor文に対するラベルとなります。


そして、10行目でbreakするラベルを指定してbreak文を実行しています。


これにより、6行目~15行目の外側のループを中断することになります。


continue文

繰り返し処理などのループ文を制御する文法として、break文の他に”continue”文があります。


break文がループを中断するのに対してcontinue文はループの先頭に戻りループを再開します。

ラベルが利用できる点もbreak文と同様です。


ループを再開しますが、ループ文で利用している値はそのままの値で引き継がれます。

処理を行うポイントが戻るだけであって、処理自体が再度新しく行われるわけではありません。


【continue文】

public class Continue{
    public static void main(String[ ] args){
        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
                System.out.println("\ti : " + i + ", j : " + j);
                if(j == 1){
                    continue;  //continue文を利用して内側のループに戻る
                }
                System.out.println("\t\t内側のループの処理");
            }
            System.out.println("外側のループの処理");
        }
        System.out.println("終了");
    }
}


実行結果

  i : 0, j : 0
    内側のループの処理
  i : 0, j : 1
  i : 0, j : 2
    内側のループの処理
外側のループの処理
  i : 1, j : 0
    内側のループの処理
  i : 1, j : 1
  i : 1, j : 2
    内側のループの処理
外側のループの処理
  i : 2, j : 0
    内側のループの処理
  i : 2, j : 1
  i : 2, j : 2
    内側のループの処理
外側のループの処理
終了


continue文が処理されると、内側のループ、もしくはラベル付けされたループの先頭に戻ります。

今回は、7行目のcontinueの次には4行目のfor文の条件判断が行われることになります。


今回はラベルを利用していないので、continue文では内側のループの先頭に戻ります。


まとめ

  • 二重ループ

ループの中にループを記述することを、多重ループや、入れ子、ネストなどと呼びます。

これらは多次元配列などと組み合わせる形で利用されることが多いです。


  • 制御の中断

ループ処理を中断したい場合はbreak文を使います。


  • 制御の継続

ループ中の処理を戻したい場合はcontinue文を使います。

breakとは異なり、ループ自体は継続されます。


参考図書



独学で挫折しそうになったら、オンラインプログラミングスクール
未来エンジニア養成所Logo



あわせて学習したい

phoeducation.work phoeducation.work