我有一个结构,我正在使用预处理宏来填充结构中的数组。
#include <stdio.h>
void init_data();
typedef struct _abc{
int a[10][10];
int b[5][5];
}abc;
static abc q_abc[]= {
#define XYZ(x,y,z) [x]={.a[y][z]=1,.b[y][z]=1},
XYZ(1,2,3)
XYZ(1,3,2)
};
static abc q_abc1[5];
void init_data()
{
#define XYZW(x,y,z) q_abc1[x].a[y][z] =1;
XYZW(1,2,3)
XYZW(1,3,2)
}
int main()
{
printf("\n %d %d\n",q_abc[1].a[2][3]);
init_data();
printf("\n %d %d\n",q_abc1[1].a[2][3]);
return 0;
}
我正在使用宏初始化结构q_abc
。但这里的问题是在宏调用 XYZ(1,2,3)
期间设置的值在调用下一个宏调用期间重置为默认值 0 XYZ(1,3,2)
。我可以理解为不指定任何显式初始化程序会将数组设置为默认值 0。
为了避免这种情况,我使用了 init_data
方法。这里我不是初始化数组而是赋值,因此数组将完整地保留所有宏调用的所有值。但这里的问题是,如果数据很大或宏调用的数量很大,则 func 调用将花费很少的时间来完成,这会增加我的 exe 运行时间的开销。
有没有办法在变量定义过程中实现 init_data
类行为?有什么建议吗?
最佳答案
在这种情况下,打开警告会对您有所帮助。用 GCC 编译你的代码给我这个:
main.cpp:8:40: warning: initialized field overwritten [-Woverride-init]
#define XYZ(x,y,z) [x]={.a[y][z]=1,.b[y][z]=1},
^
main.cpp:10:18: note: in expansion of macro 'XYZ'
XYZ(1,3,2)
^~~
main.cpp:8:40: note: (near initialization for 'q_abc[1]')
#define XYZ(x,y,z) [x]={.a[y][z]=1,.b[y][z]=1},
^
main.cpp:10:18: note: in expansion of macro 'XYZ'
XYZ(1,3,2)
并且有充分的理由。大括号初始值设定项将初始化所有字段,即使您省略了某些字段的显式初始值设定项(它们将为零)。通过编写 X(1,..) X(1,...)
可以将同一个索引初始化两次。您不能像尝试那样将其拆分为两个宏扩展。如果你真的想使用宏,它必须是一个单独的。
就个人而言,我不会对宏感兴趣。指定的初始值设定项使代码具有足够的可读性,即使没有将它们隐藏在宏后面也是如此。
关于c - 使用宏初始化结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53847326/