初始化标量类型

初始化标量类型时,assignment-expression 的值被赋给变量。 赋值的转换规则适用。 (有关转换规则的信息,请参阅类型转换。)

语法

declaration:
declaration-specifiersinit-declarator-listopt;

declaration-specifiers:
storage-class-specifierdeclaration-specifiersopt
type-specifierdeclaration-specifiersopt
type-qualifierdeclaration-specifiersopt

init-declarator-list:
init-declarator
init-declarator-list , init-declarator

init-declarator:
declarator
declarator=initializer /* 用于标量初始化 */

initializer:
assignment-expression

可以初始化任何类型的变量,前提是遵循下列规则:

  • 在文件范围级别声明的变量可初始化。 如果未显式初始化外部级别的变量,则默认情况下它将初始化为 0。

  • 常数表达式可用于初始化使用 staticstorage-class-specifier 声明的任何全局变量。 声明为 static 的变量在程序开始执行时初始化。 如果没有显式初始化全局 static 变量,则默认情况下它初始化为 0,并且为每个具有指针类型的成员分配 null 指针。

  • 使用 autoregister 存储类说明符声明的变量在每次执行控制权传递给声明它们的块时初始化。 如果在 autoregister 变量的声明中省略初始值设定项,则变量的初始值是未定义的。 对于自动值和寄存器值,初始值设定项未限制为常量;它可以是包含之前定义的值的任何表达式,甚至是函数调用。

  • 外部变量声明和所有 static 变量(无论是外部还是内部变量)的初始值必须是常数表达式。 (有关详细信息,请参阅常量表达式。)由于任何外部声明的变量或静态变量的地址为常数,因此可以使用它初始化内部声明的 static 指针变量。 不过,auto 变量的地址不能用作静态初始值设定项,因为它可能在每次执行块时都不同。 可使用常数或变量值来初始化 autoregister 变量。

  • 如果标识符的声明具有块范围,并且标识符具有外部链接,则该声明不能具有初始化。

示例

下列示例阐释了初始化:

int x = 10;

整数变量 x 将初始化为常量表达式 10

register int *px = 0;

指针 px 将初始化为 0,从而生成“null”指针。

const int c = (3 * 1024);

此示例使用常数表达式 (3 * 1024)c 初始化为由于 const 关键字而无法修改的常数值。

int *b = &x;

此语句使用另一变量 b 的地址初始化指针 x

int *const a = &z;

指针 a 是使用名为 z 的变量的地址初始化的。 不过,由于它被指定为 const,因此变量 a 只能被初始化,决不能被修改。 该指针始终指向同一位置。

int GLOBAL ;

int function( void )
{
    int LOCAL ;
    static int *lp = &LOCAL;   /* Illegal initialization */
    static int *gp = &GLOBAL;  /* Legal initialization   */
    register int *rp = &LOCAL; /* Legal initialization   */
}

全局变量 GLOBAL 是在外部级别声明的,因此它具有全局生存期。 局部变量 LOCALauto 存储类,并且在执行声明它的函数期间只有一个地址。 因此,不允许尝试使用 LOCAL 的地址来初始化 static 指针变量 lpstatic 指针变量 gp 可初始化为 GLOBAL 的地址,因为此地址始终都是相同的。 同样,*rp 可以被初始化,因为 rp 是局部变量,并且可以有非常数初始值设定项。 每次输入块时,LOCAL 都具有新地址,该地址之后将赋给 rp

请参阅

初始化