#include <stdio.h>
typedef struct { int k; int l; int a[2]; } T;
typedef struct { int i; T t; } S;
T x = {.l = 43, .k = 42, .a[1] = 19, .a[0] = 18 };
// 初始化 x 为 {42, 43, {18, 19} }
int main(void)
S l = { 1, // 初始化 l.i 为 1
.t = x, // 初始化 l.t 为 {42, 43, {18, 19} }
.t.l = 41, // 更改 l.t 为 {42, 41, {18, 19} }
.t.a[1] = 17 // 更改 l.t 为 {42, 41, {18, 17} }
printf("l.t.k is %d\n", l.t.k); // .t = x 显式设置 l.t.k 为 42
// .t.l = 42 会隐式清零 l.t.k
然而,当初始化器以左开花括号开始时,会完全重初始化其当前对象,并忽略其任何子对象的先前的显式初始化器:
struct fred { char s[4]; int n; };
struct fred x[ ] = { { { "abc" }, 1 }, // 初始化 x[0] 为 { {'a','b','c','\0'}, 1 }
[0].s[0] = 'q' // 更改 x[0] 为 { {'q','b','c','\0'}, 1 }
struct fred y[ ] = { { { "abc" }, 1 }, // 初始化 y[0] 为 { {'a','b','c','\0'}, 1 }
[0] = { // 当前对象现在是整个 y[0] 对象
.s[0] = 'q'
} // 以 { {'q','\0','\0','\0'}, 0 } 替换 y[0]
(C99 起)
初始化器列表可拥有尾随的逗号,它被忽略。
struct {double x,y;} p = {1.0,
2.0, // 尾随逗号 OK
C 中,初始化器的花括号列表不能为空(注意 C++ 允许空列表,并且注意 C 中结构体不能为空):
struct {int n;} s = {0}; // OK
struct {int n;} s = {}; // 错误:初始化器列表不能为空
struct {} s = {}; // 错误:结构体不能为空,初始化器列表不能为空
在初始化任何存储期的聚合体时,初始化器列表中的每个表达式必须都是常量表达式。
(C99 前)
同所有其他初始化,在初始化静态或线程局域 (C11 起)存储期的聚合体时,初始化器列表中的每个表达式必须为常量表达式:
static struct {char* p} s = {malloc(1)}; // 错误
任何初始化器中的子表达式求值顺序为非确定顺序:
int n = 1;
struct {int x,y;} p = {n++, n++}; // 未指定,但是良定义的行为:
// n 以任意顺序自增二次
// p 等于 {1,2} 和 {2,1} 都是合法的
(C99 起)
| 本节未完成 原因:更多实用的示例,最好初始化某些接头结构体 |
#include <stdio.h>
#include <time.h>
int main(void)
char buff[70];
// 指代初始化器简化成员顺序未指定的结构体的使用
struct tm my_time = { .tm_year=112, .tm_mon=9, .tm_mday=9,
.tm_hour=8, .tm_min=10, .tm_sec=20 };
strftime(buff, sizeof buff, "%A %c", &my_time);
puts(buff);
可能的输出:
Sunday Sun Oct 9 08:10:20 2012
- C11 standard (ISO/IEC 9899:2011):
- 6.7.9/12-38 Initialization (p: 140-144)
- C99 standard (ISO/IEC 9899:1999):
- 6.7.8/12-38 Initialization (p: 126-130)
- C89/C90 standard (ISO/IEC 9899:1990):