初始化聚合类型Initializing Aggregate Types

“聚合”类型是结构、联合或数组类型。An "aggregate" type is a structure, union, or array type. 如果聚合类型包含聚合类型的成员,则初始化规则将以递归方式应用。If an aggregate type contains members of aggregate types, the initialization rules apply recursively.

语法Syntax

initializerinitializer:
{ initializer-list } /* 用于聚合初始化 */{ initializer-list } /* For aggregate initialization */

{ initializer-list , }{ initializer-list , }

initializer-listinitializer-list:
initializerinitializer

initializer-list , initializerinitializer-list , initializer

initializer-list 是用逗号分隔的初始值设定项的列表。The initializer-list is a list of initializers separated by commas. 列表中的每个初始值设定项是常量表达式或初始值设定项列表。Each initializer in the list is either a constant expression or an initializer list. 因此,可以嵌入初始值设定项列表。Therefore, initializer lists can be nested. 此形式对于初始化聚合类型的聚合成员很有用,如本节中的示例所示。This form is useful for initializing aggregate members of an aggregate type, as shown in the examples in this section. 但是,如果自动标识符的初始值设定项是一个表达式,则它无需是常量表达式;它只需要针对标识符的适当类型的赋值。However, if the initializer for an automatic identifier is a single expression, it need not be a constant expression; it merely needs to have appropriate type for assignment to the identifier.

对于每个初始值设定项列表,常量表达式的值将按顺序赋给聚合变量的相应成员。For each initializer list, the values of the constant expressions are assigned, in order, to the corresponding members of the aggregate variable.

如果 initializer-list 具有的值少于聚合类型,则聚合类型的其余成员或元素将初始化为 0。If initializer-list has fewer values than an aggregate type, the remaining members or elements of the aggregate type are initialized to 0. 未显式初始化的自动标识符的初始值是不确定的。The initial value of an automatic identifier not explicitly initialized is undefined. 如果 initializer-list 具有的值多于聚合类型,则会导致错误。If initializer-list has more values than an aggregate type, an error results. 这些规则适用于每个嵌入的初始值设定项列表以及整个聚合。These rules apply to each embedded initializer list, as well as to the aggregate as a whole.

结构的初始值设定项要么是同一类型的表达式,要么是其成员包含在大括号 ({ }) 中的初始值设定项的列表。A structure's initializer is either an expression of the same type, or a list of initializers for its members enclosed in curly braces ({ }). 未命名的位域成员是未初始化的。Unnamed bit-field members are not initialized.

在初始化联合时,initializer-list 必须是单个常量表达式。When a union is initialized, initializer-list must be a single constant expression. 常量表达式的值将赋给联合的第一个成员。The value of the constant expression is assigned to the first member of the union.

如果数组的大小未知,则初始值设定项的数目将确定数组的大小,并且其类型将变为已完成。If an array has unknown size, the number of initializers determines the size of the array, and its type becomes complete. 无法在 C 中指定初始值设定项的重复,也无法在数组中间初始化元素而不提供前面的所有值。There is no way to specify repetition of an initializer in C, or to initialize an element in the middle of an array without providing all preceding values as well. 如果您的程序中需要此操作,请使用汇编语言编写该例程。If you need this operation in your program, write the routine in assembly language.

请注意,初始值设定项的数目可以设置数组的大小:Note that the number of initializers can set the size of the array:

int x[ ] = { 0, 1, 2 }  

但是,如果您指定大小并提供错误的初始值设定项数目,则编译器将生成错误。If you specify the size and give the wrong number of initializers, however, the compiler generates an error.

Microsoft 专用Microsoft Specific

数组的最大大小由 size_t 定义。The maximum size for an array is defined by size_t. 头文件 STDDEF.H 中定义的 size_t 是一个 unsigned int,其范围从 0x00000000 到 0x7CFFFFFF。Defined in the header file STDDEF.H, size_t is an unsigned int with the range 0x00000000 to 0x7CFFFFFF.

结束 Microsoft 专用END Microsoft Specific

示例Examples

此示例演示数组的初始值设定项。This example shows initializers for an array.

int P[4][3] =   
{  
    { 1, 1, 1 },  
    { 2, 2, 2 },  
    { 3, 3, 3,},  
    { 4, 4, 4,},  
};  

此语句将 P 声明为一个四列三行的数组,并将其第一行的元素初始化为 1,将其第二行的元素初始化为 2,将其第三行的元素初始化为 3,将其第四行的元素初始化为 4。This statement declares P as a four-by-three array and initializes the elements of its first row to 1, the elements of its second row to 2, and so on through the fourth row. 请注意,第三行和第四行的初始值设定项列表在最后一个常量表达式后包含逗号。Note that the initializer list for the third and fourth rows contains commas after the last constant expression. 最后一个初始值设定项列表 ({4, 4, 4,},) 的后面也跟有一个逗号。The last initializer list ({4, 4, 4,},) is also followed by a comma. 这些额外的逗号是允许的,但不是必需的;只需要将常量表达式彼此分隔开的逗号以及将初始值设定项列表彼此分隔开的逗号。These extra commas are permitted but are not required; only commas that separate constant expressions from one another, and those that separate one initializer list from another, are required.

如果聚合成员没有嵌入的初始值设定项列表,则只会按顺序将值赋给子聚合的每个成员。If an aggregate member has no embedded initializer list, values are simply assigned, in order, to each member of the subaggregate. 因此,前面的示例中的初始化与以下项是等效的:Therefore, the initialization in the previous example is equivalent to the following:

int P[4][3] =   
{  
   1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4  
};  

大括号还可以显示在列表中的各个初始值设定项的两边,并有助于阐明上面的示例。Braces can also appear around individual initializers in the list and would help to clarify the example above.

在初始化聚合变量时,您必须谨慎正确地使用大括号和初始值设定项列表。When you initialize an aggregate variable, you must be careful to use braces and initializer lists properly. 下面的示例更详细地阐释了编译器的大括号的说明:The following example illustrates the compiler's interpretation of braces in more detail:

typedef struct   
{  
    int n1, n2, n3;  
} triplet;  

triplet nlist[2][3] =   
{  
    { {  1, 2, 3 }, {  4, 5, 6 }, {  7, 8, 9 } },  /* Row 1 */  
    { { 10,11,12 }, { 13,14,15 }, { 16,17,18 } }   /* Row 2 */  
};  

在此示例中,nlist 声明为结构的 2x3 数组,每个结构具有三个成员。In this example, nlist is declared as a 2-by-3 array of structures, each structure having three members. 初始化的第 1 行将值赋给 nlist 的第一行,如下所示:Row 1 of the initialization assigns values to the first row of nlist, as follows:

  1. 第 1 行上的第一个左大括号告知编译器 nlist 的第一个聚合成员(即 nlist[0])的初始化已开始。The first left brace on row 1 signals the compiler that initialization of the first aggregate member of nlist (that is, nlist[0]) is beginning.

  2. 第二个左大括号指示 nlist[0] 的第一个聚合成员(即 nlist[0][0] 处的结构)的初始化已开始。The second left brace indicates that initialization of the first aggregate member of nlist[0] (that is, the structure at nlist[0][0]) is beginning.

  3. 第一个右大括号结束 nlist[0][0] 结构的初始化;下一个左大括号开始 nlist[0][1] 的初始化。The first right brace ends initialization of the structure nlist[0][0]; the next left brace starts initialization of nlist[0][1].

  4. 此过程将继续,直到右大括号结束 nlist[0] 的初始化的行的末尾。The process continues until the end of the line, where the closing right brace ends initialization of nlist[0].

    第 2 行采用类似的方法将值赋给 nlist 的第二行。Row 2 assigns values to the second row of nlist in a similar way. 请注意,包含第 1 行和第 2 行上的初始值设定项的大括号的外部集是必需的。Note that the outer sets of braces enclosing the initializers on rows 1 and 2 are required. 忽略外部大括号的下列构造将会导致错误:The following construction, which omits the outer braces, would cause an error:

triplet nlist[2][3] =  /* THIS CAUSES AN ERROR */  
{  
     {  1, 2, 3 },{  4, 5, 6 },{  7, 8, 9 },   /* Line 1 */  
     { 10,11,12 },{ 13,14,15 },{ 16,17,18 }    /* Line 2 */  
};  

在此构造中,第 1 行上的第一个左大括号开始 nlist[0](它是三个结构的数组)的初始化。In this construction, the first left brace on line 1 starts the initialization of nlist[0], which is an array of three structures. 值 1、2 和 3 将赋给第一个结构的三个成员。The values 1, 2, and 3 are assigned to the three members of the first structure. 当遇到下一个右大括号(值 3 的后面)时,nlist[0] 的初始化已完成,并且三个结构数组中的其余两个结构将自动初始化为 0。When the next right brace is encountered (after the value 3), initialization of nlist[0] is complete, and the two remaining structures in the three-structure array are automatically initialized to 0. 同样,{ 4,5,6 } 会初始化 nlist 的第二行中的第一个结构。Similarly, { 4,5,6 } initializes the first structure in the second row of nlist. nlist[1] 的其余两个结构将设置为 0。The remaining two structures of nlist[1] are set to 0. 当编译器遇到下一个初始值设定项列表 ({ 7,8,9 }) 时,它会尝试初始化 nlist[2]When the compiler encounters the next initializer list ( { 7,8,9 } ), it tries to initialize nlist[2]. 由于 nlist 只具有两个行,因此该尝试会导致错误。Since nlist has only two rows, this attempt causes an error.

在下一个示例中,int 的三个 x 成员分别初始化为 1、2 和 3。In this next example, the three int members of x are initialized to 1, 2, and 3, respectively.

struct list   
{  
    int i, j, k;  
    float m[2][3];  
} x = {  
        1,  
        2,  
        3,  
       {4.0, 4.0, 4.0}  
      };  

在上面的 list 结构中,m 的第一行中的三个元素将初始化为 4.0;m 的剩余行的元素将初始化为 0.0(默认值)。In the list structure above, the three elements in the first row of m are initialized to 4.0; the elements of the remaining row of m are initialized to 0.0 by default.

union  
{  
    char x[2][3];  
    int i, j, k;  
} y = { {  
            {'1'},  
            {'4'}   
        }  
      };  

在此示例中,将初始化联合变量 yThe union variable y, in this example, is initialized. 该联合的第一个元素是数组,因此该初始值设定项是聚合初始值设定项。The first element of the union is an array, so the initializer is an aggregate initializer. 初始值设定项列表 {'1'} 将值赋给数组的第一行。The initializer list {'1'} assigns values to the first row of the array. 由于列表中仅显示一个值,因此,第一列中的元素将初始化为字符 1,而该行中的其余两个元素将初始化为值 0(默认值)。Since only one value appears in the list, the element in the first column is initialized to the character 1, and the remaining two elements in the row are initialized to the value 0 by default. 同样,x 的第二行的第一个元素将初始化为字符 4,而该行中的其余两个元素将初始化为值 0。Similarly, the first element of the second row of x is initialized to the character 4, and the remaining two elements in the row are initialized to the value 0.

另请参阅See Also

初始化Initialization