C言語のポインタを理解する上で、前提知識として必要なのがメモリの概念です。この空間イメージが出来るかどうかで、その後の理解が全く異なると言っても良いです。そのため、今回は少しプログラムから離れて、雑談形式でメモリについて説明していきたいと思います。
例えば Z80 CPU を搭載したパソコンでは電源を入れると、メモリ空間の 0 番地から実行が開始されます。このようにリセット時に最初に PC(プログラムカウンタ)が設定される場所に、BIOS や IPL や システム ROM 等の基幹ソフトウェアが配置されています。
※ 2023/01/27-1200
0 番地から始まるのは Z80 等の CPU だけだったようですので文章を改変しました。
--
いきなりここに飛んで来ちゃった人は、よろしければ下記からご覧ください。
- メモリのアドレス
メモリは必ず 0 番地から始まっています。そして、そのメモリ空間は 1,2,3,4,5…と続いていきます。コンピュータのアドレスは16進数で表現されます。そのため、アドレスが続いていくと 8,9,A,B,C,D,E,F と続きます。そして、その次は桁上りをして 10 となります。
その16進数については、既に私のブログで説明しています。
例えば Z80 CPU を搭載したパソコンでは電源を入れると、メモリ空間の 0 番地から実行が開始されます。このようにリセット時に最初に PC(プログラムカウンタ)が設定される場所に、BIOS や IPL や システム ROM 等の基幹ソフトウェアが配置されています。
※ 2023/01/27-1200
0 番地から始まるのは Z80 等の CPU だけだったようですので文章を改変しました。
- 8bit コンピュータの場合
1980年代は 8bitパソコン全盛期です。様々な機種が発売されましたが、その殆どは 8bitであり、また大半が Z80 または互換チップとなっていました。ご承知の人も多いと思いますが 8bitのメモリ空間は最大で 64KB です(バンクを除く)。64KB は 64×1024 = 65536B(バイト)という大きさで、とても空間的には狭いのです。ですが、狭いので説明しやすいので、まずはこちらで説明します。
最大で 65536 ということは 0 番地から数えていくと、FFFF まで空間が続きます。つまり 8bitパソコンのメモリ空間は 0 ~ FFFF までとなります。16進数で 4桁固定ですので、記述としては 0000 ~ FFFF と書くのが一般的です。


8bit コンピュータと言えど、アドレスに関しては 16bit のサイズが用意されているんですね。上記のようなメモリの図をメモリマップと言います。
※ 汚れを拭き取るにはティッシュじゃなくてキムワイプを使うと良いです。ティッシュだと削れたようなカスが付着しますが、キムワイプだと何も残りません。これは一家に…いや一部屋と一箱ではないかと。- 32bit コンピュータの場合
8086 等の 16bit コンピュータを飛ばして 32bit で説明します。32bit コンピュータのメモリ空間は、大凡 32bit のサイズがあります。32bit のアドレス空間は 00000000 ~ FFFFFFFF となります。10進数で言えば 4,294,967,296B あります。VS2022 の C言語で int とすると、32bit の大きさが用意されますが、これは、現在の CPU で扱いやすいためです。
※ 今は 64bit CPU が殆どですが、互換性のために int は 32bit としているコンパイラが多いです。
つまり 32bit コンピュータは 4,294,967,296B÷1024÷1024÷1024 = 4GB のメモリ空間が存在することになります。現在の Windows OS は x64 が主流ですが、ちょっと前まで x86 がメインだったのは、CPU が 32bit が多かったため、扱えるメモリ空間が最大で 4GB だったためですね。実際には 3.2GB 程度でユーザーエリアは打ち止めになっていましたが 0.8GB は BIOS や OS などが専有していたため、4GB 全てを使えなかったのです。
メモリマップ的にはこんなイメージとなります。


- メモリの使い方
メモリの位置を番地(アドレス)と呼ぶように、イメージとしては土地にとても似ています。例えば、エムツーは郵便番号 2701143 に位置しています。この郵便番号がコンピュータで言うところのアドレスに相当します。この場所にエムツーがあります。このエムツーが変数名です。
現実の土地区画では、番地ごとのサイズはまちまちですが、コンピュータ内部の土地区画は最低単位は 1バイトです。最低区画サイズは固定です。1バイト…と言いたいところですが、CPU のアクセス単位となりますので、実際にはもう少し大きい単位が最低区画サイズになります(おそらく4バイト単位)。その場所に空きがあれば、そこに建物が建てられます。その建物が変数であり建物の名前が変数名です。
int 型の変数 sample を定義したとします。sample が建物の名前で、int が必要とする土地区画サイズです。int のサイズは 4バイトですから、コンパイラはメモリの中から 4バイト連続で空いている場所を探して、その場所に sample という名前をつけます。これが変数宣言です。どの場所に割り当てられるかは、コンパイラが自動で行います。そして、sample という名前で自動的にその割り当てられたメモリに適切に数値を配置していきます。
※ 数値の格納は CPU により入れ方が異なります。
※ 数値の格納は CPU により入れ方が異なります。
よくメモリが不足したなんて言いますが、変数割当に必要な連続したメモリの空きがなくなって、変数が割り当てられなくなる事を言うんですね。
- C言語のポインタとは
通常、変数名を用いればメモリのどの場所を使っているかを意識せずとも、コンパイラが自動的にその変数に割り当てられたメモリを使ってくれます。ポインタは変数の場所をプログラマが意識する仕組みなのです。そのため、ポインタはアドレスを直接扱うことになりますので、サイズは実行される環境によって変化します。8bit コンピュータのポインタは、16bit のサイズですし、32bit コンピュータのポインタは 32bit のサイズとなります。
次回からは、このポインタを使うと何が出来るのか、何が便利なのか、そして何が危険なのかを説明していきます。
※ 2023/01/17-1200 補足
アドレスは住所でありメモリが物理的に存在するかどうかは不明です。メモリが物理的にない状態とは今回の例えで言うなら、その住所に行ったら土地がすっぽり抜け落ちてて、亜空間になっているような状態です。建物なんて建てられませんよね。その他今回はメモリの概念の説明用なので、多少曖昧に書いてあります。分かる人をターゲットにしていないので悪しからずご了承ください。
※ PCやゲーム機やテレビやビデオの裏側など、配線がごちゃっとしがちな場所で、このチューブを使ってケーブルをまとめるとかなりすっきりします。
※ 2023/01/17-1200 補足
アドレスは住所でありメモリが物理的に存在するかどうかは不明です。メモリが物理的にない状態とは今回の例えで言うなら、その住所に行ったら土地がすっぽり抜け落ちてて、亜空間になっているような状態です。建物なんて建てられませんよね。その他今回はメモリの概念の説明用なので、多少曖昧に書いてあります。分かる人をターゲットにしていないので悪しからずご了承ください。
※ PCやゲーム機やテレビやビデオの裏側など、配線がごちゃっとしがちな場所で、このチューブを使ってケーブルをまとめるとかなりすっきりします。
コメント