在C语言中将结构体的部分赋值给另一个结构体

3
我想在C/C++中实现类似这样的概念。
struct first{
   int a,b,c;
}my1;

struct second{
   int a,b,c;
   int extended;
}my2;

一种可能的翻译是:“以某种方式能够拥有”。
my2=my1; 

我想把它解决为

(只复制相同的部分,扩展部分不变)
struct second{
     first first_;
     int extended;
 }my2;

and have

my2.first_ = my1;

但对我来说有点丑。有没有更清晰的解决方案?可能是扩展一个结构或类似的东西吗?

C还是C++,或者两者的共同子集? - CB Bailey
你必须明确指定你想要分配的对象,以及你想要修改的该对象的部分。因此,你的解决方案已经尽可能地简洁了。("_"确实很丑,但你可以选择一个不同的名称来解决这个问题)。 - Ira Baxter
2
如果您想在C++中完成这个任务,就请拿出您的C++书籍,阅读关于复制构造函数和赋值运算符的内容。 - Soren
我更喜欢C语言,因为我想将这些分配的内存复制到CUDA程序中。我担心C++可能会引入额外的内存开销,这可能无法在移动数据时被捕获。(只是想想而已) 我还看到了这个https://dev59.com/Q03Sa4cB1Zd3GeqPxbWt?rq=1,它给出了类似的答案,使用 struct second: public first{ int extended}; 但是对于赋值,我不能做到my2=my1。 - Roozbeh G
2
将问题更新为仅涉及C语言。 - clcto
你可以使用 memcpy 函数 memcpy(&second, &first, sizeof(first)); - user1551592
3个回答

2
就像这样:
struct second : first
{
    int extended;

    second& operator=(const first& f)
    {
        first::operator=(f); extended = 0; return *this;
    }
};

这看起来很棒。你能解释一下 { } 内的代码吗?first::operator=(f) 是什么意思? - Roozbeh G
@Soren 好的,谢谢。这就涉及到了 extended 的默认值是什么,这是构造函数的工作...不管怎样,我们假设它是 0 - iavr
1
不需要重载operator=:只需使用*(first*)&object = value;即可,这适用于C和C++。 - Deduplicator
@iavr:是的,它也有一个C++标签,这就是为什么我没有反对你使用C++回答的原因。不过,在我看来,它应该可以同时适用于两个标签,因为两个标签都在那里,现在你提醒我了。 - Deduplicator
@Deduplicator 我会在几分钟内删除我的回答。 - iavr
显示剩余3条评论

1

有点丑,但是这就是它:

my1 = *(first*)&my2;

我认为我也可以使用这个。但是编译器是否可能在生成my1和my2变量之间的某些填充时产生不同,导致它们的内存大小不匹配而失败? - Roozbeh G
1
@Roozbeh G,可以的。但是还有另一条规则,如果两个具有共同初始序列的结构体都是联合体的成员,则可以将共同的初始序列别名。因此,如果您包括代码 union X { struct first f; struct second g; };,那么它保证了Flibustier的建议即使您从未实例化该联合体也能正常工作。据我所知,没有任何实现会在不存在联合体的情况下使用不同的结构体,因此人们倾向于省略它并假设编译器不是反常的。 - M.M
@Matt 另一种方式 my2 = *(second*)&my1; 呢?我猜不能,因为 sizeof(my2) > sizeof(my1)。 - Flibustier
是的,那会访问你没有拥有的内存。 - M.M

0
你可以为 struct second 重载 = 运算符:
second & operator=(const first & s) {
    this->a = s.a;
    this->b = s.b;
    this->c = s.c;
    return *this;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接