Инициализация массива структур

Здесь инициализация я только что нашел в другом вопросе.

my_data data[]={
    { .name = "Peter" },
    { .name = "James" },
    { .name = "John" },
    { .name = "Mike" }
};

Я никогда раньше не видел чего-то подобного, и не могу найти объяснения, как можно правильно назвать имя. Что я ищу, так это шаг за шагом этот процесс.

Похоже, он получает:

1) data;
2) *data;
3) (*data).name;
4) (*data).name="Peter";

Или я совершенно неправ?

Ответ 1

Здесь есть только два синтаксиса.

Ответ 2

my_data - это структура с name как поле, а data[] - это структуры, вы инициализируете каждый индекс. читайте следующее:

5.20 Назначенные инициализаторы:

В инициализаторе структуры укажите имя поля для инициализации с помощью .fieldname =' до значения элемента. Например, учитывая следующую структуру,

 struct point { int x, y; };

следующая инициализация

 struct point p = { .y = yvalue, .x = xvalue };

эквивалентно

 struct point p = { xvalue, yvalue };

Другой синтаксис, имеющий то же значение, устаревший после GCC 2.5, fieldname:', как показано ниже:

 struct point p = { y: yvalue, x: xvalue };

Вы также можете написать:

my_data data[]={
    { .name = "Peter" },
    { .name = "James" },
    { .name = "John" },
    { .name = "Mike" }
};

as:

my_data data[]={
    { [0].name = "Peter" },
    { [1].name = "James" },
    { [2].name = "John" },
    { [3].name = "Mike" }
}; 

Вторая форма может быть удобной, так как вам не нужно писать, чтобы, например, выше, эквивалентно:

my_data data[]={
    { [3].name = "Mike" },
    { [1].name = "James" },
    { [0].name = "Peter" },
    { [2].name = "John" }
}; 

Чтобы понять инициализацию массива, прочитайте странное выражение инициализатора?
Кроме того, вы также можете прочитать ответ @Shafik Yaghmour для случая коммутатора: Что такое "..." в коммутаторе в C код

Ответ 3

Здесь нет "пошагового". Когда инициализация выполняется с постоянными выражениями, процесс, по существу, выполняется во время компиляции. Конечно, если массив объявлен как локальный объект, он распределяется локально и инициализируется во время выполнения, но это все еще можно рассматривать как одноэтапный процесс, который нельзя осмысленно разделить.

Назначенные инициализаторы позволяют вам снабжать инициализатор для определенного члена структурного объекта (или определенного элемента массива). Все остальные члены получают нуль-инициализацию. Итак, если my_data объявлен как

typedef struct my_data {
  int a;
  const char *name;
  double x;
} my_data;

тогда ваш

my_data data[]={
    { .name = "Peter" },
    { .name = "James" },
    { .name = "John" },
    { .name = "Mike" }
};

является просто более компактной формой

my_data data[4]={
    { 0, "Peter", 0 },
    { 0, "James", 0 },
    { 0, "John", 0 },
    { 0, "Mike", 0 }
};

Надеюсь, вы знаете, что делает последнее.

Ответ 4

Это довольно просто: my_data - это определенный тип структуры. Таким образом, вы хотите объявить my_data -array некоторых элементов, как это было бы с

char a[] = { 'a', 'b', 'c', 'd' };

Таким образом, массив будет иметь 4 элемента, и вы инициализируете их как

a[0] = 'a', a[1] = 'b', a[1] = 'c', a[1] ='d';

Это называется назначенным инициализатором (поскольку я помню правильно).

и это просто указывает, что данные должны иметь тип my_dat и должны быть массивом, который должен хранить столько структур my_data, что есть структура с именами каждого типа Peter, James, John и Mike.

Ответ 5

Он назвал назначенный инициализатор, который введен в C99. Он использовал для инициализации struct или массивов в этом примере struct.

Учитывая

struct point { 
    int x, y;
};

следующая инициализация

struct point p = { .y = 2, .x = 1 };

эквивалентен C89-стиле

struct point p = { 1, 2 };

Ответ 6

Это назначенный инициализатор, введенный со стандартом C99; он позволяет вам инициализировать определенные элементы объекта struct или union по имени. my_data, очевидно, является typedef для типа struct, который имеет член name типа char * или char [N].