在C语言中,有几种初始化结构体的方法:
struct Point { int x, y; }; struct Point p = {10, 20};
字段按声明的顺序初始化。
struct Point p = {.y = 20, .x = 10};
可以以任何顺序初始化字段。
struct Rect { int x, y, w, h; } r = {1, 2}; // w 和 h == 0
struct Color { int r, g, b; }; struct Pixel { struct Point pos; struct Color col; }; struct Pixel px = {{10,20}, {255,0,0}};
使用命名初始化可以避免错误:
struct Pixel px = {.col = {.r = 255, .g = 0, .b = 0}};
潜在问题:
问题: 如果在初始化结构时没有明确指定所有字段,而结构被声明为自动局部变量,会发生什么?
预期错误回答: "剩余的字段将始终等于零。"
正确答案: 自动(局部)变量如果没有明确初始化将保持未初始化的值。部分初始化只初始化显式规定的字段,其余字段为未定义值(除了通过= {...}初始化,其中其余字段仅对静态/全局结构为零)。
示例:
void foo() { struct Point { int x, y, z; } p = {1}; // p.x == 1, p.y 和 p.z == 0 (只有通过 = {1};) }
故事
在图形引擎项目中,在顶点结构的开头添加了一个字段,却没有重新审视不同模块中对象的初始化方式。结果,半数模块错过了对颜色或坐标的正确初始化,导致显示出现伪影。
故事
在视频处理程序中,含有嵌套指针的结构部分初始化为 = {0},这对全局变量是正确的,但不适用于局部变量。最终,指针包含“垃圾”,导致与无效地址的交互,并产生难以捕捉的故障。
故事
在向大型结构添加新字段时,作者没有更新旧代码中的顺序初始化。由于字段和初始化器的顺序不一致,关键变量开始获得不正确的值。只有通过审核结构和引入命名初始化才帮助找到原因。