ネストした制御構文のコードトレース
入れ子の制御構文は、外側の一回の処理の中で内側の分岐や反復を実行する構造です。外側と内側の変数を別に追い、内側の初期化、合計回数、break・continueの対象を読み解きます。
この単元で学ぶこと
- 入れ子ループの回数と順番を求める
- 内側変数の初期化位置とスコープを判断する
- 入れ子内の分岐と制御移動を追う
本文解説
三角形の回数を追う 外側i=1,2,3で内側j=1からiまで動かすと表示回数は1+2+3です。固定の二重ループと違い毎回の長さが増えます。各行末へ区切りを置けば1行、2行、3行の文字数を目で確認できます。
内側の値を合計する i=1..3、j=1..iでsum+=jなら各外側の加算は1、1+2、1+2+3です。総和は10で、単に内側回数6とは違います。count++なのかsum+=jなのかにより求める量を変えます。
外側の値を合計する 同じ範囲でsum+=iなら1を一回、2を二回、3を三回足すため14です。内側と外側の変数を取り違えると10と誤答します。各反復の(i,j)と加算対象を並べると確かめられます。
条件による途中終了 内側でj==iならbreakすると、毎回j=0からi-1までだけ処理します。breakより前に加算するか後に加算するかで対角の値が含まれるか変わります。各行を別の小さなループとして追います。
外側continueと更新 continue outerを実行した場合、外側forの更新式は実行されます。外側本体末尾の加算は省略されます。どの変数がforの更新欄にあり、どの加算が本体末尾にあるかを区別します。
外へ置く内側変数 int j=0を外側ループの外へ置く場合でも、各外側の先頭でj=0とすれば再び内側を完走します。初期化の宣言場所と再代入の位置は別です。再代入を忘れたコードとの違いを終了値から確認します。
ネストしたifの対応 ループ内にif(a)if(b)...else...を置いた場合もelseは内側へ結び付きます。外側ifがfalseならその内側elseも実行されません。波括弧で構造を書き直してから各ループ値を代入すると誤読を避けられます。
短絡と境界確認 配列を走査する内側条件でj<a.length&&a[j]!=0のように書けば、範囲検査が先に働きます。a[j]!=0&&j<a.lengthでは配列参照が先です。入れ子の回数だけでなく、条件式内部の左からの評価と短絡も一緒に追います。
図解
重要ポイント
- 外側の反復ごとに内側forの初期化が行われる。
- 回数が固定なら外側回数×内側回数になる。
- 内側の上限が外側変数に依存すると単純な積にならない。
- breakやcontinueの対象は最も近い対応構文か指定ラベル。
間違えやすい点
- 外側が一回進むたび内側も一回だけ進むと思わない。
- 内側カウンタを外へ置いて再初期化し忘れない。
- 入れ子で同名ローカル変数を重複宣言しない。
用語解説
- 入れ子
- ある構文の内部へ別の構文を配置する構造。
- 外側ループ
- 内側ループ全体を本体の一部に持つ反復。
- 反復回数の総和
- 外側の各回で実行した内側回数を足した数。
関連教材
参考資料
教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。
確認問題の出題・採点や学習履歴の保存にはログインが必要です。