カニゲーム攻略日記ブログ

beatmaniaIIDXやハースストーンなどのゲーム攻略日記。主にまったり勢。2016年にIIDX皆伝になった

プログラムはなぜ動くのか  第4章 四角いメモリーを丸く使う

目次

モリーやディスクの構造を物理的(ハードウェア)にも論理的(ソフトウェア)にもイメージできる

モリーの物理的な仕組み

モリーの本体は電子部品:モリーIC

以下サイトの図が、本に書いてある図とほぼ同じ
説明もだいたい同じ
https://zenn.dev/masahiro_toba/books/436c018f5cd4e2/viewer/ae91d6

例:0101010101番地に11110000データを書き込む場合

  1. アドレスを指定(A0~A9 = 0101010101)
  2. データを入力する(D0~D7 = 11110000)
  3. WR(書き込み)を1にする

例:0101010101番地からデータを読み込む場合

  1. アドレスを指定(A0~A9 = 0101010101)
  2. RD(読み込み)を1にする
  3. データが出力される(D0~D7 = 11110000)

モリーの論理的な仕組み(ビルディング)

モリーの実体はメモリーICだけど
プログラマから見れば個々のフロアにデータが格納されたビルディングだと思えばいい

これも以下サイトの図が、本に書いてある図とほぼ同じ
説明もだいたい同じ
https://zenn.dev/masahiro_toba/books/436c018f5cd4e2/viewer/ae91d6

データ型でメモリーのサイズが異なる

例:

char a;   //1byte
short b;  //2byte
long c;   //4byte

a = 123;
b = 123;
c = 123;
アドレス モリーの内容 データ型
00000000 123 char(1byte)
00000001 123 short(2byte)
00000002 0 short(2byte)
00000003 123 long(4byte)
00000004 0 long(4byte)
00000005 0 long(4byte)
00000006 0 long(4byte)

下位(00000000)からa,b,cを詰めた

ポインタ

例:ポインタ d,e,*f がいずれも00000000番地の場合

char *d;
short *e;
long *f;
アドレス モリー ポインタ*d(1byte) ポインタ*e(2byte) ポインタ*f(4byte)
00000000 1byte ここまで読み書きできる ここから ここから
00000001 1byte - ここまで読み書きできる ここも
00000002 1byte - - ここも
00000003 1byte - - ここまで読み書きできる

モリーを工夫して使う基本は配列

理由:

  • 配列がメモリーの物理的な構造そのもの
  • 配列を使うことで効率的なプログラミングが可能(短いコードで順番に読み書きできる)

例:配列 g,h,i がいずれも00000000番地の場合

char g[100];   //1byte
short h[100];  //2byte
long i[100];   //4byte
アドレス モリー g[100](1byte) h[100](2byte) i[100]\d(4byte)
00000000 1byte g[0] h[0] i[0]
00000001 1byte g[1] h[0] i[0]
00000002 1byte g[2] h[1] i[0]
00000003 1byte g[3] h[1] i[0]
... ... ... ... ...

データ構造

配列のみだと効率化に限界があるので
工夫して配列を使う

図は以下参考

https://products.sint.co.jp/topsic/blog/data-structure

表は以下

データ構造 利点 用途 応用
配列 (Array) インデックスを使った要素へのアクセスが高速 シンプルなデータの格納、要素数が固定の場合 行列計算、文字列操作
スタック (Stack) LIFO(後入れ先出し)構造、追加・削除が高速 一時的なデータ保存、関数呼び出し 逆ポーランド記法深さ優先探索
キュー (Queue) FIFO先入れ先出し)構造、追加・削除が高速 タスクのスケジューリング プリンターの印刷待ち行列幅優先探索
リングバッファ 循環構造、追加・削除が高速、メモリ効率が良い データの連続ストリーム プロデューサー/コンシューマ問題、音声処理
リスト (List) 素数が可変、要素の追加・削除が容易 順序付けられた要素の格納、要素数が可変の場合 ポリゴンの頂点リスト、プロセス管理
木構造 (Tree) 階層的なデータの表現、探索・挿入・削除が高速 データベースやファイルシステムのインデックス 構文解析、意思決定ツリー
ハッシュテーブル キーに基づく高速な検索・挿入・削除 キーと値のペアの格納 データベースインデックス、キャッシュ

トルエンディアンの名前の由来

トルエンディアン(Little-endian)という名前の由来は、イギリスの作家ジョナサン・スウィフトの『ガリバー旅行記』に関連しています。この物語の中で、2つの国がある卵を割る方法について戦争を繰り広げます。一方の国は卵を大きい方(ビッグエンド)から割ることを主張し、もう一方の国は小さい方(リトルエンド)から割ることを主張していました。

この物語は、ささいな違いによって大きな論争が生じることを風刺しています。同様に、コンピュータの世界では、データのバイト順序(エンディアン)が異なるシステム間で互換性の問題が生じることがあります。

トルエンディアンは、最も重要度の低いバイト(リトルエンド)が最初に格納されるバイト順序を指します。この名前は、『ガリバー旅行記』のリトルエンド派にちなんで命名されました。逆に、最も重要度の高いバイト(ビッグエンド)が最初に格納されるバイト順序は、ビッグエンディアン(Big-endian)と呼ばれます。