将一个C结构铸造成另一个

我有两个相同的(但不同的名字)C结构:

typedef struct { double x; double y; double z; } CMAcceleration; typedef struct { double x; double y; double z; } Vector3d; 

现在我想分配一个CMAccelerationvariables给Vector3dvariables(复制整个结构体)。 我该怎么做?

我尝试了以下,但得到这些编译器错误:

 vector = acceleration; // "incompatible type" vector = (Vector3d)acceleration; // "conversion to non-scalar type requested" 

当然,我可以单独设置所有成员:

 vector.x = acceleration.x; vector.y = acceleration.y; vector.z = acceleration.z; 

但这似乎相当不方便。

什么是最好的解决scheme?

这是你唯一的解决scheme(除了包装成一个函数):

 vector.x = acceleration.x; vector.y = acceleration.y; vector.z = acceleration.z; 

你实际上可以投它,像这样(使用指针)

 Vector3d *vector = (Vector3d*) &acceleration; 

但是这并不在规范中,因此行为取决于编译器,运行时和大绿地怪物。

你可以使用指针来进行types转换;

 vector = *((Vector3d *) &acceleration); 

你为什么不使用。

 typedef CMAcceleration Vector3d; 

(而不是创build一个全新的结构)

在这种情况下vector = acceleration; 编译就好了。

你使用了一个实用的function:

 void AccelerationToVector( struct CMAcceleration* from, struct Vector3d* to ) { to->x = from->x; to->y = from ->y; to->z = from->z; } 

memcpy(&vector, &acceleration, sizeof(Vector3d));

请注意,如果内存中结构的物理布局是相同的,那么这只能起作用。 不过,@Oli指出,编译器没有义务确保这一点!

一个安全的(尽pipe有点复杂)的方法是使用一个联合:

 union { CMAcceleration a, Vector3d v } tmp = { .a = acceleration }; vector = tmp.v; 

当被访问的成员不是最后一个成员时,值被重新解释(从C99开始)。 在这种情况下,我们设置加速度,然后访问vector,所以加速度被重新解释。

例如,这是NSRectToCGRect函数的实现方式。

这通过一个联盟很容易实现:

 typedef struct { double x; double y; double z; } CMAcceleration; typedef struct { double x; double y; double z; } Vector3d; typedef union { CMAcceleration acceleration; Vector3d vector; } view; int main() { view v = (view) (Vector3d) {1.0, 2.0, 3.0}; CMAcceleration accel = v.acceleration; printf("proof: %g %g %g\n", accel.x, accel.y, accel.z); }