2008-10-11 2 views
15

Возможно ли инициализировать массив указателей на структуры? Что-то вроде:Как инициализировать массив указателей на структуры?

struct country_t *countries[] = { 
     {"United States of America", "America"}, 
     {"England", "Europe"}, 
     {"Ethiopia", "Africa"} 
    } 

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

ответ

30

Ну, ваш код использует структуры, а не указатели на структуры. Есть способы, чтобы сделать то, что вы ищете, в том числе:

static struct country_t us = { "United States of America", "America" }; 
static struct country_t uk = { "England",     "Europe" }; 
static struct country_t et = { "Ethiopia",     "Africa" }; 

struct country_t *countries[] = { &us, &uk, &et, }; 

Есть и другие способы сделать это с назначенными инициализаторами и составными литералами в C99. Раздел 6.5.2.5 «Составные литералы» показывает способ:

struct country_t *countries[] = 
{ 
    &(struct country_t) { "United States of America", "America" }, 
    &(struct country_t) { "England",     "Europe" }, 
    &(struct country_t) { "Ethiopia",     "Africa" }, 
}; 

Стандарт иллюстрирует указатели на структуры с вызовом функции. Имейте в виду, что не все компиляторы C принимают синтаксис C99, и эти сложные литералы не присутствуют на C89 (aka C90).

Редактировать: Обновлено, чтобы использовать коды двух букв ISO 3166. Также сделанные именованные структуры статическими переменными - эти символы не были видны за пределами файла раньше (потому что они не существовали), и теперь они также не видны за пределами файла после. Я обсуждал, делать ли что-нибудь const и не решил - но использование const, когда вы можете, обычно является хорошей идеей. Кроме того, в этом примере есть 3 страны на 3 континентах. Если бы у вас было несколько стран на одном континенте (норма), вы могли бы захотеть поделиться континентами. Однако, можете ли вы сделать это безопасно (или вообще), зависит от деталей struct country_t (которые не были указаны) и о том, разрешено ли программе обновлять таблицу (которая возвращается к вопросу о константе).

+1

В первом примере, вы должен отмечать все структуры как «статические»: они не должны быть видимыми за пределами текущего блока компиляции и загромождают связь пространство имен. – ephemient 2008-10-12 01:34:12

+0

Согласен - я решил не усложнять ответ этой деталью, хотя я кодировал решение для своей собственной работы, все, что могло быть статическим (невидимым вне файла). – 2008-10-12 01:52:42

0

Это работает для меня:


struct country_t { 
    char *fullname; 
    char *shortname; 
}; 

struct country_t countries[] = { 
     {"United States of America", "America"}, 
     {"England", "Europe"}, 
     {"Ethiopia", "Africa"} 
}; 

int main(int argc, char *argv[]) 
{ 
    return 0; 
} 

Вы могли бы быть более лаконична и использование:


struct country_t { 
    char *fullname; 
    char *shortname; 
} countries[] = { 
     {"United States of America", "America"}, 
     {"England", "Europe"}, 
     {"Ethiopia", "Africa"} 
}; 

int main(int argc, char *argv[]) 
{ 
    return 0; 
} 

Edit: Я нашел эту информацию на The C Book

Смежные вопросы