Einerseits stimmt das. Wenn man das Prinzip und Möglichkeiten nicht verstanden hat, wird die Sache durchaus kompliziert - und bisweilen gefährlich.
Andererseits sind Zeiger, mit Wissen und Bedacht angewendet, ein sehr mächtiges Werkzeug. Ganz
egal, was und worauf man C programmiert, früher oder später kommt man nicht mehr um
Zeiger herum.
Ich habe den Umgang mit Zeigern ganz am Anfang meiner Informatikerkarriere in PASCAL gelernt und
war davon sofort begeistert.
Die Möglichkeiten der C-Zeiger gehen aber noch deutlich weiter und machen dadurch Sachen
möglich, die sich anders nicht oder nur sehr schwer lösen lassen.
Eine Zeigervariable braucht als erstes mal einen Typ, der angibt, auf was der Zeiger eigentlich
zeigt. Also hier mal das übliche Beispiel:
Die erste Zeile deklariert eine Variable vom Typ char, die genau ein
Byte belegt. Die zweite Zeile deklariert einen Zeiger auf etwas vom Typ char,
der genau soviel Bytes belegt wie das entsprechende System für
eine Adresse verwendet. Zunächst sind beide
Variablen undefiniert, was insbesondere bei dem Zeiger zu Verwirrungen führen kann. Denn die
übliche Abfrage, ob ein Zeiger definiert ist, lautet meistens :
Da solche Deklarationen ja des Öfteren in Funktionen vorkommen, kann man sich nicht auf den
Null-Wert verlassen, weil die Variable auf dem (vorher schon benutzen) Stack liegt. Deswegen ist
es meistens sinnvoller, die Deklaration mit einer Definition zu verknüpfen :
Das kostet kaum Platz und Ausführungszeit, hilft aber ungemein, später "seltsame" und meistens schwer aufzufindende Fehler zu vermeiden.
Jetzt haben wir also einen Zeiger, der zunächst mal ins Nirvana oder auf die Adresse 0
zeigt - noch nicht besonders nützlich.
Also lassen wir ihn auf die Variable c zeigen :
Das ist immer noch nicht viel Sinnvolles, denn wie kommen wir jetzt über den Zeiger an den
Inhalt der Variable c?
Eigentlich ganz einfach - aber von der Syntax her eher etwas verwirrend. In der Deklaration steht
der Stern ja auch vor der Zeigervariable, ohne irgendwelchen Inhalt herzugeben.
Wird der Stern außerhalb der Deklaration,
also überall sonst im Programm, verwendet, kommt der Inhalt des Speichers, auf den der Pointer
zeigt, zurück.
Im Informatiker-Sprech :
p_c refezenziert c
*p_c dereferenziert c
Jetzt könnten wir mit dem Zeiger etwas anfangen.
Zur Vereinfachung nehme ich jetzt zwei Integervariablen und einen Zeiger auf Speicherplatz vom Typ
int. Zuerst werden wie gehabt die Variablen dekalriert, dann der Zeiger
deklariert und mit 0 initialisiert.
Das alles lernt man in jedem C-Kurs, es birgt kaum Fehlermöglichkeiten. Es erscheint aber auch nicht besonders nützlich.
Aber ein bisschen weniger :
Zeiger sind nie negativ, d.h. sie können nur
positive Werte (inkl. der 0 !) annehmen. Die Länge einer Zeigervariablen entspricht i.A. der
Größe einer Adresse im Speicherraum des verwendeten Prozessors.
Und ganz wichtig und gerne vergessen :
Die Schrittweite bei der Zeigerarithmetik ist meistens nicht
ein Byte. Sie entspricht der Anzahl der Bytes, die eine Variable des Typs belegt, für
den die Zeigervariable deklariert ist. Das kann bei großen Strukturen durchaus eine Menge Bytes
ergeben.
Was zeigt uns dieser Beispiel-Code?