49. Listen: Implementation III

Die Länge einer Liste bestimmen:

int list_len(List *l)
{
  int count=0;
  Node *cur = l->first;

  while (cur) {
    count++;
    cur = cur->next;
  }
  return count;
}

Die Liste komplett freigeben:

void list_free(List *l)
{
  Node *cur = l->first, *next;

  while (cur) {
    free(cur->cont);
    next = cur->next;
    free(cur);
    cur = next;
  }
  free(l);
}

Der Tanz mit cur und next ist nötig, weil auf gefreeten Speicher nicht mehr zugegriffen werden darf.

Eine Hilfsfunktion (static!), die den Node zu einem Listenindex zurückgibt.

static Node* getNodeAt(List *l, int index)
{
  Node *cur=l->first;

  for (; cur && index; index--) {
    cur = cur->next;
  }
  return cur;
}

Der wrapper für den Zugriff über einen Index:

char *list_getAt(List *l, int index)
{
  Node *n=getNodeAt(l, index);

  if (n) {
    return n->cont;
  }
  return NULL;
}

In dieser Funktion haben wir zwei return-Statements, und der Fehlerfall wird durch das “durchfallen” der Ausführung zum letzten return erzeugt. Das ist nicht verkehrt, aber man sollte, wenn man mehrere (Nichtfehler-)returns in einer Funktion hat, aufpassen, dass die Struktur der Funktion noch klar bleibt. Lange Funktionen mit vielen returns drin tendieren zur Unverständlichkeit.

Die historische Vorschrift, nach der eine Funktion nur an einer Stelle verlassen werden kann, ist so jedenfalls unsinnig. Eine gute Diskussion dieses Punkts ist auf ist am Wiki von Cunningham and Cunningham zu finden.


Markus Demleitner

Copyright Notice