6.ぐるぐる回る
~繰り返し~

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

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の値
111回目2
222回目3
333回目4
44×


 最初に変数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の値
101回目1
212回目2
323回目3
43×


カウンタを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
1100止めてぇ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の値
10+3→3123/10→123*10→30
230+2→3212/10→132*10→320
3320+1→3211/10→0


 do while文にしたのは、xの最初の値が一桁の場合を考えてです。xが5の場合の表を作ってみましょう。
繰り返し回数①後のanswerの値②後のxの値③後のanswerの値
10+5→55/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);
 }
}