Что такое назначенный инициализатор в C?

Я знаю, что это может быть основной вопрос.

У меня есть задание, которое требует от меня понимания того, что такое назначенные инициализаторы в C и что означает инициализация переменной одним из них.

Я не знаком с этим термином и не смог найти никаких убедительных определений.

Что такое назначенный инициализатор в C?


person user7349461    schedule 09.11.2017    source источник
comment
посмотрите здесь gcc.gnu.org/onlinedocs/gcc- 4.9.2/gcc/Designated-Inits.html   -  person CIsForCookies    schedule 09.11.2017
comment
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что серьезных исследований не проводилось.   -  person chux - Reinstate Monica    schedule 09.11.2017
comment
@chux отрицательный, хотя я искал для этого дубликат, но не смог его найти, только те, которые показывают, как инициализировать либо массив, или структуру, но не даже оба.   -  person Antti Haapala    schedule 09.11.2017
comment
@chux SO должен быть хранилищем качественных ответов на актуальные вопросы, верно? Так случилось, что у меня был этот вопрос сегодня, и я был счастлив найти краткий ответ Вирсавии в месте, которому я могу доверять. (Да, у меня должен быть собственный экземпляр стандарта C11, но, увы, у меня его нет. И вообще, Стандарты не всегда лучшее место, где простые смертные могут найти ответы, так что вопрос и ответ здесь кажутся идеальными. подходящее.)   -  person Steve Summit    schedule 03.07.2018
comment
Только что посмотрел, как Джейсон объясняет это здесь, на канале C++ Weekly youtube.com/watch?v=44rs_hX1dxE   -  person Tien Do    schedule 19.12.2018


Ответы (2)


Назначенные инициализаторы бывают двух видов:

1) Он обеспечивает быстрый способ инициализации определенных элементов в массиве:

int foo[10] = { [3] = 1, [5] = 2 };

установит для всех элементов foo значение 0, кроме индекса 3, для которого будет установлено значение 1, и индекса 5, для которого будет установлено значение 2.

2) Он предоставляет способ явной инициализации struct членов. Например, для

struct Foo { int a, b; };

ты можешь написать

struct Foo foo { .a = 1, .b = 2 };

Обратите внимание, что в этом случае элементы, которые не инициализированы явно, инициализируются так, как если бы экземпляр имел длительность static.


Оба являются стандартными C, но обратите внимание, что C++ не поддерживает ни один из них (поскольку конструкторы могут выполнять работу на этом языке).

person Bathsheba    schedule 09.11.2017
comment
Взгляните на это для дальнейшее чтение о C++. Я считаю, что это хорошо для следующего стандарта. - person DeiDei; 09.11.2017
comment
@AnttiHaapala: нужно откопать мой стандарт для моего последнего комментария перед разлинованной строкой. (Увы, я на чу-чу). Я думаю, что это правильно. - person Bathsheba; 09.11.2017
comment
port70.net/~nsz/c/c11/n1570.html# 6.7.9p9 по крайней мере неименованные элементы структуры не инициализированы. - person Antti Haapala; 09.11.2017
comment
Члены (переменной), которые явно не инициализированы в коде, будут автоматически инициализированы компилятором до 0. Подобно всем статическим и глобальным переменным, они всегда автоматически инициализируются до 0, если это не сделано явно в коде. - person abetancort; 26.06.2020

Разработанный инициализатор появился со времен ISO C99 и представляет собой другой и более динамичный способ инициализации в C при инициализации struct, union или array.

Самое большое отличие от стандартной инициализации заключается в том, что вам не нужно объявлять элементы в фиксированном порядке, и вы также можете опустить элемент.

Из Руководства GNU:

Стандарт C90 требует, чтобы элементы инициализатора отображались в фиксированном порядке, таком же, как порядок элементов в инициализируемом массиве или структуре.

В ISO C99 вы можете задавать элементы в случайном порядке, указывая индексы массива или имена полей структуры, к которым они применяются, и GNU C также позволяет это как расширение в режиме C90.


Примеры

1. Индекс массива

Стандартная инициализация

  int a[6] = { 0, 0, 15, 0, 29, 0 };

Разработанная инициализация

  int a[6] = {[4] = 29, [2] = 15 }; // or
  int a[6] = {[4]29 , [2]15 }; // or
  int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

2. Структура или объединение:

Стандартная инициализация

struct point { int x, y; };

Разработанная инициализация

 struct point p = { .y = 2, .x = 3 }; or
 struct point p = { y: 2, x: 3 };

3. Комбинируйте элементы именования с обычной C-инициализацией последовательных элементов:

Стандартная инициализация

int a[6] = { 0, v1, v2, 0, v4, 0 };

Разработанная инициализация

int a[6] = { [1] = v1, v2, [4] = v4 };

4. Другие:

Пометка элементов инициализатора массива

int whitespace[256] = { [' '] = 1, ['\t'] = 1, ['\h'] = 1,
                        ['\f'] = 1, ['\n'] = 1, ['\r'] = 1 };

напишите серию указателей ‘.fieldname’ и ‘[index]’ перед ‘=’, чтобы указать вложенный подобъект для инициализации

struct point ptarray[10] = { [2].y = yv2, [2].x = xv2, [0].x = xv0 };

Гиды

person Federico Baù    schedule 03.01.2021