最近看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還是手動賦值!