将struct复制到C中的struct


74

我想将一个相同的结构复制到另一个结构中,以后再与第一个结构进行比较。问题是当我这样做时,我的编译器会警告我!我应该用其他方式还是做错了呢?

在头文件中:

在C文件中:


6
编译器会发出什么警告?
萧伯纳

1
PS-呼叫sizeofsizeof(RTCclk)不应该sizeof TRCclk吗?
尼克·肖

只是一个警告[2054]可疑的指针转换,我应该改用memset还是memmove?
基督教徒

6
@NickShaw:括号是多余的,如中所示i = (2)+(4);。我不喜欢他们 其他人也这样做。
2012年

1
我可以找到的唯一有关“警告[2054]可疑指针转换”的参考与Microchip的PIC编译器有关。它们的内存映射可以通过不同的方式访问,并且可能会受到诸如银行业务之类的影响,因此您应仔细检查memcpy()的签名是什么以及链接器将变量放置在何处。也许使用已回答的结构分配是最安全的选择。
tinman '02

Answers:


159

对于简单的结构,您可以memcpy像使用一样使用,也可以仅将一个分配给另一个:

编译器将创建代码来为您复制结构。


有关复制的重要说明:它是浅复制,就像 memcpy。这意味着,例如,如果您有一个包含指针的结构,那么将仅复制实际的指针,而不是它们指向的指针,因此在复制之后,您将有两个指向同一内存的指针。


6
即使我在struct中有数组,它也能正常工作吗?例如:struct example {int myThings [10000]; 字符名称[100]; int id; };
Rodi 2014年

那我该如何做一个深拷贝?
用户

3
@User如果该结构不包含任何指针,并且所包含的结构不包含指针,依此类推,则可以解决。如果在任何地方都有指针,则需要分配新的内存并使用eg复制memcpy
某些程序员花了

是的,这是一个链表。因此,仅对链接列表中的第一项进行存储?
用户

3
@User如果要复制列表,最简单的方法是完全从头开始创建列表。循环遍历现有列表并获取其数据,然后将其添加到新列表中。
某些程序员花了

18

您的代码是正确的。您还可以将一个直接分配给另一个(请参阅Joachim Pileborg的答案)。

当您以后比较这两个结构时,您需要小心比较各个结构,一次比较一个成员,而不是使用memcmp; 请参阅如何比较C中相等的结构?


因此,我应该这样做:dowhile(RTCclk.second!= RTCclkBuffert.second || RTCclk.minute!= RTCclkBuffert.minute || RTCclk.hour!= RTCclkBuffert.hour || RTCclk.mday!= RTCclkBuffert.mday) ;
基督教徒

1
是。虽然将比较包装在函数中可能更整洁。
Graham Borland

3

复制c中的副本结构,您只需分配如下值:

现在RTCclkBuffert.hour的值为5,

RTCclkBuffert.minute将具有值4

RTCclkBuffert.second的值为3


2

也是一个很好的例子.....


1

您的memcpy代码是正确的。

我的猜测是您缺少string.h的包含。因此,编译器假定的原型错误memcpy,因此也提出了警告。

无论如何,为了简单起见,您应该只分配结构(如Joachim Pileborg所指出的)。


2
memcpy对于结构来说,“我不知道我使用的语言是否支持结构分配”。在相同类型的两个结构之间使用memcpy的唯一原因是,由于某种原因,您需要确保准确保留结构填充。
哈兹

1

memcpy希望前两个参数为void *。

尝试: memcpy( (void*)&RTCclk, (void*)&RTCclkBuffert, sizeof(RTCclk) );

PS,虽然不是必需的,但约定规定了sizeof运算符的括号。您可以避免使用很多C语言而使代码无法维护,因此遵循惯例是优秀(可雇佣)C程序员的标志。


根据我的理解,鼓励不要对sizeof运算符使用括号。
再见SE

0

我认为您应该将指针转换为(void *)以摆脱警告。

另外,您可以使用不带括号的sizeof,可以将其与变量一起使用,但是如果RTCclk被定义为数组,则sizeof会返回数组的完整大小。如果将sizeof与type一起使用,则应与方括号一起使用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.