我有两个相同(但命名不同)的C结构:
typedef struct {
double x;
double y;
double z;
} CMAcceleration;
typedef struct {
double x;
double y;
double z;
} Vector3d;
现在我想将一个CMAcceleration变量赋给一个Vector3d变量(复制整个结构)。我怎么能这样做?
我尝试了以下操作但得到了这些编译器错误:
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;
但这似乎很不方便。
什么是最好的解决方案?
答案 0 :(得分:42)
这是你唯一的解决方案(除了将其包装成一个函数):
vector.x = acceleration.x;
vector.y = acceleration.y;
vector.z = acceleration.z;
你可以实际投射它,像这样(使用指针)
Vector3d *vector = (Vector3d*) &acceleration;
但这不在规范中,因此行为取决于编译器,运行时和大绿地怪物。
答案 1 :(得分:16)
您可以使用指针进行类型转换;
vector = *((Vector3d *) &acceleration);
答案 2 :(得分:6)
您可以使用实用程序功能:
void AccelerationToVector( struct CMAcceleration* from, struct Vector3d* to )
{
to->x = from->x;
to->y = from ->y;
to->z = from->z;
}
答案 3 :(得分:5)
memcpy(&vector, &acceleration, sizeof(Vector3d));
请注意,如果内存中结构的物理布局相同,则此方法有效。但是,正如@Oli指出的那样,编译器没有义务确保这一点!
答案 4 :(得分:5)
为什么不使用。
typedef CMAcceleration Vector3d;
(而不是创建一个全新的结构)
在这种情况下vector = acceleration;
编译得很好。
答案 5 :(得分:1)
安全(虽然有点复杂)的方法是使用联合:
union { CMAcceleration a, Vector3d v } tmp = { .a = acceleration };
vector = tmp.v;
当被访问的成员不是最后一个成员时,将重新解释值(自C99起)。在这种情况下,我们设置加速度然后我们访问向量,因此重新解释加速度。
这是NSRectToCGRect函数的实现方式,例如。
答案 6 :(得分:1)
这可以通过 union :
轻松实现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);
}
答案 7 :(得分:1)
使用C99的实用程序功能的另一个版本:
static inline struct Vector3d AccelerationToVector(struct CMAcceleration In)
{
return (struct Vector3d){In.x, In.y, In.z};
}
打开编译器优化功能(例如-Os),在调用时应该完全没有目标代码。
答案 8 :(得分:0)
您可以使用指针创建联合,从而避免复制数据。
示例:
struct Ocp1SyncHeader
{
aes70::OCP1::OcaUint8 syncVal;
aes70::OCP1::Ocp1Header header;
};
struct convertToOcp1SyncHeader
{
union
{
Ocp1SyncHeader* data;
const uint8_t* src;
};
convertToOcp1SyncHeader& operator=(const uint8_t* rvalue)
{
src = (const uint8_t*)rvalue;
return *this;
}
};
**这样访问:
convertToOcp1SyncHeader RecvData;
RecvData = src; // src is your block of data that you want to access
**这样的访问成员:
RecvData.data.header