Tutorium Software-Engineering SS14 Florian Manghofer
Zeiger (Pointer) Was ist ein Zeiger? Ein Zeiger ist eine Variable, die die Adresse einer andere Variable enthält. Wie macht man einen Zeiger? int *zeiger; // * ist „der Operator“ für einen Zeiger, Dereferenzierungsoperator Wie lasse ich den Zeiger auf etwas zeigen? int x = 3; int *zeiger;//Ein Zeiger muss den selben Datentyp haben zeiger = &x;//wie die Variable, auf der er zeigen soll Was macht jetzt das & ? & ist der Referenzierungsoperator/Adressoperator, er gibt die Adresse einer Variablen zurück Was passiert wenn ich das & weglasse? Geht nicht! Es wird versucht einen Wert (3) in einer Adresse zu speichern. Oder: Es wird versucht einen Integer(3) in einem „Datentyp Adresse“ zu speichern. String in int kann man ja auch nicht machen!
Zeiger (Pointer) Was gibt mir cout << zeiger; aus? z.B: 0x28ff44 (Adresse) Wieso ist das nicht 3? Ein Zeiger speichert die Speicheradresse einer Variablen auf die er zeigt. Somit wird hier die Speicheradresse von x ausgegeben. Und wie gebe ich nun über den Zeiger den Wert von x aus? int x = 3; int *zeiger; zeiger = &x; cout << *zeiger; //Wert der Variablen, auf die zeiger zeigt (nicht Adresse) Wieso brauche ich hier schon wieder ein *? Weil sonst der „Wert“ von zeiger ausgegeben wird(Adresse von x), und nicht der Wert. *zeiger sagt hier, hole den Wert von der Variablen die an der Adresse zeiger steht.
Zeiger (Pointer) Adresse der Variable Name der Variable Adresse des Zeigers Name des Zeigers Wert der Variable Wert des Zeigers Variablen speichern Werte! Zeiger speichern Adressen!
Zeiger (Pointer) Wie war das nochmal mit Werten und Adressen von Zeiger und Variable? Adresse von x: cout << zeiger; | cout << &x; Wert von x: cout << *zeiger; | cout << x; Adresse von zeiger: cout << &zeiger; Was hat es mit Felder und den Zeigern auf sich? Der Name des Arrays ist eigentlich ein Zeiger auf das erste Feldelement. int zahlen[] = {1,2,3}; cout << zahlen;//Adresse des Feldes cout << *zahlen; //Wert des ersten Feldelements cout << zahlen[0];//Wert des ersten Feldelements cout << &zahlen[1]//Adresse des 2ten Feldelements int *zeiger = zahlen; //Zeiger zeigt auf das erste Feldelement cout << zahlen[2];//Wert des dritten Feldelements cout << zeiger[2]; //Wert des dritten Feldelements
Zeiger (Pointer) Gibt’s Zeiger auch als Parameter oder return Wert? Ja, funktioniert wie gewohnt: void hallo(int*);//Prototyp … void hallo(int *x){ cout << x;//Adresse von x ausgeben cout << *x;//Wert von x ausgeben } int* eins();//Prototyp … int* eins(){ int x = 3; int *p = &x; return p;//“Adresse“ des Zeigers zurückgeben }
Zeiger (Pointer) Schön und gut, aber was bringen mir Zeiger außer Verwirrung und mehr Variablen? Ohne Zeiger (wie gewohnt):Mit Zeiger (neu): Ausgabe:
Zeiger (Pointer) Wieso ist das so?? Aufruf mit (a,b) swap() arbeitet mit einer Kopie von a und b, bzw. mit dessen Werten x = b y = a Swap() hat fertig, aber x und y nicht mehr sichtbar… Es wurde nicht getausch!
Zeiger (Pointer) Wieso ist das so?? Zeiger Aufruf mit Zeigern(Call by Reference) swap() arbeitet mit Zeigern, die jeweils auf a und b zeigen. Wert speichern Werte tauschen Wert zuweisen a=9 b=1
Zeiger (Pointer) Referenz = besondere Art von Zeiger, die es ermöglicht, es wie ein reguläres Objekt einzusetzen Syntax: Typ &name Bsp.:int x = 10;//normale Variable int &ref = x;//!!Referenzen müssen bei Deklarierung //initialisiert werden!! cout <<ref;//10 (Behandlung wie normale Variable) ref = 20; cout << x;//20 (Da ref auf x referenziert) (Vorstellbar als: Referenz ref ist mit x verbunden. Wenn ich den Wert von ref ändere, ändert sich auch der Wert von x.)