使用指定的初始化器

Version >= C99

C99 引入了指定初始化器的概念*。*這些允許你指定陣列,結構或聯合的哪些元素將由以下值初始化。

陣列元素的指定初始值設定項

對於像普通 int 這樣的簡單型別:

int array[] = { [4] = 29, [5] = 31, [17] = 101, [18] = 103, [19] = 107, [20] = 109 };

方括號中的術語(可以是任何常量整數表示式)指定陣列的哪個元素將由 = 符號後的術語的值初始化。未指定的元素是預設初始化的,這意味著定義了零。該示例按順序顯示指定的初始化程式; 他們沒有必要整理好。這個例子顯示了差距; 那些是合法的。該示例未顯示同一元素的兩個不同初始化; 這也是允許的(ISO / IEC 9899:2011,§6.7.9 初始化,¶19 初始化應在初始化器列表順序中進行,每個初始化器為特定子物件提供,覆蓋任何先前列出的同一子物件的初始化器 )。

在此示例中,未明確定義陣列的大小,因此指定的初始值設定項中指定的最大索引決定了陣列的大小 - 在示例中將是 21 個元素。如果定義了大小,那麼像往常一樣,初始化超出陣列末尾的條目將是一個錯誤。

結構的指定初始化器

你可以使用 . element 表示法指定結構的哪些元素已初始化 :

struct Date
{
    int year;
    int month;
    int day;
};

struct Date us_independence_day = { .day = 4, .month = 7, .year = 1776 };

如果未列出元素,則預設初始化(歸零)。

聯合的指定初始化程式

你可以使用指定的初始值設定項指定聯合的哪個元素。

Version = C89

在 C 標準之前,沒有辦法初始化 union。C89 / C90 標準允許你初始化 union 的第一個成員 - 因此首先列出哪個成員的選擇很重要。

struct discriminated_union
{
    enum { DU_INT, DU_DOUBLE } discriminant;
    union
    {
        int     du_int;
        double  du_double;
    } du;
};

struct discriminated_union du1 = { .discriminant = DU_INT, .du = { .du_int = 1 } };
struct discriminated_union du2 = { .discriminant = DU_DOUBLE, .du = { .du_double = 3.14159 } };

Version >= C11

請注意,C11 允許你在結構中使用匿名聯合成員,因此你不需要上一個示例中的 du 名稱:

struct discriminated_union
{
    enum { DU_INT, DU_DOUBLE } discriminant;
    union
    {
        int     du_int;
        double  du_double;
    };
};

struct discriminated_union du1 = { .discriminant = DU_INT, .du_int = 1 };
struct discriminated_union du2 = { .discriminant = DU_DOUBLE, .du_double = 3.14159 };

用於結構陣列等的指定初始化器

這些構造可以組合為包含陣列元素的結構陣列等。使用完整的大括號可確保符號明確無誤。

typedef struct Date Date;  // See earlier in this example

struct date_range
{
    Date    dr_from;
    Date    dr_to;
    char    dr_what[80];
};

struct date_range ranges[] =
{
    [3] = { .dr_from = { .year = 1066, .month = 10, .day = 14 },
            .dr_to   = { .year = 1066, .month = 12, .day = 25 },
            .dr_what = "Battle of Hastings to Coronation of William the Conqueror",
          },
    [2] = { .dr_from = { .month = 7, .day =  4, .year = 1776 },
            .dr_to   = { .month = 5, .day = 14, .year = 1787 },
            .dr_what = "US Declaration of Independence to Constitutional Convention",
          }
 };

在陣列初始值設定項中指定範圍

GCC 提供了一個擴充套件 ,允許你指定陣列中應該給予相同初始值設定項的元素範圍:

int array[] = { [3 ... 7] = 29, 19 = 107 };

三個點需要與數字分開,以免其中一個點被解釋為浮點數( 最大咀嚼規則)的一部分。