2011-10-20 133 views
1

我遇到了一些遺留的C代碼如下:C中傳遞參考參數

typedef struct _somestruct_ { 
/* .... */ 
} SomeStruct_t 

static void do_one_thing(SomeStruct_t *pInput){ 
    /* Do some read-only stuff with pInput */ 
} 


static void do_many_thing(SomeStruct_t input){ 
    do_one_thing(&input); 
} 

不ç居然允許這種,即使事情,如果do_one_thing可能會炸掉真正被修改寫入pInput

+0

爲什麼你期望如果寫入* pInput被炸掉? – NPE

+0

我沒有看到這個問題。 –

回答

2

這是完全合法的C代碼。代碼do_one_thing(&input)只是將參數的地址傳遞給函數do_one_thing。這沒有什麼錯。

如果do_one_thing寫入pInput,這甚至不是問題。該地址是有效的並且指向可變值。進行更新沒有任何問題。考慮

typedef struct _somestruct_ { 
int field; 
} SomeStruct_t 

static void do_one_thing(SomeStruct_t *pInput){ 
    // Completely legal 
    pInput->field = 42; 
} 

static void do_many_thing(SomeStruct_t input){ 
    do_one_thing(&input); 
} 
+0

謝謝。我想生病時必須繼續尋找那些堆疊物來自哪裏。 – nick

1

是c將允許這一點,do_many_thing將有SomeStruct_tinput通過副本,那麼您通過地址do_one_thing這是免費的讀取或寫入結構。調用者do_many_thing將不會看到在傳遞的結構上執行的任何更改。

0

這是完全合法的代碼。如果do_one_thing寫入pInput的數據,它也不會炸燬。如果程序員知道do_one_thing的更改在do_many_thing結束時消失了,那麼這也可以非常有效。

0

你基本上將一個指針傳遞給的值SomeStruct_t inputSomeStruct_t input是堆棧中的一個值,do_one_thing將修改堆棧值指針,但do_many_thing的調用者不會看到任何更改。

0

C沒有通過引用傳遞,所以這種將指針傳遞給變量的方法是實現相同語義的唯一方法。

許多其他語言允許您直接通過引用傳遞。例如,在C++中,你可以做這樣的:

static void do_one_thing(SomeStruct_t& Input){ 
    Input.foo++; 
} 

然後當你調用的函數,你做它像這樣:

do_one_thing(input); 

但是,如果沒有這種幫助,從語言你唯一的選擇是指針。

0

您的代碼清單可能並不完整,因此無法確切知道,但按照它看起來,它看起來不會「爆炸」。

do_many_thing收到一些結構的副本,如input。然後通過將其傳遞到do_one_thing來修改此副本。除非你在上依靠那個副本沒有改變,否則什麼都不會發生。而且,do_many_thing的調用者不會看到SomeStruct_t傳入的更改,所以即使在更高級別也不會有副作用。