Инициализация длинных вложенных структур в C - PullRequest
2 голосов
/ 27 марта 2012

Каков наилучший / самый чистый способ инициализации (в локальной функции) длинной цепочки вложенных структур, когда каждая структура содержит только указатели на другие структуры, например, так:

typedef struct A{
struct B{
    struct C *c /* OPTIONAL */;
    struct D *d /* OPTIONAL */;
    struct E *e /* OPTIONAL */;
    struct F *f /* OPTIONAL */;
} *b;
struct G{
    struct F *f /* OPTIONAL */;
    struct D *d /* OPTIONAL */;
    struct H *h /* OPTIONAL */;
    struct F *f /* OPTIONAL */;
} *g;
    } a;

Каждый из указателейсами вложенные структуры указывают на структуры, содержащие указатели на другие вложенные структуры (я знаю, это безумие!)

Я считаю, что мне нужно определить указатель tmp для каждого члена структуры и выделить для него память, а такжеПеременная структуры tmp и укажите первое на последнее:

B *b_ptr = CALLOC(1,sizeof(b_ptr));
B b_tmp;
b_ptr = &b_tmp;
b_tmp.itsMember1 = CALLOC(1,sizeof(itsMember1));
TypeOfItsMember1 itsMember1_tmp;
..
..

Для этого потребуется множество локальных переменных и болезненно повторяющееся кодирование.Есть ли лучший способ полностью инициализировать родительскую структуру?

Любые специалисты в доме заботятся о том, чтобы дать свои 2 цента?

Ответы [ 2 ]

1 голос
/ 27 марта 2012

Некоторые возможности:

  • Примите схему сериализации, чтобы вы могли читать график структур из файла.

  • Если еще не слишком поздно, рассмотрите возможность использования языка, такого как Java или C ++, чтобы вы могли работать в терминах классов и объектов вместо структур. Это упрощает проблему, потому что каждая «структура» может инициализировать себя.

  • Даже если вы не можете переключиться на более объектно-ориентированный язык, вы все равно можете использовать более объектно-ориентированный подход. Разбейте проблему, написав функции, которые инициализируют каждую структуру и подструктуру.

1 голос
/ 27 марта 2012

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

struct C *NewC(int f1, int f2, ...)
{
    struct C *result = malloc(sizeof(*result));
    result->f1 = f1;
    result->f2 = f2;
    .....
    return result;
}

И аналогично для других ваших структур.

Затем вы можете использовать этистроительные блоки в сочетании со стандартными инициализаторами структуры:

struct B b = {
    NewC(42, 666, ...),
    NULL, 
    NULL,
    NewF(....)
};

Если вы хотите разместить struct B в куче, а не в стеке, то вы можете написать функцию NewB в том же духе.

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

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