普通值、指標、引用作為函式引數時的理解
很多時候,我們都會看到在教科書上寫著各種值傳遞,引用傳遞,一看一大堆,有時候看的還容易迷糊,什麼情況該怎麼傳總是區分不清,下邊我們用一小版塊並結合程式碼例項講解下。
一、值傳遞
輸出結果如下:// 普通值傳遞 void test(int num) { num = 5; cout << "in function " << __FUNCTION__ << " " << "num = " << num << endl; } int main(int argc, char* argv[]) { int num = 9; test(num); cout << "in function " << __FUNCTION__ << " " << "num = " << num << endl; getchar(); return 0; }
in function test num = 5
in function main num = 9
可見按值傳遞,在test函式內部,修改num的值,對實參num並無影響,即test函式接收到的實際上是外層num的一個拷貝。
// 指標按值傳遞 void testPt(int * p) { p = new int; *p = 9; if (p) { printf("%d\n", *p); printf("in function %s p = %p\n", __FUNCTION__, p); } } int main(int argc, char* argv[]) { int *p = NULL; testPt(p); printf("in function %s p = %p\n", __FUNCTION__, p); getchar(); return 0; }
輸出結果如下:
9
in function testPt p = 032C5978
in function main p = 00000000
在這裡我們需要稍微注意下,指標作為一種特殊的值(相對於上一種情況的int值而言)進行傳遞,結合testPt理解,在testPt內部對該引數進行分配記憶體,從輸出結果可以看到在函式內部的值已改變,但是在main函式體的p依然沒有改變,而已這樣也是值拷貝,不具備回傳效果。
下邊的涉及部分new空間沒有釋放,有些是演示的需要,實際開發中,可不能這樣哦,哪裡new了,對應就得釋放掉。
二、指標的引用傳遞
例項:
void testptref(int* &pref) { pref = new int(); if (pref) { *pref = 9; printf("%d\n", *pref); printf("in function %s pref = %p\n", __FUNCTION__, pref); } } int main(int argc, char* argv[]) { int * pref = NULL; testptref(pref); printf("in function %s pref = %p\n", __FUNCTION__, pref); getchar(); return 0; }
輸出結果如下:
9
in function testptref pref = 02674F08
in function main pref = 02674F08
可以看到,在testptref函式內外輸出的結果一樣了,說明內部的修改對傳入的實參起作用了。對指標的引用作為引數傳遞,其實並沒有拷貝,而是使用了同一個變數。
三、二級指標作為引數傳遞
二級指標一般形式為int**p; 我們通常認為,一個指標變數儲存一個它所指向內容的地址。二級指標變數儲存的是指向地址的地址,即儲存了一級指標變數的地址。
例項:
void test2pt(int **p)
{
// 修改的是一級指標。
*p = new int();
if (*p)
{
**p = 9;
printf("%d\n", **p);
printf("in function %s p = %p\n", __FUNCTION__, *p);
}
}
int main(int argc, char* argv[])
{
int *p = NULL;
test2pt(&p);
printf("in function %s p = %p\n", __FUNCTION__, p);
getchar();
return 0;
}
輸出結果如下:
9
in function test2pt p = 030A4F08
in function main p = 030A4F08
從結果可以看到,內外的指標值,即內部函式的修改對外部的該指標也起作用了。