人間はコンピュータと違って、繰り返しにはあきてしまい、面倒くさくなってしまう。
プログラムを作っていて「ああまた同じようなことやってるなぁ」と思ったとき、
面倒くさがり屋はどうにかまとめられないかなどと考え、そこでいいアイデアが浮かんだりする。
働き者はそれがんばるぞと同じことをコツコツやってしまう。面倒くさがり屋万歳!
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);
}
}