web-dev-qa-db-ja.com

Cの構造体の静的配列を初期化する

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

これらの静的配列を、各カードに1つずつ初期化したいと思います。これはこんな感じだと思う

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'は正しいですか?

これは多くの質問が1つにまとまっていることは知っていますが、これをどのように進めるかについては少しあいまいです。

ありがとう。

編集:

明確にするために、私の目標は次のようなことをできるようにすることです

int cost = cardDefinitions[cardNumber].cost;

または

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

あちこちで巨大なswitchステートメントを使用する代わりに。

32
russell_h

あなたのアプローチは正確です。

  1. これは機能し、巨大なswitchステートメントを避ける良い方法です。
  2. Cで関数をインラインで定義することはできません。各関数には一意の名前が必要です。
  3. externstaticではなく、必要なものです。体をこれに変更します:

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

    次に、適切なヘッダーファイルで:

    extern struct CARD cardDefinitions[];
    
39
Greg Hewgill

あなたのアプローチは正しく、機能します。関数ポインタの構文は正しいですが、パラメータ名を使用せず、次のように入力するだけです。

int (*do_actions)(struct GAME_STATE *, int, int);
3
caf
  1. それはうまくいくはずです。あなたがカードごとに1つをやっているなら、あなたは多くの機能を持っているようですが、おそらくこの特定のゲームはそのレベルの制御を必要とします

  2. それらをインラインで定義することはできませんが、前方宣言を行うことはできます。あなたがする必要があります&func_nameしかし、構造体の初期化

  3. 番号; externは、変数が別のファイルで宣言されていることを意味します。そのため、その場所で宣言している外部変数を持つことは意味がありません。また、staticは、変数が現在のファイルからのみアクセス可能であることを意味します。これは、あなたが望むものの反対です。読み取り専用にするにはゲッター関数が必要になりますが、別のファイルからアクセスできるようにするだけの場合は、ここで通常に宣言してください(struct cardDefinitions[] = {...})および他のファイルではextern(extern struct cardDefinitions[];

1
Michael Mrozek