ポインタ

アドレスと値

変数に値を代入したとき、それがコンピュータのメモリ上にどのように 格納されているかを復習しよう。以下の例では変数の格納されるアドレスが 切り良く 0x1000 番地(16進数)や0x2000番地になっ ているが、実際は必ずしもそうならない。

整数の場合

int a = 5;

と宣言した場合、メモリ上には次のように変数用の保存場所が確保され、 値である5が入れられる。

↓a
0x10000x1001 0x10020x1003 0x1004 ………
5????? ?????

この場合、変数aのアドレスを知りたい場合は、 頭に&をつけて、&a とすればよい。

続いて、文字列を考えよう。

char s[] = "hoge";

と宣言した場合のメモリ上の様子は以下のようになる。


↓s

0x20000x2001 0x20020x2003 0x20040x2006 ………
ASCIIコード 0x680x6f 0x670x65 0x00 ??????????
文字 'h''o' 'g''e' '\0' ??????????

変数sは配列となる。配列の各要素と、アドレスの関係は 以下のようになる。

各要素 s[0]s[1] s[2]s[3] s[4]
そのアドレス 0x20000x2001 0x20020x2003 0x2004
アドレス表記 &s[0]&s[1] &s[2]&s[3] &s[4]

ポインタ

C言語では、何かの値が入っているアドレスを指し示す変数を持つことができる。 どこかに保存されている値を取り出すために持っているアドレス値のことを ポインタという。ポインタとして機能する変数のことを ポインタ変数という。具体例を見よう。

ポインタと配列

int型の配列

int x[5] = {10, 20, 14, 99, 30};

を宣言する。この状態でポインタ変数 p を宣言し、それが配列 x[] の先頭を指し示すようにするには以下のように記述する。

int *p;
p = x;

ポインタ変数は、変数の頭に * をつける。上記の2行をまとめて

int *p = x;

と書くこともできる。x は配列x[] の先頭のア ドレスを示すことに注意すると、ポインタ変数pはxの アドレスを持つ。

↓p (= x = 0x1000)
0x10000x1001 0x10020x1003 0x1004
x[0]x[1] x[2]x[3] x[4]
1020 1499 30

このとき、*p と書くと、そのアドレスに入っている int型の値を取り出すことができる。つまり、

さらに、配列x[] の次の値を取り出したいときは pに1を加えたアドレスを * で参照すると良い。 つまり、

*(p+1)

または

p++;
*p

または

*(++p)

などとするとx[1]の要素である20を取り出すことができる。

int *p と宣言したので、p は「intの値を参照するため」 に増減値が決定する。p+1 とした場合も、実際には アドレス1番地分が足されるのではなく、intの値のアドレス幅(=4)だけ 加算される。プログラムのときにはpを数値的にいくつ増やすべきかは 気にしなくて良い。


目次