次に単独のデータではなく、配列に対してどのようにアドレスが対応しているかをみてみます。例として、下記のプログラムを実行した場合、char data[3]; /* 配列の宣言 */ char *ptr; /* ポインタ変数の宣言 */ ptr = &data[0]; data[0] = 'a'; /* 文字データの代入 */ data[1] = 'b'; data[2] = 'c';
メモリ領域の状況は、上図のようになります。
- 配列の宣言が行われた時点でメモリ領域には連続した箱が用意され、アドレスも連続した値となります(アドレスの値は環境によって変化します)。
- 配列の添字部分を省略すると(例の場合data)、それ自信が配列の先頭アドレスを指すことになります。よって、data と &data[0] は同じ意味です。
- 先頭アドレス以外のアドレスは、先頭アドレスに添字の数を足すことで表現可能です。例では、data[2] のアドレスは data + 2 あるいは &data[2] で表現できます。
- ポインタ変数 ptr が data[0] のアドレスを指す場合、data[0]の内容は *ptr あるいはptr[0]で参照できます。また、上記の方法と同様に data[2] の内容は*(ptr+2) あるいはptr[2]で参照可能です。
- ここで配列の名前 data は定数であることに注意する必要があります。つまり、ptr = data;や ptr++は意味のある演算となりますが、data = ptr; や data++のような文は誤りとなります。