第24回
データ構造(3)~ポインタの基本

ポインタ~変数を間接的に指し示す変数

ポインタ(pointer)は指し示すもの(point + er)という意味で、文字通りメモリ上のデータを『間接的に指し示し』ます。

変数を間接的に示す変数

ポインタは変数なので「ポインタ変数」とも呼ばれます。通常の変数は宣言した型に応じた値を保持しており、ソース中の変数名はその変数の保持する値を示します。

一方ポインタはそのような変数の『アドレス』を保持します。そして、ポインタの保持しているアドレス(指し示した先)には変数の保持する値が存在します。それが「間接的に指し示す」ということです。従ってポインタを用いる場合、必ずなんらかの変数のアドレスを代入して初期化しなければなりません。

それにしても、ただ変数の保持している値を知るだけなら、変数名を用いればよいはずです。では、なぜポインタという機能が用意されているのでしょう?

配列とポインタ

ポインタの最も大きなメリットは『配列を効率的に扱える』ことです。既に説明したように、配列は同じ型の変数を複数並べたものです。

例えば以下のように宣言すると、符号なし整数(unsigned short int)型の変数が8個並んだ状態で確保され、それを"num"という名前でアクセスできます。
unsigned short int num[8];

このとき、変数名のnumは配列の先頭の要素であるnum[0]のアドレスを保持しています。この配列のすべての要素を「0」で初期化する処理を作る場合、forループを使って以下のようにすることが考えられます。
int i;
for (i=0; i<8; i++) {
  num[i] = 0; -------- i番の要素に0を代入
}

ポインタの扱い

ポインタは変数なので宣言が必要です。宣言の書式は一般の変数と同じですが、以下のように変数名の前に"*"を付けます。
<型> *<変数名>;

こうすることで、<型>で指定した型の値を間接的に指し示すポインタ変数が生成されます。unsigned short int型のポインタpnを宣言するなら、以下のようにします。
unsigned short int *pn;

変数名の前に*が付くところだけが、一般の変数と異なります。

*が付くときと付かないとき

ソース中でポインタ変数名を記述する場合、以下の2種類の方法があります。
ポインタ変数名だけを記述:ポインタの保持するアドレスを参照
先頭に*を付けて記述:ポインタの示すアドレスに保持されている値を参照

以下のように変数と同じ型のポインタを宣言し、変数のアドレスをポインタに代入したとします。
unsigned short int n; ---- 通常の変数
unsigned short int *p; --- ポインタ変数
p = &n; ------------------ ポインタに変数のアドレスを代入(初期化)
さらに、変数nに値を代入します。
n = 123456;
このとき先頭に*を付けない"p"は変数nのアドレスを保持しており、"*p"はそのアドレスの指し示す先──変数"n"の保持する値「123456」を示しています。ポインタの初期化では"p = &n;"というように、ポインタ変数の前に「*」記号を付けないことに注意しましょう。