C语言 将一个 C 结构转换为另一个

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3995940/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:46:34  来源:igfitidea点击:

Casting one C structure into another

ccastingstruct

提问by Ortwin Gentz

I have two identical (but differently named) C structures:

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

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


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

Now I want to assign a CMAcceleration variable to a Vector3d variable (copying the whole struct). How can I do this?

现在我想将 CMAcceleration 变量分配给 Vector3d 变量(复制整个结构)。我怎样才能做到这一点?

I tried the following but get these compiler errors:

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

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

Of course I can resort to set all members individually:

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

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

but that seems rather inconvenient.

但这似乎很不方便。

What's the best solution?

最好的解决办法是什么?

回答by Georg Sch?lly

That's your only solution (apart from wrapping it into a function):

这是您唯一的解决方案(除了将其包装到函数中):

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

You could actually cast it, like this (using pointers)

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

Vector3d *vector = (Vector3d*) &acceleration;

but this is not in the specs and therefore the behaviour depends on the compiler, runtime and the big green space monster.

但这不在规范中,因此行为取决于编译器、运行时和大型绿色空间怪物。

回答by David Gelhar

You could use a pointer to do the typecast;

您可以使用指针进行类型转换;

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

回答by sharptooth

You use an utility function for that:

您为此使用了一个实用程序函数:

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

回答by groovingandi

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

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

Please note that this works only, if the physical layout of the structs in memory are identical. However, as @Oli pointed out, the compiler is not obliged to ensure this!

请注意,这仅适用于内存中结构的物理布局相同的情况。但是,正如@Oli 所指出的,编译器没有义务确保这一点!

回答by SysAdmin

Why dont you use.

你为什么不使用。

typedef CMAcceleration Vector3d;

(instead of creating a whole new structure)

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

in that case vector = acceleration;compiles just fine.

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

回答by johnco

This is achieved easily through a 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);
}

回答by lundblade

Another version of the utility function making use of C99:

另一个使用 C99 的实用函数版本:

static inline struct Vector3d AccelerationToVector(struct CMAcceleration In)
{
    return (struct Vector3d){In.x, In.y, In.z};
}

With the compiler optimization turned up (e.g., -Os), this should turn into absolutely no object code when invoked.

随着编译器优化的开启(例如,-Os),这在调用时应该变成绝对没有目标代码。

回答by Joaquin Montero Salinas

A safe (albeit somewhat convoluted) way to do it would be to use a union:

一种安全的(尽管有些复杂)方法是使用联合:

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

Values are reinterpreted (since C99) when the accessed member is not the last set one. In this case, we set the acceleration and then we access the vector, so the acceleration is reinterpreted.

当访问的成员不是最后一组成员时,重新解释值(自 C99 起)。在这种情况下,我们设置加速度,然后访问向量,因此加速度被重新解释。

This is the way the NSRectToCGRectfunction is implemented, for example.

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