2013-04-23 3 views
1

Я несколько определений структур ниже:Инициализация структуры, содержащей указатель на другую структуру в C99

typedef struct { 
    uint16_t a ; 
} my_type1_t ; 

typedef struct { 
    uint16_t b ; 
} my_type2_t ; 

typedef struct { 
    my_type1_t* a_ptr ; 
    my_type2_t* b_ptr ; 
} both_t ; 

typedef struct { 
    both_t* both_ptr ; 
} gathered_t 

и некоторые экземпляры вышеуказанных структур:

my_type1_t a = { 
    .a = 0x01U, 
} ; 

my_type2_t b = { 
    .b = 0xAAU, 
} ; 

Я хотел бы задать возможно ли это в стандарте C99 или выше для некоторой инициализации структуры, как показано ниже:

gathered_t all = { 
    .both_ptr.a_ptr = &a, 
    .both_ptr.b_ptr = &b, 
}; 

I kno w, что решение этой проблемы может определять экземпляр структуры both_t, однако это вводит дополнительный объект, который потребляет память.

ответ

3

Поскольку ваша структура объявляет тип указателя, вам придется выделять память для объекта где-то. Но вам не нужно иметь, чтобы объявить переменную для этого, соединение буквальным бы:

gathered_t all = { 
    .both_ptr = &(both_t){ 
    .a_ptr = &a, 
    .b_ptr = &b, 
    } 
}; 

Соединение буквальным распределяется в соответствии с областью, где находится эта инициализация; если в области файлов распределение будет статическим, в противном случае оно будет автоматическим (в «стеке»);

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

+0

Я проверил ваше решение и, похоже, работает, но можете ли вы рассказать мне, где этот объект был выделен? в стеке? – Lazureus

+0

Я проверил свой файл карты еще раз, и я увидел, что этот объект в основном распределяется в ОЗУ, но не имеет никакого символа. – Lazureus

+0

@ Lazureus, см. Мое редактирование. –

0

Нет, это невозможно. В любом случае вам потребуется память для both_t. Таким образом, решение

both_t both = { &a, &b }; 
gathered_t all = { &both }; 

будет использовать столько же памяти, сколько вы ожидаете.

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

+0

да, я понял свою ошибку после ввода. –

+0

@BryanOliver Эй, Брайан, ваш код имеет смысл для меня, так как это то, что я читаю в своей книге. Но вы можете любезно рассказать мне, что эти синтаксические ссылки link {{.both_ptr = {. A_ptr = & a, .b_ptr = & b}} 'и что означает «.» Что мне не хватает? Что мне нужно изучить, чтобы понять это? Ничто из этого не упоминается в моей книге C. –

+0

@BryanOlivier Какие имена полей? Можете ли вы любезно уточнить? Я прочитал только указанный вами синтаксис, прежде чем вы отредактировали свой ответ. Как 'gather_t all = {{& a, & b}}' .Что мне не хватает? новая гамма ситакса и правил? –

0

Попробуйте

gathered_t all = { 
    .both_ptr = &(both_t){ &a, &b } 
}; 

Полный пример в http://codepad.org/kGxiPPxT

+0

Большое спасибо Арун, этот ответ кажется правдой. – Lazureus