简体   繁体   English

将结构传递给C中的函数

[英]Passing a struct to a function in C

If I have the following: - 如果我有以下情况:-

struct foo
{
  int a;
  int *b;
} bar;

void baz(struct foo qux)
{

}

Am I right in thinking that passing bar to baz() results in a local copy of bar being pushed onto the stack? 我是否正确认为将bar传递给baz()导致将bar的本地副本推入堆栈? If so, what kind of copy is this? 如果是这样,这是什么副本? in C++, I assume it would call the copy constructor, or the default copy constructor but I don't really know how this would work in C. 在C ++中,我假设它将调用复制构造函数或默认的复制构造函数,但我真的不知道在C中如何工作。

Does C have any notion of a default copy constructor and does this have a name? C是否具有默认副本构造函数的概念,并且它具有名称吗? Could something be done to perform a deep copy? 可以做一些事情来执行深层复制吗? (hypothetically). (假设)。 The only way I could think of is to actually do a deep copy and then pass it to the function. 我能想到的唯一方法是实际进行深层复制,然后将其传递给函数。

Typically, I would be passing a pointer to a foo but I'm just curious as to how it is working. 通常,我会传递一个指向foo的指针,但是我只是对它的工作方式感到好奇。 Furthermore I am under the impression that passing a pointer is faster, saves memory and is the recommended course of action to take when doing this kind of operation. 此外,我的印象是传递指针的速度更快,节省内存,并且是进行此类操作时建议采取的措施。 I would guess that it is a shallow copy; 我想这是一个浅表副本; can this be changed? 可以改变吗?

Am I right in thinking that passing bar to baz() results in a local copy of bar being pushed onto the stack? 我是否正确认为将bar传递给baz()会导致将bar的本地副本推入堆栈?

Yes. 是。

I don't really know how this would work in C. 我真的不知道如何在C中工作。

Substantially as it would with the default copy constructor in C++; 基本上与C ++中的默认复制构造函数相同; every field of the copy is initialized with the corresponding field of the original. 副本的每个字段都使用原始文档的相应字段初始化。 Of course, because of the "as if" rule the whole thing may boil down to a memcpy . 当然,由于“仿佛”规则,整个事情可能会归结为一memcpy

I am under the impression that passing a pointer is faster, saves memory and is the recommended course of action to take when doing this kind of operation. 我的印象是传递指针更快,节省内存,并且是进行此类操作时建议采取的措施。

For larger struct s it's often the case, but it's not always like that; 对于较大的struct ,通常是这种情况,但并非总是如此。 if you have a small struct of few small fields the overhead of copying will probably be smaller than that of indirection (also, using pointer parameters can be costly because the aliasing rules of C and C++ can prevent some optimizations). 如果您的struct只有几个小字段,那么复制的开销可能会比间接的开销小(同样,使用指针参数可能会很昂贵,因为C和C ++的别名规则会阻止某些优化)。

I would guess that it is a shallow copy; 我想这是一个浅表副本; can this be changed? 可以改变吗?

No, a shallow copy (blindly copy each field) is what happens with the default copy constructor (while with "deep copy" you usually mean also creating a copy of each object referenced in pointer/reference fields). 不,默认复制构造函数会发生浅复制(盲复制每个字段)的情况(使用“深复制”通常意味着还创建指针/引用字段中引用的每个对象的副本)。

What you mean is "pass by reference", and it's not the default to allow the maximum flexibility (and for coherency with the passing of primitive types). 您的意思是“按引用传递”,不是允许最大灵活性(以及与原始类型传递的一致性)的默认值。 If you want pass by reference you pass a pointer (or a reference in C++), often const if you are in just for the performance, otherwise you pass the object itself. 如果要通过引用传递,则传递一个指针(或C ++中的引用),如果只是出于性能考虑,则通常传递const ,否则传递对象本身。

Yes a local copy of bar is pushed on to the stack. 是的,bar的本地副本被压入堆栈。 and rest is commented on following working example. 其余部分将在以下工作示例中进行评论。

    #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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM