第4章 様々な方法の繰り返し処理
4.3 多重ループを利用しよう
これまで繰り返し処理は、ただ単純に決められた回数を繰り返すものでしたが、前章で学習したif文のネストのように繰り返しの中で繰り返し処理を行うこともできます。このような繰り返し処理のネストを「多重ループ」と言います。
多重ループはネストの数に応じて、二重ループ、三重ループ、・・・と呼びます。三重ループ以上はあまり使用されることは少ないため、本章では二重ループの使い方について学習していきます。
4.3.1 多重ループの構造
多重ループは単純に繰り返し内に繰り返し処理を記述したものを言います。これまで学習してきた繰り返し文の組み合わせのパターンで作成することができます。
- for文内にfor文を記述する。
- foreach文内にforeach文を記述する。
- while文内にwhile文を記述する。
- do~while文内にdo~while文を記述する。
- for文内にwhile文を記述する。
- foreach文内にfor文を記述する。
- while文内にforeach文を記述する。
- do~while文内にwhile文を記述する。
- その他の組み合わせ
上記で示したように同じ種類の繰り返し文をネストすることもあれば、違う種類の繰り返し文をネストすることもできます
例えばfor文の二重ループの書式は以下のようになります。
書式:for文2つの二重ループ
外側のループが9回、内側のループが9回繰り返す場合を例にすると、外側が1回ループする毎に内側の処理は9回処理されるため、結果9×9の81回行われることになります。
先ずはfor文を2つ使った二重ループの動作をプログラムから確認してみましょう。
for文2つの二重ループの動作を確認するプログラム
for文を2つ使った二重ループを記述し、外側と内側のループで処理がどのように繰り返されるかの違いを、Web画面にメッセージを出力して確認します。
ソース・フォルダー: myproj_basic/ch04
パッケージ: nestedLoop.php
アクセスURL:http://localhost/myproj_basic/ch04/nestedLoop.php
nestedLoop.php
解説
今回のプログラムのメインとなる多重ループは7~13行目になります。
外側は$iが1から始まり2以下の間ループするので2回ループし、内側は$jが1から3以下の間ループするので3回ループします。
以下に示す囲み部分が、外側のループ処理の対象になっています。処理内容には内側のループ処理が含まれているので、外側の処理の一部となり、外側のループが1回行われる毎に内側のループは繰り返されます。
内側のループ処理内容以下に示す囲み部分が、内側のループ処理の対象になっています。$jは式1で設定した初期値1から開始されるため、外側のループ毎に必ず1から開始されます。
今回のfor文を2つ使った多重ループの動作の流れを表すと以下のようになり、太字が画面に表示されるメッセージとなっています。
4.3.2 多重ループ内のbreak文とcontinue文の動作について
多重ループを使ってプログラムを作成する場合、知っておかなければならないことがあります。それは繰り返し処理を制御するための「break文」と「continue文」の動作についてです。
break文とcontinue文は繰り返し処理を途中で抜けたり、以降の処理をスキップする仕組みですが、ネストしたループ内で使用した場合は、外側と内側どちらのループが対象になるでしょうか。以下に示す図4.3.1を見てください。
図 4.3.1: 多重ループ内での制御構文の動作
多重ループ内のネストした側で「break文」と「continue文」を利用すると、その制御文を含んだループ文が対象になります。しかし、ネストしたループの処理によっては多重ループ全体から抜けたい、外側のループの次の繰り返しへスキップしたい場合などが出てきます。その場合にはどのようにすればいいのか、次項で詳しく説明していきます。
4.3.3 引数付きbreak文とcontinue文
多重ループのネストしたループ内で制御文を記述すると、そのループ文を対象に制御文が動作します。しかし場合によっては外側のループまで抜けたいときもあります。そのような場合にはbreak文やcontinue文に、「どの階層を対象にするのか」引数で設定することで可能になります。
例えばfor文の二重ループで、外側のループを対象にする場合の書式は以下のようになります。
書式:引数付きbreak文
書式:引数付きcontinue文
二重ループの場合は制御文(break、continue)がある内側のループが基点(1)になります。よって外側のループは1つ階層が上なので制御文(break、continue)の引数には2を設定します。
また、これまでの制御文(break、continue)では引数は設定してきませんでしたが、引数を省略すると1を設定しているのと同じ意味になっています。
では、制御文に引数を設定して、多重ループから抜けるプログラムを確認して行きましょう。
条件付きで九九表を表示するプログラム
ソース・フォルダー: myproj_basic/ch04
パッケージ: nestedLoopKuku.php
アクセスURL:http://localhost/myproj_basic/ch04/nestedLoopKuku.php
nestedLoopKuku.php
解説
今回のプログラムは、for文を2つの二重ループで九九表を作成します。その際に1~10のランダム数値を1つ生成し、そのランダム数値と該当する段が同じ場合に九九表の表示を止めるプログラムになっています。
ポイントは内側のループのbreak文に引数2を設定して、条件を満たすと二重ループ全体から抜けるようになっています。
7行目でランダム数値を1~10の範囲で1つ生成し、変数$numに代入しています。
10~15行目では、7行目で生成したランダム数値の値が10かそれ以外の場合で、画面に表示するメッセージを変化させています。$numが10ならifブロックの処理を行い、そうでなければelseブロックの処理を行います。
18~29行目が九九表を作成する二重ループになります。22行目の条件判定で、外側のループのカウンタ変数$iの値とランダム数値の$numが同じ場合、二重ループ全体から抜けるようにbreak文に引数2を設定しています。
九九表を表示する処理の流れは以下のようになります。