do-while
先に1回やってから考える
前回の while は、中身に入る前に条件を確かめました。だから条件が最初から偽なら 1 回も動きません。ところが世の中には「とりあえず 1 回はやってみて、その結果を見てから続けるか決めたい」処理があります。メニューの表示と入力がその代表です。
メニューを出す前に「もう一度出すべきか」を判断することはできません。まだ何も選ばれていないからです。こういうときに使うのが do-while です。
do {
繰り返したい処理
} while (条件);中身を先に 1 回実行し、そのあとで条件を確かめます。真ならもう一度中身に戻り、偽ならそこで終わります。つまり 中身は最低 1 回は必ず動く のが while との唯一にして最大の違いです。
末尾のセミコロンを忘れない
} while (条件); の最後にはセミコロンが要ります。while 単体のときは while (条件) { } で、閉じ波カッコのうしろにセミコロンを書きません。do-while だけは文全体がここで終わるので、セミコロンで締めます。これを忘れると、次の行が while の中身と解釈されて、原因の分かりにくいコンパイルエラーになります。
入力のやり直しに向いている
int choice;
do {
printf("番号を選んでください\n");
scanf("%d", &choice);
} while (choice < 1 || choice > 3);この形は、正しい値が来るまで聞き直す定番です。条件の書き方に注意してください。while の条件は 繰り返しを続ける条件 なので、ここに書くのは「正しい値」ではなく「やり直したい値」です。1 から 3 が正解なら、続ける条件はその否定である choice < 1 || choice > 3 になります。第3章で学んだ論理演算子がここで効いてきます。
また、while のときは scanf を 2 か所に書く必要がありましたが、do-while なら中身の中に 1 回書くだけで済みます。読んでから判定する、という順番が言語の形とそのまま一致するからです。
どちらを使うか
迷ったら、中身を 0 回で終わらせたいことがあるか で決めます。0 件の入力もありうるなら while、必ず 1 回は見せたいメニューや、少なくとも 1 回は聞きたい入力なら do-while です。
実際のところ、C のコードで do-while が出てくる場面は while や for より少なめです。それでも覚えておく価値があるのは、入力のやり直しという頻出の形に、これがぴったり当てはまるからです。while で同じことをしようとすると、ループの前に 1 回目の表示と入力を書き、ループの中にもう一度同じ表示と入力を書くことになります。前回の番兵の例で scanf が 2 か所に必要だったのと同じ事情です。同じコードが 2 か所にあると、片方だけ直して食い違う、という事故が起きます。do-while はその重複をまるごと消してくれます。
もうひとつ、繰り返しの回数を数えたいなら do-while は向きません。最低 1 回動くという性質が、0 件のときの結果を狂わせるからです。件数を数える処理は while か for に任せてください。
では、成績管理CLI のメニューを、正しい番号が選ばれるまで出し続けてみましょう。
要件
- メニューは「1 点数を入力」「2 平均を見る」「3 終了」の3行と、「番号を選んでください」の1行
- 1 から 3 以外が入力されたら、メニューをもう一度最初から表示する
- 正しい番号が来たら「2番が選ばれました」の形で表示して終わる
- do-while を使い、メニューは必ず1回は表示されるようにする
入出力例
main(2) → "1 点数を入力
2 平均を見る
3 終了
番号を選んでください
2番が選ばれました"
main(9, 0, 1) → "1 点数を入力
2 平均を見る
3 終了
番号を選んでください
1 点数を入力
2 平均を見る
3 終了
番号を選んでください
1 点数を入力
2 平均を見る
3 終了
番号を選んでください
1番が選ばれました"