breakとcontinue

ループの途中で進路を変える

ここまでのループは、条件が偽になるまで最後まで回りきる形でした。実際の集計では、そうもいかない事情が出てきます。欠席した学生は平均に入れたくありませんし、入力の終わりの合図が来たらその場でやめたくなります。

この 2 つを引き受けるのが breakcontinue です。名前は似ていますが、やることはまったく違います。

  • breakループそのものを終わらせる。波カッコの外に出て、続きの処理へ進みます
  • continueその回だけを飛ばす。中身の残りを実行せず、次の回に進みます
for (i = 1; i <= 10; i++) { scanf("%d", &score); if (score == -1) { continue; /* 欠席なので集計しない */ } if (score < 0) { break; /* 終わりの合図なのでやめる */ } total += score; }

continue が飛ばすのはどこまでか

continue を実行すると、そこから下の中身はすべて飛ばされ、ループの次の回へ移ります。for なら更新の i++ はきちんと実行されるので、回数が狂うことはありません。

気をつけたいのは while との組み合わせです。while の中身の最後で次の入力を読んでいる場合、continue はその scanf も飛ばしてしまいます。条件に使う変数が更新されないまま次の回に入るので、そのまま無限ループになります。continue を使うときは、条件を進める処理より に置いてあるかを必ず確かめてください。

break が抜けるのは1枚だけ

break が終わらせるのは、いま自分が入っている いちばん内側のループ 1 つだけ です。第3章の switch でも break を使いましたが、あれも同じで、自分を囲むいちばん近い switch を抜けています。次回学ぶ二重ループの内側で break を書いても、外側のループは回り続けます。

使いすぎない

break も continue も、読み手にとっては「ここで流れが飛ぶ」という負担です。条件式を書き直すだけで済むなら、そのほうが読みやすくなります。目安として、continue は「この回は対象外」とはっきり言えるとき、break は「もう続ける意味がない」ときに限ると、意図が伝わるコードになります。

/* continue を使わない書き方 */ if (score >= 0) { total += score; } /* continue を使う書き方 */ if (score < 0) { continue; } total += score;

この程度の短さなら、上のように if で囲むほうが素直です。continue が効いてくるのは、対象外の条件が何種類もあって、それを最初にまとめて振るい落としたいときです。先に例外を片付けてしまえば、そこから下は「まともなデータだけが来る」と思って読めるので、右へ右へと深くなる入れ子を防げます。

なお breakcontinue は、いま実行中のループにだけ効きます。関数の途中で処理を打ち切る return とは別ものです。関数は次章で学びますが、break を書けば関数が終わるわけではない、という点だけ先に押さえておいてください。

では、欠席者を飛ばしながら受験者の点数だけを集計してみましょう。

要件

  1. for で最大10回まで読み込む
  2. -1 が来たら「2人目 欠席」の形で表示し、集計には入れない
  3. -1 以外の負の数が来たら、その場で読み込みをやめる
  4. 最後に「受験者は3人、合計は240点です」の形で表示する

入出力例

main(80, -1, 90, 70, -9) → "2人目 欠席 受験者は3人、合計は240点です" main(-1, -1, -9) → "1人目 欠席 2人目 欠席 受験者は0人、合計は0点です"

ヒント

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

メモ

breakとcontinue

⌘S で保存