【例題】2つの変数の値を交換させよう

例題として、変数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の値入れ替えが完了します。

ポインタ使わずに void swap(int a, int b) じゃダメなの?
・・・残念ながらダメです。ポインタを使わなかった場合、先の説明で『main関数のa = main関数のb;』と解説した箇所などの動作が『swap関数のa = swap関数のb;』となってしまいますので、main関数内のa,bの値をいれかえることができません。

以上です。
ではまた。

タイトルとURLをコピーしました