32. structs

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

stucts und Pointer

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.

structs und Funktionen

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.


Markus Demleitner

Copyright Notice