在C中将一个结构分配给另一个结构
你能分配一个结构的一个实例到另一个,就像这样:
struct Test t1; struct Test t2; t2 = t1;
我已经看到它适用于简单的结构,它是否适用于复杂的结构?
编译器如何知道如何根据数据types复制数据项,即区分int
和string?
是的,如果结构是相同的types。 认为它是一个内存拷贝。
是的,结构支持赋值。 但是,有问题:
struct S { char * p; }; struct S s1, s2; s1.p = malloc(100); s2 = s1;
现在这两个结构的指针指向相同的内存块 – 编译器不会将指针复制到数据。 现在很难知道哪个结构实例拥有数据。 这就是为什么C ++发明了用户可定义赋值运算符的概念 – 您可以编写特定的代码来处理这种情况。
首先看这个例子:
一个简单的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”指令代替,赋值操作符仅仅意味着将数据从一个存储位置移动到另一个存储位置。 这个赋值只对结构中的直接成员执行,当结构中有复杂数据types时将无法复制。 这里COMPLEX意味着你不能有指针数组,指向列表。
结构中的字符数组本身在大多数编译器中都不起作用,这是因为赋值只是简单地尝试复制,而没有将数据types视为复杂types。
这是一个简单的拷贝,就像使用memcpy()
(实际上,一些编译器实际上会为该代码产生对memcpy()
的调用)。 C中没有“string”,只有指向string的指针。 如果你的源代码结构包含这样一个指针,那么指针会被复制,而不是字符本身。
你的意思是“复杂”,如复数中的实部和虚部? 这看起来不太可能,所以如果不是的话,你就不得不举一个例子,因为“复杂”在C语言方面没有任何具体的含义。
你会得到一个结构的直接内存副本; 这是否是你想要的取决于结构。 例如,如果结构包含一个指针,那么这两个副本将指向相同的数据。 这可能是也可能不是你想要的; 这是你的程序devise。
要执行“智能”复制(或“深层”复制),您需要实现一个function来执行复制。 如果结构体本身包含指针和结构体,这些结构体也包含指针,并且可能指向这样的结构体(这也许就是“复杂”的意思),这很难实现,而且很难维护。 简单的解决scheme是使用C ++并为每个结构或类实现复制构造函数和赋值运算符,然后每个都负责自己的复制语义,可以使用赋值语法,并且更容易维护。