2017-02-02 2 views
0

Я пишу код в C, который инициализирует кучу структур, используя части других структур. Например:Инициализация массива в структуре с помощью другого массива

//Original structure 
struct 
{ 
    int foo1; 
    int foo2; 
    int foo3; 
} orig_struct = {1,2,3}; 

//New structure 
struct 
{ 
    int bar1; 
    int bar2; 
} new_struct = {orig_struct.foo1, orig_struct.foo2}; 

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

я столкнулся с проблемой, когда одна из структур был большой массив:

//Original structure 
struct 
{ 
    int foo1; 
    int foo2[50]; 
    int foo3; 
} orig_struct = {1,{2,3,etc},52}; //<--replace "etc" with 48 more int values 

//New structure 
struct 
{ 
    int bar1; 
    int bar2[50]; 
} new_struct = {orig_struct.foo1, XXX}; 

есть все, что я могу заменить XXX с инициализировать массив в новой структуре со значениями в массиве из оригинальная структура? Опять же, я хотел бы сохранить чистый, последовательный взгляд на мой код, поэтому сохранить его в фигурных скобках было бы идеально. Я знаю, что можно ввести вручную из каждого элемента массива в пределах своих фигурных скобках:

... 
} new_struct = {orig_struct.foo1, {orig_struct.foo2[0],orig_struct.foo2[1],orig_struct.foo2[2],orig_struct.foo2[3],etc} 

Но это довольно очевидно, почему это может быстро стать несостоятельным.

ответ

1

В c, я не вижу способа сделать это в инициализаторе, поскольку назначение массива не поддерживается, а выражения должны быть постоянными выражениями; поэтому цикл или memcpy не представляется возможным во время инициализации (см array initialization reference):

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

Позже, конечно, вы могли бы написать memcpy(new_struct.bar2, orig_struct.foo2, sizeof(new_struct.bar2)), но этот код затем отделен от объявления struct/variable.

+0

Да, сейчас я использую метод memcpy. По общему признанию, это не страшно. Если вы правы, что нет другого пути, мне придется сделать этот мой постоянный код. –

1

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

На самом деле нет никакого способа напрямую назначить массив другому массиву. Это разрешено только в том случае, если сам массив инкапсулирован структурой, и вы используете назначение структуры. Так как исходная структура и новая структура имеют общий начальный префикс, вы могли бы попытаться использовать это через союз:

struct orig_struct_type orig_struct = {1,{2,3},52}; 

void some_function() 
{ 
    union { 
     struct orig_struct_type o; 
     struct new_struct_type n; 
    } *u = (void *)&orig_struct; 
    struct new_struct_type new_struct = u->n; 
    /* ... */ 
} 

Если вы просто пытаетесь уменьшить дублирование кода, вы можете поместить список массива инициализатора в макрос ,

#define VALUES {2,3,etc} //<--replace "etc" with 48 more int 

//Original structure 
struct 
{ 
    int foo1; 
    int foo2[50]; 
    int foo3; 
} orig_struct = {1,VALUES,52}; 

void some_function() 
{ 
    struct 
    { 
     int bar1; 
     int bar2[50]; 
    } new_struct = {orig_struct.foo1, VALUES}; 
    /* ... */ 
} 
Смежные вопросы