C: Как работают вложенные фигурные скобки для массива инициализации структуры? - PullRequest
12 голосов
/ 07 октября 2010
struct mystruct s[10] = {{0}};

Это похоже на инициализацию массива структур до 0. Как работает синтаксис вложенных фигурных скобок?

Ответы [ 4 ]

10 голосов
/ 07 октября 2010

Любые поля, не указанные, обнуляются.Так что здесь у вас есть множество структур.Вы инициализируете первый элемент массива инициализатором структуры, который инициализирует первый элемент структуры в ноль.Остальная часть первой структуры и остальные элементы массива тоже будут равны нулю.Это хорошая идиома.

5 голосов
/ 07 октября 2010

Как показано?

По сути, вы должны заключать каждый составной тип - массив, структуру и т. Д. - в собственный уровень скобок.

Рассмотрим:

struct mystruct
{
    int i;
    double d;
    char   s[10];
    int    a[5];
} s[10] =
{
      { 0, 0.0, "abc", { 1, 2, 3, 4, 5 } },
      { 1, 1.0, "def", { 2, 3          } }, // Partially initialized array
      { 2, 2.0, { 'x', 'y', 'z' }, { 0 } }, // Strings are a shorthand
[9] = { 9, 99,  0,     { 9, 8, 7, 6, 5 } }, // C99 - initialize row 9
};

Но вы также можете опустить фигурные скобки, если настаиваете (плохая, архаичная практика):

struct mystruct t[3] =
{ // You cannot avoid using these outside braces
  0, 0.00, "abc", 1, 2, 3, 4, 5,  // Omitted braces
  1, 1.11, "bcd", 2, 3, 4, 5, 4,
  2, 2.34,                        // Omitted values
};

Любые пропущенные инициализаторы рассматриваются как нули.

4 голосов
/ 07 октября 2010

Это не вложенные фигурные скобки, которые инициализируются. Внешние скобки указывают, что массив инициализируется:

struct mystruct s[10] = {           };

Поскольку это массив структур, каждая структура может быть инициализирована с помощью следующих фигурных скобок:

struct mystruct { int x, y, z};

struct mystruct s[10] = { {0, 1, 2}, // <-- initializes s[0].x, s[0].y, s[0].z
                          {1, 2, 3}, // <-- initializes s[1].x, s[1].y, s[1].z
                          {2, 3, 4}  // <-- initializes s[2].x, s[2].y, s[2].z
};

Обратите внимание, что инициализируются только первые три элемента. Согласно стандарту C остальные 7 элементов должны быть инициализированы равными 0. Это то же самое, что и с вашим кодом. Как xscott упомянул в своем ответе, все, что пропущено в списке инициализатора, инициализируется равным 0.

0 голосов
/ 07 октября 2010

Полезно отметить, что хотя внутренние скобки являются необязательными, компилятор проверит, чтобы открывающие скобки появлялись только там, где они должны, и что ни у одного вложенного элемента не было слишком много инициализаторов. Кроме того, можно пропустить некоторые поля структуры и заставить компилятор автоматически обнулять их, даже если структура не находится в конце массива. Обратите внимание, что реализации различаются по своей эффективности обработки этого; некоторые делят запись инициализации на маленькие части, в то время как другие просто вставляют множество нулей в код. Например, если каждая структура выглядела так:

<i>typedef</i> struct {
  char name[8];
  char more_stuff[1016];
} THINGIE;
THINGIE my_array = {{"Fred"},{"George"},{"Mark"}};

некоторые компиляторы генерировали бы 3K-данные const, в то время как другие генерировали бы три относительно небольших записи 'const-init'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...