在C中声明后如何初始化结构数组

用户名

在声明结构之后,是否可以初始化整个结构数组(也许使用复合文字)?

typedef struct
{
    int a;
    int b;
} tStruct;

/* Array of structures in declared in global scope, but not initialized */
tStruct myStruct[3];

void init()
{
  /* We want to initizlize the array with specific values*/
  
  /* using compound literals to initialize the whole array doesn't work */
  myStruct = (tStruct[])
  {
      {1, 2},
      {3, 4},
      {5, 6}
  }; 
}
PSkocik

数组不是R值,因此不能通过assignemnt复制它们。但是你可以使用memcpy

#include <string.h>
void init(void)
{
    memcpy(&myStruct,(tStruct[]) { {1, 2}, {3, 4}, {5, 6} }, sizeof(myStruct)); 
}

由优化的编译器生成的代码应该不会比您得到的差很多

void init2(void)
{
    myStruct[0] = (tStruct){1,2};
    myStruct[1] = (tStruct){3,4};
    myStruct[2] = (tStruct){5,6};
}

或者

void init3(void)
{
    myStruct[0].a = 1, myStruct[0].b = 2;
    myStruct[1].a = 3, myStruct[1].b = 4;
    myStruct[2].a = 5, myStruct[1].b = 6;
}

Gcc和clang能够消除不必要的复合变量,例如直接分配各个组件。

https://gcc.godbolt.org/z/j9f37j

该方法最大的缺点memcpy是它有点脆弱且类型不安全(如果违反了非强制类型兼容性,可能导致超出范围的读/写操作)。

如果您的C语言方言具有__typeof,那么通过一些宏观技巧,您应该几乎可以绕开C语言的局限性:

#include <string.h>
#define assignAnything(DestPtr,SrcPtr) ((void)((__typeof(SrcPtr)){0} = (__typeof(DestPtr)){0}) /*typecheck*/, memcpy(DestPtr, SrcPtr, sizeof(*(DestPtr))))

/* A Ptr-less version:
#define assignAnything2(Dest,Src) ((void)((__typeof(&(Src))){0} = (__typeof(&(Dest))){0}), memcpy(&(Dest), &(__typeof(Src)){Src}, sizeof(Dest)))
doesn't always work, unfortunately */

int main()
{
    int d[3][2][1]={0};
    int const s[3][2][1] = {0};
    assignAnything(&d,&s); //works
    #if NOPE
    assignAnything(&s,&d); //will (correctly) compile-time fail because s has more qualifs (const) than d
    #endif
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章