人間はコンピュータと違って、繰り返しにはあきてしまい、面倒くさくなってしまう。プログラムを作っていて「ああまた同じようなことやってるなぁ」と思ったとき、面倒くさがり屋はどうにかまとめられないかなどと考え、そこでいいアイデアが浮かんだりする。働き者はそれがんばるぞと同じことをコツコツやってしまう。面倒くさがり屋万歳!
3回回ってワン!
繰り返し処理の記述はは最重要常識。でもここでは割とあっさり終わらせてしまいます。なぜならこれから配列だ文字列だとたびたび必要になるので、その度に理解を深めていってもらおうと言う魂胆だからです。
あらかじめ繰り返しの回数が決まっているときはfor文がよいです。構文は次のようになります。
for(文; 条件; 式) {
文の集まり
}
まず文が実行され、後は条件が成立している間ずーっと、文の集まりと式の部分を繰り返し実行します。つまりこういう順序。
文→条件チェック→文の集まり→式→条件チェック→文の集まり→式→条件チェック→…
条件チェックで不成立時にこの繰り返しは終了します。もちろんこの形であれば、回数チェックにこだわらずどんな繰り返し処理にも使えます。
3回回ってワン!と言ってみましょう。(意味ないですね。もうちょっと我慢我慢)
int i; for (i = 1; i <= 3; i++) { System.out.println(i + "回目"); } System.out.println("ワン!");
こんな出力です。
1回目
2回目
3回目
ワン!
では変数iの変化を中心に表にしてみましょう。
繰り返し回数 | iの値 | i<=3 | 出力内容 | i++後のiの値 |
1 | 1 | 〇 | 1回目 | 2 |
2 | 2 | 〇 | 2回目 | 3 |
3 | 3 | 〇 | 3回目 | 4 |
4 | 4 | × |
最初に変数iに1が代入されます。次にi<=3がチェックされ、1回目と出力されます。最後にi++でiの値が2になり、2回目の繰り返しに突入です。iは2なのでi<=3は成立、2回目と出力され、iは3になります。3回目の繰り返しではiは3ですが、最後で4になります。4回目の繰り返しに入ったところで、i<=3のチェックに引っかかり、このwhile文の次の文に実行が移ります...とこの表は読んでください。
実はこのように回数がわかっていて繰り返す場合、カウンターの役目をするiは0からはじめるのが普通です。上を書き換えてみましょう。出力結果はまったく同じになります。
for (i = 0; i < 3; i++) { System.out.println((i + 1) + "回目"); } System.out.println("ワン!");
どこが変わったかわかりますか。比べてみてください。これも表にしてみましょう。
繰り返し回数 | iの値 | i<3 | 出力内容 | i++後のiの値 |
1 | 0 | 〇 | 1回目 | 1 |
2 | 1 | 〇 | 2回目 | 2 |
3 | 2 | 〇 | 3回目 | 3 |
4 | 3 | × |
カウンタを0からスタートさせるこの書き方には慣れておきましょう。特にあとでやる配列ではたくさん出てきます。
誰か止めてぇ
繰り返す回数がわからない場合、while文を使います。構文はこうです。
while(条件) {
文の集まり
}
条件が成立している間は文の集まりを繰り返します。条件のチェック→文の集まり→条件のチェック→文の集まり→...と繰り返されます。きちんと条件を指定してないと恐ろしいことが起こります。
int a = 100; while (a <= 100) { System.out.println("止めてぇ"); a -= 2; }
変数aの値は100からスタートしてどんどん減っているのに、条件がa<=100ではいつまでたっても不成立にはなりません。つまり「止めてぇ」がジャカジャカジャカジャカ出てしまうのです。ではこれはどうでしょう。
int a = 100; while (a < 100) { System.out.println("止めてぇ"); a += 2; }
条件の部分の=をはずしました。もうお分かりですか?そう、1回も「止めてぇ」は出てきません。aは100なので、最初のa<100のチェックに引っかかり、何もせずwhile文の次の文に移るのです。門前払いですね。1回ぐらいいいじゃないか、と言う方は次を読んでください。
1回ぐらいいいじゃないか
最初の条件チェックをしない文もあります。do while文です。構文はこうです。
do {
文の集まり
} while(条件);
最後のセミコロンを忘れずに。この文は正直余り使われません。while文とほとんど同じですが、最初の条件チェックがありません。よって最低1回は文の集まりが実行されます。
int a = 100; do { System.out.println("止めてぇ"); a += 2; } while (a < 100);
めでたく1回は「止めてぇ」が出てきます。念のため表を入れておきます。1回で終わりなのでちょっと寂しい。
繰り返し回数 | aの値 | 出力内容 | a+=2後のaの値 | a<100 |
1 | 100 | 止めてぇ | 102 | × |
モウヤァメタ!
繰り返しの途中で「もうやぁめた!」と飛び出すことができます。switch文でも出てきたbreak文を使います。
変数xに与えられた0以上の整数値を逆さにしてanswerに求める処理を考えてみましょう。たとえば123であれば321、87であれば78、5であれば5という具合です。
int x = 123; int answer = 0; do { answer += x % 10; //① x /= 10; //② if (x == 0) { break; } answer *= 10; //③ } while (x != 0); System.out.println(answer);
xの値を10で割りながら、下一桁を取り出していきます。上では3,2,1の順で取り出せます。これをanswerに足していくのですが、足すたびに10掛けて位をあげてやります。3,32,321という感じですね。ここで10で割っていったxの値が0になったら終わりにしたいので、breakで飛び出しています。飛び出さないと③をやってしまい、10倍の答えになってしまうからです。表にしてみました。
繰り返し回数 | ①後のanswerの値 | ②後のxの値 | ③後のanswerの値 |
1 | 0+3→3 | 123/10→12 | 3*10→30 |
2 | 30+2→32 | 12/10→1 | 32*10→320 |
3 | 320+1→321 | 1/10→0 |
do while文にしたのは、xの最初の値が一桁の場合を考えてです。xが5の場合の表を作ってみましょう。
繰り返し回数 | ①後のanswerの値 | ②後のxの値 | ③後のanswerの値 |
1 | 0+5→5 | 5/10→0 |
本当はbreakがあるので、最後のx!=0のチェックは不要です。そこでこんな形でも書けます。
int x = 123; int answer = 0; while (true) { answer += x % 10; x /= 10; if (x == 0) { break; } answer *= 10; }
do while文がwhile文になりました。条件がtrueなので無限に繰り返されることになります。出口はbreak文のところのみということになります。
スキップスキップランランラン
繰り返している途中で処理の後半をスキップする方法です。continue文を使いますが、普通余り使われません。さらっと見ておきましょう。
1から100までの数で、3でも7でも割り切れないものを出力する処理です。
int k; for (k = 1; k <= 100; k++) { if (k % 3 == 0 || k % 7 == 0) { continue; } System.out.println(k); }
continueが実行されると、その繰り返し処理の残りの部分、ここでは出力処理がスキップされ、k++に制御が移ります。確かに3でも7でも割り切れないもののみ出力されますが、こんな風に書き換えればcontinueも不要になります。
int k; for (k = 1; k <= 100; k++) { if (k % 3 != 0 && k % 7 != 0) { System.out.println(k); } }