如果内存大小相等,如何将C结构转换为另一种结构类型?

Eon*_*nil 10 c struct casting unions

我有2个矩阵结构意味着相同的数据,但有不同的形式,如下所示:

// Matrix type 1.
typedef float Scalar;
typedef struct { Scalar e[4]; } Vector;
typedef struct { Vector e[4]; } Matrix;

// Matrix type 2 (you may know this if you're iPhone developer)
// Defines CGFloat as float for simple description.
typedef float CGFloat;
struct CATransform3D
   {
   CGFloat m11, m12, m13, m14;
   CGFloat m21, m22, m23, m24;
   CGFloat m31, m32, m33, m34;
   CGFloat m41, m42, m43, m44;
};
typedef struct CATransform3D CATransform3D;
Run Code Online (Sandbox Code Playgroud)

他们的记忆大小相等.所以我相信有一种方法可以转换这些类型而无需任何指针操作或复制,如下所示:

// Implemented in external lib.
CATransform3D CATransform3DMakeScale (CGFloat sx, CGFloat sy, CGFloat sz);
Matrix m = (Matrix)CATransform3DMakeScale ( 1, 2, 3 );
Run Code Online (Sandbox Code Playgroud)

这可能吗?目前,编译器打印"错误:转换为请求的非标量类型"消息.

Pau*_*l R 16

可能最好的解决方案是将两个结构组合成一个联合体.如果您想以两种不同的方式解释相同的数据,那么这是显而易见的选择.另一种方法是使用指针强制转换,但这很难看,打破了别名规则,并且可以隐藏编译器可能报告的错误.

typedef float Scalar;
typedef struct { Scalar e[4]; } Vector;
typedef struct { Vector e[4]; } Matrix;

struct CATransform3D
{
   CGFloat m11, m12, m13, m14;
   CGFloat m21, m22, m23, m24;
   CGFloat m31, m32, m33, m34;
   CGFloat m41, m42, m43, m44;
};
typedef struct CATransform3D CATransform3D;

typedef union
{
    CATransform3D t;
    Matrix m;
} UMatrix;

CATransform3D CATransform3DMakeScale (CGFloat sx, CGFloat sy, CGFloat sz);
UMatrix um;
um.t = CATransform3DMakeScale ( 1, 2, 3 );
//
// now you can just use um.m when you need to refer to the Matrix type...
//
Run Code Online (Sandbox Code Playgroud)