46. Fallstudie: Liste

Wir wollen etwas wie Python-Listen auch in C haben. Dazu werden wir ein Modul schreiben, das einen Teil der Funktionalität – wenigstens mal für Strings – bietet.

Die Implementation einer Liste ist pädagogisch gemeint – Implementationen von Listen in C (oder fast jeder anderen Sprache) gibt es wie Sand am Meer. Gemäß der Golden Rule “Whenever possible, steal code” sollte niemand mehr wirklich Listen von Grund auf programmieren. Sinn der Übung ist die Demonstration, wie ein Modul geschrieben wird und auch ein kleiner Einblick in die Liste als Datenstruktur.

Übrigens kann man die Python-Bibliothek und damit auch deren Listen auch in eigenen C-Programmen verwenden. Wie, werden wir später sehen.

Die Schnittstelle zu einem Modul, das eine Liste von Strings implementiert:

  • List: der Listentyp
  • List *list_new(void); legt eine neue Liste an
  • int list_free(List *l); gibt eine Liste frei
  • int list_append(List *l, char *item); hängt item an l an
  • char *list_getAt(List *l, int index); gibt den String an Positon index zurück
  • int list_deleteAt(List *l, int index); löscht das Element bei index
  • int list insertBefore(List *l, int ind, char *it); fügt it vor der Position ind ein
  • list_len(List *l); gibt die Zahl der Elemente der Liste zurück
  • list_sort(List *l); sortiert die Liste

Wir haben die Funktionen wieder durch Verben bezeichnet – wie schon in Python sollen auch C-Funktionen in erster Linie etwas tun, und wieder haben wir alle Namen unseres Moduls mit dem Präfix list_ gekennzeichnet – schon free statt list_free würde mit der Funktion free aus der Standardbibliothek kollidieren.

Wir versuchen, so viel von den Prinzipien der Objektorientierung wie möglich nach C zu retten. Trennung von Implementation und Schnittstelle: Headerfile definiert Methoden, die unabhängig von der Implementierung sind.

Module lassen sich einzeln warten, Fehler bleiben lokalisiert, “one code line – one programmer” auch in großen Projekten, Wiederverwendbarkeit.

Als Beispiel für die Modularisierung größerer Projekte kann die glib dienen, in der arrays, hashes, nodes usf. alle ihre eigenen Module haben. In diesem Fall haben die einzelnen Module nicht eigene Headerdateien – sie sind alle in der zentralen Headerdatei glib.h vereinigt.

Im Headerfile: Deklaration exportierter Typen, Prototypen exportierter Funktionen.

In der Quelldatei: Alles, was nicht unbedingt von außen sichtbar sein muss, ist static.


Markus Demleitner

Copyright Notice