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

posted @ 2021-06-22 10:29  王舰  阅读(265)  评论(0编辑  收藏  举报