我在C程序中有两个结构: SmallStructABC和BigStructXYZ
我在他们两个人中都有几个成员; SmallStructABC的所有10个成员与BigStructXYZ的前10个成员完全相同。 BigStructXYZ还有50名成员。
将这两个结构相互转换为可以吗?
SmallStructABC *i = (BigStructXYZ*)j;
BigStructXYZ *a = (SmallStructABC*)b;
我只能在打字后访问前10个(普通)成员。
我写了C程序,它在我的机器上工作正常。只是想验证我是否需要处理任何极端情况(对齐,无效读取,非gcc编译等)..
编辑: 问:为什么我想做这样的事情?
答:BigStructXYZ的大小非常大(比如说50KB)并且包含一些标题(键,地图等)。 我在通过网络发送之前压缩这些数据。我保留标题(在我们的例子中是SmallStructABC)。 通过类型转换,我可以在需要时从头文件中访问这些键。
答案 0 :(得分:10)
不,这不是个好主意。更好的方法是将结构指针输入结构并通过指针操作它们:
void DoSomething(Small *thing) {
// ...
}
int main() {
Big big = {0};
Small small = {0};
Small *p0 = (Small*)&big;
Small *p1 = &small;
DoSomething(p0);
DoSomething(p1);
return 0;
}
另一种更安全的设计是根据Big
定义Small
:
typedef struct Small {
int foo;
};
typedef struct Big {
Small small;
int y;
};
答案 1 :(得分:3)
上面的代码无法编译。 j
已经是BigStructXYZ,你的意思是将其转换为SmallStructABC吗?
无论如何,你要做的是一个坏主意。将SmallStructXYZ作为BigStructXYZ中的第一个字段并更好地工作会更好:
SmallStructABC i = j.smallStruct;
BigStructXYZ a = { b };
答案 2 :(得分:1)
我可以想到这样的情况不能保证在我的头脑中起作用,但在大多数情况下大多数平台应该没问题。我想到的一点是,对齐应该由结构的最大成员决定,所以如果在更大的结构中有64位成员或其他东西,它可能会影响对齐前几个成员。对不起,我现在没有更坚实的消息来源或更明确的解释。
在我自己的代码中,我更喜欢将标题直接嵌入到更大的结构中,如Frank Kreuger的答案所述,并使用bigStruct.header.someMember
类型的接口来避免任何和所有的转换和对齐困难。
答案 3 :(得分:0)
是的,你可以做到。 SmallStructABC将在内存中与BigStructXYZ的第一部分完全相同。
我和工会一起使用了这个。系统接收有效负载,可能是标头或标头+数据。
我写了这样的联盟:
union HeaderOrHeaderData
{
SmallStructABC header;
BigStructXYZ headerData;
};
HeaderOrHeaderData* ptr = (HeaderOrHeaderData*) data_ptr;
这种方法优于直接转换的优点是可能 - 错误 - bug结构的指针(实际上指向小结构)并使用它,因为它指向大结构。
如果你总是使用工会,你会三思而行。
我尝试了几个编译器,操作系统和平台的解决方案。它在任何时候都可以正常工作。