int 型の変数 a, b があったときに、 a, b の値をいれかえるにはどうしたら良いでしょうか?
main()の中で
作業用の変数を一つ用意して、 次のようにします。
int main(void) {
int a, b ;
int wk ;
wk = a ;
a = b ;
b = wk ;
return 0 ;
}
これはカンタンですね。
関数を使う - 1
"変数の値をいれかえる" なんとなく関数にできそうですね。 そこで次のような関数を作ってみました。
void swap(int x, int y) {
int wk ;
wk = x ;
x = y ;
y = wk ;
}
この関数を main() の中から呼んでみます。
int main(void) {
int a, b ;
swap(a, b) ;
return 0 ;
}
関数 swap() の中は、 (1) の main() とまったく同じ形をしています。 問題はなさそうですが、 ほんとにこれで大丈夫でしょうか?
結論から言ってしまうと、 swap() の呼び出し前後で、 a,b の値は不変で、 いれかわりません。
前回の "関数引数の受け渡し" で解説したように、 関数が見ているのは引数のコピーにすぎません。 ですから、上の関数 swap() がやっていることは、 a, b の値を x, y にコピーして、 コピーをいれかえているのです。
つまり、
int main(void) {
int a, b ;
{
int x, y ;
int wk ;
x = a ;
y = b ;
wk = x ;
x = y ;
y = wk ;
}
return 0 ;
}
とやっているのと同じです。
例えていえば、 本棚にある二冊の本をいれかえたいときに、 そのコピーをとって、 コピーの方の場所をいれかえたようなものですね。 本棚の本はそのままでしょ?
関数を使う - 2
では、関数を使って値をいれかえることはできないのでしょうか。
いいえ、できるのです。
次の例を見てください。
void swap(int* x, int* y) {
int wk ;
wk = *x ;
*x = *y ;
*y = wk ;
}
int main(void) {
int a, b ;
swap(&a, &b) ;
return 0 ;
}
これでうまくいきます。
変った点は、 swap() の引数の型が int* になったことで、 あわせて、main() 側の呼び出しかたも変りました。
呼び出された関数 swap() では、 引数 x, y を変えるのではなく、 引数が指しているメモリの内容 *x , *y を変えています。
引数が指しているのは main() の a, b ですから、 swap() の呼び出し前後で、 a, b の値がいれかわります。
つまり、
int main(void) {
int a, b ;
{
int *x, *y ;
int wk ;
x = &a ;
y = &b ;
wk = *x ;
*x = *y ;
*y = wk ;
}
return 0 ;
}
とやっているのと同じです。
また本の例え話しをすると、 こんどは本が本棚のどこにあるか、 場所を教えて、 その場所にある本をいれかえさせるわけです。