Unsere Datenschutzrichtlinie wird in Kürze aktualisiert. Bitte sehen Sie sich die Vorschau an.

C++ Grundkurs

Zeiger

Testen Sie unsere 2016 Kurse

10 Tage kostenlos!

Jetzt testen Alle Abonnements anzeigen
Sämtliche Typen verfügen in C++ über einen zugehörigen Zeiger. Dieser enthält die Speicheradresse, an welcher sich Daten des Typs befinden.
09:08

Transkript

In dieser Lektion will ich Ihnen Zeiger in C++ genau vorstellen. Insbesondere will ich Ihnen zeigen, wie Sie Zeiger dereferenzieren können und Zeigerarithmetik betreiben können. Ich werde Ihnen aber auch zwei besondere Zeiger vorstellen, den sog. Null-Zeiger und den void-Zeiger. Zum Schluss zeige ich auch noch Zeiger auf Funktionen. Natürlich, was dann noch folgt, sind die Beispiele. Also für jeden Type T gibt es einen zugehörigen Typezeiger auf T. Der Zeiger enthält die Speicheradressen, in der sich die Daten befinden. Ein Zeiger ist eine gewisse Art von Indirektion. Ein Typ T wird durch das Sternchen zum Zeiger auf T. Ich habe hier ein kleines Beispiel. Ich habe hier eine Variable i vom Typ int mit dem Wert 20 initialisiert, und einen Zeiger auf diese Variable bekomme ich dadurch, dass ich einerseits mir Adresse von dem i hier schnappe und andererseits mir einen Zeiger auf Adresse erzeuge. Das ist ein Zeiger auf int. Der Unteroperator ermittelt die Adresse der Variablen. In diesem Fall die Adresse von einer Variablen int. Genau das ist der Wert, den der Zeiger benötigt. Wichtig ist zu wissen, ein Zeiger kann nur auf die Adresse eines gleichen Typs gesetzt werden. Ich habe hier ein int und ich habe hier einen Zeiger auf int, int, Zeiger auf int, haben den zugrundeliegenden gleichen Typ. Was kann man mit Zeigern anstellen? Man kann sie natürlich dereferenzieren. D. h., man kann sich den Wert, der dem Zeiger zugrunde liegt, anschauen oder auch modifizieren. Das geschieht durch das, dass Sie ein Sternchen voranstellen. Noch ein Beispiel. Das Beispiel von vorher ein bisschen ausgebaut. int i = 20, das kennen Sie, durch Adresse von i bekommen Sie die Adresse von i und können somit auch den Zeiger i-Pointer initialisieren. Dadurch dass Sie jetzt hier das Sternchen anwenden, wird der Pointer - auf Deutsch Zeiger - wiederum dereferenziert und Sie können den Wert einer Variablen j zuweisen. Hier sehen Sie den ganzen Vorgang. Sie fangen bei i an, neuer Wert, gehen zum Zeiger und kommen wieder zurück zum Wert. Da gehe ich noch ein bisschen auf die Zeigerarithmetik ein. Es gibt eine enge Verwandtschaft von Zeigern und C-Arrays in C++. Das sehen Sie hier. Ich habe hier ein C-Array, das ich mit fünf Werten initialisiert habe, über eine sog. Initialisiererliste und wenn ich auf das dritte Element zugreifen will, 0, 1, 2, 3, Sie wissen, Arrays beginnen mit dem Index 0, dann ist das das Gleiche wie wenn ich sage, intArray + 3. D. h., ich schnappe mir die Adresse von intArray, addiere 3 hinzu und lande dann, nachdem ich es dereferenziert habe, mit diesem Sternchen an der 4. Weiter geht es mit einem dieser zwei besonderen Zeiger. Der erste besondere Zeiger ist der void-Zeiger. Der kann auf beliebige Daten verweisen. Ich habe hier eine Instanz eine Klasse Circle c, habe hier einen void-Pointer, der noch keinen Wert hat, der uninitialisiert ist. Jetzt kann ich mir die Adresse von meiner Instanz c schnappen und sie dem void-Pointer p zuweisen, und damit verweist p auf die Instanz c. Es gibt noch etwas Besonderes. Wenn Sie einen void-Pointer auf einen Zeiger eines anderen Typs verweisen lassen wollen, müssen Sie einen expliziten Cast ausführen. Das zeige ich hier mit einem C++ Cast, einem sog. static_cast, der zur Compilezeit ausgeführt wird. Wieder mein Circle c. D. h., ich instanziiere ein Objekt von der Klasse Circle und kann diesem Objekt die Adresse von p zuweisen. Diese Syntax ist hier ein bisschen hart zu lesen. Hier habe ich meinen Zeiger p. Ich caste p zu einem Pointer auf Circle und das mache ich dadurch, dass ich einen static_cast anwende. Jetzt zeige ich Ihnen auch noch den nächsten besonderen Zeiger, den sog. Null-Zeiger oder auch Null-Pointer. Den gibt es erst mit modernem C++, sprich mit C++11. D. h., Zeiger beliebigen Typs kann dem Null-Pointer zugewiesen werden. Damit wird der Zeiger zum Null-Zeiger. Das Besondere ist, dieser Zeiger verweist dann auf kein Datum, auf keinen Wert und lässt sich auch nicht dereferenzieren. Null-Pointer können mit allen Zeigern verglichen werden und in allen anderen Zeigern implizit konvertiert werden. Implizit heißt, der Compiler macht das automatisch. Hier kommt der wichtige Punkt, wieso es den Null-Pointer gibt. Er kann in keinen integralen Typ wie short, int, long long implizit konvertiert werden. Das konnten Sie früher mit der Null und das war sehr typunsicher. Der Compiler kann ihn aber in einen Boolwert implizit konvertieren. Null-Pointer können in logischen Ausdrücken verwendet werden. Hier habe ich einen Null-Pointer. Sie sehen, wie ich ihn initialisiere. Das ist ein Zeiger auf int, initialisiert auf Null, beim Null-Pointer. Jetzt kann ich sagen, wenn du ungleich 0 bist, will be called. So kann ich das sicherstellen, dass ich diese Funktionalität nur aufrufe, wenn a auch wirklich auf einen vernünftigen Wert weist. Jetzt noch zur letzten Art von Zeigern, Zeiger auf Funktionen. Wie der Name schon sagt, es ist ein Zeiger, der auf eine Funktion verweist. Der Typ des Zeigers leitet sich von der Signatur und dem Rückgabetyp der Funktion ab. Die Signatur einer Funktion sind die Typen, die sie der Funktion übergeben, und der Name der Funktion und der Rückgabetyp ist das void hier. Was macht die Funktion? Sie nimmt eine Referenz auf x an und addiert 1 dazu. Genau das, was sie verspricht, addOne. Jetzt zeige ich Ihnen ein paar Variationen. Hier in rot sehen Sie die Zeiger, die ich definiere. Erst in der umständlichen, klassischen Syntax und dann in der neuen moderneren Syntax. In der umständlichen Syntax definiere ich hier einen Zeiger inc1. So heißt dieser Zeiger. Der nimmt eine Integerreferenz an und gibt ein void zurück. Das sehen Sie hier. Die Integerreferenz entspricht dieser Integerreferenz hier oben, void entspricht dem void hier oben. Diesen Zeiger, den habe ich hier nur einen Namen gegeben, den initialisiere ich durch addOne. D. h., er verweist auch auf die Funktion addOne. Das geht viel einfacher, indem ich hier einfach auto hinschreibe. Da leitet der Compiler aus der Signatur von addOne und dem Rückgabetyp von addOne den richtigen Typ von inc2 ab, und das war es. Hier noch eine kleine Anwendung. Hier habe ich eine Variable a vom Typ int. Es ist egal, ob ich jetzt addOne (a) aufrufe, inc1 (a) aufrufe, inc2 (a) aufrufe. inc1 und inc2 sind Zeigerfunktionen. Das ist die Funktion. Es kommt immer 11 raus. Das Ganze will ich Ihnen jetzt noch gerne in der Anwendung zeigen. Das ist die Funktion addOne, die ich Ihnen gerade gezeigt habe. Da gehe ich mit Ihnen von oben bis unten alles durch. Hier habe ich eine Variable i vom Typ int. Der weise ich den Wert 2011 zu. Sie sehen, wenn ich mir die Adresse von i schnappe, kann ich damit den Zeiger auf int deklarieren und gleich den Wert zuweisen, also auch definieren. Hier sehen Sie, hier gebe ich den Wert aus. Erst den Wert des Zeigers und dann den Wert der zugrundliegenden Variablen. Das sehen Sie genau hier. Sie sehen, das ist der Zeiger. Sie sehen, wenn ich den Zeiger dereferenziere, wenn ich sozusagen die Interaktion auflöse, dann habe ich den Wert. Das ist tatsächlich die Adresse eines Speicherbereiches. Ein bisschen weiter im Text. Jetzt erkläre ich nochmal einen Zeiger: jptr habe ich ihn genannt. Diesem Zeiger weise ich die Adresse von meinem Zeiger hier oben vom iptr zu. Was ich jetzt mache, jetzt verändere ich nicht den Zeiger, sondern den den Wert, auf den jptr zeigt. Da jptr auf die gleiche Speicheradresse zeigt wie iptr, verändern sich beide Werte. Sie sehen, beide Zeiger zeigen noch auf den Wert von iptr. Hier ist die gleiche Adresse wie hier. Ist die gleiche Adresse wie hier. Aber der Wert der zugrundliegenden Variablen hat sich von 2011 auf 2014 geändert. Noch ein kleines Beispiel zur Zeigerarithmetik. Hier habe ich ein intArray initialisiert mit 5 Werten über eine Initialisierungsliste. Jetzt kann ich auf das dritte Element des intArrays auf zwei Arten zugreifen. Erstens indem ich mir den dritten Index schnappe. Das ist das Gleiche, wie wenn ich sage, intArray + 3, und dann dereferenziere ich diesen Zeiger, den ich da erhalte. Zum Schluss noch der Null-Pointer und meine Funktionszeiger. Null-Pointer: sehen Sie, was hier passiert. Ich kann Null-pointer verwenden, um einen beliebigen Zeiger, in diesem Fall einen Zeiger auf int zu initialisieren. Ich kann damit keine Variable initialisieren. Das erlaubt C++ nicht, weil es eben nicht implizit nach Integer konvertierbar ist. Aber ich kann ein Bool damit initialisieren. Das geht. Wenn ich jetzt wieder std::boolalpha sage, bekomme ich schön ein Ergebnis. D. h., mein b hat den Wert false. D. h., ein Null-Pointer hat per Default den Wert false. Jetzt noch ein bisschen Zeigerarithmetik. Da zeige ich Ihnen das, was ich vorher schon in der Theorie beschrieben hatte. Meine Funktionszeiger inc1, den ich auf eine Funktion addOne verweisen lasse. Das Gleiche mit der automatischen Typableitung mittels auto addOne ist der zweite Funktionszeiger. Jetzt rufe ich einfach sowohl die Funktion wie auch die zwei Funktionszeiger auf. Sie sehen hier addOne ergbit 11, inc1 ergibt 12, inc2 ergibt 13. Da werde ich natürlich immer um eins größer, weil ich erstens von 10 ausgehe und zweitens die Funktion addOne ihr Argument per Referenz annimmt. In dieser Lektion habe ich Ihnen Zeiger vorgestellt. Insbesondere habe ich Ihnen gezeigt, wie Sie Zeiger dereferenzieren und Zeigerarithmetik betreiben können. Ich habe Ihnen zwei besondere Zeiger - Null-Zeiger und Void-Zeiger - vorgestellt und ich habe Ihnen auch noch Zeiger auf Funktionen vorgestellt.

C++ Grundkurs

Steigen Sie in die mächtige Programmiersprache C++ ein und lernen Sie dabei alle wichtigen Funktionen mit Anwendungsbeispielen kennen.

8 Std. 14 min (147 Videos)
Derzeit sind keine Feedbacks vorhanden...
 

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!