break・continueとラベルのコードトレース
検索の打切りと対象外データの除外をコードで比較します。二重ループでも、抜ける反復と継続する反復を正確に指定して出力を予測します。 Silverではさらにラベルで外側の反復やブロックを指定する場合を扱います。
この単元で学ぶこと
- breakとcontinueの移動先を区別する
- forの更新とwhileの条件への移動を追跡する
- 入れ子の最も内側の反復を識別する
- ラベル付きbreakとcontinueの合法性・対象を判定する
本文解説
入力による打切り int[] a={4,0,7}; int s=0; for(int x:a){if(x==0)break;s+=x;}は4です。区切り値0以後を集計しない設計です。0が先頭なら0、存在しなければ全要素の合計となります。
除外と継続 同じ例のbreakをcontinueへ変えると11です。0を加算しないだけで、後ろの7は読むためです。打切り条件なのか、除外条件なのかを仕様の文章で確認します。
分岐前の加算 for(int i=1;i<=4;i++){s+=i;if(i==2)break;}ならsは3です。判定より前に2を加算しています。文の順を逆にすると1になります。ソースを読み替えるときに順序まで変えないようにします。
continueと表示位置 for(int i=0;i<3;i++){System.out.print(i);if(i==1)continue;System.out.print("X");}は0X12Xです。1は先に表示されますが、その回のXは飛ばします。本体全体がなかったことになるわけではありません。
ラベルで対象を指定 outer: for(int i=0;i<3;i++){for(int j=0;j<3;j++){if(j==1)break outer;System.out.print(i);}}は0です。ラベルouterは外側forに付いています。break outerは内側だけでなく外側からも抜け、外側forの直後へ移ります。ラベルは変数ではなく、対象の文を識別する名前です。
外側を継続 同じ二重forでbreak outerをcontinue outerへ変えると000ではなく012です。各iでj=0を一回表示し、j=1で外側の更新i++へ進みます。内側の残りと外側本体の残りを飛ばしますが、外側forの更新は実行します。
ラベルの使える対象 exit: {System.out.print("A");if(args.length==0)break exit;System.out.print("B");}のようにラベル付きブロックをbreakで抜けることもできます。一方continueの対象ラベルは反復文に付いている必要があり、単なるブロックのラベルへのcontinueはコンパイルエラーです。存在しないラベル、囲んでいない文へのラベルも使えません。
ラベルの検証 ラベルなし、break outer、continue outerを同じ小さな二重ループで比較します。内側の表示、外側本体の末尾、外側の更新を別々に追います。対象を飛び越えて任意の位置へ移るgotoではありません。可読性のため、入れ子を減らす設計とも比較します。
図解
重要ポイント
- breakは対象のループ等を終了する。
- continueはその回の残りを飛ばす。
- forのcontinueは更新欄を実行してから条件へ進む。
- ラベルなしでは最も内側の対象へ作用する。
- continueのラベルは反復文を指す必要がある。
間違えやすい点
- breakでメソッド全体が必ず終わると考えない。
- continueが更新を常に省略すると考えない。
- whileの更新を飛ばす経路を作らない。
用語解説
- break
- 対象の反復やswitch等を抜ける文。
- continue
- 対象の反復の次の回へ進む文。
- 入れ子
- ある制御構造の本体に別の制御構造を置くこと。
- 更新欄
- 基本forの第三部分。次の条件判定より前に実行する。
- ラベル
- 対象となる文の直前に名前とコロンを付けた識別子。
参考資料
教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。
確認問題の出題・採点や学習履歴の保存にはログインが必要です。