Когда вы используете агрегатные инициализаторы (инициализаторы в {}
) на «традиционном» языке ANSI C (C89 / 90), вы должны предоставить отдельный инициализатор для каждого элемента структуры по порядку, начиная с первого. Например
struct S { int a, b, c, d; };
struct S s = { 1, 2, 3, 4 };
/* 1 for `s.a`, 2 for `s.b` and so on... */
От вас не требуется указывать инициализаторы для всех участников, т. Е. Вы можете остановиться в любое время (остальные участники будут инициализироваться нулем).
Если по какой-то причине вы только хотели явно инициализировать третий элемент структуры, вам пришлось предоставить «фиктивные» явные инициализаторы для первого и второго членов (просто чтобы добраться до нужного третьего)
/* We only care to explicitly initialize `s.c` */
struct S s = { 0, 0, 3 };
/* but we have to explicitly initialize `s.a` and `s.b` as well */
или полностью отказаться от конкретной инициализации (вероятно, заменив ее на общую = { 0 }
) и использовать последующее присвоение конкретным элементам
struct S s = { 0 };
s.c = 3;
Одним заметным преимуществом этого подхода на основе присвоения является то, что он не зависит от позиции члена c
в объявлении struct S
.
Новая спецификация языка C (C99) позволяет вам использовать «тегированные» инициализаторы, предоставляя желаемое имя члена в {}
struct S s = { .c = 3 };
Таким образом, вы только явно инициализируете желаемый элемент (ы) (и имеете компилятор для инициализации нуля остальных). Это не только экономит время при наборе, но и делает агрегатные инициализаторы независимыми от порядка, в котором члены указаны в объявлении типа структуры.
Агрегатные инициализаторы, как вы, наверное, знаете, могут использоваться и с массивами. И C99 также поддерживает «теговую» инициализацию с массивами. Как выглядят «теги» в случае массива, иллюстрируется следующим примером
int a[10] = { [5] = 3 };
/* `a[5]` is initialized with 3, the rest of `a` is zero-initialized */
Стоит еще раз отметить, что язык C продолжает придерживаться подхода «все или ничего» для агрегированной инициализации: если вы укажете явный инициализатор только для одного (или нескольких) членов структуры или массива, вся совокупность инициализируется, а члены без явных инициализаторов инициализируются нулями.