目次
メモリーやディスクの構造を物理的(ハードウェア)にも論理的(ソフトウェア)にもイメージできる
メモリーの物理的な仕組み
以下サイトの図が、本に書いてある図とほぼ同じ
説明もだいたい同じ
https://zenn.dev/masahiro_toba/books/436c018f5cd4e2/viewer/ae91d6
例:0101010101番地に11110000データを書き込む場合
- アドレスを指定(A0~A9 = 0101010101)
- データを入力する(D0~D7 = 11110000)
- WR(書き込み)を1にする
例:0101010101番地からデータを読み込む場合
- アドレスを指定(A0~A9 = 0101010101)
- RD(読み込み)を1にする
- データが出力される(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)と呼ばれます。