Инициализировать статический массив структур в C - PullRequest
31 голосов
/ 15 апреля 2010

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

Учитывая такую ​​структуру (и я не уверен, что у меня есть синтаксис для указателя функции)

struct CARD {
    int value;
    int cost;
    // This is a pointer to a function that carries out actions unique
    // to this card
    int (*do_actions) (struct GAME_STATE *state, int choice1, int choice2);
};

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

int do_card0(struct GAME_STATE *state, int choice1, int choice2)
{
    // Operate on state here
}

int do_card1(struct GAME_STATE *state, int choice1, int choice2)
{
    // Operate on state here
}

extern static struct cardDefinitions[] = {
    {0, 1, do_card0},
    {1, 3, do_card1}
};
  1. Будет ли это работать, и я ли вообще буду делать это правильно? Я пытаюсь избежать огромного количества операторов switch.

  2. Нужно ли заранее определять функции 'do_cardN' или есть какой-то способ определить их встроенными при инициализации структуры (что-то вроде лямбда-функции в python)?

  3. Мне понадобится доступ только для чтения к cardDefinitions из другого файла - для этого подходит 'extern static'?

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

Спасибо.

Edit:

Для ясности, моя цель - сделать что-то вроде

int cost = cardDefinitions[cardNumber].cost;

или

int result = cardDefinitions[cardNumber].do_action(state, choice1, choice2);

Вместо повсеместного использования огромных операторов switch.

Ответы [ 3 ]

37 голосов
/ 15 апреля 2010

Ваш подход совершенно правильный.

  1. Это будет работать, и это хороший способ избежать огромных switch утверждений.
  2. Вы не можете определить функции, встроенные в C, каждая из которых должна иметь уникальное имя.
  3. extern - это то, что вы хотите, а не static. Измени свое тело, чтобы быть таким:

    struct CARD cardDefinitions[] = { 
        {0, 1, do_card0}, 
        {1, 3, do_card1} 
    }; 
    

    затем в соответствующем заголовочном файле:

    extern struct CARD cardDefinitions[];
    
3 голосов
/ 15 апреля 2010

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

int (*do_actions)(struct GAME_STATE *, int, int);
1 голос
/ 15 апреля 2010
  1. Это должно работать нормально. Кажется, что у вас было бы много функций, если вы выполняете одну на карту, но, возможно, эта конкретная игра требует такого уровня контроля

  2. Вы не можете определить их встроенными, но вы можете просто сделать предварительную декларацию. Вам нужно сделать &func_name в инициализации структуры, хотя

  3. Нет; extern означает, что переменная объявлена ​​в другом файле, поэтому нет смысла иметь переменную extern, которую вы объявляете в этом месте. Кроме того, static означает, что переменная доступна только из текущего файла, что противоположно тому, что вы хотите. Чтобы сделать его доступным только для чтения, потребуется функция получения, но если вы просто хотите сделать его доступным из другого файла, объявите его здесь (struct cardDefinitions[] = {...}), а в другом файле используйте extern (extern struct cardDefinitions[];)

...