講義メモ つづき

p.164(戻り値のないメソッド、引数のないメソッド)

・戻り値のないメソッドでは、戻り値型にvoidを指定する
・この場合、returnは必須ではなくなるが、指定は可能
・returnを指定する事で、メソッドの途中で呼び出し側に戻ることができるので、効率が上がる
 ※ メソッドの出口が複数化するので、推奨されない場合もある
・引数のないメソッドでは、仮引数の記述は不要だが、定義および呼び出しでは「()」が必要

p.165 noreturnvalue.cs

//p.165 noreturnvalue.cs
using System;
class Kakeibo { //利用される家計簿クラス
    private int total = 0; //残高(直接操作されないようにprivateにする)
    public void nyukin(int en) { //入金(引数は入金額)メソッド:戻り値なし
        total += en; //入金額を残高に足しこむ
        Console.WriteLine("{0}円を入金しました", en);
        return; //なくても良い
    }
    public void shishutsu(int en) { //支出(引数は出金額)メソッド:戻り値なし
        if (total < en) { //残高を超えていたら
            Console.WriteLine("{0}円も支出できません", en);
            return; //なくても良い
        } else { //残高以下なら
            total -= en; //出金額を残高から差し引く
            Console.WriteLine("{0}円を支出しました", en);
            return; //なくても良い
        }
    }
    public void gettotal() { //残高の表示(引数なし)メソッド:戻り値なし
        if (total == 0) { //残高ゼロ?
            Console.WriteLine("残高はありません");
            return; //なくても良い
        } else {
            Console.WriteLine("残高は{0}円です", total);
            return; //なくても良い
        }
    }
}
class noreturnvalue {
    public static void Main() {
        Kakeibo k = new Kakeibo(); //家計簿クラスのインスタンスを生成
        k.gettotal();
        k.nyukin(1000);
        k.gettotal();
        k.nyukin(2000);
        k.gettotal();
        k.shishutsu(500);
        k.gettotal();
        k.shishutsu(10000);
        k.gettotal();
    }
}

アレンジ演習:p.165 noreturnvalue.cs

・各メソッドの最後のreturnは必要ないので削除しよう
・また、ifの最後のreturnがあれば、elseが不要になることを確認しよう

作成例

//アレンジ演習:p.165 noreturnvalue.cs
using System;
class Kakeibo { //利用される家計簿クラス
    private int total = 0; //残高(直接操作されないようにprivateにする)
    public void nyukin(int en) { //入金(引数は入金額)メソッド:戻り値なし
        total += en; //入金額を残高に足しこむ
        Console.WriteLine("{0}円を入金しました", en);
        //return; //なくても良い
    }
    public void shishutsu(int en) { //支出(引数は出金額)メソッド:戻り値なし
        if (total < en) { //残高を超えていたら
            Console.WriteLine("{0}円も支出できません", en);
            return; //メソッドの途中で戻る
        }
        total -= en; //出金額を残高から差し引く
        Console.WriteLine("{0}円を支出しました", en);
        //return; //なくても良い
    }
    public void gettotal() { //残高の表示(引数なし)メソッド:戻り値なし
        if (total == 0) { //残高ゼロ?
            Console.WriteLine("残高はありません");
            return;  //メソッドの途中で戻る
        }
        Console.WriteLine("残高は{0}円です", total);
        //return; //なくても良い
    }
}
class noreturnvalue {
    public static void Main() {
        Kakeibo k = new Kakeibo(); //家計簿クラスのインスタンスを生成
        k.gettotal();
        k.nyukin(1000);
        k.gettotal();
        k.nyukin(2000);
        k.gettotal();
        k.shishutsu(500);
        k.gettotal();
        k.shishutsu(10000);
        k.gettotal();
    }
}

p.166(カプセル化)

・このプログラムの「private int total = 0; //残高(直接操作されないようにprivateにする)」のように、
 データメンバを守ることをカプセル化という
・特に、データの特性により最大値、最小値が決まっている場合(負の数禁止も含む)や、直接操作されることによる危険性が
 ある場合はカプセル化が必要
・基本的には、データメンバは全てprivateにし、これを操作するメソッドをpublicにする
・このプログラムでは、totalの値が負の数にならないようにカプセル化している

p.167 コンストラクタ

・newによりインスタンスを生成すると、自動的に実行される特別なメソッドがあり、これをコンストラクタという。
・コンストラクタの有無は自由で、記述しないと自動的に中身のないコンストラクタが作られて動作する
・コンストラクタを記述する事で、インスタンスを生成するときに行いたい事を指定できる
・これは、主にデータメンバへの初期値の設定や、複雑なメソッドを持つクラスにおける開始処理などに用いる
 例: Monster rimuru = new Monster(100, 500); //コンストラクタにHPとMPを渡して初期値にしてもらう
・コンストラクタは特別なメソッドで名前がなくクラス名になり、戻り値はなく、必ずpublicとする。

p.167 construct01.cs

//p.167 construct01.cs
using System;
class MyClass { //部品クラス
    int x; //インスタンス変数
    public void showx() { //xの値を表示するメソッド
        Console.WriteLine("x = " + x);
    }
    // コンストラクタ クラスと同じ名前、戻り値なし
    public MyClass() {
        x = 10; //インスタンス変数の初期値を設定
        Console.WriteLine("xに10を代入しました"); //テスト用
    }
}
class construct01 { //実行用クラス
    public static void Main() { //実行用メソッド
        // newしたときにコンストラクタが呼ばれます
        MyClass mc = new MyClass();
        mc.showx();
    }
}

アレンジ演習:p.167 construct01.cs

・複数のオブジェクトを生成すると、その都度、コンストラクタが動作することを確認しよう

作成例

//アレンジ演習:p.167 construct01.cs
using System;
class MyClass { //部品クラス
    int x; //インスタンス変数
    public void showx() { //xの値を表示するメソッド
        Console.WriteLine("x = " + x);
    }
    // コンストラクタ クラスと同じ名前、戻り値なし
    public MyClass() {
        x = 10; //インスタンス変数の初期値を設定
        Console.WriteLine("xに10を代入しました"); //テスト用
    }
}
class construct01 { //実行用クラス
    public static void Main() { //実行用メソッド
        // newしたときにコンストラクタが呼ばれる
        MyClass mc = new MyClass();
        mc.showx();
        MyClass md = new MyClass(); //【追加】再度コンストラクタが呼ばれる
    }
}

p.168(コンストラクタの引数とオーバーロード)

・コンストラクタもメソッドの一種なので、パラメータリストを指定できる
 例: public Monster(int h, int m) { hp = h; mp = m; }
・これはnewによって呼び出す時に、その値を指定する
 例: Monster rimuru = new Monster(100, 500); //コンストラクタにHPとMPを渡して初期値にしてもらう
・パラメータリストを指定したコンストラクタと指定しないコンストラクタを混在できる
・また、呼び出しにおいて区別できるのであれば、パラメータリストを指定したコンストラクタを複数記述できる
・このことをオーバーロードという
例: 
  public Monster()             { hp = 10; mp = 20; } //コンストラクタ①
 public Monster(int h)        { hp = h;  mp = 20; } //コンストラクタ②
 public Monster(int h, int m) { hp = h;  mp = m;  } //コンストラクタ③
 :
  Monster veldra = new Monster(); //コンストラクタ①を呼ぶ
  Monster slalin = new Monster(100); //コンストラクタ②を呼ぶ
  Monster rimuru = new Monster(100, 500); //コンストラクタ③を呼ぶ

提出:アレンジ演習:p.167 construct01.cs

講義メモ

・p.160「メソッドを定義しよう」から

p.160 メソッドを定義しよう

・実行用で特別な性質を持つのがMainメソッド(非インスタンス(静的)メソッド)
・とは異なる通常のメソッドをプログラマが記述できる
・通常のメソッドはクラスに所属するのでインスタンスメソッドといい、インスタンスの持つデータを扱うのに便利
・例: MonsterクラスにHoimiメソッドとデータメンバhp、mpを定義し、インスタンスRimuruをnewsすると、
 「Rimuru.Hoimi()」を実行する事で、Rimuru.mpを減らし、Rimuru.hpを増やせる
・メソッドは値を0または1個返すことができる
・0個返すメソッド=何も返さないメソッドには戻り値型(返却値型)としてvoidを指定する
・1個返すメソッドには戻り値型を指定する。また、内部に1つ以上の「return ●」を記述する
・例:整数の和を返すメソッドは戻り値型も整数
・メソッドのカッコ内には引数群を0個以上記述できる。これをパタメータのリストともいう
・引数はメソッドの呼び出し時に与えたいデータで「型 引数名」でカンマ繋で記述する
・例: int add(int a, int b){ int c = a + b; return c; } //整数2値の和を返すメソッド

p.161 method01.cs

//p.161 method01.cs
using System;
class MyClass { //method01クラスで用いられるクラス
    public int Add(int x, int y) { //2つの整数の引数を受け取って整数和を返すメソッド
        int z; //メソッド内でのみ用いる変数(ローカル変数)
        z = x + y; //2つの整数の引数の和を代入
        return z; //変数zの値を返す
    }
}
class method01 {
    public static void Main() {
        MyClass a = new MyClass(); //利用したいクラスのインスタンスを生成
        int sum; //合計用の変数(ローカル変数)
        sum = a.Add(100, 200); //インスタンスにあるメソッドに2整数を渡して呼び、結果を変数に代入
        Console.WriteLine("sum = {0}", sum); //変数の値(合計値)を表示
    }
}

アレンジ演習:p.161 method01.cs

・MyClassクラスにint型のインスタンス変数xを追加する
・そして、AddメソッドをAdd(int a)に変更し、引数の値とxの値の和を返すようにしよう
・Mainメソッドで、インスタンス変数xに適当な値を与えてから、Addメソッドを呼びだすこと。

作成例

//アレンジ演習:p.161 method01.cs
using System;
class MyClass { //method01クラスで用いられるクラス
    public int x; //【追加】インスタンス変数
    public int Add(int y) { //【変更】整数の引数を受け取ってxとの和を返すメソッド
        return x + y; //インスタンス変数xと引数yの和を返す
    }
}
class method01 {
    public static void Main() {
        MyClass a = new MyClass(); //利用したいクラスのインスタンスを生成
        Console.Write("加算値:"); a.x = int.Parse(Console.ReadLine()); //インスタンス変数の値を代入
        Console.WriteLine("100に加えると{0}", a.Add(100)); //合計値を表示
        Console.WriteLine("200に加えると{0}", a.Add(200)); //合計値を表示
        Console.WriteLine("300に加えると{0}", a.Add(300)); //合計値を表示
    }
}

p.163(実引数と仮引数)

・メソッドの定義における引数を仮引数ともいい、メソッドの中でのみ変数と同様に利用できる
・メソッドの呼び出しにおける引数を実引数ともいい、値や式(変数)を指定できる
・実引数から仮引数へは値のコピーが行われる(値渡し)
・この時、実引数には名前は不要で、指定順に仮引数に渡されていく
 ※これを明示するために、実引数と仮引数に渡す変数名は同じにしないことが望ましい

p.163 bmiclass.cs

//p.163 bmiclass
using System;
class BMI { //インスタンス変数とメソッドを持ち利用されるクラス
    private double blm; //身長(m単位):インスタンス変数(クラス内部用)
    public double Calc(double bl, double bw) { //身長を体重を受取ってBMI値を返すメソッド
        blm = bl / 100.0; //m単位に換算し、インスタンス変数に格納
        return bw / Math.Pow(blm, 2.0); //BMIを算出して返す
    }
}
class bmiclass {
    public static void Main() {
        string strBl, strBw; //入力用
        double blcm, bwkg;
        Console.Write("身長(cm)---");
        strBl = Console.ReadLine();
        blcm = Double.Parse(strBl);
        Console.Write("体重(kg)---");
        strBw = Console.ReadLine();
        bwkg = Double.Parse(strBw);
        BMI bmi = new BMI(); //BMI計算用のクラスのインスタンスを生成
        Console.WriteLine("BMIは{0:#.##}です", bmi.Calc(blcm, bwkg)); //身長と体重をメソッドに渡す
    }
}

アレンジ演習:p.163 bmiclass

・BMIクラスに計算式を返すSentenseメソッドを追加しよう
・Calcメソッドの実行により、インスタンス変数blmには身長(m単位)が格納されるので、これを用いて
 「体重を【blmの値】の2乗で割った結果です」と表示しよう

作成例

//アレンジ演習:p.163 bmiclass
using System;
class BMI { //インスタンス変数とメソッドを持ち利用されるクラス
    private double blm; //身長(m単位):インスタンス変数(クラス内部用)
    public double Calc(double bl, double bw) { //身長を体重を受取ってBMI値を返すメソッド
        blm = bl / 100.0; //m単位に換算し、インスタンス変数に格納
        return bw / Math.Pow(blm, 2.0); //BMIを算出して返す
    }
    public string Sentense() { //【追加】説明文を返す
        return "体重を" + blm + "の2乗で割った結果です"; //インスタンス変数の値を再利用
    }
}
class bmiclass {
    public static void Main() {
        string strBl, strBw; //入力用
        double blcm, bwkg;
        Console.Write("身長(cm)---");
        strBl = Console.ReadLine();
        blcm = Double.Parse(strBl);
        Console.Write("体重(kg)---");
        strBw = Console.ReadLine();
        bwkg = Double.Parse(strBw);
        BMI bmi = new BMI(); //BMI計算用のクラスのインスタンスを生成
        Console.WriteLine("BMIは{0:#.##}です", bmi.Calc(blcm, bwkg)); //身長と体重をメソッドに渡す
        Console.WriteLine(bmi.Sentense()); //【追加】説明文を受け取って表示
    }
}

アレンジ演習:p.163 bmiclass

・Shar(身長180cm、体重75kg)とAmuro(身長170cm、体重60kg)のBMIの差を表示する処理を追加しよう

作成例

//アレンジ演習:p.163 bmiclass
using System;
class BMI { //インスタンス変数とメソッドを持ち利用されるクラス
    private double blm; //身長(m単位):インスタンス変数(クラス内部用)
    public double Calc(double bl, double bw) { //身長を体重を受取ってBMI値を返すメソッド
        blm = bl / 100.0; //m単位に換算し、インスタンス変数に格納
        return bw / Math.Pow(blm, 2.0); //BMIを算出して返す
    }
    public string Sentense() { //【追加】説明文を返す
        return "体重を" + blm + "の2乗で割った結果です"; //インスタンス変数の値を再利用
    }
}
class bmiclass {
    public static void Main() {
        string strBl, strBw; //入力用
        double blcm, bwkg;
        Console.Write("身長(cm)---");
        strBl = Console.ReadLine();
        blcm = Double.Parse(strBl);
        Console.Write("体重(kg)---");
        strBw = Console.ReadLine();
        bwkg = Double.Parse(strBw);
        BMI bmi = new BMI(); //BMI計算用のクラスのインスタンスを生成
        Console.WriteLine("BMIは{0:#.##}です", bmi.Calc(blcm, bwkg)); //身長と体重をメソッドに渡す
        Console.WriteLine(bmi.Sentense()); //【追加】説明文を受け取って表示
        BMI Shar = new BMI(); //SharのBMI計算用のインスタンスを生成
        BMI Amuro = new BMI(); //AmuroのBMI計算用のインスタンスを生成
        double s = Shar.Calc(180, 75); //SharのBMIを得る
        double a = Amuro.Calc(170, 60); //AmuroのBMIを得る
        Console.WriteLine("SharとAmuroのBMIの差は{0}", s - a); //差を表示
    }
}

参考:応用例:名前とbmi値をオブジェクトに持たせてみよう

//アレンジ演習:p.163 bmiclass
using System;
class BMI { //インスタンス変数とメソッドを持ち利用されるクラス
    public string name; //名前
    public double bmi; //BMI値
    private double blm; //身長(m単位):インスタンス変数(クラス内部用)
    public double Calc(double bl, double bw) { //身長を体重を受取ってBMI値を返すメソッド
        blm = bl / 100.0; //m単位に換算し、インスタンス変数に格納
        return bmi = bw / Math.Pow(blm, 2.0); //BMIを算出して返す
    }
    public string Sentense() { //【追加】説明文を返す
        return "体重を" + blm + "の2乗で割った結果です"; //インスタンス変数の値を再利用
    }
}
class bmiclass {
    public static void Main() {
        string strBl, strBw; //入力用
        double blcm, bwkg;
        Console.Write("身長(cm)---");
        strBl = Console.ReadLine();
        blcm = Double.Parse(strBl);
        Console.Write("体重(kg)---");
        strBw = Console.ReadLine();
        bwkg = Double.Parse(strBw);
        BMI bmi = new BMI(); //BMI計算用のクラスのインスタンスを生成
        Console.WriteLine("BMIは{0:#.##}です", bmi.Calc(blcm, bwkg)); //身長と体重をメソッドに渡す
        Console.WriteLine(bmi.Sentense()); //説明文を受け取って表示
        BMI Shar = new BMI(); //SharのBMI計算用のインスタンスを生成
        Shar.name = "アズナブル";//【追加】
        BMI Amuro = new BMI(); //AmuroのBMI計算用のインスタンスを生成
        Amuro.name = "レイ";//【追加】
        Shar.Calc(180, 75); //SharのBMIを得る //【変更】
        Amuro.Calc(170, 60); //AmuroのBMIを得る //【変更】
        Console.WriteLine("{0}と{1}のBMIの差は{2}", Shar.name, Amuro.name, Shar.bmi - Amuro.bmi); //【変更】差を表示
    }
}

今週の話題

販売本数ランキング 今回トップは「ゼルダの伝説 ティアーズ オブ ザ キングダム(Switch)」GO!
【BitSummit Let’s Go!!】ビットサミットが本日7月14日より開幕!『ウマ娘 熱血ハチャメチャ大感謝祭!』、『クロックタワー』移植版、『Stray』、『東方シンセカイ』などが出展 GO!
ゲームセンター運営のGENDAが新規上場、利益が出やすくなった理由は?【ゲーム企業の決算を読む】GO!
さまざまなカスタマイズが可能!PS5用「Access コントローラー」12月6日全世界同時発売決定―価格は12,980円 GO!
MSのActivision Blizzard買収裁判、勝訴判決に対するFTCの控訴が却下か―判事署名の文書が明らかに GO!
「gamescom 2023」出展者増―前年を超える60か国から多数の企業等が参加 GO!
「なんでも相談所」ブースもーユニティ・テクノロジーズ・ジャパン、今年も「BitSummit Let’s Go!!」にスポンサー参加 GO!

Unity、迷惑行為対策ソリューション「Safe Voice」を発表―クローズドベータにて提供 GO!
良作DRPG『ダンジョントラベラーズ2』『2-2』Steamでの発売中止へ―国内タイトルに厳しすぎた表現基準の壁 GO!

前回のコメント

・ビデオの方で先生がホワイトボードの方に図で説明をしてくれていたものなのですがまだピンときていなかったのでもう一度詳しく説明いただければありがたいです(^▽^)

 承知しました。次回冒頭でフォローしますね。

・一応ビデオの方のミニ演習のほうをやったので送ります。確認お願いいたします。

 拝見しました。できていますね。20行目のインデントを合わせると完璧です。
 なお、この作成例のようなMainメソッドのあるソースにデータメンバを置く形式は簡単に見えて難解です。
 これも次回冒頭でフォローしますね。

前回のコメント

・最後の練習問題、途中になりすみません。
 悔しいので先生の出してくれたヒントを元に家で作ってみようと思います。

 難度が上がっていますので、未完成提出でもOKです。
 完成にあまりこだわらずに挑戦してみてください。

・未完成だった課題ができあがりましたので新たに送らせていただきます。
 達成感半端ないです!完ぺきではないと思いますが。。。!
 余談ですが、来週お仕事の都合でお休みいただきます。
 ビデオ補講の方で11回目を勉強します。
 よろしくお願いします。

 完成、何よりです。お疲れ様でした。
 次回、お休みとのこと承知致しました。
 スタッフからビデオ補講の案内があると思いますので、下記の講義メモ(半年前のクラス)を見ながら学習してみてください。
 ・講義メモ p.152「練習問題」他 https://ha226.rundog.org/?p=577
 ・講義メモ 第7章 クラスの基礎 https://ha226.rundog.org/?p=582
 疑問点がありましたら。提出フォームからお送りください。

講義メモ 後半

p.150 foreach文による反復処理

・foreach文は配列の全要素について繰り返したい場合の簡略構文で、後述する配列以外の構造(コレクション)にも対応している
・書式: foreach(型 作業変数 in コレクション){作業変数を用いる処理}
・型はvarでOK
・例: foreach(var 作業変数 in 配列){ Console.Write(作業変数); } //配列の全要素を表示
・コレクション側の値の変更は反映しない。よって、配列の要素を書き換える処理はできない

p.150 foreach01.cs

//p.150 foreach01.cs
using System;
class foreach01 {
    public static void Main() {
        string[] Animal = new string[]{"犬", "猫", "雉", "猿"};
        int[] Num = new int[]{10, 20, 30, 40};
        foreach (string str in Animal) { //配列Animalの全要素について順にstrに取り出しながら繰返す
            Console.WriteLine(str);
        }
        Console.WriteLine();
        foreach (int i in Num) { //配列Numの全要素について順にiに取り出しながら繰返す
            Console.WriteLine(i);
        }
    }
}

アレンジ演習:p.150 foreach01.cs

・varキーワードを出来るかぎり用いてみよう

作成例

//アレンジ演習:p.150 foreach01.cs
using System;
class foreach01 {
    public static void Main() {
        var Animal = new string[]{"犬", "猫", "雉", "猿"};
        var Num = new int[]{10, 20, 30, 40};
        foreach (var str in Animal) { //配列Animalの全要素について順にstrに取り出しながら繰返す
            Console.WriteLine(str);
        }
        Console.WriteLine();
        foreach (var i in Num) { //配列Numの全要素について順にiに取り出しながら繰返す
            Console.WriteLine(i);
        }
    }
}

アレンジ演習:p.150 foreach01.cs 続き

・2次元配列、ジャグ配列の要素をforeachで表示しよう

作成例

//アレンジ演習:p.150 foreach01.cs
using System;
class foreach01 {
    public static void Main() {
        var name = new [,]{{ "Taro", "Jiro" }, { "Saburo", "Shiro" } }; //nameはstring[,]型配列になる
        foreach (var str in name) { //配列nameの全要素について順にstrに取り出しながら繰返す
            Console.WriteLine(str);
        }
        var f = new[] { new[]{ 0.5, 9.9, 0.9 }, new[]{ 1.5, 2.3 } }; //fはdouble[][]型ジャグ配列になる
        foreach (var i in f) { //ジャグ配列fの全要素について順に1次元配列iに取り出しながら繰返す
            foreach (var w in i) { //1次元配列iの全要素について順にwに取り出しながら繰返す
                Console.WriteLine(w);
            }
        }
    }
}

p.152 練習問題 ヒント

・合計sumを0で初期化しておく
・コンソールに「受験者数:」と表示して受験者数numに入力
・受験者数を要素数とする点数の配列pointを生成
・点数pointの全要素についてカウンタiを用いて下記を繰返す
 ・i + 1を用いて「●番目:」と表示して点数point[i]に入力
 ・点数point[i]の値を合計sumに足しこむ
・sumをdouble型にキャストして受験者数numで割り平均値を得て表示
・配列pointをソート
・配列pointを逆順にする
・配列pointの全要素を表示

提出:p.152 練習問題

講義メモ

・p.144「jagged01.cs」から再開します

p.144 ジャグ配列(再掲載)

・要素数の積ではなく、配列の配列によって多次元配列を表すのがジャグ配列
・型と意味が同じであれば要素数が異なる配列をまとめることができるので、使わない要素が増えてしまうことがない
 例: a[0][0],a[0][1],a[1][0],a[1][1],a[1][2],a[1][3],a[1][4]とできる
・ただし、初期化などの書式が煩雑になる
・以下は2次元の場合:
・宣言の書式: 型[][] 配列名; //例: string[][] names; ジャグ配列namesの宣言
・生成の書式: 配列名 = new 型[要素数][]; //末尾の要素数は自由なので指定不要
・宣言と生成は1文で行える 例:string[][] names = new string[4][];
・内側の配列の初期化が可能
・例: 
  int[][] n = new int[3][]; 
  n[0] = new int[1]{0}; 
  n[1] = new int[2]{1, 2}; 
  n[2] = new int[3]{1, 2, 3};
・例:上記を1行にできる
 var m = new int[3][]{ new int[1]{0}, new int[2]{1, 2}, new int[3]{1, 2, 3} };

p.144 jagged01.cs

//p.144 jagged01.cs
using System;
class jagged01 {
    public static void Main() {
        int[][] ar; //2次元のジャグ配列の宣言
        ar = new int[2][]; //構成する配列数の定義
        ar[0] = new int[3]; //2次元のジャグ配列を構成する配列[0]の生成
        ar[1] = new int[3]; //2次元のジャグ配列を構成する配列[1]の生成
        for (int i = 0; i < 2; i++) { //構成する配列全てについて繰返す
            for (int j = 0; j < 3; j++) { //構成する配列の全要素て繰返す
                ar[i][j] = (i + 1) * (j + 1); //添字①+1と添字②+1の積を代入
            }
        }
        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]); //値の表示
            }
        }
    }
}

アレンジ演習:p.144 jagged01.cs

・ar[0]の要素数を4にしてみよう
・これに対応するために、外側のループの回数を2固定からar.Lengthで得よう
・また、内側のループの回数を3固定からar[i].Lengthで得よう
※2次元のジャグ配列の場合、配列名.Lengthで、中にある配列の数が得られる
※また、配列名[添字]で中にある配列が得られるので、その要素数は配列名[添字].Lengthで得られる

作成例

//アレンジ演習:p.144 jagged01.cs
using System;
class jagged01 {
    public static void Main() {
        int[][] ar; //2次元のジャグ配列の宣言
        ar = new int[2][]; //構成する配列数の定義
        ar[0] = new int[4]; //【変更】2次元のジャグ配列を構成する配列[0]の生成
        ar[1] = new int[3]; //2次元のジャグ配列を構成する配列[1]の生成
        for (int i = 0; i < ar.Length; i++) { //【変更】構成する配列全てについて繰返す
            for (int j = 0; j < ar[i].Length; j++) { //【変更】構成する配列の全要素て繰返す
                ar[i][j] = (i + 1) * (j + 1); //添字①+1と添字②+1の積を代入
            }
        }
        for (int i = 0; i < ar.Length; i++) { //【変更】構成する配列全てについて繰返す
            for (int j = 0; j < ar[i].Length; j++) { //【変更】構成する配列の全要素て繰返す
                Console.WriteLine("ar[{0}][{1}] = {2}", i, j, ar[i][j]); //値の表示
            }
        }
    }
}

p.146 jagged02.cs

//p.146 jagged02.cs
using System;
class jagged02 {
    public static void Main() {
        string[][] name = new string[2][]; //2次元で要素配列が2のジャグ配列の宣言と定義
        name[0] = new string[2]{"田中", "工藤"}; //ジャグ配列の要素配列[0]の初期化
        name[1] = new string[3]{"吉田", "佐藤", "池田"}; //ジャグ配列の要素配列[1]の初期化
        for (int i = 0; i < name[0].Length; i++) { //要素配列[0]の全要素について繰返す
            Console.WriteLine(name[0][i]);
        }
        for (int i = 0; i < name[1].Length; i++) { //要素配列[1]の全要素について繰返す
            Console.WriteLine(name[1][i]);
        }
    }
}

アレンジ演習:p.146 jagged02.cs

・forを2重ループに書き換えよう

作成例

//アレンジ演習:p.146 jagged02.cs
using System;
class jagged02 {
    public static void Main() {
        string[][] name = new string[2][]; //2次元で要素配列が2のジャグ配列の宣言と定義
        name[0] = new string[2]{"田中", "工藤"}; //ジャグ配列の要素配列[0]の初期化
        name[1] = new string[3]{"吉田", "佐藤", "池田"}; //ジャグ配列の要素配列[1]の初期化
        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 暗黙の型指定がなされた配列

・配列の初期化においてもvarキーワードが利用できる
・これにより、配列型の変数を自動的に定義できる
・例: var name = new[]{"田中", "工藤"}; //nameはstring[2]型になる
・例: var f = new[]{0.5 ,0.39, 1.5, 2.3}; //nameはdouble[4]型になる

補足:p.147 var03.cs

・Mainメソッドはvoid型で良く、「return 0;」は不要。

p.147 var03.cs

//p.147 var03.cs
using System;
class var03 {
    public static void Main() {
        var name = new []{"太郎", "次郎", "三郎", "四郎"}; //nameはstring[4]型になる
        for (var i = 0; i < name.Length; i++) {
            Console.WriteLine(name[i]);
        }
        var f = new[] { 0.5, 0.9, 1.5, 2.3 }; //fはdouble[4]型になる
        for (var i = 0; i < f.Length; i++) {
            Console.WriteLine(f[i]);
        }
        Console.WriteLine("nameの型は{0}, fの型は{1}", name.GetType(), f.GetType());
    }
}

アレンジ演習:p.147 var03.cs

・2次元配列やジャグ配列でvarキーワードが利用できるかどうか調べよう

作成例

//アレンジ演習:p.147 var03.cs
using System;
class var03 {
    public static void Main() {
        var name = new [,]{{ "太郎", "次郎" }, { "三郎", "四郎" } }; //nameはstring[,]型配列になる
        for (var i = 0; i < name.Length; i++) { //2次元配列のLengthは全要素数
            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 } }; //fはdouble[][]型ジャグ配列になる
        for (var i = 0; i < f.Length; i++) { //ジャグ配列の全要素配列について繰返す
            for (var j = 0; j < f[i].Length; j++) { //要素配列[i]の全要素について繰返す
                Console.WriteLine(f[i][j]);
            }
        }
        Console.WriteLine("nameの型は{0}, fの型は{1}", name.GetType(), f.GetType()); //String[,], Double[][]
    }
}

p.148 1次元配列のソート

・1次元配列の要素を昇順(小さい方から大きい方へ)にソート(整列)するには、Arrayクラスが提供するSortメソッドを利用できる。
・書式: Array.Sort(配列名);
・また、1次元配列の要素を反転する(逆順にする)には、Arrayクラスが提供するReverseメソッドを利用できる。
・書式: Array.Reverse(配列名);
・上記を順に用いることで、1次元配列の要素を降順(大きい方から小さい方へ)にソートできる。

p.148 sort01.cs

//p.148 sort01.cs
using System;
class sort01 {
    public static void Main() {
        string[] name = new string[5]{"Eric", "Peter", "Frank", "Kate", "Thomas"};
        for (int i = 0; i < name.Length; i++) { //配列の全要素について繰返す
            Console.WriteLine(name[i]); //表示する
        }
        Console.WriteLine(); //改行する
        Array.Sort(name); //昇順にソートする
        for (int i = 0; i < name.Length; i++) { //配列の全要素について繰返す
            Console.WriteLine(name[i]); //表示する
        }
        Console.WriteLine(); //改行する
        Array.Reverse(name); //逆順にする
        for (int i = 0; i < name.Length; i++) { //配列の全要素について繰返す
            Console.WriteLine(name[i]); //表示する
        }
    }
}

アレンジ演習:p.148 sort01.cs

・「あ」「ア」「ぁ」「ァ」がどういう順序になるか確認しよう
・同様に「A」「a」「A」「a」がどういう順序になるか確認しよう

作成例

//アレンジ演習:p.148 sort01.cs
using System;
class sort01 {
    public static void Main() {
        string[] name = new string[4]{"あ","ア","ぁ","ァ"};
        Array.Sort(name); //昇順にソートする
        for (int i = 0; i < name.Length; i++) { //配列の全要素について繰返す
            Console.WriteLine(name[i]); //表示する ⇒ ァ、ぁ、ア、あ の順になる
        }
        string[] alp = new string[4]{"A","a","A","a"};
        Array.Sort(alp); //昇順にソートする
        for (int i = 0; i < alp.Length; i++) { //配列の全要素について繰返す
            Console.WriteLine(alp[i]); //表示する ⇒ a、a、A、A の順になる
        }
    }
}

アレンジ演習:p.148 sort01.cs つづき

・2次元配列、ジャグ配列の要素をArray.Sortでソートしてみよう

作成例

//アレンジ演習:p.148 sort01.cs
using System;
class sort01 {
    public static void Main() {
        var name = new [,]{{ "Taro", "Jiro" }, { "Saburo", "Shiro" } }; //nameはstring[,]型配列になる
        string[] work = new string[name.Length]; //作業用の1次元配列
        for (var i = 0; i < name.Length; i++) { //2次元配列のLengthは全要素数
            work[i] = name[i / 2, i % 2]; //1次元配列にコピー
        }
        Array.Sort(work); //昇順にソートする
        for (var i = 0; i < name.Length; i++) { //2次元配列のLengthは全要素数
            name[i / 2, i % 2] = work[i]; //2次元配列に戻す
            Console.WriteLine(name[i / 2, i % 2]); //[0,0][0,1][1,0][1,1]となる
        }
        var f = new[] { new[]{ 0.5, 9.9, 0.9 }, new[]{ 1.5, 2.3 } }; //fはdouble[][]型ジャグ配列になる
        int cnt = 0;
        for (var i = 0; i < f.Length; i++) { //ジャグ配列の全要素配列について繰返す
            for (var j = 0; j < f[i].Length; j++) { //要素配列[i]の全要素について繰返す
                cnt++; //要素数をカウント
            }
        }
        double[] w = new double[cnt]; //作業用の1次元配列
        int idx = 0;
        for (var i = 0; i < f.Length; i++) { //ジャグ配列の全要素配列について繰返す
            for (var j = 0; j < f[i].Length; j++) { //要素配列[i]の全要素について繰返す
                w[idx++] = f[i][j]; //1次元配列にコピー
            }
        }
        Array.Sort(w); //昇順にソートする
        idx = 0;
        for (var i = 0; i < f.Length; i++) { //ジャグ配列の全要素配列について繰返す
            for (var j = 0; j < f[i].Length; j++) { //要素配列[i]の全要素について繰返す
                f[i][j] = w[idx++]; //ジャグ配列に戻す
                Console.WriteLine(f[i][j]);
            }
        }
    }
}

今週の話題

販売本数ランキング 今回トップは「ファイナルファンタジーXVI(PS5)」GO!
『プロセカ』『ソニック』人気のセガサミー…好決算は手放しで喜べる内容なのか?【ゲーム企業の決算を読む】GO!
『CoD』はチーターに「幻覚」を見せる―不正ツール利用者は存在しないプレイヤーと戦うことに GO!
「GTMF東京」の注目セッションを紹介…4年ぶり開催のゲーム開発者向けイベント【GTMF2023】GO!
【IVS2023京都】過去最大1万人が来場するベンチャーの祭典が開幕、オープニングでは岸田首相からのメッセージも GO!
CRI・ミドルウェアとヤマハ、協業を発表―ゲームの立体音響普及のため「CRI ADX」に「Sound xR」標準搭載を目指す GO!
Unity、AIマーケットプレイスを新規立ち上げ―Unity公認ソリューションからサードパーティまで、ゲーム開発をサポートするツールを提供 GO!

「学習元が不明なAI生成コンテンツは販売を許可しない」PCゲーム最大手Steam、AI生成作品販売に警戒色見せる―開発者報告 GO!

参考:「メタバース」を活用したサービスの展示会 GO!

前回のコメント

・Hello!World!
・今日の授業は配列をやりました。アレンジ演習を何個かやったのですが、いろんな書き方だったり、
 今まで習った関係演算子やら条件演算子を使うことでかなり短縮できたりなどとても勉強になりました!(^^) なんか日記みたいになっちゃいました

 何よりです。リアクション感謝します。