この記事では、当社 の新人エンジニア研修の参考にJava8を解説します。
前回は条件分岐と判定条件について解説しました。
今回は繰り返し処理について解説します。
人間だったら嫌になってしまう繰り返し処理もコンピュータにとっては何でもありません。
コンピュータの偉大さを感じる瞬間です。
ここでは、以下の3つの繰り返し処理を学びましょう。
1.while文
2.for文
3.do while文
です。
なお、繰り返し処理のことをループとも言います。
1.while文
英語のwhileには「~の間」という意味がありました。
継続条件を満たしている間は処理を繰り返すというのがwhile文です。
whileの基本構文です。
While(継続条件式){
文;
}
「継続条件式」がtrueなら「文」を処理する。 false ならwhile文を終了する。
という意味になります。
具体例で見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 |
package chap05; public class Example01 { public static void main(String[] args) { int i = 0; while (i < 6) { System.out.println(i); i++; } } } |
<結果>
0 1 2 3 4 5 |
ここでは、9行目のインクリメントに着目してください。
もしも、このインクリメントがないと、継続条件式がいつまでもtrueのままでループを抜けませんから、無限ループになってしまいます。
気をつけましょう。
2.for文
先のwhile文では、ループに入る前に変数のiを初期化して、ループの中で更新(インクリメント)する必要がありました。
この構造を見やすく1行で表現できるのがfor文です。
基本構文です。
for(初期化文; 継続条件式; 更新文){
文;
}
1.ループに入る前に初期化文を一度だけ行います。
2.継続条件式がtrueなら文を実行し、falseならループを終了します。
3.更新文を実行します。
これも具体例で見てみます。
1 2 3 4 5 6 7 8 9 10 |
package chap05; public class Example02 { public static void main(String[] args) { for (int i = 0; i < 6; i++) { System.out.println(i); } } } |
<結果>
0 1 2 3 4 5 |
処理内容は先ほどのwhile文と同じですが、シンプルに書けているのがお分かりになると思います。
ループの制御構造が一か所にまとまっているので繰り返したい処理ブロックが長くなっても可読性が保たれるのがfor文の良いところです。
一般的には、繰り返し回数が分かっている場合にはfor文を使います。
一方、繰り返し回数が分からない場合に使われることが多いのがwhile文です。(後述)
ここで少し繰り返し処理というテーマから外れますが、初学者が間違いやすい変数の有効範囲(スコープ)ということについて注意喚起です。
例えば、以下のようなプログラムはException (例外)というものが出て止まってしまいます。
1 2 3 4 5 6 7 8 9 10 11 |
package chap05; public class Example03 { public static void main(String[] args) { for (int i = 0; i < 6; i++) { System.out.println(i); } System.out.println(i); } } |
<結果>
(一部省略) Exception in thread “main” java.lang.RuntimeException: Uncompilable source code – Erroneous tree type: <any> |
といいますのは、変数(ローカル変数)の有効範囲は同じブロック内({}波カッコの中)というルールがあるからです。
もしも、変数iをfor文の外でも使いたい場合には、以下のように変数宣言をfor文の外でします。
1 2 3 4 5 6 7 8 9 10 11 12 |
package chap05; public class Example04 { public static void main(String[] args) { int i; for (i = 0; i < 6; i++) { System.out.println(i); } System.out.println(i); } } |
<結果>
0 1 2 3 4 5 6 |
for文で間違えやすいのは、 継続条件式は繰り返し処理を実行する前に判定される ということです。
また、更新文は繰り返し処理が終わってから実行されます。
初期化文 → 継続条件式 → 繰り返し処理 → 更新文 → 継続条件式 → 以下繰り返しという実行の順番を確実に覚えましょう。
3.ループを中断するbreak、1回スキップするcontinue
先ほど、繰り返し回数が分からない場合に while(true) として無限ループとともに使われるのがwhile文だと書きました。
無限ループだといつまでたってもプログラムが終了しないのでは?
と思った人も多いかと思います。
無限ループと良く組み合わせて使われるのがbreakという文です。
break(破る)ということでループを抜けます。
具体例で見てみましょう。1から順に2、3、4…と整数値を足していって合計値が1000を超えるときの合計を求めます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package chap05; public class Example05 { public static void main(String[] args) { int i = 0, sum = 0; while (true) { i++; sum += i; System.out.println("I added up to " + i + " and the total was " + sum); if (sum > 1000) { break; } } System.out.println("When I added up to " + i + " , it exceeded 1000 and the total at that time was " + sum); } } |
<結果>
I added up to 1 and the total was 1 (中略) When I added up to 45 , it exceeded 1000 and the total at that time was 1035 |
このように、「繰り返しの中に(if+break)」という形は頻繫に登場しますので覚えてください。
※もちろん、この例では、以下のようにした方がコードが短いですが、あくまで説明のためのプログラムです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package chap05; public class Example06 { public static void main(String[] args) { int i = 0, sum = 0; while (sum < 1000) { i++; sum += i; System.out.println("I added up to " + i + " and the total was " + sum); } System.out.println("When I added up to " + i + " , it exceeded 1000 and the total at that time was " + sum); } } |
<結果>
(中略) |
ところで、Example05の(sum > 1000)というのは終了の条件です。
一方、Example06の(sum <= 1000)といのは継続の条件です。
終了条件を継続条件に変えるときは不等号をひっくり返して=がなければ足し、あれば無くします。
つまり、
!(sum > 1000) = (sum <= 1000)
!(sum <= 1000) = (sum > 1000)
という論理になります。
continueはブロックないの残りの文をスキップします。
具体例で見てみましょう。1から順に3、5と奇数を足していって合計値が1000を超えるときの合計を求めます。
今回はあえてfor文を使ってみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package chap05; public class Example07 { public static void main(String[] args) { int i = 0, sum = 0; for (i = 1; sum < 1000; i++) { if (i % 2 == 0) { continue; } sum += i; System.out.println(i + "を加算して合計は" + sum); } System.out.println(i + "までの奇数を加えたら1000を超えてその時の合計は" + sum); } } |
途中経過を表示しながら、最後は、「64までの奇数を加えたら1000を超えてその時の合計は1024」となりました。
4.ループのネスト
ループ処理の中にループ処理を入れることがあります。ループのネスト、または入れ子処理といいます。
例えば、九九を表示することを考えてみます。
1の段は、掛けられる数(1)を固定してその数に1~9までの数を繰り返し掛けます。
2の段は、掛けられる数を1増やして(2になる)その数に1~9までの数を繰り返し掛けます。
以降同様にかけられる数は9まで繰り返し増やして処理を継続します。
つまり、繰り返しの中に繰り返しがあります。
Javaのコードでは例えば、こうなります。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package chap05; public class Example08 { public static void main(String[] args) { for (int i = 1; i <= 9; i++) { for (int j = 1; j <= 9; j++) { System.out.print(i + "×" + j + "=" + i * j + "\t"); //最後のタブは見やすさのため } System.out.println(""); //改行のため } } } |
5.do while文
最後にwhile文やfor文ほど使用頻度は高くありませんが、もう一つのループ処理の記述方法であるdo while文を簡単に見ておきましょう。
do while文の構文
do {
文;
} while(継続条件式);
1.まず無条件に1回、文を実行します。
2.継続条件式がtrueなら1に戻り、falseならルールを抜けます。
具体例です。
1 2 3 4 5 6 7 8 9 10 11 12 |
package chap05; public class Example09 { public static void main(String[] args) { int i = 0; do { System.out.println(i); i++; } while (i < 6); } } |
0,1,2,3,4,5と6つの数字を表示しました。
do while文の条件式の後には、文末ですのでセミコロンが必要です。
しかし、while文の()の後にセミコロンをつけてしまうと空分だと解釈されて、何も処理されなくなってしまいます。
※もっともIDEを使っていればミスを指摘してくれますが。
初学者が犯しやすいミスなので、気をつけてください
ここまで理解できたら、まとめとして演習問題にチャレンジしましょう。
今回はJavaの繰り返し処理について見てきました。
次回は、この繰り返し処理と親和性の高い配列の作成と使用を学んで変数の名前付け問題から解放されましょう。
JavaSE8の解説に戻る