10.10    Arrays von Zeigern

Arrays von Zeigern (auch: Zeiger-Arrays) können je nach Anwendung als Alternative für zweidimensionale Arrays eingesetzt werden, ganz besonders gerne wird dies bei zweidimensionalen char-Arrays (Strings) getan, z. B. in der folgenden Weise:

char german[10][50] = {
"eins", "zwei", "drei", "vier", "fünf",
"sechs", "sieben", "acht", "neun", "zehn"
};

char english[10][50] = {
"one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten"
};

Sie sehen hier zwei zweidimensionale Arrays mit Zeichenketten, die jeweils 10 Elemente mit jeweils 50 Zeichen aufnehmen können. Hier fällt sofort die Speicherverschwendung auf, weil keiner der Strings 50 Zeichen benötigt, und die Array-Einträge auch wahrscheinlich im weiteren Verlauf nicht mehr geändert werden. Dies ist also im Endeffekt das Gegenteil des vorangehenden Beispiels. Der längste String in der Tabelle benötigt in diesem Beispiel gerade mal sieben Zeichen. Und was ist, wenn Sie noch mehr Strings hinzufügen wollen? Klar, Sie können ein größeres zweidimensionales Array verwenden. Allerdings wird hierzu meistens wieder zu viel Speicher reserviert.

Ein zweidimensionales Array – wie hier mit mehreren Strings – hat also häufig das Problem, dass entweder unnötig viel Speicher belegt wird oder dass es unflexibel ist. Daher bieten sich für solche Fälle Arrays von Zeigern an. Dasselbe Beispiel mit solchen Arrays von Zeigern ist:

char *german[] = {
"eins", "zwei", "drei", "vier", "fünf",
"sechs", "sieben", "acht", "neun", "zehn"
};

char *english[] = {
"one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten"
};

Beide Arrays von Zeigern erfüllen hier denselben Zweck wie im vorangehenden Beispiel. Sie haben allerdings den Vorteil, dass jetzt nur so viel Speicherplatz wie nötig verwendet wird.

Ein solches Array speichert nicht mehr die Strings selbst, sondern Zeiger auf diese Strings, die sich irgendwo auf dem Speicher befinden können.

Benötigen Sie ein Array mit einer bestimmten Anzahl von Zeigern eines Datentyps, können Sie dies folgendermaßen deklarieren:

char *strings[100];

Hiermit haben Sie 100 Zeiger auf Strings angelegt. Richtig sinnvoll können Sie ein Array mit solchen Zeigern allerdings erst verwenden, wenn Sie Kenntnisse der dynamischen Speicherverwaltung besitzen. Die einzelnen Adressen können Sie mithilfe des Indizierungsoperators vergeben. Hier ein Beispiel:

strings[0] = "Hallo"; // 1. Zeiger auf Stringkonstante
strings[1] = "Welt"; // 2. Zeiger auf Stringkonstante
...

Hierzu noch ein kurzes Listing, das die einfache Verwendung von Arrays von Zeigern in der Praxis demonstrieren soll:

00  // Kapitel10/ptr_arrays.c
01 #include <stdio.h>
02 #include <stdlib.h>

03 int main(void) {
04 char *german[] = {
"eins", "zwei", "drei", "vier", "fuenf",
"sechs", "sieben", "acht", "neun", "zehn"
};
05 char *english[] = {
"one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten"
};
06 int ival = 0;
07 printf("Bitte eine Ganzzahl von 1 bis 10: ");
08 if( scanf("%d", &ival) != 1 ) {
09 printf("Fehler bei der Eingabe\n");
10 return EXIT_FAILURE;
11 }
12 else if( ival <= 0 || ival > 10 ) {
13 printf("Dies ist kein Wert von 1 bis 10\n");
14 return EXIT_FAILURE;
15 }
16 else {
17 printf("Ganzzahl: %d\n", ival);
18 printf("Englisch: %s\n", english[ival-1]);
19 printf("Deutsch : %s\n", german[ival-1]);
20 }
21 return EXIT_SUCCESS;
22 }

Listing 10.8    ptr_arrays.c demonstriert die Verwendung von Zeiger-Arrays anhand von Strings.

Im letzten Beispiel werden Sie nach einer Ganzzahl von 1 bis 10 gefragt. Je nach Eingabe der Ganzzahl erhalten Sie in den Zeilen (18) und (19) den entsprechenden ganzzahligen Wert als englisches und deutsches Wort.

Das Programm gibt bei der Ausführung z. B. Folgendes aus:

Bitte eine Ganzzahl von 1 bis 10: 8
Ganzzahl: 8
Englisch: eight
Deutsch : acht