Variable Tabellen In Cee Idiom Sammlung
 
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern

Egal wie und in welcher Programmiersprache man arbeitet, man stößt oft auf das Problem Daten in Form von Tabellen (Arrays, Vektoren) im Speicher verwalten zu müssen. Moderne Programmiersprachen bieten häufig einfache Mechanismen, um solche Datenstrukturen aufzubauen, zu verwalten und in der Größe zu verändern. In C ist man auf die dynamische Speicherverwaltung mit malloc/realloc/free angewiesen. Wie kann man in C am besten vorgehen? Welche Variationsmöglichkeiten gibt es und wie kann man mit minimalem Aufwand maximale Flexibilität erreichen?

Als Beispiel für die Beispiel wird eine Tabelle (eindimensionaler Array) einer einfachen Datenstruktur mit Personendaten folgenden Aufbaus verwendet:

typedef struct PERSON {
   char familienname[...];
   char vorname[...];
   char geschlecht;
   ... 
} PERSON;

Oft ist am Beginn einer Entwicklung noch nicht klar, ob es sich lohnt, eine komplexe dynamische Verwaltung für bestimmte Daten einzurichten. Also verzichtet man einfach darauf und richtet eine entsprechend große globale Tabelle ein (nehmen wir an, dass wir mit 200-300 Personen rechnen):

#define PERSON_TAB_DIM 500
PERSON PersonTab[PERSON_TAB_DIM];
int PersonTabDim=PERSON_TAB_DIM;
int PersonTabN=0;

Aus der Erfahrung ergibt sich, dass solche Tabellen mit einer gewissen Wahrscheinlichkeit auf eine dynamische Verwaltung umgestellt werden müssen. Für diesen Fall ist es besser, die Größe der Tabelle von vorneherein in einer Variablen (PersonTabDim) zu verwalten und z. B. beim Einfügen zur Kontrolle zu verwenden.

Für den Fall, dass wir eine Tabelle mit fix initialisierten Daten haben, könnte das so aussehen:

/* Variante 2 */
PERSON PersonTab[]= 
{
   { "Albert","Einstein",'M' },
   { "Marie","Curie",'W' }
};
int PersonTabDim=TABDIM(PersonTab);
int PersonTabN=TABDIM(PersonTab);

Wobei das in einem Header plazierte Macro

#define TABDIM(table) (sizeof(table)/sizeof(table[0]))

beim Verändern solcher voll ausgefüllter Tabellen die Arbeit des Abzählens erspart, und das Macro

#define TABEND(table) ((table)+TABDIM(table))

auch die (für manche C-Programmierer ebenfalls idiomatischen) Schleifen der Art

PERSON *p;

for (p = PersonenTab; p != TABEND(PersonenTab); ++p)
{
   /* Verarbeite p */
}

erlaubt.

Wesentlich ist, dass auch in diesen rudimentären Formen die wichtigen Informationen über die Tabelle (Adressinformation, Dimension, Anzahl der vorhandenen Elemente) schon so gehalten werden, wie sie bei einer späteren Dynamisierung benötigt werden.

Man kann also z. B. schon Operationen programmieren, deren Schleifenbearbeitung oder Overflow-Check

for(i=0; i<...TabN; i++) {
   ...
}

...TabAddElement(...) 
{
   if(..TabN >= ..TabDim) {
      /* (optional: Tabellenvergrößerung) */
      /* Fehlerbehandlung*/  
   }
   ...Einfügen der Daten
   ...TabN++; 
}

sich nicht von späteren dynamischen Varianten unterscheidet.

Dabei ist es ziemlich egal, ob die drei Variablen getrennt bleiben:

PERSON *PersonTab=NULL;
int PersonTabDim=0;
int PersonTabN=0;

oder zu einer objektartigen Struktur zusammengefasst werden:

typedef struct PERSON_TAB {
   PERSON *Ptr;
   int Dim;
   int N;
} PERSON_TAB;

oder zu einem Datenverwaltungsobjekt mit variabler Objektgröße abstrahiert werden:

typedef struct DATA_TAB {
   void *Ptr;
   int Dim;
   int N;
   int element_size;
} DATA_TAB;

Die interessante Operationen für solche Tabellen sind das unsortierte Einfügen (Append), das gezielte Löschen, das Sortieren, das gezielte Einfügen (Insert mit Positionsangabe) und die automatische Größenveränderung solcher Tabellen. Eventuell auch das Suchen bzw. die Erweiterung solcher Tabellen in Richtung auf Hash-Zugriff.

ToDo IN ARBEIT -- HelmutLeitner


KategorieC KategorieCee
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Text dieser Seite ändern (zuletzt geändert: 29. November 2007 8:48 (diff))
Suchbegriff: gesucht wird
im Titel
im Text