著者:崎間
ポインタはアドレスを扱います.馴れないと混乱してしまいますが, Windows のショートカットの様なものと考えると理解しやすいかもしれません.ショートカット自体は実行ファイルでもなんでもありませんが,ファイルのある場所への情報を持っています.ポインタもこれと同じで,データのある場所,つまりメモリ上のアドレスという情報を持ちます.
ポインタを理解するために,つぎのプログラムを実行してみます.
#include <stdio.h> int main(void) { int *pa, a; pa = &a; /* paにaのアドレスを入力 */ a = 10; /* aに10を代入 */ printf("pa = %d\n", pa); /* paの内容 (aのアドレス) */ printf("*pa = %d\n", *pa); /* paが指す先の内容 (aの値) */ }
実行結果は下のようになります.
pa = -1073744076 *pa = 10
pa はポインタの内容,つまりポインタの指している a というデータのメモリ上のアドレスです.メモリのどの部分に a のデータが格納されるかは実行するまでわからないので,この値は実行する度に異なったものになります. Windows のショートカットの例でいうと,pa はファイルのある場所を表しています.
「*pa」はそのアドレスに格納されている値,つまりポインタの参照先です.この場合は a の内容の 10 という整数値です. Windows のショートカットの例でいうと,*pa はファイルそのものになります.
ポインタの必要性を最初に感じるのは,おそらく複数の戻り値を持つ関数を作ろうとする時ではないでしょうか.代表的なのはつぎのようなプログラムです.
#include <stdio.h> void swapXY(double *x, double *y){ /* xとyをポインタで受け取る */ double tmp; tmp = *x; *x = *y; *y = tmp; } int main(void){ double a, b; a = 2.0; b = 4.5; swapXY(&a, &b); /* アドレスで渡す */ printf("a = %f\nb = %f\n", a, b); }
このプログラムでは swapXY という関数で,変数 x と y の中身を入れ換えています.引数が2つで,戻り値も2つ必要ですが,return 文では2つの戻り値を返す事ができません.そこで,ポインタがアドレスの先を参照するという性質を使います.
関数通常の変数に & をつけると,その変数のアドレスになりまから,それを引数として与えます.これをポインタで受け取ると関数の内側からでも, main 関数で宣言された変数の値を直接操作することができます.実行結果は下のようになります.
a = 4.5 b = 2.0
関数swapXYからの戻り値はありませんが,ちゃんとaとbの値は入れ替わっています.これはポインタを使うことによってmainのなかのaとbの値を直接関数から操作できたからです.