今天和同學討論到指針和引用的傳遞問題,有些想法從推理上講是正確的,但是因爲是推理,說出自己觀點的時候不是那麼有底氣,本着實踐是檢驗真理的唯一標準的原則,在電腦上敲了幾段代碼,驗證了推理的正確性。 先上代碼,再分析。
代碼1:
void Swap0(int a1,int b1){
int temp;
temp=a1;
a1=b1;
b1=temp;
}
void Swap1(int *a1,int *b1){ //交換地址
int *temp;
temp=a1;
a1=b1;
b1=a1;
}
void Swap2(int *a1,int *b1){
int temp;
temp=*a1;
*a1=*b1;
*b1=temp;
}
void Swap3(int &a1,int &b1){
int temp;
temp=a1;
a1=b1;
b1=temp;
}
int main(){
int a=1,b=2;
Swap0(a,b);
cout<<"Swap0 a:"<<a<<" b:"<<b<<endl;
Swap1(&a,&b);
cout<<"Swap1 a:"<<a<<" b:"<<b<<endl;
Swap2(&a,&b);
cout<<"Swap2 a:"<<a<<" b:"<<b<<endl;
a=1;b=2;
Swap3(a,b);
cout<<"Swap3 a:"<<a<<" b:"<<b<<endl;
return 1;
}
運行結果:
關於Swap0(int a1,int b1),當調用這個函數時,main函數中的a=1,b=2會把1和2,這兩個值傳遞給Swap0()中的a1和b1,Swap0()中的a1和b1是這個函數的局部變量,他們只是接受了1和2這兩個值,並在函數內部將這兩個局部變量的值做了交換,和main()中的a,b不存在關聯也就是對main()中的a,b的值沒有影響,所有執行Swap0後輸出的值還是a爲1,b爲2。
關於Swap1(int *a1,int *b1)和Swap2(int *a1,int *b1)它們的參數是一樣的,不同的是Swap1的函數內部操作的是指針,而Swap2使用的是解引用*,有什麼不同呢,從內存的角度來分析:main函數中定義了a和b,並且賦值爲1和2,可以理解爲系統爲a分配了一塊內存來存儲1,爲b分配了一塊內存來存儲2,我們可以先假設分配給a的內存的起始地址爲1000,b的是1004,也就是&a=1000,&b=1004。調用Swap1(int *a1,int *b1),把這兩個地址分別傳遞給a1,b1,也就是a1=1000,b1=1004,對指針變量的值進行交換,只不過是變成了a1=1004,b1=1000,變得只是a1,b1這兩個指針變量的值,對a和b的內存沒有影響,所以輸出結果還是a=1,b=2。但是Swap2就不同了,它進行了解引用操作,*a1表示他獲得了1000這個地址的值,並對這個地址上的數據進行操作(重點是要理解這個解引用操作,百度百科解釋點擊打開鏈接)它操作的是這塊內存,所以它能成功修改a和b的值。
關於Swap3(int &a1,int &b1)它是傳遞引用,引用是變量的別名,和操作a,b這兩個變量一樣,所以能夠改變a,b的值。
代碼2:
typedef struct{
int a;
}A;
void f1(A *p){
p->a=p->a+1;
}
void f2(A *p){
(*p).a=(*p).a+1;
}
int main(){
A p;
p.a=1;
f1(&p);
cout<<"f1 p.a="<<p.a<<endl;
p.a=1;
f2(&p);
cout<<"f2 p.a="<<p.a;
return 1;
}
運行結果:
關於f1(A *p),它傳遞的也是地址,在函數內部使用這個符號“->”它操作的是這個地址對應的內存中的數據,所以可以修改成員的值。f2(A *p)同樣是解引用操作參見上面的Swap2。
如有錯誤,多謝指正。