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.