Ответ 1
Когда вы используете агрегатные инициализаторы (инициализаторы в {}
) на "традиционном" языке 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... */
Вам не обязательно указывать инициализаторы для всех членов, т.е. вы можете остановиться в любое время (остальные члены будут инициализированы нулями).
Если по какой-то причине вам просто нужно было явно инициализировать третий элемент структуры, вам нужно было снабдить явные инициализаторы "dummy" для первого и второго членов (просто чтобы получить нужную третью)
/* 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 продолжает придерживаться подхода "все или ничего" для агрегационной инициализации: если вы укажете явный инициализатор только для одного (или некоторых) элементов структуры или массива, целая совокупность инициализируется, а члены без явных инициализаторов получают нуль-инициализацию.