我有一个结构,并且我正在使用预处理宏在struct中填充数组。
#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)
的调用过程中,对XYZ(1,3,2)
的宏调用期间设置的值被重置为默认0。我可以理解为未指定任何显式初始化程序会将数组设置为默认值0。
为避免这种情况,我使用了init_data
方法。在这里,我不是在初始化数组而是在分配数组,因此数组将完整保留所有宏调用中的所有值。但是这里的问题是,如果数据很大或宏调用的数量很大,那么func调用将花费很少的时间来完成,这会增加我的exe运行时的开销。
在变量定义本身期间,有什么方法可以实现init_data
的行为?有什么建议吗?
答案 0 :(得分:3)
在这种情况下,打开警告会对您有所帮助。用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,...)
,您可以两次初始化相同的索引。您不能像尝试那样将其拆分为两个宏扩展。如果您确实希望使用宏,则必须在一个中。
就个人而言,我不会喜欢宏。指定的初始化程序即使不将代码隐藏在宏后面也可以使代码具有足够的可读性。