while

回数が決まっていない繰り返し

前回の for は「5 回」「40 回」のように回数が先に決まっているときの道具でした。ところが成績管理では、何件入力されるか実行するまで分からない、という場面のほうが多くなります。こういうときに使うのが while です。

while (条件) { 繰り返したい処理 }

読み方はそのまま「条件が真であるあいだ、中身を繰り返す」です。for の丸カッコから初期化と更新を取り除き、条件だけを残した形だと考えると分かりやすくなります。

終わらせ方は自分で用意する

for は i++ が自動で条件に近づけてくれましたが、while にはそれがありません。中身のどこかで条件を偽に近づける処理を 自分で書かないと、永久に止まりません。これが無限ループです。

int score; int total = 0; scanf("%d", &score); while (score >= 0) { total += score; scanf("%d", &score); }

この形は「番兵」と呼ばれる定番です。負の数が来たら終わり、という合図の値をあらかじめ決めておき、それが来るまで読み続けます。点数は 0 以上しかありえないので、負の数を終了の合図に使えます。

注目してほしいのは scanf2 か所 にあることです。ループに入る前に 1 件目を読んでおき、中身の最後で次の 1 件を読みます。こうしないと、条件を確かめる時点で score にまだ何も入っていない、という状態になります。初期化していない変数の中身は決まっていないので、そのまま条件に使うと結果が予測できません。

1回も回らないことがある

while も for と同じく、条件を確かめるのは中身の です。1 件目にいきなり負の数が来たら、中身は 1 回も実行されません。件数が 0 件でも合計が 0 と正しく出るように、totalcount はループの前に 0 で初期化しておきます。

無限ループを作ってしまったときは、total += score; は書いたのに 2 つ目の scanf を忘れた、というのが定番の原因です。条件に出てくる変数が、中身のどこで変わるのかを指で追って確かめてください。

for と while は書き換えられる

じつは for で書けるものは while でも書けます。for (i = 1; i <= 5; i++) は、int i = 1; をループの前に出し、while (i <= 5) と書き、中身の最後に i++; を置けば、まったく同じ動きになります。逆に while で書いたものを for に直すこともできます。

どちらを使うかは、動きの違いではなく 何が主役か で決めます。回数が主役なら for、条件が主役なら while です。初期化と更新が丸カッコの中にまとまっている for は、回数を数える意図がひと目で伝わります。一方 while は、終わる条件だけを目立たせたいときに読みやすくなります。同じ動きをする書き方が複数あるとき、意図がいちばん伝わるものを選ぶ、というのはこの先ずっと付いてくる判断です。

では、負の点数が来るまで点数を読み続けて、件数と合計を出してみましょう。

要件

  1. 点数を読むたびに「1件目 80点」の形で表示する
  2. 負の数が来たら読み込みをやめ、「入力終了」と表示する
  3. 最後に「3件の合計は240点です」の形で件数と合計を表示する
  4. 1件も入力されなかった場合も 0件 0点 と正しく表示する

入出力例

main(80, 90, 70, -1) → "1件目 802件目 903件目 70入力終了 3件の合計は240点です" main(-1) → "入力終了 0件の合計は0点です"

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.c
学習モード

メモ

while

⌘S で保存