最近看linux代码时发现了结构体 struct 一种新的初始化方式,各方查找对比后总结如下:
1. 顺序初始化
教科书上讲C语言结构体初始化是按照顺序方式来讲的,没有涉及到乱序的方式。顺序初始化struct必须要按照成员的顺序进行,缺一不可,如果结构体比较大,很容易出现错误,而且表现形式不直观,不能一眼看出各个struct各个数据成员的值。
2.乱序初始化
乱序初始化是C99标准新加的,比较直观的一种初始化方式。相比顺序初始化而言,乱序初始化就如其名,成员可以不按照顺序初始化,而且可以只初始化部分成员,扩展性较好。linux内核中采用这种方式初始化struct。
目前看到3种不同的乱序初始化方式:
一是用点(.)符号, 二是用冒号(:), 三是当字段是数组时可使用索引初始化。
比较推荐的方式是第一种!
直接看示例代码吧:
1 typedef struct al_data 2 { 3 int a; 4 int b; 5 int c; 6 char ch; 7 }al_data; 8 9 struct al_data ad = 10 { 11 1, 12 3, 13 9, 14 ‘A‘, 15 }; 16 17 struct al_data ad2 = 18 { 19 .a = 2, 20 .b = 6, 21 .c = 18, 22 .ch = ‘B‘, 23 }; 24 25 struct al_data ad3 = 26 { 27 a:3, 28 b:9, 29 c:27, 30 ch:‘C‘ 31 }; 32 33 34 int main() 35 { 36 37 printf("ad.a=%d, ad.b=%d, ad.c=%d, ad.ch=%c \n", ad.a, ad.b, ad.c, ad.ch); 38 printf("ad2.a=%d, ad2.b=%d, ad2.c=%d, ad2.ch=%c \n", ad2.a, ad2.b, ad2.c, ad2.ch); 39 printf("ad3.a=%d, ad3.b=%d, ad3.c=%d, ad3.ch=%c \n", ad3.a, ad3.b, ad3.c, ad3.ch); 40 return 0; 41 }
上面是顺序初始化和前两种乱序初始化。
从结果看确实都可以初始化成功。
最后看下数组索引初始化方式:
1 struct st_al 2 { 3 int i; 4 al_data ald[3]; 5 }; 6 7 struct st_al sa = 8 { 9 .i = 1, 10 .ald = 11 { 12 [0] = {4,5,6,‘q‘}, 13 [1] = {8,9,10,‘w‘}, 14 }, 15 };
验证也是通过的!但其实索引后接的内容也是形如顺序初始化。。。。
最后写一个陷阱,不要混用不同的初始化方式,以免带来意料之外的错误
比如:先用. 初始化后面跟着顺序初始化是上一个元素的下一个元素值,容易错
1 struct al_data ad2 = 2 { 3 .c = 18, 4 .b = 6, 5 3, 6 .ch = ‘B‘, 7 };
第5行其实相当于 .c = 3
没有初始化的a赋值为了0,但不是绝对的,需要0还是手动赋值!