摘要:簡要比較了直接、指針、引用三中函數參數傳遞方式,并對其優缺點進行了大致的說明
1. 眾所周知,函數參數的直接傳遞就是實現一個拷貝值,這個拷貝值的變化,并不會改變原值的變化,因為兩個被來就是不同的個體,就好比兩個克隆的個體,雖然兩者之間有很多相同的地方,但是它們的思維是獨立的。
2. 通過指針的方式給函數參數傳值呢,從根本上來講,它仍然是直接傳值,但是這個拷貝的值比較特殊,是一個地址罷了,如:
1: void fun(int *pnValue)
2: {
3: ...;
4: }
5: int main()
6: {
7: int nValue = 6;
8: fun(&nValue);
9: }
它其實是將nValue的地址拷貝給了pnValue,如果在fun函數中,一開始就將pnValue的值給改變,如pnValue=&nValue2,那么pnValue指向的內容的改變,將不會影響到nValue。
同時有一點需要注意的是,空指針對象是沒有意義的,會引起程序的奔潰,因此在開始因該進行檢測,if(!pnValue) return;
通過指針傳參數的優點:
1) 允許你改變傳遞的參數的值
2) 由于它拷貝的僅僅是一個字節大小的地址,因此傳遞的過程是快速的,特別對于較大的結構或是類
3) 我們通過這種傳參方式,獲取從函數中返回的多個量
缺點:
1) 傳遞的只能是普通的變量,不能是字面常量或表達式
2) 所有的傳遞值都得檢查是不是空指針
3. 通過引用的方式傳遞參數
雖然在底層的操作中,通過引用也是通過“指針的方式”進行實現的http://blog.csdn.net/wanwenweifly4/article/details/6739687),但是從語言上考慮,引用是對象的別名,也是一個對象,并不是指針,因為它的概念是在語言上定義的,而不是底層的實現方式,換一種思維,拋開所有的比匯編語言高級的語言,回到匯編語言建立初期,單單從匯編語言上考慮,那時有沒有指針的概念呢?因此應該理性的對待引用在C++語言中的概念,也應該冷靜的認識它在底層中的實現方式,區分的對待,其實也不用爭執于這個問題,認清了,會用了,就成了。(這些僅個人見解,批判的看待吧)。
它在傳參中的優點:
1) 允許你改變傳遞的參數的值
2) 傳遞的過程是快速的,特別對于較大的結構或是類
3) 可以通過添加一個const,避免不經意的改變
4) 我們通過這種傳參方式,獲取從函數中返回的多個量
缺點:
1) 非const類型的參數,傳遞的只能是普通的變量,不能是字面常量或表達式
2) 不容易區分哪些變量是input,需要output,或都是
3) 通過函數的調用,很難看出那個參數是將被改變的,因為它和直接傳值的方式相同,只能通過函數原型進行辨認,當程序員不小心忽視的時候,可能會導致錯誤的發生
ps:
1: #include <iostream>
2:
3: int nFive = 5;
4: int nSix = 6;
8: void SetToSix(int *pTempPtr);
9:
10: int main()
11: {
12: using namespace std;
13:
16: int *pPtr = &nFive;
19: cout << *pPtr;
20:
23: SetToSix(pPtr);
27: cout << *pPtr;
28:
29: return 0;
30: }
31:
33: void SetToSix(int *pTempPtr)
34: {
35: using namespace std;
36:
38: pTempPtr = &nSix;
41: cout << *pTempPtr;
42: }
上面這個程序中輸出的結果是 565
如果想使得輸出的結果為566呢,有一個方法可以實現,就是采用指針的引用,如下:
1: // pTempPtr is now a reference to a pointer to pPtr!
2: // This means if we change pTempPtr, we change pPtr!
3: void SetToSix(int *&pTempPtr)
4: {
5: using namespace std;
6:
7: pTempPtr = &nSix;
8:
9: // This will print 6
10: cout << *pTempPtr;
11: }