ポインタの宣言

& 演算子で取得したポインタは、変数に保存できます。このようなポインタを保存するには、通常の整数型の変数などではなく、ポインタが指す変数の型に従ったポインタを保存する専用の変数が必要です。こうした変数は「~型へのポインタ」などと呼びます。ポインタを宣言するには、変数宣言における宣言指定子列に対して、ポインタ宣言子 * を指定します。具体的には、次のような形になるでしょう。

型指定子 * 変数名 ;

例えば、int 型変数のアドレスを保存するポインタは int * 型として宣言しなければなりません。同様に、char 型変数のアドレスを保存する場合は char * 型として宣言します。int 型へのポインタ p の宣言は、次のようになります。

int* p;

上のポインタ p は、通常の変数と同じようにアドレスを保存するための領域が割り当てられています。ただし、通常の変数とは違って、生の値ではなく、他の変数のアドレス(つまりアドレス演算子 & の結果)を保存するための変数として使われます。当然、ポインタ p を利用するには、適切なアドレスを代入して初期化しなければなりません。

int 型へのポインタには、int 型の変数のアドレスを保存します。int 型の変数 x が存在するとして、次のようにアドレスを保存できます。

p = &x;

これで、ポインタ p には x 変数を指すアドレスが保存されています。ポインタが有効な変数を指すアドレスを保持している場合、間接演算子 * のオペランドに指定することで、元の変数にアクセスできます。変数 x のアドレスを保存しているポインタ p に対する以下の式は、常に条件が満たされます。

(*p) == x

上記のおけるポインタ p もまた、実質的には変数と同じです。アドレスを保存する特別な変数がポインタなのです。ポインタもまた、アドレスを保存するためのメモリ領域を持っているため、ポインタのアドレスを取得するということが可能です。しかし、本稿ではポインタのポインタについては割愛します。

Sample04

#include <stdio.h>

int main(void)
{
    int x;
    int* p;

    x = 10;
    p = &x;

    printf("x=%d, *p=%d\n", x, *p);
    printf("p=%p, &x=%p\n", p, &x);

    return 0;
}

実行結果

サンプル04の実行結果

Sample04 は、int 型の変数 x と、x のアドレスを保存するための int 型へのポインタ p を宣言しています。最初に変数 x に 10 を代入し、その後 p に & 演算子で取得した x のアドレスを代入しています。これで p は x を指すポインタとして利用できます。実行結果を見れば x と *p が同じ値であり、ポインタ p に保存されているアドレスから、間接演算子 * を使って x 変数の値を取得できていることが確認できます。また、ポインタ p とは、実質的にアドレスを保存している変数にすぎないので、p の値を取得すると、x 変数のアドレスと同じであることも同時に確認しています。