Scalar initialization
标量(包括布尔类型和枚举类型的整型对象、包含复数和虚数的浮点类型、以及包含函数指针的指针类型)的初始化器必须是单个表达式,可选择性地用花括号括起 ,或使用空初始化器 (C23起) :
=
表达式
|
(1) | ||||||||
=
{
表达式
}
|
(2) | ||||||||
=
{
}
|
(3) | (C23起) | |||||||
注释
由于按赋值转换规则所适用的准则,在确定要将
表达式
转换为何种类型时,声明类型上的
const
和
volatile
限定符将被忽略。
参见 初始化 了解未使用初始化式时的适用规则。
与所有其他初始化一样,当初始化具有静态或线程局部 存储期 的对象时, 表达式 必须是 常量表达式 。
该 表达式 不能是 逗号运算符 (除非使用括号括起),因为顶层的逗号会被解释为下一个声明符的开始。
当初始化浮点类型对象时,对于具有自动 存储期 的对象,所有计算都如同在运行时执行,并受 当前舍入模式 影响;浮点错误将按照 math_errhandling 的规定进行报告。对于具有静态和线程局部存储期的对象,计算如同在编译时执行,且不会引发异常:
void f(void) { #pragma STDC FENV_ACCESS ON static float v = 1.1e75; // 不会引发异常:静态初始化 float u[] = { 1.1e75 }; // 引发 FE_INEXACT float w = 1.1e75; // 引发 FE_INEXACT double x = 1.1e75; // 可能引发 FE_INEXACT(取决于 FLT_EVAL_METHOD) float y = 1.1e75f; // 可能引发 FE_INEXACT(取决于 FLT_EVAL_METHOD) long double z = 1.1e75; // 不会引发异常(转换是精确的) }
示例
#include <stdbool.h> int main(void) { bool b = true; const double d = 3.14; int k = 3.15; // 从 double 到 int 的转换 int n = {12}, // 可选花括号 *p = &n, // 对自动变量允许使用非常量表达式 (*fp)(void) = main; enum {RED, BLUE} e = RED; // 枚举类型同样属于标量类型 }
参考文献
- C17 标准 (ISO/IEC 9899:2018):
-
- 6.7.9/11 初始化 (p: 101)
- C11 标准 (ISO/IEC 9899:2011):
-
- 6.7.9/11 初始化 (p: 140)
- C99标准(ISO/IEC 9899:1999):
-
- 6.7.8/11 初始化(页:126)
- C89/C90 标准 (ISO/IEC 9899:1990):
-
- 6.5.7 初始化