[英]Passing a struct to a function in C
如果我有以下情況:-
struct foo
{
int a;
int *b;
} bar;
void baz(struct foo qux)
{
}
我是否正確認為將bar
傳遞給baz()
導致將bar
的本地副本推入堆棧? 如果是這樣,這是什么副本? 在C ++中,我假設它將調用復制構造函數或默認的復制構造函數,但我真的不知道在C中如何工作。
C是否具有默認副本構造函數的概念,並且它具有名稱嗎? 可以做一些事情來執行深層復制嗎? (假設)。 我能想到的唯一方法是實際進行深層復制,然后將其傳遞給函數。
通常,我會傳遞一個指向foo
的指針,但是我只是對它的工作方式感到好奇。 此外,我的印象是傳遞指針的速度更快,節省內存,並且是進行此類操作時建議采取的措施。 我想這是一個淺表副本; 可以改變嗎?
我是否正確認為將bar傳遞給baz()會導致將bar的本地副本推入堆棧?
是。
我真的不知道如何在C中工作。
基本上與C ++中的默認復制構造函數相同; 副本的每個字段都使用原始文檔的相應字段初始化。 當然,由於“仿佛”規則,整個事情可能會歸結為一memcpy
。
我的印象是傳遞指針更快,節省內存,並且是進行此類操作時建議采取的措施。
對於較大的struct
,通常是這種情況,但並非總是如此。 如果您的struct
只有幾個小字段,那么復制的開銷可能會比間接的開銷小(同樣,使用指針參數可能會很昂貴,因為C和C ++的別名規則會阻止某些優化)。
我想這是一個淺表副本; 可以改變嗎?
不,默認復制構造函數會發生淺復制(盲復制每個字段)的情況(使用“深復制”通常意味着還創建指針/引用字段中引用的每個對象的副本)。
您的意思是“按引用傳遞”,不是允許最大靈活性(以及與原始類型傳遞的一致性)的默認值。 如果要通過引用傳遞,則傳遞一個指針(或C ++中的引用),如果只是出於性能考慮,則通常傳遞const
,否則傳遞對象本身。
是的,bar的本地副本被壓入堆棧。 其余部分將在以下工作示例中進行評論。
#include <stdio.h>
struct foo
{
int a;
int *b;
} bar;
void baz(struct foo qux)
{
bar.a = 2; // if its a different copy then printf on main should print 1 not 2.
*bar.b = 5; // if its a different copy then printf on main should print 5 not 4. since the place pointer pointing to is same
}
int main(){
bar.a=1;
bar.b = (int*)malloc(sizeof(int));
*bar.b = 4;
baz(bar); // pass it to baz(). now the copy of bar in the stack which is what baz going to use
printf("a:%d | b:%d\n",bar.a,*bar.b);
//answer is 2 and 5
/*So indeed it does a shallow copy thats why we lost the "4" stored in bar.b it did not created new space in heap to store "5" instead it used the same space that b was pointing to.
*/
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.