&これまで配列を中心にポインタの利用方法を見て来ました。ここでは配列以外のオブジェクトについて,ポインタ型データの取得方法とポインタの利用の仕方を見てみます。
配列の場合,式に使うと第1要素を指し示すポインタになります。すなわち,配列型は式で使えば直接,ポインタ型データ,すなわち,アドレスを取得できます。これに対し,配列以外のオブジェクト,例えば,
int x = 1;
などの場合,アドレスをどのように取得できるのでしょうか。というのは,アドレスが取得できなければ,アドレスを変数にしたポインタは利用できないからです。ポインタ型データ,すなわち,アドレスを取得するための演算子が「アドレス演算子」です。
■アドレス演算子 (Address Operator)
&オペランド
オペランドには,関数指示子(関数の名称を示す識別子,function designator)か,オブジェクトを示す左辺値。但し,register記憶域クラスではないオブジェクトであること。
アドレス演算子はオペランドのアドレスを返します。オペランドの型がT のとき,アドレス演算子は T *型(T へのポインタ型)としてアドレスを返します。
/* Example 10.10 */
#include <stdio.h>
int main(void)
{
       int x = 2, y = 3;
       int *p;    // int *型変数(intへのポインタ)の宣言
       printf("x = %d [%p]\n", x, &x);
       printf("y = %d [%p]\n", y, &y);
       p = &x;
       printf("p = %p\n", p);
       *p = 10;   // * は間接演算子
       p = &y;
       printf("p = %p\n", p);
       *p = 10;   // * は間接演算子
       printf("x = %d\n", x);
       printf("y = %d\n", y);
       return 0;
}
実行結果です。
x = 2 [0xbffffa98] y = 3 [0xbffffa9c] p = 0xbffffa98 p = 0xbffffa9c x = 10 y = 10
x は最初 2,y は 3 です。それを 10 に変えています。
先ず,式文
p = &x;
でポインタ p を x のアドレス 0xbffffa98 に設定します。これは3つ目の出力でも確認できます。そこで,間接参照を利用して,すなわち,
x == *&x == *p
+------------+ アドレス | 0xbffffa98 | &x → +------------+ ↓ *&x = *p 値 | x | ← ← +------------+
となることを利用して,アドレス 0xbffffa98 のメモリに記憶されている値を 10 に変えます。それが式文
*p = 10;
です。(*p = 10 は代入式。= は単純代入演算子。)同じ操作を y についても行います。
 ポインタ p に代入しているのはアドレス &x や &y であることを見れば,ポインタがアドレス上の変数であることが再確認できるかと思います。