1次元・多次元配列のコードトレース

行ごとに異なる件数の点数データを集計します。外側の配列、各行、各要素を別の箱として描き、参照をコピーした後にどの値が変わるかを予測します。各コードは正しいmain内で実行するものとします。

この単元で学ぶこと

  • 配列の宣言・生成・初期値を区別できる
  • 多次元配列の外側と内側のlengthを判断できる
  • 参照共有・null・範囲外をコードから識別できる

本文解説

点数データの構造 int[][] scores={{2,4},{6}};では行は二つ、最初の行に2と4、次の行に6があります。scores.lengthは2、scores[0].lengthは2、scores[1].lengthは1です。合計の要素数3を外側のlengthと混同しないでください。

二重ループのトレース int total=0; for(int i=0;i<scores.length;i++){for(int j=0;j<scores[i].length;j++){total+=scores[i][j];}}は、添字(0,0)、(0,1)、(1,0)の順に2、4、6を加え、totalは2、6、12と変化します。i=1でj=1まで進めば範囲外なので、行ごとのlengthが重要です。

外側だけの配列を補う int[][] pending=new int[2][]; pending[1]=new int[3];ならpending[0]はnull、pending[1]は0を三つ持ちます。pending[1][2]は0ですが、pending[0].lengthは例外です。未設定の行を処理対象から除くならnullを確認し、必要な行なら先に生成します。

参照のコピーと差替え int[] a={2,4}; int[] b=a; b[0]=8;ならa[0]も8です。その後b=new int[]{10};としてもaは元の二要素配列を指すのでa[0]は8のままです。要素の変更は共有先へ見えますが、変数bの代入先変更は変数aを変更しません。

外側をcloneする int[][] original={{1,2},{3}}; int[][] copy=original.clone(); copy[0][0]=9;とするとoriginal[0][0]も9です。続けてcopy[1]=new int[]{7};としてもoriginal[1][0]は3です。最初は共有した行の要素を変更し、次は複製済みの外側の一要素だけを差し替えているためです。

各行を独立させる 生成済みでnullを含まない行なら、int[][] copy=new int[original.length][]; for(int i=0;i<original.length;i++){copy[i]=original[i].clone();}のように各行も複製できます。intの行要素であれば、この後copy[0][0]を変更してもoriginalの要素は変わりません。参照型要素をさらに含む場合は、その参照先の共有も別に考えます。

拡張forとfinalの注意 for(int n:a){n++;}は各要素の値を受け取ったローカル変数nを増やすだけで、aの要素を更新しません。添字を使うa[i]++なら要素を更新します。final int[] a={1};でもa[0]=2;は可能です。finalは変数aの再代入を禁止し、配列要素を自動で不変にはしません。

実行検証 各例を別々にコンパイルし、外側と行のlength、変更前後の特定要素、合計値をprintlnで出します。例外を確認する例は他の成功例と分け、null参照なのか生成済み配列の範囲外なのかを記録します。配列そのものをprintすると要素一覧の形式にはならないため、ここでは確かめたい要素を明示して表示します。

図解

二次元のcloneは外側だけ
共有行の要素変更と、外側の参照の差替えは影響範囲が違う。

重要ポイント

  • 配列の長さと最後の有効添字は一つ違う。
  • 二次元配列は配列への参照を並べた配列。
  • 行の長さは行ごとに調べる。
  • 参照の代入と要素の複製は異なる。

間違えやすい点

  • new int[2][]で内側も生成済みと思わない。
  • 二次元配列が常に長方形だと思わない。
  • 二次元のcloneで全ての行も独立すると思わない。

用語解説

添字
配列要素を選ぶ0始まりの整数位置。
length
生成済み配列の要素数を表すフィールド。
参照
配列などのオブジェクトを指す値。
ジャグ配列
行ごとの長さが異なる配列の配列。
浅いコピー
外側の要素をコピーしても参照先の内部オブジェクトは共有されるコピー。

参考資料

教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。

確認問題の出題・採点や学習履歴の保存にはログインが必要です。