講義メモ ・p.137「2次元配列」から p.137 2次元配列 ・2つの添字を用いる配列を2次元配列という ・C#には2種類の2次元配列があり、通常型の2次元配列は●×■の積の要素を持つ構造。 ・例えば、2クラスに各5人の生徒の成績なら、2×5=10要素の2次元配列になる ・宣言の書式: 型[,] 配列名; ・生成の書式: 配列名 = new 型[要素数①, 要素数②]; ・1次元配列と同様に、宣言と生成はまとめて行える  例: int[,] point = new int[2, 5]; //2×5=10要素の2次元配列の宣言と生成 ・1次元配列と同様に、初期化も可能で、2重繰返し構造を{{},…}で示す  例: int[,] point = {{10,20,30,40,50}, {11,22,33,44,55}}; //2×5=10要素の2次元配列の宣言と生成 ・要素には「配列名[添字①, 添字②]」でアクセスできる アレンジ演習:p.138 array01.cs ・forのカウンタ用変数をfor文の中で宣言しよう ・2次元配列の要素に値を代入する処理を表示とは別の2重繰り返しで行うようにしよう 作成例その1 //アレンジ演習:p.138 array01.cs using System; class array01 { public static void Main() { int[,] MyArray = new int[2,3]; //MyArray[0, 0] = 1; //MyArray[0, 1] = 2; //MyArray[0, 2] = 3; //MyArray[1, 0] = 4; //MyArray[1, 1] = 5; //MyArray[1, 2] = 6; for (int i = 0; i < 2; i++) { //【以下追加】 for (int j = 0; j < 3; j++) { MyArray[i, j] = i * 3 + j + 1; } } for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { Console.WriteLine("MyArray[{0}, {1}] = {2}", i, j, MyArray[i, j]); } } } } 作成例その2 //アレンジ演習:p.138 array01.cs using System; class array01 { public static void Main() { int[,] MyArray = new int[2,3]; int s = 0; //【追加】 for (int i = 0; i < 2; i++) { //【以下追加】 for (int j = 0; j < 3; j++) { MyArray[i, j] = ++s; //1,2,3,4,…を順に代入 } } for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { Console.WriteLine("MyArray[{0}, {1}] = {2}", i, j, MyArray[i, j]); } } } } p.139 12行目正誤 ・誤: 全部の要素の初期値を書く必要はありません。初期値が指定されていない要素は0で初期化されます ・正: 指定された要素数と、初期値の数が一致しないとエラーになります(p.135参照) アレンジ演習:p.139 array02.cs ・2次元配列の初期値を「{{0,1,2,3},{0,4,5,6}}」に変更しても動作することを確認しよう 作成例 //アレンジ演習:p.139 array02.cs using System; class array02 { public static void Main() { int[,] MyArray = {{0, 1, 2, 3}, {0, 4, 5, 6}}; //【変更】配列の初期化 for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { Console.WriteLine("MyArray[{0}, {1}] = {2}", i, j, MyArray[i, j]); //6要素のみ表示 } } } } アレンジ演習:p.140 array03.cs ・現状では何も入力しないでEnterを押すと異常終了してしまう ・2箇所ある「if (●.Length >= 2)」を「if (●.Length != 1)」に書き換えて解決しよう 作成例 //アレンジ演習:p.140 array03.cs using System; class array03 { public static void Main() { string[,] Name = new string[2, 5] { {"田中六郎", "吉田一郎", "太田太郎", "粂井康孝", "岡田三郎"}, {"横田芳子", "池田和子", "目黒貴和子", "武田信子", "園田淳子"} }; int MyClass, No; string strClass, strNo; while (true) { //無限ループ Console.Write("クラスは---"); strClass = Console.ReadLine(); if (strClass.Length != 1) { //【変更】 Console.WriteLine("入力は1桁のみです"); continue; //以降をスキップして次の繰返しへ(つまり、やりなおし) } if (Char.IsNumber(strClass, 0) != true) { Console.WriteLine("数字を入力してください"); continue; //以降をスキップして次の繰返しへ(つまり、やりなおし) } MyClass = Int32.Parse(strClass); if (MyClass <= 0 || MyClass >= 3) { Console.WriteLine("クラスは1組か2組です"); continue; //以降をスキップして次の繰返しへ(つまり、やりなおし) } break; //全チェックOKなので繰返しを抜ける } while (true) { //無限ループ Console.Write("出席番号は---"); strNo = Console.ReadLine(); if (strClass.Length != 1) { //【変更】 Console.WriteLine("入力は1桁のみです"); continue; //以降をスキップして次の繰返しへ(つまり、やりなおし) } if (Char.IsNumber(strNo, 0) != true) { Console.WriteLine("数字を入力してください"); continue; //以降をスキップして次の繰返しへ(つまり、やりなおし) } No = Int32.Parse(strNo); if (No <= 0 || No >= 6) { Console.WriteLine("出席番号は1番から5番までです"); continue; //以降をスキップして次の繰返しへ(つまり、やりなおし) } break; //全チェックOKなので繰返しを抜ける } Console.WriteLine("{0}クラスの出席番号{1}番は{2}さんです", strClass, strNo, Name[MyClass - 1, No - 1]); } } p.142 3次元以上の配列 ・C#の配列では次元数の宣言はある ・ただし次元ごとの要素数の積で増えるので、メモリの占有などに注意すること ・たとえば、利用しない領域ができてしまう場合は、配列を分割して定義することなどを検討すると良い 以下は3次元の場合: ・宣言の書式: 型[,,] 配列名; ・生成の書式: 配列名 = new 型[要素数①, 要素数②, 要素数③]; ・宣言と生成の例: int[,,] point = new int[2, 5, 3]; //2×5×3=30要素の3次元配列の宣言と生成 ・初期化も可能で、3重繰返し構造を{{{},…}, …}で示す  例: int[,,] p = {{{1, 2, 3},{4, 5, 6}},{{1, 2, 3},{4, 5, 6}}}; //2×2×3=12要素の3次元配列の宣言と生成 ・要素には「配列名[添字①, 添字②, 添字③]」でアクセスできる  例: p[0, 0, 0] は 1、p[0, 0, 1] は 2、p[1, 1, 2] は 6 ・なお、配列の次元数はRankプロパティを用いて「配列名.Rank」で得られる ・また、配列の全要素数はLengthプロパティを用いて「配列名.Length」で得られる  ※ C#では、Lengthで通常の配列の次元ごとの要素数を得ることはできない アレンジ演習:p.143 Array4.cs ・全要素の合計値も表示しよう 作成例 //アレンジ演習:p.143 Array4.cs using System; class array04 { public static void Main() { int[,,] ar = new int[2, 2, 3] { { {0, 1, 2}, //順に[0,0,0][0,0,1][0,0,2] {3, 4, 5} }, //順に[0,1,0][0,1,1][0,1,2] { {6, 7, 8}, //順に[1,0,0][1,0,1][1,0,2] {9, 10, 11} } //順に[1,1,0][1,1,1][1,1,2] }; Console.WriteLine("配列の次元 = {0}", ar.Rank); //次元数を表示 Console.WriteLine("arの個数 = {0}", ar.Length); //要素数を表示 int sum = 0; //【追加】合計用 for (int i = 0; i < 2; i++) { //1番目の添字 for (int j = 0; j < 2; j++) { //2番目の添字 for (int k = 0; k < 3; k++) { //3番目の添字 Console.Write("{0}, ", ar[i, j, k]); //順に表示 sum += ar[i, j, k]; //【追加】合計に加算 } } } Console.WriteLine("合計:{0}", sum); //【変更】 } } p.144 ジャグ配列 ・多次元配列を「要素数の積」ではなく「配列の配列」で表すものがジャグ配列 ・型が同じであれば、要素数の異なる配列を含む多次元配列ができるので、メモリの利用効率が良い ・2次元のジャグ配列の場合、要素は配列名[添字①][添字②]と表す。 ・例えば、中学校の学年ごとのクラスの人数を表すとき、1年が2クラス、2年が3クラス、3年が1クラスなら:  1年 : n[0][0]、n[0][1]  2年 : n[1][0]、n[1][1]、n[1][2]  3年 : n[2][0] 以下は2次元のジャグ配列の場合: ・宣言の書式: 型[][] 配列名; ・外側の生成の書式: 配列名 = new 型[要素数][]; //2つめの要素数は自由なので指定不要 ・内側の生成の書式: 配列名[添字] = new 型[要素数]; //これを1つめの要素数の文、繰返す ・宣言と外側の生成の例: int[][] n = new int[3][]; //3つの配列による2次元のジャグ配列の宣言と生成 ・初期化は煩雑だが内側の配列に対して行うことで可能  例: int[][] n = new int[3] { new int[2]{15, 16}, new int[3]{17, 18, 19}, new int[1]{20} } ・なお、内側の配列に対しての代入が可能  例: n[0] = new int[2]{15, 16}; アレンジ演習:p.144 jagged01.cs ・全要素の合計値も表示しよう 作成例 //アレンジ演習:p.144 jagged01.cs using System; class jagged01 { public static void Main() { int[][] ar; //ジャグ配列の宣言 ar = new int[2][]; //外側[0],[1]の生成 ar[0] = new int[3]; //内側[0][0],[0][1],[0][2] の生成 ar[1] = new int[3]; //内側[1][0],[1][1],[1][2] の生成 for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { ar[i][j] = (i + 1) * (j + 1); //添字を用いて値(1,2,3,2,4,6)を得て順に格納 } } int sum = 0; //【追加】合計用 for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { Console.WriteLine("ar[{0}][{1}] = {2}", i, j, ar[i][j]); sum += ar[i][j]; } } Console.WriteLine("合計:{0}", sum); } } p.146 ジャグ配列(要素数) ・ジャグ配列のLengthプロパティは通常の配列とは仕様が異なる ・ジャグ配列名.Length:ジャグ配列に含まれる配列の数  例: int[][] ar = new int[3][]; であれば、ar.Lengthは3 ・ジャグ配列名[添字].Length:ジャグ配列名[添字]に含まれる要素の数 ・よって、ジャグ配列の全要素について繰返す場合、forの2重ループを下記のように用いると良い  for (int i = 0; i < ジャグ配列名.Length; i++) {   for (int j = 0; j < ジャグ配列名[i].Length; j++) { //内側の要素数だけ繰返す    繰返す処理   }  } アレンジ演習:p.146 jagged02.cs ・表示処理をforの2重ループで書き直そう 作成例 //アレンジ演習:p.146 jagged02.cs using System; class jagged02 { public static void Main() { string[][] name = new string[2][]; //ジャグ配列 name[0] = new string[2]{"田中", "工藤"}; name[1] = new string[3]{"吉田", "佐藤", "池田"}; for (int i = 0; i < name.Length; i++) { //含まれる全配列について繰返す for (int j = 0; j < name[i].Length; j++) { //配列[i]の全要素について繰返す Console.WriteLine(name[i][j]); } } } } p.147 暗黙の型指定がなされた配列 ・p.61で説明したvarキーワードを用いて、配列の初期化における型も暗黙の型指定が可能 ・例: string[] name = {"A", "B"}; ⇒ var name = new []{"A", "B"};  ※ 2次元配列やジャグ配列でも可能 ・なお、配列名.GetType()を実行すると「型情報[]」が返される  ※ 2次元配列だと「型情報[,]」が、ジャグ配列だと「型情報[][]」が返される アレンジ演習:p.147 var03.cs ・配列nameを[2, 2]の2次元配列にして動作を確認しよう ・また、配列fを[2][]のジャグ配列にして動作を確認しよう ※ 「int Main()」となっているが「void Main()」で良く「return 0;」も不要 作成例 //アレンジ演習:p.147 var03.cs using System; class var03 { public static void Main() { var name = new [,]{ {"太郎", "次郎" }, {"三郎", "四郎" } }; //2次元配列 for (var i = 0; i < name.Length; i++) { //全要素について繰返す Console.WriteLine(name[i / 2, i % 2]); //[0,0][0,1][1,0][1,1]の順に表示 } var f = new[] { new [] {0.5, 0.9 }, new [] {1.5, 2.3 } }; //ジャグ配列 for (var i = 0; i < f.Length; i++) { //全配列について繰返す for (var j = 0; j < f[i].Length; j++) { //各配列の全要素について繰返す Console.WriteLine(f[i][j]); } } Console.WriteLine("nameの型は{0}, fの型は{1}", name.GetType(), f.GetType()); } } p.148 1次元配列のソート ・C#が提供するArrayクラスのSortメソッドを用いると、1次元配列の昇順ソート(整列)が可能 ・書式: Array.Sort(1次元配列名) ・また、ArrayクラスのReverseメソッドを用いると、1次元配列の逆順化が可能 ・書式: Array.Reverse(1次元配列名) ・よって、上記を順に行うことで、降順ソートも可能 アレンジ演習:p.148 sort01.cs ・5人の名前を全て小文字にした要素を追加して10要素にし、どう整列されるか確認しよう  ⇒小文字と大文字は同じ順序だが、同じ字の小文字と大文字では小文字の方が前になる ・英記号「!,#,$,%,&」がどう整列されるか確認しよう  ⇒文字コード順になる(文字コードは順に 21,23,24,25,26) ・負の数を含む実数値の場合、どう整列されるか確認しよう  ⇒小さい(-∞に近い)ものからの順になる ・「ちぢっつづてで」のように小文字や濁点を含むひらがなの場合、どう整列されるか確認しよう  ⇒文字コード順になる(文字コードは順に 3061,3062,3063,3064,3065,3066,3067) 提出:アレンジ演習:p.148 sort01.cs(内容は自由) 次回予告:p.150「foreach文による反復処理」から