現代 C (C11/C17/C23)

指定初始化子(designated initializer)

/ DEZ-ig-nay-ted /

當你填入結構或陣列時,舊做法是依精確順序列出值:struct point p = { 3, 4 };——你得記住哪個位置對應哪個欄位。指定初始化子讓你具名指出要設定的成員或索引,於是你可以任意順序撰寫、略過某些項,並讓程式碼自我說明:struct point p = { .x = 3, .y = 4 };

語法對結構或聯合的欄位用 .成員、對陣列元素用 [索引],後面接 = 與值。任何你「沒有」提到的成員或元素都會被初始化為零(依其型別),就如同你寫了 = {0} 一樣。你可以混用它們、指向像 .cfg.timeout = 5 的巢狀成員,也可以像 [0] = 1, [99] = 1 這樣設定稀疏陣列元素,只填一百個中的兩個。這個特性出自 C99(C++ 在很久之後才加入較受限的形式,所以別假設規則完全相同)。

它重要在於讓初始化既可讀又能抵抗變更:往結構加一個欄位,既有的指定初始化子仍能編譯,且新欄位被零初始化。提醒:若後面的指定子指向同一個位置,會「覆蓋」前面的,所以重疊時順序仍有影響;而未提到的成員被歸零是你應該刻意依賴的特性,而非偶然碰上的。

struct config { int port; int timeout; const char *host; }; struct config c = { .port = 8080, .host = "local" }; // .timeout 未提到,所以是 0 int days[7] = { [0] = 1, [6] = 1 }; // 設定週末,其餘為 0

只命名你在意的欄位;未提到的一律零初始化,且順序不再重要。

未提到的成員會被零初始化(而非留為不確定值),但若兩個指定子指向同一位置,後者勝出——重疊的指定子對順序敏感。

又称
designated initializationnamed-field initializer具名欄位初始化