char *p
配列は要素型のオブジェクトが連続してメモリに記憶されるデータであり,配列型は式で使うと第1要素のアドレスに変換され,そのアドレスのメモリ箇所に入っている値に直接アクセスできる方法(間接参照)があることも見ました。ポインタ型データ,すなわち,アドレスについて理解したことでしょう。ここでは,ポインタ型データを扱うための変数,「ポインタ」の導入方法を見ます。
ポインタを導入するためには,宣言子にポインタ宣言子を用います。
■ポインタ宣言子(Pointer Declarator)
*識別子
T *識別子 = 初期化子;
と宣言しなければなりません。この宣言よって得られる変数 識別子
がT
へのポインタ型データに対するポインタです。型は「T
へのポインタ」であり,それは
T *
となります。初期化子には,T
へのポインタ型データを代入します。
/* Example 10.5 */ #include <stdio.h> int main(void) { char str[] = "ABCDEFG"; char *p = str; printf("str[0] = '%c' [%p]\n", *p, p); return 0; }
これは Example 10.3
をポインタ p
を用いて書き直したものです。ポインタ p
は char *
型,すなわち,char
へのポインタ型です。str
は配列の第1要素を指し示す char
へのポインタです。したがって,ポインタ p
は str
に初期化されることになります。すなわち,宣言
char *p = str;
は,char *
部分が型,p = str
部分が初期化であり,したがって,char *
型変数の初期化になります。
一方,printf
関数
printf("'%c' [%p]\n", *p, p);
の中の *p
は p
の間接参照です。すなわち,*p
の *
は間接演算子です。また,p = str
なので,printf
関数内の p
は str
の値となります。
かくして,実行結果は,
str[0] = 'A' [0xbffffa18]
となり,Example 10.3
の結果と同じになります。(但し,機械によってはアドレスは異なるかもしれません。)