Linux C-Programmieranleitung Teil 21: Zeichenzeiger, Zeigerarray und Zeiger zu Zeiger

Das Konzept der Zeiger ist in der Tat eines der sehr wichtigen Konzepte in der Programmiersprache C. Bis jetzt haben wir mehrere Aspekte von Zeigern in C diskutiert. In diesem Tutorial werden wir darauf aufbauend einige weitere Zeigerkonzepte diskutieren.

Zeichenzeiger, Array von Zeigern und Zeiger auf Zeiger in C

Beginnen wir mit Zeichenzeigern mit den folgenden Zeilen Code:

char p[] = "I like HowtoForge"
char *p = "I like HowToForge"

Die erste Zeile definiert ein Array ‚p‘ mit einer Größe, die der Anzahl der Zeichen in doppelten Anführungszeichen entspricht. Die nächste Zeile definiert jedoch einen Zeiger ‚p‘, der auf eine Zeichenkettenkonstante zeigt.

Der Unterschied besteht darin, dass das erste ‚p‘ ein Array ist, Sie können den Inhalt des Arrays leicht modifizieren oder ändern. Da aber das zweite ‚p‘ auf eine Zeichenkettenkonstante zeigt, können Sie den Inhalt der Zeichenkette einfach nicht ändern.

Zum Beispiel versucht das folgende Stück Code, eine Zeichenkettenkonstante zu modifizieren:

#include <stdio.h>
int main()
{
char *p = "I like HowToForge";

p[0] = 'U';

return 0;
}

Und hier ist die Ausgabe, die dieser Code auf meinem System erzeugt:

Segmentation fault

Dieser Fehler deutet darauf hin, dass die Programmausführung zu einem abrupten Ende gekommen ist, und das liegt daran, dass wir versucht haben, etwas zu ändern, das konstant ist.

Denken Sie auch daran, dass der Zeiger ‚p‘ zwar auf eine andere Zeichenkette zeigen kann, Sie aber die Basisadresse des Arrays ‚p‘ nicht ändern können (wenn Sie sich erinnern, haben wir dies bereits in einem unserer früheren Tutorials besprochen).

Jetzt gehen wir zu Zeiger-Arrays über, so wie Sie Ganzzahl, Zeichen und einen anderen Typ von Arrays gesehen haben, kann es auch ein Array von Zeigern geben. Das folgende Programm definiert zum Beispiel ein Array ‚arr‘ aus ganzzahligen Zeigern und weist ihm Werte zu.

#include <stdio.h>
int main()
{
int *arr[3];
int a = 0, b = 1, c = 2;

arr[0] = &a;
arr[1] = &b;
arr[2] = &c;

return 0;
}

Beachten Sie, dass die dem Array zugewiesenen Werte Adressen sind. Das liegt daran, dass ‚arr‘ ein Array von Zeigern ist, und Zeiger speichern nichts als Adressen. Wenn Sie nun auf Werte zugreifen wollen, die an diesen Adressen gespeichert sind, müssen Sie den *-Operator verwenden.

Das folgende Beispiel (das nichts anderes als eine Erweiterung des vorherigen Beispiels ist) zeigt dies:

#include <stdio.h>
int main()
{
int *arr[3];
int a = 0, b = 1, c = 2;

arr[0] = &a;
arr[1] = &b;
arr[2] = &c;

for(int i=0; i < 3; i++)
printf("\n arr[%d] is: %d",i,*(arr[i]));

return 0;
}

Hier ist die Ausgabe:

arr[0] is: 0 
arr[1] is: 1 
arr[2] is: 2

Ähnlich wie bei ganzzahligen Zeiger-Arrays (wie wir sie hier besprochen haben) können Sie Arrays haben, die Zeichenzeiger und mehr speichern.

Gehen wir nun zu Zeigern auf Zeiger über. Wie wir bisher mehrfach wiederholt haben, speichert ein Zeiger eine Adresse. Bisher haben wir in dieser laufenden C-Programmier-Tutorialserie nur einen Zeiger gesehen, der auf eine Nicht-Zeiger-Variable zeigt, aber Tatsache ist, dass Zeiger auch auf andere Zeiger zeigen können.

Das bedeutet, dass ein Zeiger eine Adresse eines anderen Zeigers speichern kann. Es folgt beispielsweise ein doppelter Zeiger oder ein Zeiger auf einen Zeiger:

int **ptr;

Hier ist ein Stück Code, das einen doppelten Zeiger verwendet:

#include <stdio.h>
int main()
{
int *ptr;
int **p;

int a = 10;

ptr = &a;

p = &ptr;

printf("\n Pointer 'p' points to pointer 'ptr' which further points to value: %d", **p);

return 0;
}

Hier ist die Ausgabe:

Pointer 'p' points to pointer 'ptr' which further points to value: 10

Dies war also ein Beispiel für einen doppelten Zeiger. Auf ähnlichen Zeilen können Sie einen Zeiger auf einen Zeiger auf einen Zeiger haben, der z.B. als int ***ptr definiert ist. Die maximale Anzahl solcher ‚Zeiger auf Zeiger auf……‘ Ebenen ist implementierungsspezifisch (in einigen Fällen ist die Grenze jedoch 12).

In der Praxis werden Sie jedoch wahrscheinlich nur auf Zeiger bis zur dritten Ebene stoßen, da die Logik mit mehr Ebenen komplexer zu verstehen und aufrechtzuerhalten ist.

Schlussfolgerung

Wir haben hier drei wichtige Konzepte im Zusammenhang mit Zeigern diskutiert. Wir empfehlen Ihnen, die Beispiele und Konzepte, die wir hier besprochen haben, auf Ihrem System auszuprobieren, um eine bessere Vorstellung davon zu bekommen, wie diese Dinge funktionieren. Im Falle von Zweifeln oder Fragen können Sie uns unten einen Kommentar schicken.

Das könnte dich auch interessieren …