例題として、変数a, bの値を交換するプログラムについて考えてみましょう。
なんだ、簡単じゃん。
これでいけるっしょ。
a = b;
b = a;
これではダメです。
両方bになってしまいます。
ということで、真面目にやってみましょう。
動かしてみよう
サンプルコードを動かしてみましょう。
サンプルではswap関数を作成し、その機能によってa, bの値を入れ替えています。
解説
ではサンプルコードの要点をみてみましょう。
/* プロトタイプ宣言 */
void swap(int *pa, int *pb);
これは関数のプロトタイプ宣言ですね。
main関数内でswap関数を用いていますが、swap関数の定義がmain関数よりも後ろで実装されているため、『swap関数っていうのがあるよ。』と事前に書いておく必要があります。(逆にいうと、main関数の前にswap関数を書くのであれば省略してよい記述です。)
また、プロトタイプ宣言からわかるとおり、swap関数は引数を2つ持ち、両方ともポインタです。
大丈夫です。ポインタは怖くありません。
変数の持つ数値ではなく、変数のアドレスを扱うだけです。
続いてmain関数内の下記。
swap(&a, &b);
変数a,bのアドレスをswap関数に渡してあります。
swap関数の引数がポインタ型なので、コール時に変数アドレスを渡す必要があるためです。
続いてswap関数の中身をみてみましょう。
void swap(int *pa, int *pb)
int* pa, int* pb という引数が用意してあります。
先のmain関数の処理において、swap(&a, &b); という記述がありましたので、swap関数のコール時点で、pa = &a, pb = &b が実行されており、pa,pbにはそれぞれa,bのアドレスが格納されている状態になっています。
int temp = *pa; /* paが指す先の値をtempに退避 */
paには&a(aのアドレス)が格納されていますので、*pa と記述することで a そのものにアクセスすることができます。
よって上記式により、temp = main関数のa; が実施されます。
*pa = *pb; /* pbが指す先の値でpaが指す先の値を更新 */
先と同様の理由により、上記式では main関数のa = main関数のb; が実施されます。
*pb = temp; /* tempでpbが指す先の値を更新 */
最後に main関数のb = temp; によって、swap関数内でmain関数のa, bの値入れ替えが完了します。
・・・残念ながらダメです。ポインタを使わなかった場合、先の説明で『main関数のa = main関数のb;』と解説した箇所などの動作が『swap関数のa = swap関数のb;』となってしまいますので、main関数内のa,bの値をいれかえることができません。
以上です。
ではまた。