用C
类型转换更大或更小结构我在C程序两种结构: SmallStructABC和BigStructXYZ用C
我在两者的几个成员; SmallStructABC的所有10个成员与BigStructXYZ的前10名成员完全相同。 BigStructXYZ有50个额外的成员。
将这两个结构键入对方可以吗?
SmallStructABC *i = (BigStructXYZ*)j;
BigStructXYZ *a = (SmallStructABC*)b;
我只能访问第10(普通)会员类型转换后..
我写的C程序,我的机器上它的工作的罚款。只是想验证是否需要照顾任何角落的情况下(对齐,无效阅读,非GCC汇编等)..
编辑: 问:为什么我想要做这样的事情? A:BigStructXYZ的大小非常大(比如50KB)并且包含一些标题(键,地图等)。 我在通过网络发送之前压缩此数据。我保留标题(在我们的例子中是SmallStructABC)。 通过进行类型转换,我可以在需要时从标题访问这些键。
不,这不是一个好主意。更好的是通过指针类型转换指针的结构和操作它们:
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;
}
另一种更安全的设计是在Small
来定义Big
:
typedef struct Small {
int foo;
};
typedef struct Big {
Small small;
int y;
};
上面的代码不会编译。 j
已经是BigStructXYZ了,你的意思是把它投射到SmallStructABC?
无论如何,你试图做的是一个坏主意。将SmallStructXYZ作为BigStructXYZ内部的第一个字段并因此工作会更好:
SmallStructABC i = j.smallStruct;
BigStructXYZ a = { b };
我可以想想这种情况下,不能保证我的头顶上的工作,但它应该在大多数平台大多数情况下罚款。一个我想到的是,我认为对齐应该由结构体的最大成员来决定,所以如果在较大的结构体中有一个64位成员或其他东西,它可能会影响对齐前几名成员。对不起,我目前没有更可靠的资料或对此有更明确的解释。
在我自己的代码中,我宁愿直接将头文件嵌入到Frank Kreuger的回答中提到的较大结构中,并使用bigStruct.header.someMember
类型的接口来避免任何和所有的铸造和对齐困难。
是的,你可以做到这一点。 SmallStructABC将采用与BigStructXYZ的第一部分完全相同的内存位置。
我用这与工会。系统收到一个有效载荷,它可能是头或头+数据。
我写了工会这样的:
union HeaderOrHeaderData
{
SmallStructABC header;
BigStructXYZ headerData;
};
HeaderOrHeaderData* ptr = (HeaderOrHeaderData*) data_ptr;
这种方法比直接铸造的优点是可-By缺陷结构的mistake-指针(实际上指向小结构),并使用它,因为它指向大结构。
如果你总是使用工会,你会三思。
我用几个编译器,操作系统和平台试过这个解决方案。它在任何时候都可以正常工作。
你为什么要这样做?顺便说一句,看看工会,也许他们是你的解决方案? – 2009-12-28 04:22:37
不要那样做。将*指针指向结构* – 2009-12-28 04:26:02
@Jack - 不要忘记实际接受您收到答案的那些问题的答案。 – 2009-12-28 05:08:44