Arrays speichern nur Objekte gleichen Typs. Verschiedene Typen kann man in Strukturen sammeln:
struct token { char content[MAX_WORD_LEN]; int type; int seen; };
Das erinnert ein bisschen an Pythons Klassen. In der Tat verwenden die objektorientierten Nachfolger von C, allen voran C++, Erweiterungen des struct-Konzepts für ihre Klassen. Mit Funktionspointern können wir structs in der Tat auch mit Methoden ausstatten.
Eine struct-Variable wird so definiert:
struct token tok;
Zugriff auf die Elemente eines structs (auch: member) über den Punktoperator:
strcpy(tok.content, "Struktur"); tok.type = TOK_NOUN; tok.seen = 0; printf("%s %d %d\n", tok.content, tok.type, tok.seen);
Die Elemente zweier verschiedener structs haben nichts miteinander zu tun:
struct token tok1, tok2; tok1.type = 1; tok2.type = 2; printf("%d %d\n", tok1.type, tok2.type);
Meistens hat man Pointer auf structs. Der Punkt bindet stärker als der Stern, also (*tok).contents schreiben. Abkürzung: tok->content – ist auch schöner.
In der Regel nehmen Funktionen keine structs und geben sie auch nicht zurück. Beides ist zwar im Prinzip möglich, aber fast immer unnötig und langsam – structs werden per value übergeben, es muss also immer der komplette struct kopiert werden. Stattdessen sollte mit Pointern auf structs gearbeitet werden:
int tokEqual(struct tok *tok1, struct tok *tok2) { return (tok1->type==tok2->type) && !strcmp(tok1->content, tok2->content) } ... struct tok myTok1, myTok2; ... if (tokEqual(&myTok1, &myTok2)) ...
Für die Rückgabe von Structs über Pointer brauchen wir dynamische Speicherverwaltung, das muss also warten.
Technik: Der Compiler implementiert structs letztlich so, dass er Offsets für alle Felder eines structs berechnet (er sagt euch diese Offsets sogar, wenn ihr ihn mit dem offsetof-Operator danach fragt) – danach kann er einfach mit Displacement adressieren: Aus r->field könnte einfach ein 8(%esi) werden wenn r in esi steht und field einen Offset von 8 hat. Mit anderen Worten ist auch der Pfeiloperator in sehr schnellen Code zu kompilieren.