C语言中如何在结构体自身或匿名对象中引用成员值?
在C18中实现结构体成员关联初始化(无需对象名/支持匿名对象)
首先明确:C18标准中没有类似C++里this的指针,供结构体初始化器直接引用当前对象的其他成员,而且你之前用对象名直接引用的写法(struct Example ex = {.member_a=50, .member_b=ex.member_a*2})其实属于编译器非标准扩展,并非C18规范允许的行为——标准C中,初始化阶段对象尚未完全构造,直接引用其成员属于未定义行为,不能跨编译器依赖。
要在标准C18下实现无冗余的成员关联初始化(支持命名对象和匿名对象),可以用以下两种方案:
方案1:用宏封装初始化逻辑
通过宏把成员关联的逻辑打包,只需要传入member_a的值,宏会自动计算member_b,既避免冗余,也不依赖对象名:
#define INIT_EXAMPLE(a) {.member_a = (a), .member_b = (a) * 2} // 初始化命名对象 struct Example ex = INIT_EXAMPLE(50); // 初始化匿名对象(比如作为函数参数传递) void process_example(struct Example e); process_example((struct Example)INIT_EXAMPLE(50));
这种方式写法简洁,完全符合标准C18,且适配所有场景。
方案2:用初始化函数(构造风格)
如果成员关联逻辑比较复杂(比如涉及更多计算、条件判断),可以写一个专门的初始化函数,返回构造好的结构体对象:
struct Example create_example(int a) { struct Example result; result.member_a = a; result.member_b = a * 2; // 后续可以添加更复杂的关联逻辑 return result; } // 使用命名对象 struct Example ex = create_example(50); // 使用匿名对象 process_example(create_example(50));
这种方式可读性更强,逻辑扩展更灵活,同样完全兼容标准C18。
额外说明
- 无法在结构体定义本身中直接实现成员间的自动关联(比如让
member_b默认等于member_a的倍数),C18不支持这种成员级的默认初始化逻辑。 - 你之前尝试的
.member_b = member_a或.member_b = .member_a写法,标准C初始化器不支持这种直接引用其他成员的语法,所以编译器无法识别。
内容的提问来源于stack exchange,提问作者Harshit Gupta
相关产品推荐
相关产品推荐

