昨天QQ里有個學(xué)C++的朋友問我個問題,怎樣利用swap(int *x,int *y)交換x,y指向的地址值。起初我很簡單的給了他一個方法:

方法一:
int *p;
void swap(int *x,int *y)
{
?cout<<"swap("<<*x<<","<<*y<<")"<<endl;
?p=x;
?x=y;
?y=p;
?cout<<"swap("<<*x<<","<<*y<<")"<<endl;
}
int main()
{
?int a=10;
?int b=2;
?int *x=&a;
?int *y=&b;
?cout<<*x<<" "<<*y<<endl;
?swap(x,y);
?cout<<*x<<" "<<*y<<endl;
}
運(yùn)算結(jié)果卻是:
10? 2
10? 2?? //swap
2??? 10 //swap
10? 2
從結(jié)果上可以看出swap()仍然沒有起到效果

接著用&來做實(shí)驗(yàn)
方法二:
void swap(int &x,int &y)
{
?cout<<"swap("<<x<<","<<y<<")"<<endl;
?int temp;
?temp=x;
?x=y;
?y=temp;
?cout<<"swap("<<x<<","<<y<<")"<<endl;
}
int main()
{
?
?int a=10;
?int b=2;
?int &x=a;
?int &y=b;
?cout<<x<<" "<<y<<endl;
?swap(x,y);
?cout<<x<<" "<<y<<endl;
}
運(yùn)算結(jié)果是:
10? 2
10? 2?? //swap
2??? 10 //swap
2??? 10
從結(jié)果上可以看出swap()起到預(yù)定效果

用int *&做實(shí)驗(yàn)
方法三:
int *p;
void swap(int *&x,int *&y)
{
?cout<<"swap("<<*x<<","<<*y<<")"<<endl;
?p=x;
?x=y;
?y=p;
?cout<<"swap("<<*x<<","<<*y<<")"<<endl;
}
int main()
{
?int a=10;
?int b=2;
?int *x=&a;
?int *y=&b;
?cout<<*x<<" "<<*y<<endl;
?swap(x,y);
?cout<<*x<<" "<<*y<<endl;
}?
運(yùn)算結(jié)果是:
10? 2
10? 2?? //swap
2??? 10 //swap
2??? 10
從結(jié)果上可以看出swap()起到預(yù)定效果

最后,再次用int *做實(shí)驗(yàn),注意swap()部分的變化
方法四:
void swap(int *x,int *y)
{
?int temp=0;
?cout<<"swap("<<*x<<","<<*y<<")"<<endl;
?temp=*x;
?*x=*y;
?*y=temp;
?cout<<"swap("<<*x<<","<<*y<<")"<<endl;
}
int main()
{
?
?int a=10;
?int b=2;
?int *x=&a;
?int *y=&b;
?cout<<*x<<" "<<*y<<endl;
?swap(x,y);
?cout<<*x<<" "<<*y<<endl;
}
運(yùn)算結(jié)果是:
10? 2
10? 2?? //swap
2??? 10 //swap
2??? 10
從結(jié)果上可以看出swap()起到預(yù)定效果
=============================================================
好,現(xiàn)在來說下為什么使用方法一和方法四,同樣是傳遞的地址,為什么結(jié)果會不同?答案就在swap(int *x,int *y)上。在main()里雖然有x和y指針,但是,在swap()里的x,y卻是臨時變量。首先說明這一點(diǎn)是有好處的。我們來繼續(xù)分析以下代碼內(nèi)容:
?(一)
?? p=x;??//該方法看似我們希望通過交換臨時指針x,y所指向的地址,來達(dá)到交換main()函數(shù)中實(shí)參x,y所指
?? x=y;??//向地址,從而達(dá)到交換數(shù)值的效果。雖然邏輯上是正確的,程序編譯也通過,但是,卻忽略了??
???y=p; //一個非常重要的內(nèi)容,那就是swap()中的x,y仍然是臨時的,雖然該程序確實(shí)在swap中暫時交換
?????????? //了x,y所指向的地址,但是實(shí)際上x,y所指向地址的數(shù)值仍然沒有被改變!

?(四)
?? int temp=0;?? //通過對 方法一 的總結(jié),我們作如下調(diào)整,在swap()函數(shù)中,我們立刻改變臨時指針?
???temp=*x;???? //x,y所指向地址的數(shù)值,即改變main()函數(shù)中實(shí)參指針x,y所指向地址的數(shù)值。所以,即使
?? *x=*y;???????? //swap()函數(shù)調(diào)用完后內(nèi)部臨時x,y消失,但它們所做的工作已經(jīng)完成:改變數(shù)值!
?? *y=temp;

同理,對于方法三和方法二,通過int & 和int *&也是做了類似方法四的工作,所以能正確swap所需內(nèi)容。
至于說使用哪種方法,就是仁者見仁的事了。