Initialisieren Sie das statische Array von Strukturen in C

Lesezeit: 4 Minuten

Benutzer-Avatar
russell_h

Ich implementiere ein Kartenspiel in C. Es gibt viele Arten von Karten und jede hat eine Reihe von Informationen, einschließlich einiger Aktionen, die einzeln per Skript zugeordnet werden müssen.

Bei einer Struktur wie dieser (und ich bin mir nicht sicher, ob ich die richtige Syntax für den Funktionszeiger habe)

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

Ich möchte ein statisches Array davon initialisieren, eines für jede Karte. Ich vermute, das würde in etwa so aussehen

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. Funktioniert das und gehe ich überhaupt richtig vor? Ich versuche, eine große Anzahl von Switch-Anweisungen zu vermeiden.

  2. Muss ich die ‘do_cardN’-Funktionen im Voraus definieren, oder gibt es eine Möglichkeit, sie inline bei der Initialisierung der Struktur zu definieren (etwas wie eine Lambda-Funktion in Python)?

  3. Ich benötige schreibgeschützten Zugriff auf cardDefinitions aus einer anderen Datei – ist „extern static“ dafür richtig?

Ich weiß, das sind viele Fragen in einer, aber ich bin wirklich etwas vage, wie ich das angehen soll.

Vielen Dank.

Bearbeiten:

Um es klar zu sagen, mein Ziel ist es, so etwas tun zu können

int cost = cardDefinitions[cardNumber].cost;

oder

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

Anstatt überall riesige Switch-Anweisungen zu verwenden.

Dein Ansatz ist genau richtig.

  1. Dies wird funktionieren und ist eine gute Möglichkeit, große Mengen zu vermeiden switch Aussagen.
  2. Sie können in C keine Funktionen inline definieren, sie müssen alle einen eindeutigen Namen haben.
  3. extern ist, was Sie wollen, nicht static. Ändern Sie Ihren Körper so:

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

    dann in einer entsprechenden Header-Datei:

    extern struct CARD cardDefinitions[];
    

  • Sie können tatsächlich “Inline”-Funktionen in C haben. Das Wort, nach dem Sie suchen, ist “anonyme Funktionen”. Außerdem würde ich {0, 0, NULL} als letztes Element des Arrays hinzufügen, damit Sie seine Größe nicht separat speichern müssen.

    – Philipp

    14. April 2010 um 23:06 Uhr

  • @Philip Nun, diese “Inlines” haben nichts mit dem zu tun, wovon er spricht, aber ja, du hast Recht. Und ich bevorzuge die “sizeof(cardDefinitions)/sizeof(cardDefinitions[0])” Trick für solche Fälle

    – Michael Mrozek

    14. April 2010 um 23:08 Uhr

  • @Michael: Dieser Trick funktioniert nicht, wenn Sie “extern struct CARD cardDefinitions[];”.

    – Philipp

    15. April 2010 um 0:09 Uhr

Dein Ansatz ist richtig und wird funktionieren. Ihre Funktionszeiger-Syntax ist richtig, außer dass Sie keine Parameternamen verwenden – nur Typen:

int (*do_actions)(struct GAME_STATE *, int, int);

  1. Das sollte gut funktionieren. Es scheint, als hätten Sie viele Funktionen, wenn Sie eine pro Karte ausführen, aber vielleicht erfordert dieses spezielle Spiel dieses Maß an Kontrolle

  2. Sie können sie nicht inline definieren, aber Sie können einfach eine Vorwärtsdeklaration durchführen. Sie müssen tun &func_name in der Strukturinitialisierung

  3. Nein; extern bedeutet, dass eine Variable in einer anderen Datei deklariert wird, daher ist es nicht sinnvoll, eine externe Variable zu haben, die Sie an dieser Stelle deklarieren. Ebenfalls, static bedeutet, dass auf die Variable nur von der aktuellen Datei aus zugegriffen werden kann, was das Gegenteil von dem ist, was Sie wollen. Um es schreibgeschützt zu machen, wäre eine Getter-Funktion erforderlich, aber wenn Sie es nur von einer anderen Datei aus zugänglich machen möchten, deklarieren Sie es normalerweise hier (struct cardDefinitions[] = {...}) und in der anderen Datei ein extern (extern struct cardDefinitions[];)

  • Das müssen Sie nicht tun &func_name. Entweder func_name oder &func_name ist in Ordnung (ein bloßer Funktionsname wird in einen Zeiger auf die Funktion umgewandelt, analog zu der Art und Weise, wie ein bloßer Array-Name in einen Zeiger auf das erste Element des Arrays umgewandelt wird).

    – Café

    14. April 2010 um 22:34 Uhr

  • 1. Ja, das Spiel (“Dominion”) ist so ziemlich lächerlich 2. Danke für die Klärung des Extern-Bits, das macht viel mehr Sinn. Mein Ansatz bestand darin, einfach mit Schlüsselwörtern zu werfen, bis es funktionierte …

    – russell_h

    14. April 2010 um 22:50 Uhr

  • Oh wow, ich habe tatsächlich vor einer Weile mit einer Implementierung dieses Spiels begonnen, aber entschieden, dass es wahrscheinlich nicht annähernd so viel Spaß machen würde wie IRL. Sie brauchen wahrscheinlich nicht für jede Karte separate Funktionen, Sie können einfach Eigenschaften definieren, wie viel Geld Ihnen eine Karte gibt, wie viele Karten Sie ziehen müssen, wie viele Käufe und Aktionen Sie erhalten und wie viele VPs sie wert ist das wird die meisten Fälle abdecken

    – Michael Mrozek

    14. April 2010 um 22:59 Uhr


  • @café Interessant. Es gibt einige Fälle, in denen das & erforderlich ist, weil ich schon früher darauf gestoßen bin und mir angewöhnt habe, es immer einzuschließen, aber Sie haben Recht, es ist anscheinend nicht immer erforderlich

    – Michael Mrozek

    14. April 2010 um 23:03 Uhr

  • Der einzige Fall, wo die & ist erforderlich, wenn Sie es als Operand von verwenden sizeof Operator (der Funktionsbezeichner zerfällt in diesem Fall nicht zu einem Funktionszeiger, und using sizeof auf einem Funktionsbezeichner ist nicht erlaubt).

    – Café

    15. April 2010 um 0:55 Uhr

1384690cookie-checkInitialisieren Sie das statische Array von Strukturen in C

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy