Как инициализировать структуру в соответствии со стандартами языка программирования C

Я хочу инициализировать элемент структуры, разделенный декларацией и инициализацией. Это то, что у меня есть:

typedef struct MY_TYPE { boolean flag; short int value; double stuff; } MY_TYPE; void function(void) { MY_TYPE a; ... a = { true, 15, 0.123 } } 

Это способ объявить и инициализировать локальную переменную MY_TYPE в соответствии со стандартами языка программирования C (C89, C90, C99, C11 и т. Д.)? Или есть что-то лучше или, по крайней мере, работает?

Обновление. В итоге у меня появился элемент статической инициализации, в котором я задал каждый подэлемент в соответствии с моими потребностями.

В (ANSI) C99 вы можете использовать назначенный инициализатор для инициализации структуры:

 MY_TYPE a = { .flag = true, .value = 123, .stuff = 0.456 }; 

Редактировать: другие члены инициализируются как ноль: «Элементы опущенного поля неявно инициализируются так же, как объекты, имеющие статическую продолжительность хранения». ( https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html )

Вы можете сделать это с помощью составного литерала . Согласно этой странице, он работает на C99 (который также считается ANSI C ).

 MY_TYPE a; a = (MY_TYPE) { .flag = true, .value = 123, .stuff = 0.456 }; ... a = (MY_TYPE) { .value = 234, .stuff = 1.234, .flag = false }; 

Обозначения в инициализаторах необязательны; вы также можете написать:

 a = (MY_TYPE) { true, 123, 0.456 }; ... a = (MY_TYPE) { false, 234, 1.234 }; 

Я вижу, вы уже получили ответ об ANSI C 99, поэтому я брошу кость ANSI C 89. ANSI C 89 позволяет вам инициализировать структуру следующим образом:

 typedef struct Item { int a; float b; char* name; } Item; int main(void) { Item item = { 5, 2.2, "George" }; return 0; } 

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

Если вы не инициализируете значения в своей структуре, все переменные будут содержать «значения мусора».

Удачи!

a = (MYTYPE){ true, 15, 0.123 };

отлично справится с C99

Вы почти получили это …

 MY_TYPE a = { true,15,0.123 }; 

Быстрый поиск по ‘struct initialize c’ показывает мне это

как сказал Рон Нуни:

 typedef struct Item { int a; float b; char* name; } Item; int main(void) { Item item = {5, 2.2, "George"}; return 0; } 

Важно помнить: на данный момент вы инициализируете даже один объект / переменную в структуре, все остальные переменные будут инициализированы значением по умолчанию.

Если вы не инициализируете значения в своей структуре (т. Е. Если вы просто объявите эту переменную), все variable.members будут содержать «значения мусора», только если объявление является локальным!

Если объявление является глобальным или статическим (как в этом случае), все неинициализированные variable.members будут автоматически инициализированы:

  • 0 для целых чисел и с плавающей запятой
  • '\0' для char (конечно, это то же самое, что и 0 , а char – целочисленный тип)
  • NULL для указателей.

C стандарт языка программирования ISO / IEC 9899: 1999 (обычно известный как C99) позволяет использовать назначенный инициализатор для инициализации членов структуры или объединения следующим образом:

 MY_TYPE a = { .stuff = 0.456, .flag = true, .value = 123 }; 

Он определен в paragraph 7 , раздел 6.7.8 Initialization стандарта ИСО / МЭК 9899: 1999 как:

Если обозначение имеет форму
, идентификатор
то текущий объект (определенный ниже) должен иметь структуру или тип объединения, а идентификатор должен быть именем члена этого типа.

Обратите внимание, что в paragraph 9 того же раздела говорится, что:

За исключением случаев, когда явно указано иное, для целей данного подпункта неназванные члены объектов структуры и типа объединения не участвуют в инициализации. Безмерные элементы структурных объектов имеют неопределенное значение даже после инициализации.

Однако в реализации GNU GCC исключенные элементы инициализируются как нулевые или нулевые значения типа. Как указано в разделе 6.27 «Назначенные инициаторы документации GNU GCC:

Пропущенные члены поля неявно инициализируются так же, как объекты, имеющие статическую продолжительность хранения.

Компилятор Microsoft Visual C ++ должен поддерживать назначенные инициализаторы с версии 2013 согласно официальной публикации в блоге C ++ Conformance Roadmap . Параграф Initializing unions and structs статьи « Инициализаторы» в документации MSDN Visual Studio предполагает, что неназванные члены инициализируются нулевыми значениями аналогично GNU GCC.

Новый стандарт ISO / IEC 9899: 2011 (обычно известный как C11), который заменил ISO / IEC 9899: 1999, сохраняет назначенные инициализаторы в разделе 6.7.9 Initialization . Он также сохраняет paragraph 9 без изменений.

 void function(void) { MY_TYPE a; a.flag = true; a.value = 15; a.stuff = 0.123; } 

Если MS не обновилась до C99, MY_TYPE a = {true, 15,0.123};

Я нашел другой способ инициализации структур.

Структура:

 typedef struct test { int num; char* str; } test; 

Инициализация:

 test tt = { num: 42, str: "nice" }; 

Согласно документации GCC, этот синтаксис устарел после GCC 2.5 .

Мне не понравился ни один из этих ответов, поэтому я сделал свой собственный. Я не знаю, является ли это ANSI C или нет, это просто GCC 4.2.1 в режиме по умолчанию. Я никогда не помню брекетинг, поэтому я начинаю с подмножества моих данных и сражаюсь с сообщениями об ошибках компилятора, пока он не закроется. Считываемость – мой первый приоритет.

  // in a header: typedef unsigned char uchar; struct fields { uchar num; uchar lbl[35]; }; // in an actual c file (I have 2 in this case) struct fields labels[] = { {0,"Package"}, {1,"Version"}, {2,"Apport"}, {3,"Architecture"}, {4,"Bugs"}, {5,"Description-md5"}, {6,"Essential"}, {7,"Filename"}, {8,"Ghc-Package"}, {9,"Gstreamer-Version"}, {10,"Homepage"}, {11,"Installed-Size"}, {12,"MD5sum"}, {13,"Maintainer"}, {14,"Modaliases"}, {15,"Multi-Arch"}, {16,"Npp-Description"}, {17,"Npp-File"}, {18,"Npp-Name"}, {19,"Origin"} }; 

Данные могут начать жизнь в виде файла с разделителями табуляции, который вы заменяете, чтобы массажировать в нечто другое. Да, это материал Debian. Итак, одна внешняя пара {} (указывающая массив), затем другая пара для каждой структуры внутри. С запятыми между. Помещение вещей в заголовок не является строго необходимым, но у меня есть около 50 элементов в моей структуре, поэтому я хочу их в отдельном файле, чтобы сохранить беспорядок из моего кода, и поэтому его легче заменить.

Структура в C может быть объявлена ​​и инициализирована следующим образом:

 typedef struct book { char title[10]; char author[10]; float price; } book; int main() { book b1={"DS", "Ajay", 250.0}; printf("%s \t %s \t %f", b1.title, b1.author, b1.price); return 0; } 

Я прочитал документацию Microsoft Visual Studio 2015 для инициализации совокупных типов, но все формы инициализации с помощью {...} объясняются там, но здесь не упоминается инициализация с точкой с названием «обозначение». Это тоже не работает.

Стандартная глава C99 6.7.8 Инициализация объясняет возможность указателей, но, на мой взгляд, для сложных структур не совсем понятно. Стандарт C99 в формате pdf .

На мой взгляд, может быть лучше

  1. Используйте = {0}; -инициализация для всех статических данных. Это меньше усилий для машинного кода.
  2. Использовать macros для инициализации, например

    typedef MyStruct_t{ int x, int a, int b; } MyStruct; define INIT_MyStruct(A,B) { 0, A, B}

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

 void init_MyStruct(MyStruct* thiz, int a, int b) { thiz->a = a; thiz->b = b; } 

Эта процедура выглядит как ObjectOriented в C. Используйте thiz , а не this чтобы скомпилировать ее с C ++ тоже!

 MyStruct data = {0}; //all is zero! init_MyStruct(&data, 3, 456); 
  • Что означает синтаксис структуры C ++ "a: b"
  • Инициализация / сброс структуры до нуля / null
  • Давайте будем гением компьютера.