C 指定初始化器
指定初始化器(designated initialize)是C99的新特性,该特性可以执行初始化数组的元素或结构的属性。
1.数组
例如只想初始化数组的最后一个元素,传统的C语法是这样的
int arr[6] = {0, 0, 0, 0, 0, 212}; // 传统C语法
而C99规定,可以在初始化列表中使用带方括号的下标指明带初始化的元素
int arr[6] = {[5] = 212}; // C99 指定初始化器
对于一般的初始化,在初始化一个元素后,未初始化的元素都会被设置为0。下面程序中的初始化比较复杂
// designate.c -- 使用指定初始化容器
#include <stdio.h>
#define MONTHS 12
int main(void)
{
int days[MONTHS] = {31, 28, [4] = 31, 30, 31, [1] = 29};
int i;
for (i = 0; i < MONTHS; i++)
printf("%2d %d\n", i + 1, days[i]);
return 0;
}
该程序在支持C99的编译器中输出如下:
1 31
2 29
3 0
4 0
5 31
6 30
7 31
8 0
9 0
10 0
11 0
12 0
以上的输出揭示了初始化器的两个重要特性
- 如果指定初始化器后面有更多的值,如该例中的初始化列表中的片段:[4] = 31,30,31,那么
后面这些值将被用于初始化指定元素后面的元素
。也就是说,在days[4]被初始化为31后,days[5]和days[6]将分别被初始化为30和31。 - 如果再次初始化指定的元素,那么
最后的初始化将会取代之前的初始化
。例如,上述程序中,初始化列表开始时把days[1]初始化为28,但是days[1]又被后面的指定初始化[1] = 29初始化为29。
如果未指定元素大小会怎样?
int stuff[] = {1, [6] = 23}; // 会发生什么?
int staff[] = {1, [6] = 4, 9, 10}; // 会发生什么?
编译器会把数组的大小设置为足够装得下初始化的值
。所以,stuff数组有7个元素,编号为0~6;而staff数组的元素比stuff数组多两个(即有9个元素)。
2. 结构
#define MAXTITL 40
#define MAXAUTL 40
struct book
{
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
初始化结构的传统语法
struct book library = {
"The Pious Pirate and the Devious Damsel",
"Renee Vivotte",
1.95
}
C99和C11为结构提供了指定初始化器(designated initializer),其语法与数组的指定初始化器类似。但是,结构的指定初始化器使用点运算符和成员名
(而不是方括号和下标)标识特定的元素。例如,只初始化book结构的value成员,可以这样做:
struct book surprise = {.value = 10.99};
可以按照任意顺序使用指定初始化器
struct book gift = {.value = 25.99,
.author = "James Broadfool",
.title = "Rue for the Toad"};
与数组类似,在指定初始化器后面的普通初始化器,为指定成员后面的成员提供初始值。另外,对特定成员的最后一次赋值才是它实际获得的值。例如,考虑下面的代码:
struct book gift = {.value = 18.90,
.author = "Philionna Pestle",
0.25}
赋给value的值是0.25,因为它在结构声明中紧跟在author成员之后。新值0.25取代了之前的18.9。
另外,初始化一个属性后,其他属性都被设置为0