2012-11-08 58 views
1

如果我傳遞一個int值,它將被傳遞。
void something(int i)
如果我通過一些類型的陣列,將通過引用傳遞的。
void something(int i[])
OR void something(int *i);哪些類型按引用傳遞,哪些類型按值傳遞?

類型如int將由值傳遞,陣列將作爲引用傳遞。

第一個問題是,還有更多的類型會通過引用傳遞嗎?
第二個問題是,數組(int i[])的第一次通過與第二次(int *i)的第一次通過有什麼區別?

編輯: 我會澄清我的問題。 您傳遞給函數的其他類型(如數組)在函數內部可以更改。 (正如你所解釋的那樣,它並不完全按照引用傳遞)。

void something(int i[]) 
{ 
i[0]=5; 
} 

something(i); 

這將改變陣列不僅在本地。

結構怎麼樣?工會?指向他們的指針也傳遞了?

回答

2

一切都按價值,週期傳遞。

所不同的是用C如何處理陣列表達式。除了它是sizeof,或一元&運算符的操作數,或者是用於在聲明中初始化另一個數組的字符串文字之外,「N-element array of T」的表達式將被轉換(「衰減「)轉換爲類型爲」指向T的指針「的表達式,表達式的值將是數組的第一個元素的地址。

所以賦予相同

int a[10] = {0}; 

聲明每當表達a在代碼的任何地方出現以外&asizeof a,或者_Alignof a,它會被轉換爲指針的表達和表達的值將是無論表達式是否傳遞給函數,地址爲a[0]

因此,在一個函數調用等

foo(a); 

表達a轉換爲指針表達式,並且指針表達(&a[0])的值被傳遞給函數。

同樣,在函數參數聲明中,T a[]T a[N]被解釋爲T *a;無論數組表示法如何,該參數都被聲明爲指針,而不是數組。

0

所有類型通過值,但該值(在函數調用上下文)的陣列的名字是第一個元素的地址。

+0

謝謝你的回答,我澄清了我的問題。 – Lior

4

所有類型的傳遞由C.數組值實際上並不在功能上獲得通過調用 - 當你聲明數組參數,編譯器默默替換數組的指針,當你調用它,你通過數組第一個元素的地址。

指針也通過值傳遞。只是當你複製一個指針時,你仍然可以修改指向的值,所以它與(通過引用)非常相似(但不完全相同)。用C

+0

謝謝你的回答,我澄清了我的問題。 – Lior

2

一切是按值傳遞。數組不是通過引用傳遞的,而是會衰減爲一個指針,與所有其他指針一樣,這個指針是按值傳遞的。

通過傳遞值的指針意味着它保存地址被複制,並且在函數內給您的副本,它指向相同的數據外指針操作。試圖改變指針本身的函數內的值,但不會影響調用者已通過指針:

void fn (int *ptr) 
{ 
    // this is OK and the data that the pointer points to will be updated, 
    // even though the pointer itself is a copy 
    *ptr = 5; 

    // this will not have an effect out of the function since ptr is merely a copy 
    ptr = NULL; 
} 

在上面的例子,如果你要改變的ptr的價值,你會必須聲明函數爲具有int **參數,而不是int *

void fn (int **ptr) 
{ 
    *ptr = NULL; 
} 
... 
int *x; 
// at this point, x is uninitialised 
fn(&x); 
// x is now NULL 
+0

謝謝你的回答,我澄清了我的問題。 – Lior

0

任何數據類型你能想到的(即使你枚舉的那些)既可以作爲參考或作爲值傳遞。

+0

謝謝你的回答,我澄清了我的問題。 – Lior