次回予告:LinuxとWindowsの通信 など
講義メモ:memo20241023.txt
for trainees of Hirano's class only
次回予告:LinuxとWindowsの通信 など
講義メモ:memo20241023.txt
VirtualBox ダウンロード【再掲載】
公式サイトからOracle VM VirtualBoxをダウンロード https://www.oracle.com/jp/virtualization/technologies/vm/downloads/virtualbox-downloads.html 64-bit Windows Windows Installer をクリック
Debian ダウンロード【再掲載】
Linux=Debian ISOイメージのダウンロード Debianの公式サイトから「netinst」ISOイメージをダウンロードします https://www.debian.org/CD/netinst/index.ja.html netinst CD イメージ (約 150-300 MB ですがアーキテクチャよって変わります)の「amd64」をクリック
VirtualBoxとLinuxのインストール【再掲載】
・VirtualBox-7.0.18-162988-Win.exeを実行し「Next」「Next」「Yes」「Install」「はい」「インストール」 「Finish」の順にクリックするとインストール完了 ・VirtualBoxが起動したら、「新規」をクリック ・名前に「Debian Minimal」と入力すると、タイプ「Linux」、バージョン「Debian (64-bit)」が自動設定されます。 ・ISOイメージの「V」をクリックしてダウンロードしてある「debian-12.7.0-amd64-netinst.iso」を選択。 ・「自動インストールをスキップ」をオンにします。 ・「完了」をクリック ・「Debian Minimal」を右クリックして「設定」をクリック ・「ネットワーク」をクリックし、「割り当て」を「ブリッジアダプター」に変更 ・名前にそのPCのネットワークアダプタが表示されているのを確認して「OK」をクリック
Debianのインストール
仮想マシンの起動:
「起動」をクリックすると、仮想マシンが起動します。 「キーボードの自動キャプチャ」が表示されたら右側の×をクリックして閉じる ※ インストーラが先に進んでしまったら「X」「仮想マシンの電源オフ」「OK」で閉じて、再度、「起動」をクリック ↓キーで「Install」を選択してEnterキーを押します。 「マウス統合」が表示されたら右側の×をクリックして閉じる
インストールプロセス:
Language:が表示されたら「English」のままでEnterキーを押します。 Country:で「United States」のままでEnterキーを押します。 Keymap:で↓を押し続けて「Japanese」にしてからEnterキーを押します。(待ち有り) Please enter the host name で「Debian」のままでEnterキーを押します。 The domain nameで「athuman.com」と入力してからEnterキーを押します。 Root passwordで「root」と入力してからEnterキーを押します。 Re-enter passwordでも「root」と入力してからEnterキーを押します。 Full name for new user:で「user user」と入力してからEnterキーを押します。 Username for your accountは「user」のままでEnterキーを押します。 password for the new userで「user」と入力してからEnterキーを押します。 Re-enter passwordでも「user」と入力してからEnterキーを押します。 Select your time zoneでは↓を押し続けて「Pacific」にしてからEnterキーを押します。 Partitioning methodで「Guided – use entire disk」のままでEnterキーを押します。 Select diskで「SCSI2」または「SCSI3」のままでEnterキーを押します。 Partitioning schemeで「All files」のままでEnterキーを押します。 「Finish」のままでEnterキーを押します。 Write the change で「←」キーを押して「Yes」にしてからEnterキーを押します。(待ち有り) 「Scan extra」で「No」のままでEnterキーを押します。 「Debian archive」では↑を押し続けて「Japan」にしてからEnterキーを押します。 次の「Debian archive」で「deb.debian.org」のままでEnterキーを押します。 「HTTP proxy」では、未入力のままでEnterキーを押します。(待ち有り) 「Participate」では「No」のままでEnterキーを押します。 インストールプロセスが進行し、ソフトウェアの選択画面が表示されます。
ソフトウェアの選択:
「Choose」では、スペースキーを押して「Debian desktop」のチェックを外し、 「↓」キーで「GNOME」に移動して再度スペースキーを押してチェックを外します。 そして、「standard system utilities」のチェックのみがオンであることを確認してEnterキーを押します。 ※ これによりX Window Systemを含まないCUI環境になります。(長い待ち有り)
GRUBブートローダのインストール:
「Install the GRUB」で「Yes」のままでEnterキーを押します。 「Device for boot」では「↓」を押して「/dev/sda」にしてからEnterキーを押します。(待ち有り)
インストール完了と再起動とログイン:
「Please choose」で「Continue」のままでEnterキーを押します。 仮想マシンが再起動して「Debian login:」が表示されたら「user」と入力しEnterキーを押します。 「Password:」が表示されたら「user」と入力しEnterキーを押します。※何も表示されないがOK(自分を信じて!) これで、CUI環境のDebianがVirtualBox上で動作するようになります。 X Window Systemをインストールせず、軽量かつシンプルなシステムとして利用できます。
動作の確認
「top」と入力しEnterキーを押すと、実行中のプロセス一覧がリアルタイムで表示される 「q」キーを押すと表示終了 ※ Windows側でマウスを用いてLinuxのウィンドウサイズを少し大きくすると全体が表示される 「ip a」と入力しEnterキーを押すと、ネットワーク設定を確認できる。 その中の「inet 127.0.0.1」ではない方の「inet」に表示されているアドレスがLinux側のIPv4アドレス 例:10.16.8.22 次にWindow側のIPv4アドレスをネットワークアイコンの右クリックから「ネットワーク設定とインターネット設定」を選んで 「プロパティ」をクリックすると表示できる 例:10.16.8.1 では、LinuxからWindowsにパケットを送ってみよう。Linux側で「ping Window側のIPv4アドレス」 例:ping 10.16.8.1 ※実行し続けるので「Ctrl + C」で止めること ※環境によっては1行表示されるのみ(セキュリティの為、返答が得られない) また、WindowsからLinuxにパケットを送ってみよう。Windows側で「スタート」「すべてのアプリ」「Windowsツール」で 「コマンドプロンプト」をダブルクリックで起動し、「ping Linux側のIPv4アドレス」 例:ping 10.16.8.22
提出:VBoxのログファイル
・ユーザー¥〇〇〇¥VirtualBox VMs¥Debian Minimal¥Logs¥VBox.log ファイルを提出 ※ 〇〇〇は利用者名 ・エラーになったらZIPファイルに圧縮してください ・ユーザー¥〇〇〇¥.VirtualBoxフォルダではないので注意。
次回予告:「7. クラス:7.2 メンバ関数:const メンバ関数」から
https://rinatz.github.io/cpp-book/ch07-02-member-functions/
講義メモ:memo20241023.zip
7. クラス:7.1 データメンバ
https://rinatz.github.io/cpp-book/ch07-01-data-members/
・クラス:構造体の上位概念で、変数と関数を集約した型をつくるための仕組み
・なお、C/C++の構造体は変数を集約した型をつくるための仕組み
※ C#の構造体は軽量のクラスなので、C/C++の構造体とは意味が異なる
・メンバ:クラスの構成要素のことで、主に変数と関数
・データメンバ:クラスが持つ変数で、メンバ変数ともいう
・クラスが持つメンバは基本的にクラス内でのみ有効で、外部からアクセスできないが「public:」以降のメンバはアクセス可能
・クラスの基本的な定義書式: class クラス名 { メンバの定義; … }; //末尾にセミコロンが必要
・外部からアクセスできるデータメンバを持つクラスの書式例:
class クラス名 {
public:
データメンバの型 データメンバ名;
:
}
・データメンバを用いる側では、クラスを型とする変数を定義し、データメンバ名の前に「変数名.」を前置することで、
通常の変数と同様に利用できる
書式例: クラス名 変数名; 変数名.データメンバ名 = 値;
・なお、C++ではクラスを型とする変数を定義した時点で、クラスの実体であるインスタンスが自動生成される
(この場合、C#の様にnewで生成する必要はない)
演習:データメンバ その1 project1/p070101.cpp
・データメンバのサンプルソース(「データメンバを参照するには」まで)を動作可能にしよう ・データメンバ値の表示を追加すること ・クラス定義はmain関数の外に置くと良い
作成例
//演習:データメンバ その1 project1/p070101.cpp
#include <iostream>
class Rectangle { //四角形クラスの定義
public: //これ以降は公開メンバ
int height_; //データメンバ(高さ)
int width_; //データメンバ(幅)
};
int main() {
Rectangle r; //クラスを型とする変数の宣言(インスタンスが生成される)
r.height_ = 10; //データメンバ(高さ)に代入
r.width_ = 20; //データメンバ(幅)に代入
std::cout << " height = " << r.height_ << std::endl; //データメンバ(高さ)の値を表示
std::cout << " width = " << r.width_ << std::endl; //データメンバ(幅)の値を表示
return 0;
}
7. クラス:7.1 データメンバ(つづき)
・クラスには大量のデータメンバや要素数の大きな配列を記述できる ・すると、インスタンスも大容量になるので、変数ではなくポインタで扱うと効率的 ・クラスのオブジェクト(インスタンス)をポインタで扱うには、変数の場合と同様に「*」と「&」を用いる 書式例: クラス名* ポインタ名 = &変数名; ・データメンバをポインタ経由で参照するには「変数名.」を「(*ポインタ名).」とする ※メンバ演算子「.」がポインタ解決演算子「*」より優先度が高いのでカッコが必要 ・この記法は見づらく、ミスの元なので、アロー演算子「->」を用いて「ポインタ名->メンバ名」とすれば良い
演習:データメンバ その2 project1/p070102.cpp
・データメンバのサンプルソース(「(*r). の代わりに r->」)を動作可能にしよう ・データメンバ値の表示を追加すること
作成例
//演習:データメンバ その2 project1/p070102.cpp
#include <iostream>
class Rectangle { //四角形クラスの定義
public: //これ以降は公開メンバ
int height_; //データメンバ(高さ)
int width_; //データメンバ(幅)
};
int main() {
Rectangle rectangle; //クラスを型とする変数の宣言(インスタンスが生成される)
Rectangle* r = &rectangle; //インスタンスを指すポインタを定義
r->height_ = 10; //データメンバ(高さ)にポインタ経由で代入
r->width_ = 20; //データメンバ(幅)にポインタ経由で代入
std::cout << " height = " << r->height_ << std::endl; //ポインタ経由で値を表示
std::cout << " width = " << r->width_ << std::endl; //ポインタ経由で値を表示
return 0;
}
7. クラス:7.2 メンバ関数
・クラスには(構造体とは異なり)メンバとして関数を定義できる ・これにより、データとデータを扱う処理をまとめて扱えること(オブジェクト指向・部品の基礎)が可能 ・メンバ関数の書式は通常の関数と同様だが、定義の上下関係による呼び出しや利用の可否はない ・よって、あるメンバ関数の定義位置より下で定義しているデータメンバや他のメンバ関数を利用・呼び出し可能 ・メンバ関数を用いる側では、クラスを型とする変数を定義し、メンバ関数名の前に「変数名.」を前置することで、 通常の関数と同様に利用できる
演習:メンバ関数 project1/p070201.cpp
・メンバ関数のサンプルソースを動作可能にしよう ・メンバ関数Area()の戻り値を表示する処理を追記すること
作成例
//演習:メンバ関数 project1/p070201.cpp
#include <iostream>
class Rectangle { //四角形クラスの定義
public: //これ以降は公開メンバ
int Area() { //メンバ関数「面積」
return height_ * width_; //下方で定義しているデータメンバを利用
}
int height_; //データメンバ
int width_; //データメンバ
};
int main() {
Rectangle r; //クラスを型とする変数の宣言(インスタンスが生成される)
r.height_ = 10; //データメンバ(高さ)に代入
r.width_ = 20; //データメンバ(幅)に代入
std::cout << "面積 = " << r.Area() << std::endl; //メンバ関数を呼んで戻り値を表示
}
7. クラス:7.2 メンバ関数:クラス宣言とは別に定義
・クラス宣言の中に関数定義を記述するとクラス定義の内容が長文化して見通しが悪くなる ・そこで、クラス定義の中にはメンバ関数のプロトタイプ宣言を置き、メンバ関数の内容は別に定義することが可能 ・別に定義する場合は、メンバ関数名の前に「クラス名::」を前置すること
演習:メンバ関数:クラス宣言とは別に定義 project1/p070202.cpp
・「クラス宣言とは別に定義」のサンプルソースを動作可能にしよう ・メンバ関数Area()の戻り値を表示する処理を追記すること ・また、別に定義するRectangle::Area()の記述場所が自由であることも確認しよう ⇒ クラス定義の後であれば、main()関数の前でも後でも良い
作成例
//演習:メンバ関数:クラス宣言とは別に定義 project1/p070202.cpp
#include <iostream>
class Rectangle { //四角形クラスの定義
public: //これ以降は公開メンバ
int Area(); //メンバ関数「面積」のプロトタイプ宣言
int height_; //データメンバ
int width_; //データメンバ
};
int Rectangle::Area() { //メンバ関数「面積」の定義をクラスの外で行う
return height_ * width_; //下方で定義しているデータメンバを利用
}
int main() {
Rectangle r; //クラスを型とする変数の宣言(インスタンスが生成される)
r.height_ = 10; //データメンバ(高さ)に代入
r.width_ = 20; //データメンバ(幅)に代入
std::cout << "面積 = " << r.Area() << std::endl; //メンバ関数を呼んで戻り値を表示
}
7. クラス:7.2 メンバ関数:暗黙的な inline 指定
・inline 指定については「4.5 inline関数」を参照 https://rinatz.github.io/cpp-book/ch04-05-inline-functions/ ・クラス宣言の中でメンバ関数を定義した場合、暗黙的にinline指定が行われる ・これにより、クラスの定義をヘッダ内で行い、その中でメンバ関数を定義しても良い。
演習:メンバ関数:暗黙的な inline 指定 project070203/rectangle.h,something.h,something.cpp,main.cpp
・「暗黙的な inline 指定」前半のサンプルソースの動作を確認しよう ・4ソースで構成しているので、専用のプロジェクトを作成すると良い
作成例
//演習:メンバ関数:暗黙的な inline 指定 project070203/rectangle.h
#ifndef RECTANGLE_H_
#define RECTANGLE_H_
class Rectangle { //四角形クラスの定義
public: //これ以降は公開メンバ
int Area() { //メンバ関数「面積」
return height_ * width_; //下方で定義しているデータメンバを利用
}
int height_; //データメンバ
int width_; //データメンバ
};
#endif // RECTANGLE_H_
//演習:メンバ関数:暗黙的な inline 指定 project070203/something.h
#ifndef SOMETHING_H_
#define SOMETHING_H_
void Something(); //通常関数のプロトタイプ宣言
#endif // SOMETHING_H_
//演習:メンバ関数:暗黙的な inline 指定 project070203/something.cpp
#include "something.h" //自前のヘッダを利用
#include <iostream>
#include "rectangle.h" //クラス定義を含むヘッダを利用
void Something() { //ヘッダで宣言している関数の内容を記述
Rectangle r; //クラスを型とする変数の宣言(インスタンスが生成される)
r.height_ = 2; //データメンバ(高さ)に代入
r.width_ = 3; //データメンバ(幅)に代入
std::cout << r.Area() << std::endl; //メンバ関数を呼んで戻り値(面積)を表示
}
//演習:メンバ関数:暗黙的な inline 指定 project070203/main.cpp
#include <iostream>
#include "rectangle.h" //クラス定義を含むヘッダを利用
#include "something.h" //自前のヘッダを利用
int main() {
Rectangle r; //クラスを型とする変数の宣言(インスタンスが生成される)
r.height_ = 10; //データメンバ(高さ)に代入
r.width_ = 20; //データメンバ(幅)に代入
std::cout << r.Area() << std::endl; //メンバ関数を呼んで戻り値(面積)を表示
Something(); //別ソース(something.cpp)で定義済の関数を呼ぶ
return 0;
}
7. クラス:7.2 メンバ関数:暗黙的な inline 指定と「クラス宣言とは別に定義」
・クラス宣言とは別にメンバ関数を定義すると暗黙的な inline 指定はされなくなる ・よって、ヘッダファイル内のクラス宣言とは別にメンバ関数の定義を行うとリンク時にエラーとなる ・ヘッダファイル内でクラス宣言とは別にメンバ関数の定義を行うには、明示的に inline 指定する必要がある
提出:演習:メンバ関数:暗黙的な inline 指定 project070204/rectangle.h,something.h,something.cpp,main.cpp
・「暗黙的な inline 指定」後半のサンプルソースの動作を確認しよう ・inline指定をしていない場合にどうなるかを確認してから、inlineを追記しよう ・4ソースで構成しているので、専用のプロジェクトを作成すると良い ※ 4ソースを1つのZIPファイルに圧縮して「提出フォーム」から提出すること ※ rectangle.hのみでも良いが、圧縮して「提出フォーム」から提出すること
講義メモ
・「6.メモリの管理:6.5 スマートポインタ:リソースの所有権」の続きから
https://rinatz.github.io/cpp-book/ch06-05-smart-pointers/
6.メモリの管理:6.5 スマートポインタ:リソースの所有権【再掲載】
・ポインタはコピー可能なため、ポインタが指す先のリソースを複数のオブジェクトから参照することが可能 ・動的確保したリソースを扱う場合、 誤って delete を忘れたり、同じリソースを複数回 delete したりすることを防ぐために、 どの変数がリソースの所有権(リソースを参照する権利と解放する権利)を持つのかをプログラマが細心の注意を払ってコードを 書く必要がある
提出フォロー:演習:リソースの所有権 project1/p0604501.cpp
・リソースの所有権のサンプルソースを動作可能にしよう ・「a と b のどちらを delete するべきか?」の下で両方をdeleteして、どうなるか確認しよう ⇒ どちらをdeleteしても良いが、両方を消そうとすると、delete済なので異常終了する
作成例
//演習:リソースの所有権 project1/p060501.cpp
#include <iostream>
int main() {
int* a = new int(100); //動的に領域を確保
int* b = a; // b からも a と同じリソースを参照できるようにする。
// a と b のどちらを delete するべきか?
delete a;
std::cout << "delete a is done" << std::endl;
delete b; //対象が存在しないので異常終了する
std::cout << "delete b is done" << std::endl;
return 0;
}
6.メモリの管理:6.5 スマートポインタ:std::shared_ptr
・動的確保したリソースの所有権を共有することができるスマートポインタ ・スマートポインタはヘッダにて提供されている ・内部で所有権を持つオブジェクトの一覧を管理し、所有者がいなくなった時に自動的に delete する仕組みを提供する ・std::shared_ptr オブジェクトを生成するには、 std::make_shared を利用する ・デストラクタはオブジェクトの生存期間が尽きる(消える)とシステムが判断したときに自動的に呼び出す関数 ・デストラクタはクラスの中で記述するものだが(副テキストp.471)、スマートポインタの利用により、 動的に確保された領域に対しても delete が動作するようになっている
演習:std::shared_ptr project1/p060502.cpp
・std::shared_ptrのサンプルソースを試してみよう ・xとyの明示的な消去(delete)ができるかどうか確認しよう
作成例
//演習:std::shared_ptr project1/p060502.cpp
#include <iostream>
#include <memory>
int main() {
std::shared_ptr<int> x = std::make_shared<int>(100); // int* x = new int(100); の代わり
// 所有者は1人。
{ //ブロックにすることでyの有効範囲(生存期間)を制限している
std::shared_ptr<int> y = x; // 通常のポインタ同様、コピーすることで所有権が共有される
// 所有者が2人に増える。
std::cout << "*y = " << *y << std::endl;
// delete y; //シェアードポインタのdeleteは不可
} // y が破棄されて所有者が1人になる。(yの有効範囲(生存期間)はここまでなので)
std::cout << "*x = " << *x << std::endl;
// delete x; //シェアードポインタのdeleteは不可
return 0;
} // 所有者が0人になるので、 x のデストラクタで自動的に delete が行われる。
6.メモリの管理:6.5 スマートポインタ:std::unique_ptr
・std::shared_ptr と違い、コピーが出来ないのが std::unique_ptr。 ・よって、そのため、確保したリソースの所有者が常に1人になるようにしたい場合に用いる。
演習:std::unique_ptr project1/p060503.cpp
・std::unique_ptrのサンプルソースを試してみよう ・「// std::unique_ptry = x;」のコメントアウトを戻して、どういうエラーになるか確認しよう ⇒ コンパイルエラーになるが、VC++では「C++関数は参照できません -- これは削除された関数です」というエラーが表示され、 誤解を招くので注意。
作成例
//演習:std::unique_ptr project1/p060503.cpp
#include <iostream>
#include <memory>
int main() {
std::unique_ptr<int> x(new int(100)); //コピーできないスマートポインタで生成される
std::unique_ptr<int> y = x; // コピー出来ないのでコンパイルエラーになる
std::cout << *x << std::endl;
return 0;
} // x が所有しているリソースが解放される。
6.メモリの管理:6.5 スマートポインタ:std::unique_ptr(続き)
・所有権の共有はできないが、std::move を使うことで所有権の移動は出来る ・このことで std::shared_ptr よりも軽快に動作する
演習:std::unique_ptr その2 project1/p060504.cpp
・std::unique_ptrの2つめのサンプルソースを試してみよう ・「所有権を移動したため、x は何も所有していない」ことを確認する処理を追記しよう
作成例
//演習:std::unique_ptr その2 project1/p060504.cpp
#include <iostream>
#include <memory>
int main() {
std::unique_ptr<int> x(new int(100));
std::unique_ptr<int> y(std::move(x)); // ムーブは出来るため、所有権の移動は可能。
std::cout << "*y = " << *y << std::endl;
// 所有権を移動したため、x は何も所有していない。
std::cout << "*x = " << *x << std::endl; //よってここで異常終了する(コンパイルエラーにはならない)
return 0;
} // y が所有しているリソースが解放される。
※ std::auto_ptr、std::weak_ptrは割愛
【プログラミング言語Ⅳ】
・わかりやすかったです
・ファイル書き出し、メモリ管理について理解した。
・授業ありがとうございました。
・ありがとうございました。
・何とか出来ました。
何よりです。
・メモリの管理関連のコードが難しく感じた。
・難しかったです。
お持ちのC/C++のテキストも読むと理解しやすいかもしれません。
・授業スピード丁度良かったです。
・ペース丁度良かったです。
・講義のペースは丁度良かったです
・まだわからないとこが多いです、ペースはちょうどいいです
・丁度いい速さでした
・授業の速さはちょうどよかったです。
・ペース問題ないです。
・ペース大丈夫です
了解です。リアクション感謝します。
・エラーが出ました。(ブレークポイント指令が実行されましたと出た。)
何をしたら出たエラーなのかを明示してください。正確なエラーメッセージも必要です。
エラー発生画面をプリントスクリーンするか、スマフォで撮影すると良いですよ。
【ネットワークプログラミングⅡ】
・わかりやすかったです
・一応Logs出せました
・VirtualBoxを利用したサーバの設定についてを学んで、これを使ったネット対戦などの制作に興味がわいた
・Vboxの使い方がわかりました。一応Log出せました。
何よりです。
・授業ありがとうございました。
複雑でわからないことだらけですが、VirtualBoxlを使って何かを作れるよう励みたいです。
・Linuxを触ってみたいと思っていたので楽しみです。
・Vboxの操作は初めてなので授業で勉強できるのが楽しみです。
お楽しみあれ。
・難しかったです。
・色々なアプリをインストールや図での説明を見て次回はとても複雑で難しい内容になると感じた。
・第一回から追っていたのですが途中で詰まり難しかったです。
私もフォローしますが、クラスメイトの助力もお願いすると良いですよ。
・ペース丁度良かったです。
・ペース大丈夫です
・ペース丁度良かったです。
・授業の速さはちょうどよかったです。
・ペース問題ないです。
了解です。リアクション感謝します。
・質問は、このVbox、Linaxは実際にITやゲーム業界の社会でもよく使われているのでしょうか?
はい、主にサーバ系や多環境開発などで活用されています。
サーバ系では高機能な1筐体上に複数の仮想サーバを構築することで、負荷分散や最適化を行います。
多環境開発では1筐体上に複数のOSをインストールすることで、開発を効率化しています。
・最後の行程のネットワークアダプタが表示されなかったです
Linuxからネットワークが使えない可能性がありますので、再確認しましょう。
isoファイルの入れ直しで解決するかもしれません。
・数年前にはVMwareを使ったことがありますが、VBoxは初めてです…何の違いがありますか?
私も数年前までVMwareを使っていましたが、商利用制限や対応OSの少なさなどで、VBoxに切り替えました。
ちなみに、VMware Playerは2024年5月に廃止されました。
VMware Workstation Proが個人利用においては無料とのことですが、微妙ですね。
講義メモ
・リスト、スタック、キュー
コレクションクラス
・C#などのオブジェクト指向言語が提供する仕掛けで、構造体と同様にデータ構造を提供するクラス
・リスト、スタック、キューなどがある
ジェネリクス
・リスト、スタック、キューのようなデータ構造を提供するコレクションクラスに対して「何を格納するのか」を指定できる仕組み
・これにより、1つのコレクションクラスでどんなデータ型にも対応できる
・無論、構造体オブジェクトを格納するコレクションクラスも作れる
リスト
・https://learn.microsoft.com/ja-jp/dotnet/api/system.collections.generic.list-1
・C#ではList<T>クラスとして提供されており、Tはジェネリクスで格納したいデータの型を指定する
・整数用のリストオブジェクトの生成書式例: List<string> mylist = new List<string>();
・リストへの格納は「リスト名.Add(要素)」で行う
例: mylist.Add("Veldra");
・リストの内容の表示はforeachが使える
例: foreach (var w in mylist) { Console.WriteLine(w); } //リストの全件を表示
・リストからの削除は「リスト名.Remove(要素)」で行う
・リストのn番目は配列と同様に「リスト名[先頭を0とする番号]」で得られる。
演習 ex111301.cs
・monstersというstring型のリストを生成せよ
・要素として"Veldra"、"Rimuru"、"Hakuo"を追加
・リストの全要素を表示
・要素から"Rimuru"を削除
・リストの0件目と1件目を表示
作成例
List<string> monsters = new List<string>(); //string型のリストを生成
monsters.Add("Veldra"); //リストに要素を追加(要素[0]になる)
monsters.Add("Rimuru"); //リストに要素を追加(要素[1]になる)
monsters.Add("Hakuo"); //リストに要素を追加(要素[2]になる)
foreach (var w in monsters) { //リストの全要素について
Console.WriteLine(w); //表示
}
monsters.Remove("Rimuru"); //リストの要素[1]を削除すると前に詰まるので
Console.WriteLine("monsters[0] = {0}", monsters[0]); //要素[0]はそのまま
Console.WriteLine("monsters[1] = {0}", monsters[1]); //要素[2]が要素[1]になっている
キュー
・https://learn.microsoft.com/ja-jp/dotnet/api/system.collections.queue
・待ち行列ともいうデータを溜め込むデータ構造
・先に入れた要素から順番に取り出せるので、FIFO=先入先出構造。
・C#ではQueue<T>クラスとして提供されており、Tはジェネリクスで格納したいデータの型を指定する。
・文字列用のキューオブジェクトの生成書式例: Queue<string> myQue = new Queue<string>();
・キューの末尾への追加は「キュー名.Enqueue(要素)」で行う
例: myQue.Enqueue("Veldra");
・リストの内容の表示はforeachが使える
例: foreach (var w in myQue) { Console.WriteLine(w); } //キューの全件を表示
・キューの先頭からの取出しは「キュー名.Dequeue()」で行う。戻り値は取り出した要素
・キューの先頭要素を知りたいときは「キュー名.Peek()」で得られる。
・なお、キューに格納されている要素数は「キュー名.Count」で得られる。
演習 ex111302.cs
・monsterqというstring型のキューを生成せよ
・要素として"Veldra"、"Rimuru"、"Hakuo"を順に末尾に追加
・キューの全要素を表示
・先頭要素を取り出して表示
・キューの件数と、現在の先頭要素を表示
作成例
Queue<string> monsterq = new Queue<string>();
monsterq.Enqueue("Veldra"); //キューの末尾に追加(1件目になる)
monsterq.Enqueue("Rimuru"); //キューの末尾に追加(2件目になる)
monsterq.Enqueue("Hakuo"); //キューの末尾に追加(3件目になる)
foreach (var w in monsterq) { //キューの全要素について
Console.WriteLine(w); //表示
}
string s = monsterq.Dequeue(); //キューの先頭から取り出す(キューから取り除かれる)
Console.WriteLine("{0}を取り出した!", s); //取り出した要素を表示
Console.WriteLine("キューの格納数は{0}", monsterq.Count); //取出し後の格納数を表示(2)
Console.WriteLine("現在の先頭は{0}", monsterq.Peek()); //専用要素を(取り出さずに)表示
スタック
・https://learn.microsoft.com/ja-jp/dotnet/api/system.collections.generic.stack-1
・データを溜め込んで順序を変えられるデータ構造
・最後に入れた要素から取り出せるので、LIFO=後入先出構造。
・C#ではStack<T>クラスとして提供されており、Tはジェネリクスで格納したいデータの型を指定する。
・文字列用のスタックオブジェクトの生成書式例: Stack<string> myStack = new Stack<string>();
・スタックへの押し込みは「スタック名.Push(要素)」で行う
例: myStack.Push("Veldra");
・スタックの内容の表示はforeachが使える
例: foreach (var w in myStack) { Console.WriteLine(w); } //スタックの全件を表示
・スタックの一番上からの飛び出しは「スタック名.Pop()」で行う。戻り値は飛び出した要素
・スタックの一番上の要素を知りたいときは「スタック名.Peek()」で得られる。
・なお、スタックに格納されている要素数は「スタック名.Count」で得られる。
演習 ex111303.cs
・monsterkというstring型のスタックを生成せよ
・要素として"Veldra"、"Rimuru"、"Hakuo"を順に押し込む
・スタックの全要素を表示
・先頭要素を飛び出しさせて表示
・スタックの件数と、現在の先頭要素を表示
作成例
Stack<string> monsterk = new Stack<string>();
monsterk.Push("Veldra"); //スタックに押し込む(1件目になる)
monsterk.Push("Rimuru"); //スタックに押し込む(1件目になる、2件目はVeldra)
monsterk.Push("Hakuo"); //スタックに押し込む(1件目になる、2件目はRimuru、3件目はVeldra)
foreach (var w in monsterk) { //スタックの全要素について
Console.WriteLine(w); //表示
}
string s = monsterk.Pop(); //スタックの一番上から飛び出す(スタックから取り除かれる)
Console.WriteLine("{0}を取り出した!", s); //飛び出した要素を表示
Console.WriteLine("スタックの格納数は{0}", monsterk.Count); //取出し後の格納数を表示(2)
Console.WriteLine("現在の一番上は{0}", monsterk.Peek()); //専用要素を(取り出さずに)表示
演習 ex111304.cs
・要素数5の文字列配列を作り、スタックを用いて要素順序を反転しよう
作成例
string[] monsters = {"Veldra", "Rimuru", "Hakuo", "Benimaru", "Shuna"};
Stack<string> monsterk = new Stack<string>();
foreach (var w in monsters) { //文字列配列の全要素について
monsterk.Push(w); //スタックに押し込む
}
for(int i = 0; i < monsters.Length; i++) {
monsters[i] = monsterk.Pop(); //スタックの一番上から飛び出して配列へ
}
foreach (var w in monsters) { //文字列配列の全要素について
Console.WriteLine(w); //表示
}
演習 ex111305.cs
・先週作ったMonster構造体のオブジェクトをmonstermスタックに格納し、格納状態を表示しよう
struct Monster { //魔物を示す構造体
public int hp; //HP
public int mp; //MP
public string name; //名前
public Monster(int h, int m, string n) { //コンストラクタ①
hp = h; mp = m; name = n; //メンバの値に引数を代入
}
public Monster(int h, int m) { //コンストラクタ②
hp = h; mp = m; name = "名無し"; //メンバの値に引数や文字列を代入
}
public Monster(string n) { //コンストラクタ
hp = 0; mp = 0; name = n; //メンバの値に数値や引数を代入
}
public override string ToString() { //【追加】メソッド
return "HP = " + hp + " MP = " + mp + " 名前 = " + name; //メンバの値の文字列
}
};
提出:演習 ex111305.cs
販売本数ランキング 今回トップは「Fate/Samurai Remnant(フェイト/サムライレムナント)(Switch)」GO!
新型PS5が11月10日に発売。30%以上小型化、SSDストレージは1TBへ増量。価格はディスクドライブ搭載版が66980円、デジタル・エディションが59980円 GO!
生成AIは“割と雑なシステム”?―ゲームメーカー大手4社の専門家によるディスカッションをレポート【TGS2023】GO!
大手ゲームエンジン「Unity」のCEOが即時退任を発表―大きな成長を主導も、“Unity税”導入で大きな汚点を残す GO!
ホロライブ運営のカバーはライセンス収入増で営業利益率を高められるか?【ゲーム企業の決算を読む】GO!
Unreal Engineもサブスク形式で値上げに…ただし対象はゲーム以外―原因は「財務上の問題」?EGSの継続もアナウンス GO!
発覚から3年…2020年にセクハラ告発で退社した元副社長含むユービーアイソフト元幹部5人が逮捕か GO!
全銀ネットでシステム不具合 三菱UFJやりそななど、11の銀行で振込できず 原因、復旧時期不明 GO!
販売本数ランキング 今回トップは「Pikmin 1+2 (ピクミン1+2)(Switch)」GO!
バンク・オブ・イノベーションは『メメントモリ』の減衰を押しとどめることができるか【ゲーム企業の決算を読む】GO!
コナミ、ブロックチェーン技術活用Web3プロジェクト「PROJECT ZIRCON」とNFTマーケットプレイス「リセラ」を正式発表【TGS2023】GO!
『ブループロコトル』の敵AIは如何にして思考するかを細かく解説ー「企画意図をふるまいに反映させるために行ったこと」レポ【CEDEC2023】GO!
Unity、開発者の猛反発受け価格体系を改訂 GO!
Unityの代替として注目集まる!オープンソース2D/3Dゲームエンジン「Godot」月当たり支援額2倍、メンバー3倍の大躍進記録 GO!
『モンハンNow』が世界740万DL突破―リリース2日でダウンロード数トップに GO!
「バイオハザード RE:4」納品まで残り1カ月の現場、カメラ100台で“のぞき見” NHKがドキュメンタリー放送 GO!
セガ新作『Hyenas』開発中止―収益性悪化でCreative Assemblyなど関連会社の未発表新作も軒並み整理。特損は約143億に GO!
「iPhone 15」シリーズの「予想より熱くなる」問題、「iOS 17.1」で解消するとApple GO!
販売本数ランキング 今回トップも「ピクミン4(Switch)」GO!
gamescom award 2023の受賞作が発表。『ゼルダの伝説 ティアキン』が4冠に輝く【gamescom 2023】 GO!
バンダイナムコスタジオが語る、オンラインホワイトボードMiroを使ったリモートワークの効率化とコミュニケーションの円滑化【CEDEC2023】GO!
『FF16』顔のシワは形状の変形ではなくテクスチャのブレンドで表現。3Dキャラに必須の仕事人“リガー”のイロハと魅力【CEDEC2023】GO!
数値化された盛り上がりでシャウトを5段階に!条件設定や負荷軽減法が紹介された『ストリートファイター6』自動実況機能セッション【CEDEC2023】GO!
四半期過去最高益の任天堂―映画『マリオ』の大ヒットはなぜ重要?【ゲーム企業の決算を読む】GO!
NVIDIA、新発表「DLSS 3.5」によるAI強化のリアルタイムレイトレーシングを公開 GO!
販売本数ランキング 今回トップも「ピクミン4(Switch)」GO!
サイバーエージェントが下方修正、『ウマ娘』の反動で冬の時代到来か【ゲーム企業の決算を読む】GO!
連続投入した『モンスト』最新作が不発―MIXIの業績に黄色信号【ゲーム企業の決算を読む】GO!
【CEDEC2023】「Live2D Cubism」がCEDEC2023に登壇・展示―Unityでの活用方法を紹介 GO!
【決算】TCG好調のブシロード、『ヴァイスシュヴァルツ』が過去最高売上も純利益4割減 GO!
『ロケットリーグ』まさかの映画化?実話をもとにしたe-Sports映画「PLAY! ~勝つとか負けるとかは、どーでもよくて~」2024年春公開決定 GO!
【CEDEC2023】ロケーションゲーム特化のデジタルマップ開発技術を紹介―マップボックス・ジャパン「CEDEC2023」に初出展 GO!
「生成AIは著作権保護の検討が不十分」新聞協会など声明 「著作権法30条の4は大きな課題」GO!
X(旧Twitter)のイーロン・マスクCTO、「ブロック機能を削除する予定」とポスト GO!
「早急なパスワード変更を」 ピクブラ情報漏えいで、ニコニコやピクシブなどが注意喚起 GO!
【追記】Unity ゲーミングレポート 2023 (日本語版)公開 GO!
販売本数ランキング 今回トップも「ピクミン4(Switch)」GO!
スクエニが2024年3月期 第1四半期の決算を発表。『FF16』『FF ピクセルリマスター』の発売や既存店売上高の上昇でデジタルとアミューズメント事業は増収に GO!
ゲーム業界人材派遣のコンフィデンス、「高ROEランキングトップ」のカラクリとは【ゲーム企業の決算を読む】GO!
SNK社長 松原健二氏も登壇―欧州最大ゲーム開発者カンファレンス「devcom Developer Conference 2023」の追加講演発表 GO!
Amazon DynamoDBがゲーム開発の現場で活用される理由とは―ゲームクリエイターの知見を深める「AWS Dev Day 2023 Tokyo」ゲーム開発トラックレポ GO!
Cygames、ゲーム開発者向けカンファレンス「CEDEC」にて行った過去の講演動画をYouTubeに無期限公開 GO!
「YouTube Premium」日本でも値上げ 月100円アップ、1280円に GO!
『GTA V』による急激な需要拡大が原因?「Xbox Cloud Gaming」キュータイムが増加傾向でユーザーから不満噴出 GO!
ポケモンGOのリアルイベントで障害 「ドコモ回線に問題発生」と名指しで告知 GO!
販売本数ランキング 今回トップは「ピクミン4(Switch)」GO!
上場以来初の赤字に転落したUUUM、勝ち筋は利益率重視の「IP戦略」か【ゲーム企業の決算を読む】GO!
PS5の実売台数4,000万台達成!コミュニティーが選ぶ40タイトルも公開 GO!
クリエイターのための世界観「ISEKAI CREATORS」の『RPG Maker Unite』製サンプルゲーム公開―『RPG Maker MV/MZ』用DLCのSteam販売も開始 GO!
iOS 17にも「ゲームモード」開発中?AirPodsや無線コントローラが低遅延に、ベータから手がかり GO!
テーマは「コントロール」―UE使用作品制作ミニコンテスト「第20回UE5ぷちコン」エントリー受付中 GO!
サイバーエージェント、ゲーム事業で1億円の赤字 「ウマ娘」ヒット以来初の赤転 バブル崩壊か GO!
Microsoft決算は増収増益 「Azure OpenAI」の顧客は1万1000社超え GO!
Alphabet(google)決算は増収増益 クラウドの売上高が28%増と好調な他、YouTube広告も復調 GO!
「ちょっとした改変」も厳禁…Blizzardが『ディアブロ IV』Mod使用者をBANする方針を改めて明示 GO!
中国で『原神』チート開発・販売に関わった2名が逮捕―「リーク」に対する取り締まりも強化か GO!
金曜ドラマで“本物”のハッキングシーン 手口もコマンドも専門家が監修した「トリリオンゲーム」GO!
「マルウェア入り画像」で生成AIにサイバー攻撃 入力すると回答結果をハック、悪意サイトへの誘導も GO!
・サイトの「Aフローチャート」をクリックし、「Start」した時に「デバイス」ウィンドウが表示されたら:
1.「新規ファイルを作成する」をクリック
2.「白紙ファイル」「作成する」
3. ファイル名を「algo.xml」と入力して「保存」「保存」
・以降は変わっていません。「> フローチャート」を開いて作図しましょう。
※提出はいつもの提出フォームではなく
アルゴリズムⅠ・前期末課題提出フォーム https://ha233.rundog.org/?page_id=968 から、
フローチャートとプログラムを別々にZIP圧縮して提出すること
→ 受付を終了しました。
提出はいつもの提出フォームではなく
プログラミング言語Ⅰ・期末課題提出フォーム https://ha233.rundog.org/?page_id=963 から
→ 受付を終了しました。
次回(後期)予告:p.162「配列の受け渡しとconst型修飾子」から
講義メモ:memo20230724c.zip
p.158 ヘッダとインクルード
・printf、scanfなどのC言語が提供するライブラリ関数の場合、その関数原型宣言はstdio.hなどのヘッダファイルに格納されている ・よって「#include <stdio.h>」することで、ここに関数原型宣言が含まれるライブラリ関数を自由に呼び出せる ※ VC++などでは、stdio.hは仮想的存在でシステム内部に含まれている
p.159 関数の汎用性
・関数は部品であり、可能な限り使いまわす前提で設計し実装しよう ・そのためにも、関数間において受け渡す情報は引数で行うべきであり、ファイル有効範囲の変数や配列は不向き
p.160 配列の受け渡し
・引数に配列を指定できる ・呼び出し側(実引数)は、定義済の配列名を指定すれば良い ・関数側(仮引数)は「配列の型 配列の仮引数名[]」とし、[]をつけ、要素数は指定しない ・そして、別の引数などを用いて要素数を受け渡すのが基本
p.160 list0611.cpp
//p.160 list0611.cpp 英語の点数と数学の点数の最高点を求める
#include <stdio.h>
#define NUMBER 5 // 学生の人数
//--- 要素数nの配列vの最大値を返す ---//
int max_of(int v[], int n) { //戻り値型がintで、int型の配列とその要素数を受けとる関数
int max = v[0]; //仮に専用要素が最大値だとする
for (int i = 1; i < n; i++) { //次の要素以降の全要素について繰り返す
if (v[i] > max) { //最大値超なら
max = v[i]; //最大値更新
}
}
return max; //最大値を返す
}
int main(void) {
int eng[NUMBER]; // 英語の点数
int mat[NUMBER]; // 数学の点数
printf("%d人の点数を入力せよ。\n", NUMBER);
for (int i = 0; i < NUMBER; i++) {
printf("[%d] 英語:", i + 1); scanf("%d", &eng[i]);
printf(" 数学:"); scanf("%d", &mat[i]);
}
int max_e = max_of(eng, NUMBER); // 英語の最高点(配列と要素数を渡して最大値を得る)
int max_m = max_of(mat, NUMBER); // 数学の最高点(〃)
printf("英語の最高点=%d\n", max_e);
printf("数学の最高点=%d\n", max_m);
return 0;
}
補足:p.160 list0611.cpp について
・関数max_ofの中でNUMBERを用いれば、要素数を引数で受け取る必要はないが、関数の汎用性が下がるので、引数で渡すほうが良い
プログラミング言語Ⅰ・講義メモ
・p.154「List6-9」から
p.154 list0609.cpp
//p.154 list0609.cpp 読み込んだ正の整数値を逆順に表示
#include <stdio.h>
//--- 正の整数を読み込んで返す ---//
int scan_pint(void) { //②戻り値型がint、引数がない関数の定義
int tmp; //この関数内でのみ有効な作業用の変数(繰り返しの前で定義する)
do { //繰り返し開始
printf("正の整数を入力せよ:");
scanf("%d", &tmp);
if (tmp <= 0) { //入力が0以下?
puts("\a正でない数を入力しないでください。");
}
} while (tmp <= 0); //入力が0以下である間、繰り返す=先に進ませない
return tmp; //入力値を返す
}
//--- 非負の整数を反転した値を返す ---//
int rev_int(int num) { //⑤戻り値型がint、引数はint型1個の関数の定義
int tmp = 0; //この関数内でのみ有効な作業用の変数(繰り返しの前で定義する)
if (num > 0) { //引数の値が正であれば
do { //繰り返し開始
tmp = tmp * 10 + num % 10; //tmpを10倍してnumの1一桁を足す(tmpにnumの下1桁をつなぐ)
num /= 10; //「num = num / 10」と同じ(numの下1桁を取り除く)
} while (num > 0); //numに値が残っている間、繰り返す
}
return tmp; //numを反転した結果が入っている作業変数の値を返す
}
int main(void)
{
int nx = scan_pint(); //①正の整数を読み込んで返す関数を読んで、③戻り値を代入
printf("反転した値は%dです。\n", rev_int(nx)); //④反転した結果を返す関数を読んで、⑥戻り値を表示
return 0;
}
《自由参加課題》アレンジ演習:p.154 list0609.cpp
・入力値の末尾が0の場合に、0から表示されるようにしたい ・入力桁数を4桁に固定して(1000から9999まで)実装しよう
p.155 ブロック有効範囲
・ブロック{}内で宣言した変数はブロック内でのみ有効なこと
・よって、有効範囲が異なれば同じ名前の変数でも異なるものとみなされるので便利(名前の重複によるバグを回避できる)
※ なお、C#では有効範囲が異なっても1ソースファイル内では同じ名前の変数は使えないので注意。
p.156 ファイル有効範囲
・ブロック{}外で宣言した変数はソースファイル全体で有効なこと
・よって、宣言がまとめて行えて便利に見える場合があるが、宣言位置と利用位置の間が空きやすく、有効範囲を絞れないことによる
ミスを招きやすいので注意
・関数と関数の間のデータの受け渡しを楽にする効果があるが、ミスの原因になりやすいので、できるかぎり引数で渡すことが望ましい
・ブロック内で定義していない変数や配列を利用をする場合、外部で宣言していることを示すキーワード「extern」を用いることができる。
ただし、同じソースであれば省略可。
※ 外部での宣言を明示するために、また、将来、ソースを分割する可能性がある場合を考えて、extern指定が求められることがある
p.157 関数原型宣言
・プロトタイプ宣言ともいい、関数の呼び出しに必要な情報である「戻り値型 関数名(引数リスト)」のこと ・これをファイル有効範囲で記述しておけば、その内容の記述が後方(や、別のソースファイル)にあってもコンパイル可能になる ※ 関数原型宣言がないその時点で未定義な関数を呼ぶと、VC++ではエディタ上にはエラー表示されないがコンパイルするとエラーになる ※ 呼び出す関数が同じソースにある場合、先に定義しておけば関数原型宣言は不要なので、そのほうが望ましいが、将来、 ソースを分割する可能性がある場合を考えて、関数原型宣言が求められることがある。
p.156 list0610.cpp
//p.156 list0610.cpp 最高点を求める
#include <stdio.h>
#define NUMBER 5 // 学生の人数
int tensu[NUMBER]; // 配列の定義(ファイル有効範囲)
int top(void); // 関数topの関数原型宣言(top関数の定義を後方や別ファイルに置けるように)
int main(void) {
extern int tensu[]; // 配列の宣言(省略可):外部で宣言した変数を用いることを示す
printf("%d人の点数を入力せよ。\n", NUMBER);
for (int i = 0; i < NUMBER; i++) {
printf("%d:", i + 1);
scanf("%d", &tensu[i]);
}
printf("最高点=%d\n", top()); //top関数を呼んで戻り値を表示
return 0;
}
//--- 配列tensuの最大値を返す関数topの関数定義 ---//
int top(void) {
extern int tensu[]; // 配列の宣言(省略可)):外部で宣言した変数を用いることを示す
int max = tensu[0]; //仮に先頭要素が最大値だとする
for (int i = 1; i < NUMBER; i++) { //次の要素から残り全要素について繰り返す
if (tensu[i] > max) { //最大値超なら
max = tensu[i]; //最大値更新
}
}
return max; //最大値を返す
}
販売本数ランキング 今回トップも「ゼルダの伝説 ティアーズ オブ ザ キングダム(Switch)」GO!
KADOKAWAはアニメ発のゲーム開発でヒットの再現性を高められるか【ゲーム企業の決算を読む】GO!
インディーゲーム/VTuberのモーションキャプチャも低価格で提供ー「MyDearestモーキャプスタジオ」一般向けにレンタル開始 GO!
Mint Town、10億円の資金調達を実施―ゲームクリエイターを中心に採用強化 GO!
グリー子会社REALITY XR cloud、『スタディサプリ ENGLISH for KIDS』に開発協力 GO!
「ROG Ally」注目デバイス故か…過去にもDualSenseドリフト問題など提起の米法律事務所が不具合の情報提供呼びかけへ―集団訴訟へ発展の可能性も GO!
ガチャは子供に悪影響?英国ゲーム業界がルートボックスを制限する業界原則を発表―確率開示や返金の容易化を含む11項目 GO!
販売本数ランキング 今回トップは「ゼルダの伝説 ティアーズ オブ ザ キングダム(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!
・ありがとうございました。
簡略化できるコードはなんでも簡略化できるよう心がけたいです。
・ペース丁度良かったです。
・難しかった
・今日のC#の授業は、「検索とソートまとめ」について学びました。ライブラリメソッドのことやそれを用いたフローチャートを制作しました。
・今回はいつもより追い付くことができました。
二週間後も頑張ります
・ペース良かったです
・なんとか出来ました。
確認のほどよろしくお願い。
・ペースちょうどよかったです
・ok
・ペース丁度良かったです
・講義のペースはちょうど良かったです。
・ソートのプログラムが意外と簡単にできました。
・ありがとうございました。
・ちゃんとフローチャートをかけるようにします。スピードはちょうどよかったです。
・前期の提出のためにも難しかったところを復習します。
・2次元配列のソートやジャグ配列について学習した。覚えにくい仕組みで難しい。
ペース大丈夫です。
・使えば使うほど配列は便利だなと思った
ペースちょうどよかったです!!
・6/26 アルゴリズムⅠ
欠席分の提出
・先週の提出課題です
よろしくお願いし
・授業ありがとうございました。
理解できるまで自分のペースで進めることも大切だと気付きました。
・復習をしっかりしようと思います
・復習してきます
・今日のC言語の授業は、「関数」について学びました。関数の引数として変数指定できる「値渡し」や、関数に渡す引数として式を記述できるものなど色々な関数式を学びました。
・分かりやすかったです
・講義のペースはちょうど良かったです。
・ペースちょうどよかったです
・新たに自作の関数を用意することよって、より便利に多彩なことができることがわかりました。
・ok
・しっかりと授業についていけました。
ペースはちょうどいいです。
・ペース丁度良かったです!
・複雑になってきましたが、何とか理解することができました。
・休みの分も取り返せるように頑張ります
・関数の定義や呼び出し、汎用性について理解した。
ペース大丈夫です。
・今回は分かりやすかったです。
・授業に追い付くことができました。
次回も追いつけるよう頑張ります。
・今回のは結構理解できました
ペースちょうどよかったです!!
・今日もスムーズで良かったです。
・なんとか出来ました。
確認のほどよろしくお願い。
・6/26 プログラミング言語Ⅰ
欠席分の提出
・次はテストなのでそれまでに復習し万全の状態で頑張りたいと思います。
・自分が課題をどれが出せてて、どれが出せていないかの確認方法ってありますか?
皆さんからは確認できませんので、ご自分の記憶やメモにしたがってください。何度提出してもOKです。
※今期は10科目を担当しています。1人1人の集計はこれからになりますので、個別の返答はできません。
販売本数ランキング 今回トップは「超探偵事件簿 レインコード(Switch)」GO!
ANYCOLORの作戦勝ちか?カバーに差をつけた戦略の真髄とは【ゲーム企業の決算を読む】GO!
翻訳、コード管理、NPC運用まで…ゲーム開発におけるAI活用の多様な事例と可能性ー日本マイクロソフトのセッションをレポート【GTMF2023】GO!
ゲーム開発QA工程をAIで自動化する「Playable!」提供開始―無料トライアルも開始 GO!
「東京ゲームショウ2023」来場者向け公式サイトオープンー「ビジネスデイ」事前登録は7月26日 GO!
アップル、Vision Pro用に自社製VRコントローラーを計画せず。サードパーティ製品に対応する予定もなし GO!
日本初「eスポーツ×新卒採用プラン」ーFENNELが運営するコミュニティと連携して2社が実施 GO!
「QB」大活躍!1万人以上のチーターをBANした新たなPCチート対策『レインボーシックス シージ』コンソール版マウス・キーボード排除も大きく進む GO!
Twitter、ThreadsをめぐってMetaを提訴すると脅迫 GO!
次回予告:前期ラストで時間内課題作成(フローチャートとプログラム)テーマは「ソート」
講義メモ:memo20230703a.zip
自由度の高い配列(C#のジャグ配列)
・Java言語などでは配列の配列によって2次元以上の配列を表現している
つまり、a[]={1,2}、b[]={3,4,5} とすると ab[][] = {{1,2},{3,4,5}} とできる
・よって、配列が「要素数×要素数」ではなくても良い
・これはC/C++の配列や、C#の通常の配列では表現できない
・しかし、C#のジャグ配列を用いると可能
・ジャグ配列の宣言と生成: 型[][] 配列名 = new 型[要素数][];
・ジャグ配列の初期化の書式: 型[][] 配列名 = { new 型[]{値,…}, … }
例: int [][] aa = { new[] {1,2}, new[] {3,4,5} };
・ジャグ配列に対するforeach文は2次元では2重ループになる
foreach (var wa in aa) { //ジャグ配列aaの全要素配列について繰返す
foreach (var ww in wa) { //要素配列を入れた作業変数waの全要素について繰返す
Console.WriteLine(ww);
}
}
ジャグ配列の線形探索:アルゴリズム
①ジャグ配列の全要素配列について下記を繰返す ・要素配列の全要素について下記を繰返す ・探索値と要素値が等しければ「ある」と表示して抜ける ②なかった場合は「ない」と表示する
参考:通常の配列の場合
int[,] val = { {10,20,30 },{40,50,60 } }; //元の2次元配列
Console.Write("検索値:");
var goal = int.Parse(Console.ReadLine());; //検索値
int i = 0, j = 0;
bool f = false; //完了フラグをオフにしておく
for(; i < 2; i++) {
for(j = 0; j < 3; j++) {
if(val[i, j] == goal) {
Console.WriteLine("[{0}][{1}]にある", i, j); //先頭が1番目だとする
f = true; //完了フラグオン
break; //内側のループを抜ける
}
}
if(f) { //完了フラグがオンなら
break; //外側のループも抜ける
}
}
if (!f) { //完了フラグがオフのままになっていたら
Console.WriteLine("見つからない");
}
自由参加課題
最初に見つかった位置を「aa[1][2]にあります」というように表示しよう。
提出:ジャグ配列の線形探索:プログラム
ソート:ライブラリメソッドを用いて2次元配列をソート
・「Array.Sort(配列名);」は1次元配列専用なので、2次元配列を直接には扱えない
・例えば int[,] val = {{70,20,30},{40,50,60}}; をソートしたら、
{{20,30,40},{50,60,70}} となるようにしたい。
ソート:ライブラリメソッドを用いて2次元配列をソート:アルゴリズム
① 作業用の1次元配列を2次元配列の全要素数(配列名.Length)で用意する ② 2次元配列の全要素を作業用の1次元配列にコピーする ③ 作業用の1次元配列をライブラリメソッドを用いてソート ④ 作業用の1次元配列の全要素を2次元配列に書き戻す ・フローチャートにしよう※ XML:https://ha233.rundog.org/wp-content/uploads/2023/07/2dsort.zip
ソート:ライブラリメソッドを用いて2次元配列をソート:プログラム例
int[,] val = {{70,20,30},{40,50,60}}; //元の2次元配列
int[] w = new int[val.Length]; //作業用の1次元配列を2次元配列の全要素数で用意する
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 3; j++) {
w[i * 3 + j] = val[i, j]; //2次元配列の全要素を作業用の1次元配列にコピー
}
}
Array.Sort(w); //作業用の1次元配列を昇順にソート
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 3; j++) {
val[i, j] = w[i * 3 + j]; //作業用の1次元配列の全要素を2次元配列に書き戻す
}
}
foreach (int i in val) { //2次元配列の全要素について繰返す
Console.WriteLine(i);
}
ソート:ライブラリメソッドを使おう
・C#は配列の要素の昇順整列に特化したライブラリメソッドを提供してくれている ・よって、これだけが目的なら「Array.Sort(配列名);」を実行すれば良い
ソート:ライブラリメソッドを使おう:プログラム
・上のプログラムを「Array.Sort(配列名);」を試す形に書き換えよう。
作成例
int[] val = {80,20,10,40,50,60}; //元の配列
Array.Sort(val); //配列の全要素を昇順にソート
foreach (int i in val) { //配列の全要素について繰返す
Console.WriteLine(i);
}