ページ 11

swap関数について

Posted: 2012年4月14日(土) 15:26
by yt
初歩的な質問で申し訳ないのですが、swap関数をポインタを使わずに行うと何故上手く行かないかよく分かりません。例えば

コード:

#include <stdio.h>

swap(int x,int y);
int main(void)
{
	int a,b;
	a=1;
	b=2;
	swap(a,b);
	printf("a=%d,b=%d",a,b);
	printf("\n");
return(0);
}
swap(int x,int y){
	int temp;
	temp=x;
	x=y;
	y=temp;
}
とした時、a=1,b=2としてしか認識してません。

コード:

#include <stdio.h>

swap(int *x,int *y);
int main(void)
{
	int a,b;
	a=1;
	b=2;
	swap(&a,&b);
	printf("a=%d,b=%d",a,b);
	printf("\n");
return(0);
}
swap(int *x,int *y){
	int temp;
	temp=*x;
	*x=*y;
	*y=temp;
}
とするとうまくいくのですが、どうしてそのような違いが起こるのでしょうか?
宜しくお願いいたします。

Re: swap関数について

Posted: 2012年4月14日(土) 16:02
by softya(ソフト屋)
これは、実引数が仮引数に渡されるときは値はコピーというか代入されるだけと言うことを理解しないといけません。これを俗に値渡しと呼びます。
最初のプログラムでは暗黙的にx=a;y=b;が行われたのと同じです。

関数の部分を展開すると、こう書いたのと同じになります。

コード:

#include <stdio.h>

int main( void )
{
	int a, b;
	a = 1;
	b = 2;
	{
		//swap(a,b)を展開したもの
		int x, y;
		int temp;
		x = a;
		y = b;
		temp = x;
		x = y;
		y = temp;
	}
	printf( "a=%d,b=%d", a, b );
	printf( "\n" );
	return( 0 );
}
コレで入れ変わらない理由も納得できませんか?

ポインタを使ったものは、自分で展開したものを書いてみてください。

Re: swap関数について

Posted: 2012年4月14日(土) 17:28
by yt
ありがとうございます。
ポインタを使わずに行うと出来ない理由は分かりました。
ただ今度は逆にでは何故ポインタを使うとうまくいくのかよく分からなくなってしまいました…

コード:

#include <stdio.h>

int main(void)
{
	int a,b;
	a=10;
	b=2;
	{
		int *x,*y;
		int temp;
		x=&a;
		y=&b;
		temp=*x;
		*x=*y;
		*y=temp;
	}
	printf("a=%d,b=%d",a,b);
	printf("\n");
return(0);
}
ポインタを使った場合だとこうなりますか?
ただそうしたら
xの値はbのアドレスを指し、yの値はaのアドレスを指してる。
と言うだけで先程のswap(a,b)みたいに仮引数では入れ替わっても実引数で入れ替わるというのが…

Re: swap関数について

Posted: 2012年4月14日(土) 17:44
by beatle
yt さんが書きました: xの値はbのアドレスを指し、yの値はaのアドレスを指してる。
ちょっと違います。
x=&a;
としているのですから、xはaのアドレスを保持しています。そして、*xはa自体を表していますので、
*x = *y;
とやると、a自体にb自体が代入され、目的達成です。

Re: swap関数について

Posted: 2012年4月14日(土) 17:49
by softya(ソフト屋)
ポインタの理解が不十分で誤解されていると思います。

コード:

        int *x,*y;
        int temp;
        x=&a;
        y=&b;
        temp=*x;
        *x=*y;
        *y=temp;
xとyはそれぞれaとbのポインタですが、*xと*yはポインタの指す先である変数の実体aとbをそれぞれ指します。
なので、*x=*y;とするとa=b;と同じ意味となります。

ポインタにしても変わらないんだったらポインタの存在する意味がありませんよね。
何のために存在しているかを考えてみたほうが良いかと思います。

Re: swap関数について

Posted: 2012年4月15日(日) 02:42
by yt
お二方ありがとうございます。
> beatleさん
beatle さんが書きました: *xはa自体を表していますので、
とは、xがaのアドレスを保持している→*xはxの保持しているアドレス(aのアドレス)が保持しているものを示す=aの値
ということですよね?

> softya(ソフト屋)さん
ポインタを使うことによって、仮引数から実引数に値を渡すことが出来ないことが出来るようになってるんですよね?
言葉にちょっとし難いのですが、何となく分かって来ました!