Как инициализировать структуру в соответствии со стандартами языка программирования 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 и др.)? Или есть что-то лучше или хотя бы работает?



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

982   13  

13 ответов:

в (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 для целых чисел и с плавающей точкой
  • '' на char (конечно, это то же самое, что 0 и char тип integer)
  • 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++ Соответствие "Дорожная карта". Пункт 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 для инициализации агрегатных типов тем не менее, все формы инициализации с {...} объясняются там, но инициализация с точкой, названной "обозначение", там не упоминается. Это тоже не работает.

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

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

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

    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. Use thiz, а не this чтобы скомпилировать его с C++ тоже!

MyStruct data = {0}; //all is zero!
init_MyStruct(&data, 3, 456);

Comments

    Ничего не найдено.