代码之家  ›  专栏  ›  技术社区  ›  shreyasva

在C中将一个结构分配给另一个结构

  •  127
  • shreyasva  · 技术社区  · 15 年前

    是否可以将结构的一个实例分配给另一个实例,如下所示:

    struct Test t1;
    struct Test t2;
    t2 = t1;
    

    我见过它适用于简单的结构,但是它适用于复杂的结构吗?
    编译器如何知道如何根据数据项的类型复制数据项,即区分 int 字符串?

    5 回复  |  直到 7 年前
        1
  •  126
  •   fabmilo    15 年前

    如果结构类型相同,则为“是”。把它当作记忆复制品。

        2
  •  121
  •   anon    15 年前

    是的,结构支持赋值。但是,也存在一些问题:

    struct S {
       char * p;
    };
    
    struct S s1, s2;
    s1.p = malloc(100);
    s2 = s1;
    

    现在两个结构的指针指向同一个内存块-编译器不会复制指向数据的指针。现在很难知道哪个struct实例拥有数据。这就是为什么C++发明了用户可定义的赋值操作符的概念——你可以编写特定的代码来处理这种情况。

        3
  •  21
  •   Anders R. Bystrup    12 年前

    首先看这个例子:

    下面给出了一个简单c程序的c代码

    struct Foo {
        char a;
        int b;
        double c;
        } foo1,foo2;
    
    void foo_assign(void)
    {
        foo1 = foo2;
    }
    int main(/*char *argv[],int argc*/)
    {
        foo_assign();
    return 0;
    }
    

    foo_assign()的等效asm代码是

    00401050 <_foo_assign>:
      401050:   55                      push   %ebp
      401051:   89 e5                   mov    %esp,%ebp
      401053:   a1 20 20 40 00          mov    0x402020,%eax
      401058:   a3 30 20 40 00          mov    %eax,0x402030
      40105d:   a1 24 20 40 00          mov    0x402024,%eax
      401062:   a3 34 20 40 00          mov    %eax,0x402034
      401067:   a1 28 20 40 00          mov    0x402028,%eax
      40106c:   a3 38 20 40 00          mov    %eax,0x402038
      401071:   a1 2c 20 40 00          mov    0x40202c,%eax
      401076:   a3 3c 20 40 00          mov    %eax,0x40203c
      40107b:   5d                      pop    %ebp
      40107c:   c3                      ret    
    

    如您所见,在汇编中,赋值被“mov”指令简单地替换,赋值运算符只是意味着将数据从一个内存位置移动到另一个内存位置。 赋值只对结构的直接成员执行,当结构中有复杂的数据类型时将无法复制。这里complex意味着不能有指向列表的指针数组。

    结构中的字符数组本身在大多数编译器上都不起作用,这是因为赋值只会尝试复制,而不会将数据类型视为复杂类型。

        4
  •  15
  •   Thomas Pornin    15 年前

    这是一个简单的拷贝,就像你用 memcpy() (实际上,有些编译器实际上会调用 MEMcPy.() 为了那个密码)。C中没有“字符串”,只有指向一堆字符的指针。如果源结构包含这样的指针,则会复制指针,而不是复制字符本身。

        5
  •  6
  •   Clifford    15 年前

    你的意思是复数中的“复数”吗?这似乎不太可能,所以如果不可能,你必须举个例子,因为“complex”在c语言中没有任何具体的含义。

    您将获得结构的直接内存副本;这是否是您想要的取决于结构。例如,如果结构包含指针,则两个副本将指向同一数据。这可能是您想要的,也可能不是您想要的;这取决于您的程序设计。

    要执行“智能”复制(或“深层”复制),需要实现一个函数来执行复制。如果结构本身包含指针和也包含指针的结构,并且可能包含指向此类结构的指针(可能这就是您所说的“complex”)并且很难维护,那么这可能很难实现。简单的解决方案是使用C++并为每个结构或类实现复制构造函数和赋值运算符,然后每一个都为其自己的复制语义负责,可以使用赋值语法,并且更容易维护。