1 引言
舉個例子:在func函數退出後,指針pInt所指的内容*pInt為 12
#include <stdio.h>
//公衆号:C語言與CPP程式設計
int func(int* pRes)
{
if(pRes == NULL)
pRes = new int(12);//配置設定新的記憶體空間給指針pRes,并指派
return 0;
}
int main ()
{
int *pInt = NULL;
int val = func(pInt);
printf("%d\n",*pInt); return 0;
}
解析:int func(int* pRes)函數的形參是指針類型 int *pRes,在函數體中 new了一塊記憶體并指派 12,将記憶體位址指派給指針 pRes。在main函數中,定義了指針pInt,調用func函數,把pInt作為參數傳入func函數中。結果*pInt并不是 12。
原因:在func函數調用過程中,形參和實參的傳遞使用了值傳遞方式,這種情況下,形參變量在函數體内發生了變化,在函數結束之後,形參變量随之釋放,不能把變化的結果傳回給實參。
可以使用指針傳遞或者引用傳遞。想要在函數體内改變pRes的值,并把這個變化傳回到main函數中,必須傳遞pRes的指針。因為pRes本身就是指針,是以應該傳遞指針的指針,或者指針的引用。
指針的引用
int v = 1;
int *p = &v;'
int *&rp = p;
&說明r是一個引用。*确定r引用的類型是一個指針。
因為引用不是對象,故無引用的數組,無指向引用的指針,無到引用的引用:
int& a[5]; // 錯誤
int&* p; // 錯誤
int& &r; // 錯誤
是以修改函數int func(int* pRes);為int func(int *&pRes);
2 傳值、傳引用差別和聯系
傳值:實參拷貝傳遞給形參。就是把實參指派給形參,指派完畢後實參就和形參沒有任何聯系,對形參的修改就不會影響到實參。
傳位址:把實參位址的拷貝傳遞給形參。就是把實參的位址複制給形參。複制完畢後實參的位址和形參的位址沒有任何聯系,對實參形參位址的修改不會影響到實參, 但是對形參位址所指向對象的修改卻直接反應在實參中,因為形參指向的對象就是形參的對象。
傳引用:本質沒有任何實參的拷貝,兩個變量指向同一個對象。這是對形參的修改,必然反映到實參上。
無論傳值還是傳指針,函數都會生成一個臨時變量,但傳引用時,不會生成臨時變量,
傳值時,隻可以引用值而不可以改變值,但傳值引用時,可以改變值,
傳指針時,隻可以改變指針所指的内容,不可以改變指針本身,但傳指針引用時,既可以改變指針所指的内容,又可以改變指針本身,
引用傳遞函數的參數,在記憶體中并沒有産生實參的副本,它是直接對實參操作;而使用一般變量傳遞函數的參數,當發生函數調用時,需要給形參配置設定存儲單元,形參變量是實參變量的副本;如果傳遞的是對象,還将調用拷貝構造函數。是以,當參數傳遞的資料較大時,用引用比用一般變量傳遞參數的效率和所占空間都好。
參考書籍《C陷阱與缺陷》