使用指定的初始化器

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 };

三个点需要与数字分开,以免其中一个点被解释为浮点数( 最大咀嚼规则)的一部分。