Answers:
是,如果结构是相同类型。认为它是内存副本。
是的,结构支持赋值。但是,存在一些问题:
struct S {
char * p;
};
struct S s1, s2;
s1.p = malloc(100);
s2 = s1;
现在,两个结构的指针都指向相同的内存块-编译器不会复制指向数据的指针。现在很难知道哪个结构实例拥有数据。这就是C ++发明了用户可定义的赋值运算符的概念的原因-您可以编写特定的代码来处理这种情况。
struct
本身的数据被清楚地复制。
首先看这个例子:
下面给出了一个简单的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表示您不能有指向列表的指针数组。
结构中的字符数组本身不能在大多数编译器上使用,这是因为赋值将仅尝试复制而无需查看复杂类型的数据类型。
这是一个简单的副本,就像您要进行的操作一样memcpy()
(实际上,某些编译器实际上会memcpy()
对该代码进行调用)。C中没有“字符串”,只有指向一串字符的指针。如果您的源结构包含此类指针,则该指针将被复制,而不是字符本身。
memcpy
,请参见此处:godbolt.org/z/nPxqWc-但现在,如果我传递相同的指针a
和b
,并且*a = *b
被转换memcpy
为未定义的行为,因为对于memcpy
“内存区域不得重叠”。(引自手册页)。那么编译器在使用中memcpy
是错误的还是我在编写这样的赋值时是错误的?
您是用复杂的数字表示实部和虚部的意思吗?这似乎不太可能,因此,如果不是这样,则您必须举一个例子,因为“复杂”在C语言方面没有任何具体含义。
您将获得该结构的直接内存副本。那是否是您想要的取决于结构。例如,如果结构包含一个指针,则两个副本都将指向相同的数据。这可能是您想要的,也可能不是。这取决于您的程序设计。
要执行“智能”副本(或“深度”副本),您将需要实现执行该副本的功能。如果结构本身包含指针以及也包含指针的结构,并且可能还包含指向此类结构的指针(也许就是您所说的“复杂”的意思),则很难实现,并且很难维护。一种简单的解决方案是使用C ++并为每个结构或类实现副本构造函数和赋值运算符,然后每个人都对自己的副本语义负责,可以使用赋值语法,并且维护起来更容易。