目录搜索
文字
分享

对象的声明可以通过称为初始化的过程提供其初始值。

对于每个声明符,如果不省略,初始化符可能是以下之一:

= expression

(1)


= {  initializer-list }

(2)


其中 initializer-list 是一个非空的以逗号分隔的初始化器列表(带有可选的尾随逗号),其中每个初始化器都有三种可能的形式之一:

expression

(1)


{  initializer-list }

(2)


designator-list = initializer

(3)


其中,指定者列表是表单标识符的[常量表达式]或结构/联合成员指示符形式的数组指示符的列表.; 请参阅数组初始化和结构初始化

说明

初始化程序指定存储在对象中的初始值。

显式初始化

如果提供了初始化程序,请参阅。

  • 标量类型初始化的标量初始化

  • 数组初始化用于数组类型的初始化

  • 结构初始化用于结构和联合类型的初始化。

隐式初始化

如果未提供初始化程序:

  • 具有自动存储持续时间的对象被初始化为不确定的值(可能是陷阱表示)

  • 具有静态和线程局部存储持续时间的对象按如下进行初始化

  • 指针被初始化为它们类型的空指针值

  • 整型的对象被初始化为无符号零

  • 浮动类型的对象被初始化为正零

  • 数组成员,结构体和联合体如上所述进行初始化,递归地加上所有填充位被初始化为零

(在空指针和浮点零都具有全零位表示的平台上,静态初始化的这种形式通常通过在程序映像的.bss节中分配来实现)

笔记

初始化静态或线程局部存储持续时间的对象时,初始化程序中的每个表达式都必须是常量表达式或字符串常量。

初始化器不能用于不完整类型的对象,VLA 和具有链接的块范围对象的声明。

函数参数的初始值是通过从函数调用的参数中分配而不是通过初始化(直到C11之后的缺陷报告 DR 427,其改变了使用初始化的措辞)而建立的。

如果将不确定值用作任何标准库调用的参数,则行为是未定义的。否则,任何涉及不确定值的表达式的结果都是不确定的值(例如,int n;可能不会与自身等同,并且可能会在后续读取中更改它的值)。

#include <stdlib.h>int a[2]; // initializes a to {0, 0}int main(void){
    int i;          // initializes i to an indeterminate value    static int j;   // initializes j to 0
    int k = 1;      // initializes k to 1 
    // initializes int x[3] to 1,3,5    // initializes int* p to &x[0]
    int x[] = { 1, 3, 5 }, *p = x; 
    // initializes w (an array of two structs) to    // { { {1,0,0}, 0}, { {2,0,0}, 0} }
    struct {int a[3], b;} w[] = {[0].a = {1}, [1].a[0] = 2}; 
    // function call expression can be used for a local variable
    char* ptr = malloc(10);    free(ptr); //  Error: objects with static storage duration require constant initializers//  static char* ptr = malloc(10); //  Error: VLA cannot be initialized//  int vla[n] = {0};}

参考

  • C11 standard (ISO/IEC 9899:2011):

    • 6.7.9 Initialization (p: 139-144)

  • C99 standard (ISO/IEC 9899:1999):

    • 6.7.8 Initialization (p: 125-130)

  • C89/C90 standard (ISO/IEC 9899:1990):

    • 3.5.7 Initialization