2012-12-19 35 views
-1

特別是,爲什麼像*param這樣的參數更改不會傳播回函數的調用者,而是像**param這樣的參數更改會傳播回去?有人可以使用視覺圖解釋C中**參數和*參數之間的區別嗎?

+0

http://www.thegeekstuff.com/2011/12/c-pointers-fundamentals/ – Jeyaram

+0

你可以發表一些描述你所看到的示例代碼嗎? –

+2

這個問題假設一個錯誤的前提。請指定一個代碼示例,使您感到困惑,或者做不到您期望的操作,以便有人可以提供有意義的答案。 – user4815162342

回答

1

int param是一個變量,即數據。

int * param指向的變量,即數據的存儲器地址。

int * * param指向的指針指向變量,即數據的存儲器地址的存儲器地址。

依此類推。

當使用變量作爲參數調用某個函數時,該參數將複製到堆棧(按值調用)。函數對其參數所做的任何更改實際上都是在副本上完成的,當函數返回時該副本會與堆棧框架的其餘部分一起銷燬。

void foo(int x) 
{ 
    x = 23;  // any changes done on x are strictly local 
} 

int main() 
{ 
    int a = 42; 
    foo(a); // no matter what foo() does, a will still be 42. 
    return 0; 
} 

如果傳遞指針一個變量作爲自變量的函數,它也被複制 - 而是一個內存地址的副本仍然指向相同的內存地址,所以該函數可以訪問即內存地址(即原始變量,而不是其在堆棧上的拷貝)。該函數對該內存地址的內容所做的更改會影響該函數的調用者。

void foo(int * x) 
{ 
    *x = 23;  // changing the contents of the memory address pointed to by x 
} 

int main() 
{ 
    int a = 42; 
    foo(&a); // passing the address of a; a will be changed to 23. 
    return 0; 
} 

你應該可以自己從那裏拿走它。

2

在這兩種情況下,更改都會傳播,但它取決於調用函數。

見下文的情況下(因爲你沒有給任何代碼,所以,我假設一般情況下)

著名的交換功能

int a=5,b=10; 
swap(&a,&b) // Calling by address 

void swap(int *paramA,int *paramB) 
{ 
// Do the swap 
} 

你看,即使在函數定義只*params但變化反映回呼叫環境。當它是按值傳遞

但在其他情況下*param可能不反映,手段,

看到這個代碼,

int a; 
int *p = &a; 


foo(p); // calling by value 

void foo(int *param) 
{ 
// if you do anything or change param to point to some other memory location 
// then it will not be reflected back and p still be pointing to a. 
} 

而如果你這樣做

foo(&p); //calling 

void foo(int **param) 
{ 
// if you do anything or change param to point to some other memory location 
// then it must be reflected back in calling environment. 
} 

這些東西在調用函數時被稱爲Pass by valuePass by AddressC中。

我希望你明白了。

相關問題