🧭 1. ポインタの本質:「アドレスを記憶する変数」
まず前提として、ポインタとは「**メモリ上の住所(アドレス)**を記憶する変数」です。
たとえば:
int a = 10;
int *p = &a;
ここで p は a のメモリ上の場所(アドレス)を覚えています。
🧠 メモリ図:
| 変数 | アドレス | 内容 |
|---|---|---|
| a | 0x1000 | 10 |
| p | 0x2000 | 0x1000(aの場所) |
🧩 2. 「型付き」とは何か?
C言語のポインタが単なる「数値アドレス」ではなく “型を知っている” という点が重要です。
ポインタには必ず「どんな型のデータを指すか」がセットになっています。
int *p; // int型を指すポインタ
double *q; // double型を指すポインタ
char *r; // char型を指すポインタ
この「型情報」によって、ポインタが行うアドレス計算やメモリ参照の方法が決まります。
⚙️ 3. 型によってアドレス計算の単位が変わる
Cのルール:
ポインタの加算・減算は「その型のサイズ単位」で行われる。
例:
int *p; // int は 4バイト
p = p + 1; // 4バイト先に移動
char *r; // char は 1バイト
r = r + 1; // 1バイト先に移動
🧮 実際の内部処理では:
p + n = (元のアドレス) + n × sizeof(型)
つまり、int *p; p++ → アドレス + 4char *r; r++ → アドレス + 1double *q; q++ → アドレス + 8
のように自動的に型サイズ分進みます。
これが「型付きアドレス」という意味です。
単なる数値アドレスなら、どの型を指しているかなんて分かりません。
🔍 4. 型情報は「値の解釈方法」も決める
もうひとつの重要な点は、ポインタの型はメモリの中の値をどう読むかも決める、ということです。
たとえば:
int a = 0x41424344; // メモリに 44 43 42 41 が格納されているとする
int *p = &a;
char *c = (char *)&a;
| 型 | 参照の仕方 | 結果(例:リトルエンディアン) |
|---|---|---|
*p | 4バイトを整数として読む | 1094861636 |
*c | 1バイトを文字として読む | ‘D’ (0x44) |
つまり、同じアドレスを指していても型が違えば読み方が違うのです。
これも「ポインタが型付きアドレスである」ことの大きな意味です。
🧠 5. 図で整理すると
メモリ: [0x1000] [0x1001] [0x1002] [0x1003]
内容: 44 43 42 41
| 宣言 | 意味 | 参照結果 |
|---|---|---|
int *p = (int*)0x1000; | 4バイトをintとして扱う | 0x41424344 |
char *c = (char*)0x1000; | 1バイトをcharとして扱う | ‘D’ (0x44) |
同じアドレスでも、型が違えば意味が違う。
C言語のポインタは「アドレス+型情報」のペアなのです。
✅ まとめ
| 項目 | 内容 |
|---|---|
| ポインタの本質 | メモリ上のアドレスを保持する変数 |
| 「型付き」とは | そのアドレス先のデータ型のサイズと意味を知っている |
| 影響① | p++ の移動距離が型サイズに比例する |
| 影響② | *p の読み方(1バイト/4バイト/8バイトなど)が型に依存する |
| 結論 | ポインタは「アドレス」ではあるが、単なる数値ではなく「どの型のデータを指すアドレスか」を含む |

コメント