在c中将数组转换为结构,反之亦然

时间:2017-02-16 08:36:45

标签: c arrays struct casting

设为以下结构:

typedef struct { 
    int x;
    int y;
} st;

我可以"演员"一个int数组到结构st:

st z;
int t[2];
t[0] = 0;
t[1] = 1;
z = *(st*)(t);
printf("%d,%d\n", z.x, z.y);

然后输出为例外:

0,1

但我不能将struct st转换为int数组:

st z = {0, 1};
int t[2];
t = *(int*)(&z);

因为在初始化之后无法分配数组。

那么,我怎么能实现这个目标呢? 谢谢你的帮助。

2 个答案:

答案 0 :(得分:2)

z = *(st*)(t);

从语法上讲,这段代码将被编译(赋值给struct)并且可能会产生预期或意外的结果,因为它违反了严格的别名要求。

t = *(int*)(&z);

由于多种原因,这段代码在语法上是不正确的,因此编译本身就会失败。首先,您不能分配给数组,其次,您要将int的指针分配给int数组。更好的选择是使用memcpyunion代替。虽然我会建议会员副本。

答案 1 :(得分:0)

这里有几个问题需要解决。您对如何在运行时为数组赋值的关注是一个问题。指针转换期间的“严格别名”是另一种。

关于严格别名,不允许您访问int [2]类型的数组,就好像它是struct { int x; int y; }一样。在形式上,这可以被视为未定义的行为。一些编译器,尤其是gcc,可能会对这些代码进行奇怪的优化。

要解决这些问题以及阵列分配问题,我建议您将代码更改为:

typedef union 
{ 
  struct
  {
    int x;
    int y;
  }; //Anonymous structure, C11 feature, won't compile on old legacy compilers.
  int array [2];
} st;

这解决了所有别名问题,您现在可以使用简单的赋值复制这些“数组”:

s1 s1 = ...;
s1 s2 = s2;

代码

st z;
int t[2] = {1, 1};
z = *(st*)t;

现在是良好且定义明确的行为(*)。

(*)C11 6.5 / 7:

  

“对象的存储值只能由左值访问   具有以下类型之一的表达式:“/ - /

     
      
  • “在其成员中包含上述类型之一的聚合或联合类型”
  •