導入
ポインタを学ぶ前に、まず「メモリ(memory)」を知りましょう。変数は魔法で存在しているのではなく、メモリという場所に、確かな「住所」を持って置かれています。
説明
コンピュータのメモリは、同じ大きさの小さな箱が、一列にびっしり並んだものだと考えてください。箱1つの大きさは 1バイト(=8ビット=0か1が8個)です。そして、それぞれの箱には先頭から順に 0, 1, 2, 3 … と通し番号がついています。この番号が アドレス(住所・番地) です。
flowchart TB
subgraph MEM["メモリ = 番地つきの箱が一列に並んだもの"]
direction LR
b0["1000番地"]
b1["1001番地"]
b2["1002番地"]
b3["1003番地"]
b4["1004番地"]
b5["1005番地"]
end
「ビット」は 0 か 1 のどちらかを表す最小単位です。これが8個集まって1バイト、というのがメモリの数え方の基本です。
- ビット (bit) … 0 か 1(電気が ON か OFF か)。情報の最小単位。
- バイト (byte) … ビット8個ぶん。メモリの箱1つ=1バイト。
- アドレス … 箱1つ1つについた通し番号(何番目の箱か)。
変数を作ると、コンピュータは「この変数用に、ここからここまでの箱を使うぞ」とメモリの一区画を確保し、そこに値を書き込みます。型によって必要な箱の数(バイト数)が違います。実際に何バイト使うかは sizeof で調べられます。
#include <stdio.h>
int main() {
printf("charは %d バイト\n", (int)sizeof(char)); // 1
printf("intは %d バイト\n", (int)sizeof(int)); // 4
printf("doubleは %d バイト\n", (int)sizeof(double)); // 8
int x = 5;
printf("x = %d (intなので %d バイトの区画を使う)\n", x, (int)sizeof(x));
return 0;
}
たとえば int x = 5; と書くと、int は 4バイトなので、メモリのどこか連続した4つの箱がまとめて x 用に確保され、そこに 5 が書き込まれます。その区画の先頭の番地こそが「x の住所」です。
flowchart TB
subgraph MEM["int x = 5; を実行したメモリのようす"]
direction LR
a["1000番地"]
b["1001番地"]
x0["1002番地"]
x1["1003番地"]
x2["1004番地"]
x3["1005番地"]
c["1006番地"]
end
x0 -.->|"この4バイトに 5 が入る(先頭 1002番地 が x の住所)"| x3
ここで大事なのは、変数には「名前(x)」だけでなく「住所(何番地にあるか)」もあるという事実です。ふだんは名前で読み書きしていますが、住所を直接あつかう道具が――次のレッスンで学ぶポインタです。
やってみよう
sizeof にいろいろな型(char、int、double、long)を渡して、型ごとに必要なバイト数(箱の数)が違うことを確かめましょう。配列 int a[10]; の sizeof(a) も見てみると、「4バイト × 10個 = 40」になるはずです。
演習
sizeof(double) の値を表示してください(結果は 8)。これは「double 型の変数1つが、メモリ上で何個の箱=バイトを使うか」を表します。printf の書式は %d を使い、(int) でキャストしてください。
ヒント1を見る
printf("%d\n", (int)sizeof(double));。