web-dev-qa-db-fra.com

Initialiser un tableau statique de structures en C

J'implémente un jeu de cartes en C. Il existe de nombreux types de cartes et chacune a un tas d'informations, y compris certaines actions qui devront être individuellement scriptées associées.

Étant donné une structure comme celle-ci (et je ne suis pas certain d'avoir la bonne syntaxe pour le pointeur de fonction)

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);
};

Je voudrais initialiser un tableau statique de ceux-ci, un pour chaque carte. Je suppose que cela ressemblerait à quelque chose comme ça

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. Est-ce que cela fonctionnera et est-ce que j'y vais du tout dans le bon sens? J'essaie d'éviter un grand nombre de déclarations de commutateur.

  2. Dois-je définir les fonctions 'do_cardN' à l'avance, ou existe-t-il un moyen de les définir en ligne dans l'initialisation de la structure (quelque chose comme une fonction lambda en python)?

  3. J'aurai besoin d'un accès en lecture seule à cardDefinitions à partir d'un autre fichier - est-ce que "statique externe" est correct pour cela?

Je sais que c'est beaucoup de questions regroupées en une seule, mais je suis vraiment un peu vague sur la façon de procéder.

Merci.

Éditer:

Pour être clair, mon objectif est de pouvoir faire quelque chose comme

int cost = cardDefinitions[cardNumber].cost;

ou

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

Au lieu d'utiliser d'énormes instructions switch partout.

32
russell_h

Votre approche est exactement la bonne.

  1. Cela fonctionnera et est un bon moyen d'éviter les énormes instructions switch.
  2. Vous ne pouvez pas définir de fonctions en ligne en C, chacune doit avoir un nom unique.
  3. extern est ce que vous voulez, pas static. Changez votre corps pour être ceci:

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

    puis dans un fichier d'en-tête approprié:

    extern struct CARD cardDefinitions[];
    
39
Greg Hewgill

Votre approche est juste et fonctionnera. La syntaxe de votre pointeur de fonction est correcte, sauf que vous n'utilisez pas de noms de paramètres - saisissez simplement:

int (*do_actions)(struct GAME_STATE *, int, int);
3
caf
  1. Cela devrait bien fonctionner. Il semble que vous auriez beaucoup de fonctions si vous en faites une par carte, mais peut-être que ce jeu particulier nécessite ce niveau de contrôle

  2. Vous ne pouvez pas les définir en ligne, mais vous pouvez simplement faire une déclaration directe. Tu as besoin de faire &func_name dans l'initialisation de la structure

  3. Non; extern signifie qu'une variable est déclarée dans un autre fichier, donc cela n'a pas de sens d'avoir une variable externe que vous déclarez à cet emplacement. De plus, static signifie que la variable n'est accessible qu'à partir du fichier actuel, ce qui est l'opposé de ce que vous voulez. Le rendre en lecture seule nécessiterait une fonction getter, mais si vous voulez simplement le rendre accessible à partir d'un autre fichier, déclarez-le normalement ici (struct cardDefinitions[] = {...}) et dans l'autre fichier utilisez un extern (extern struct cardDefinitions[];)

1
Michael Mrozek