天天看點

C++值傳遞、指針傳遞、引用傳遞的差別

值傳遞:

形參是實參的拷貝,改變形參的值并不會影響外部實參的值。從被調用函數的角度來說,值傳遞是單向的(實參->形參),參數的值隻能傳入,不能傳出。當函數内部需要修改參數,并且不希望這個改變影響調用者時,采用值傳遞。

指針傳遞:

形參為指向實參位址的指針,當對形參的指向操作時,就相當于對實參本身進行的操作

引用傳遞:

形參相當于是實參的“别名”,對形參的操作其實就是對實參的操作,在引用傳遞過程中,被調函數的形式參數雖然也作為局部變量在棧中開辟了記憶體空間,但是這時存放的是由主調函數放進來的實參變量的位址。被調函數對形參的任何操作都被處理成間接尋址,即通過棧中存放的位址通路主調函數中的實參變量。正因為如此,被調函數對形參做的任何操作都影響了主調函數中的實參變量。

舉例:

#include<iostream>
using namespace std;

//值傳遞
void change1(int n){
	cout << "值傳遞--函數操作位址" << &n << endl;
	n++;
}

//引用傳遞
void change2(int & n){
	cout << "引用傳遞--函數操作位址" << &n << endl;
	n++;
}

//指針傳遞
void change3(int *n){
	cout << "指針傳遞--函數操作位址 " << n << endl;
	*n = *n + 1;
}

int main(){
	int n = 10;
	cout << "實參的位址" << &n << endl << endl;
	change1(n);
	cout << "after change1() n=" << n << endl;
	change2(n);
	cout << "after change2() n=" << n << endl;
	change3(&n);
	cout << "after change3() n=" << n << endl;
	system("pause");
	return 0;
}
           

執行結果為:

實參的位址008FFBB4

值傳遞--函數操作位址008FFAE0
after change1() n=10
引用傳遞--函數操作位址008FFBB4
after change2() n=11
指針傳遞--函數操作位址 008FFBB4
after change3() n=12
           

可以看出,實參的位址為008FFBB4。采用值傳遞的時候,函數操作的位址是008FFAE0并不是實參本身,是以對它進行操作并不能改變實參的值;再看引用傳遞,操作位址就是實參位址 ,隻是相當于實參的一個别名,對它的操作就是對實參的操作;接下來是指針傳遞,也可發現操作位址是實參位址。

指針傳遞的實質:

指針傳遞參數本質上是值傳遞的方式,它所傳遞的是一個位址值。值傳遞過程中,被調函數的形式參數作為被調函數的局部變量處理,即在棧中開辟了記憶體空間以存放由主調函數放進來的實參的值,進而成為了實參的一個副本。值傳遞的特點是被調函數對形式參數的任何操作都是作為局部變量進行,不會影響主調函數的實參變量的值。(這裡是在說實參指針本身的位址值不會變)

指針傳遞和引用傳遞一般适用于:

函數内部修改參數并且希望改動影響調用者。對比指針/引用傳遞可以将改變由形參“傳給”實參(實際上就是直接在實參的記憶體上修改,不像值傳遞将實參的值拷貝到另外的記憶體位址中才修改)。

另外一種用法是:當一個函數實際需要傳回多個值,而隻能顯式傳回一個值時,可以将另外需要傳回的變量以指針/引用傳遞給函數,這樣在函數内部修改并且傳回後,調用者可以拿到被修改過後的變量,也相當于一個隐式的傳回值傳遞吧。

繼續閱讀