Willkommen beim dritten Teil des C-Kurses! |
Heute behandeln wir ein Thema, welches ihr mit besonderer Sorgfalt durcharbeiten
solltet, da es euch immer wieder in C / C++ begegnen wird: Der Zeiger.
Auf neu-Deutsch auch oft als Pointer bezeichnet.
Zeiger |
Wie immer am Anfang ein kleines Beispielprogramm:
|
Wie wir am oberen Beispiel sehen können, zeichnet sich die Variable 'zeiger' dadurch aus, das sie mit einem Sternchen beginnt. Damit wird dem Compiler gesagt, das es sich hierbei um einen Zeiger handelt. Bevor ich nun in ewige Verdammnis gestürzt werde, weil ich immer noch nicht sagte, was ein Zeiger ist: Ein Zeiger beinhaltet nicht einen Variablenwert, sondern zeigt nur auf die Adresse, wo der Variablenwert hinterlegt ist.
Arbeiten wir unser Beispiel ab, dann wird auch am ehesten die obere Darstellung, was ein Zeiger ist, klar.
Wir erzeugen die Variable 'zahl' und den Zeiger 'zeiger'. Der Variablen 'zahl' wird der Wert 5 zugeordnet. Der Zeiger 'zeiger' wird die Adresse der Variable 'zahl' zugewiesen. Dies geschieht durch den Adressoperator & !
Grundsätzlich wird ein Variable durch einen vorangestellten Stern als Zeiger deklariert!
Bsp.:
int *pointer1;
float *pointer2; |
Der Vorteil von Zeigern ist der, das in ihnen nur eine Adresse und keine
Variablen stehen. Dadurch sind sie extrem flexibel und schnell. Zu beachten
ist: Der Zeiger muß denselben Datentyp besitzen, auf den er zeigt!
Folgendes funktioniert also nicht:
|
Damit wir auch Vorteile aus der Benutzung von Zeigern ziehen können, wollen wir uns einmal anschauen, was man alles mit Zeigern machen kann. Da dies im übrigen sehr viel ist, werden wir uns hier mit dem grundlegenden beschäftigen.
Zugriff auf den Variablenwert, auf den ein Zeiger zeigt erfolgt mittels des *-Operators! Man bezeichnet ihn auch als Inhalts-Operator
Aber Vorsicht: NICHT MIT DEM MULTIPLIKATOR VERWECHSELN! Das sind zwei verschiedene Operatoren!
Der Compiler entscheidet anhand des Zusammenhangs, ob es sich um einen
Zeiger-Operator oder um eine Multiplikation handelt.
|
Starten wir nun das Programm, so erhalten wir als Ausgabe:
Zahl = 5
Jetzt ist Variable Zahl = 10 |
Wie immer eine Erläuterung, was passiert ist:
Dem Zeiger 'zeiger' wurde die Adresse der Variable 'zahl' zugewiesen. Somit steht in 'zeiger' die Ardresse, wo im Speicher die Variable 'zahl' steht. Als erstes geben wir unsere Variable 'zahl' aus.
Nun wird in die Adresse ( ! ) , die in 'zeiger' gespeichert ist, der Wert 10 geschrieben! Dadurch, daß in dieser Adresse der Wert der Variable 'zahl' steht, schreiben wir in die Variable 'zahl' den Wert 10 hinein.
Diesen Effekt sehen wir, wenn wir das Programm starten: Erst steht in der Variablen 'zahl' der Wert 5 und nach dem überscheiben der Wert 10.
Man sagt auch: Durch einen Zeiger wird ein Objekt referenziert.
Keine Panik :-) In diesem Satzt steht nichts anderes, als das der Zeiger
auf die Variable zeigt.
Wenn man ehrlich ist,klingt alles immer noch recht theoretisch, aber
alles kann durch etwas Übung klarer werden.
Nein, wir steigen nicht in den Gärungsprozeß, sondern in
ein weiteres Beispiel ein :-)
|
Es ist wichtig, daß die oberen Beispiele verstanden werden!
Klasse! Doch Zeiger müssen doch zu was gut sein, oder ? Den wahren
Nutzen der Zeiger können wir erkennen, wenn wir zum nächsten
Lernabschnitt, den Feldern, oder auf neu-Deutsch Arrays , kommen. Doch
zu beginn das Grundlegende:
Felder |
Felder, also Gruppen oder Aneinanderreihungen von Variablen eines Typs
kann man als Felder auffassen.
int feld [ 10 ] ; |
erzeugt also ein Feld von 10 Elementen des Typs Integer.
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
Die Elemenente sind feld[ 0 ] .... feld[ 9 ] . |
Richtig bemerkt, die Feldindizes fangen bei 0 an.
Schauen wir mal, was man mit Zeigern und Feldern alles machen kann:
|
An diesem Beispiel ist zu sehen, das
zeiger = &feld [ 0 ];
var = *( zeiger + 2 ); |
und
var = feld [ 2 ]; |
gleichwertig sind. Wieso ?
Dazu schauen wir uns mal die erste Zuweisung genauer an.
'zeiger' wird mit der Adresse von 'feld [ 0 ]' geladen, zeigt also auf 'feld [ 0 ]'.Jetzt kommst: Die Adresse von 'zeiger' wird um 2 Elemente vom Typ 'zeiger' erhöht. Damit zeigt der Ausdruck auf das zweite Feldelement, also auf 'feld [ 2 ]'. Nun wird der Inhalt von 'feld [ 2 ]' in 'var' gespeichert.
Damit sind beide Ausdrücke gleichwertig.
Bisher hatten sich sicher viel gefragt, wie man ganze Zeichenketten
oder auch Sätze in Variablen speichern kann. Wer schon andere Programmiersprachen
kennt, fragt sich, ob es nicht so etwas wie Strings, also Variablentypen
für Zeichenketten, gibt. Um hier mit einem Zitat zu antworten: Im
Prinzip schon, in der Praxis nein :-)
Strings und deren Erzeugung |
Es gibt zwei prinzipielle Arten Strings zu generieren.
/* String als Feld */
char zeichen [ ] = "hallo"; |
oder
/* String als Zeiger */
char *zeichen = "hallo"; |
Was machen nun beide Anweisungen ?
Wird ein String durch ein Feld erzeugt, so ist das generierte Feld gerade
so groß, damit der String hineinpaßt. Bei genauerer Betrachtung
ist das Feld aber 5+1 Zeichen groß.
Wieder ein Mysterium von C ? 5 Elemente für die 5 Buchstaben von
'hallo' - OK , wo aber kommt das 6. Element her ?
Dazu müssen wir uns anschauen, wie Zeichenketten intern gespeichert
werden.
Damit das System weiß, das der String zu Ende ist steht hinter
der Zeichenkette immer noch ein '\0'. Das ist ein sogenanntes Nullzeichen.
|
Wird ein String durch einen Zeiger erzeugt, so wird irgendwo im Speicher,der. Der Zeiger zeigt auf das erste Element des Strings. Auch hier wird mit einem Nullzeichen abgeschlossen.
Auch hier ein kleines Beispiel:
|
Als kleine Übung versuchen sie zu erklären, was passiert,
wenn sie folgendes kleines Programm starten würden. Mit dem bisher
gelernten, dürfte es zu schaffen sein:
|
Soviel erstmal zum Thema Zeiger, die Erste. Wir werden uns später weiterführend mit Zeigern beschäftigen. Aber da alles in kleinen verstehbaren Portionen zu genießen ist, soll es diesmal genügen.
Die Zeiger sind ein wesentlicher Bestandteil der Sprache C ! Es sollte
also auch nicht davor zurückgeschreckt werden, bei Unklarheiten mir
eine Mail zu schreiben, bzw. eine Nachricht im Pinboard unter C-Kurs /
C-Kurs-Talk zu schreiben.
...das Obligatorische |
Autor: Sebastian Cyris \ PCD Bascht
Dieser C-Kurs dient nur zu Lehrzwecken! Eine Vervielfältigung ist ohne vorherige Absprache mit dem Autor verboten! Die verwendete Software unterliegt der GPL und unterliegt der Software beiliegenden Bestimmungen zu deren Nutzung! Jede weitere Lizenzbestimmung die der benutzten Software beiliegt, ist zu beachten!