初始化C中的结构

初始化C中的结构,c,struct,init,c-preprocessor,C,Struct,Init,C Preprocessor,我有一个关于C中结构初始化的问题。 我有一个结构: struct TestStruct { u8 status; u8 flag1; u8 flag2; }; 我需要一个通用函数/宏来初始化此结构并设置一个参数的值,例如status=1,简单的方法是: TestStruct t = {}; t.status = 1; 但是,通过这样做,我已经将status的值设置了两次,第一次在init函数中将其设置为0,第二次将其设置为1(优化没有帮助?。 (请不要告诉我t={1,0,0}我在寻找一种通用

我有一个关于C中结构初始化的问题。 我有一个结构:

struct TestStruct
{
u8 status;
u8 flag1;
u8 flag2;
};
我需要一个通用函数/宏来初始化此结构并设置一个参数的值,例如status=1,简单的方法是:

TestStruct t = {};
t.status = 1;
但是,通过这样做,我已经将status的值设置了两次,第一次在init函数中将其设置为0,第二次将其设置为1(优化没有帮助?。
(请不要告诉我t={1,0,0}我在寻找一种通用方法)
我在考虑init函数中的宏,类似于:

#define INIT_TESTSTRUCT (param, value) \
{ .status=0, .flag1=0, .flag2=0, .param=value }
TestStruct t = INIT_TESTSTRUCT(status, 0);
但是,编译器给出了错误“initialized field overwrited”,因为我已经设置了两次status的值

请帮助指出如何改变宏以实现我想要的,非常感谢

#define INIT_TESTSTRUCT(param, value) \
    { .param=(value) }
TestStruct t = INIT_TESTSTRUCT(status, 0);

我应该这样做。然后将变量添加到
.data
段中-因为它是一个初始化的段-并且编译器(而不是链接器或加载程序)将所有未明确提及的字段设置为0。

您在错误的位置有一个空格:

#define INIT_TESTSTRUCT(param, value) \
{ .status=0, .flag1=0, .flag2=0, .param=(value) }
我应该这样做

宏定义的
必须紧跟在宏名称之后。否则,解析器将其视为没有参数的宏,并将其扩展为
(param,value)…等…
,在您的情况下,这显然是一个语法错误

还请注意,通常最好在替换文本中的参数周围放置
()
,以避免语法混乱

TestStruct t = {};
在C中是非法的。如果它在您的情况下编译,它必须是非标准编译器扩展。您可以通过

TestStruct t = { 0 };
这在C中是合法的。它将整个结构中的所有字段设置为零

其次,即使使用指定的初始值设定项,C语言也遵循传统的“要么全部初始化,要么什么都不初始化”方法:如果只初始化聚合中的一个字段,则所有其他字段都隐式初始化为零

这意味着在你的情况下,你所要做的就是

TestStruct t = { .status = 1 };
初始化整个结构。
状态
字段将设置为
1
,而所有其他字段将设置为零

因此,您的宏可以实现为

#define INIT_TESTSTRUCT(param, value) { .param = value }
TestStruct t = INIT_TESTSTRUCT(status, 1);

无需显式地将所有其他字段设置为零-它将自行发生。

谢谢,这有助于我理解struct init function:)值不应该在()括号中吗?我不确定缺少它们是否会破坏任何东西,但安全总是好的。你是对的,
value
应该有
()
,以防它包含混乱的内容,但在
param
的情况下,它将是连续生产的。@DarthHunterix通常,你会把
()
如果您有一个可以放入函数中的宏:
#定义两次(x)(2*(x))
。在这种情况下,
两次(2+2)
产生
(2*(2+2))
,这很好。只需一个
2*x
你就可以做
~两次(2+2)
,这将产生
~2*2+2
,而这意味着
(~2)*2)+2
,根本不是你想要的东西。