Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Pointer. Grundsätzliches: Im Arbeitsspeicher werden Daten gespeichert. Um auf die Daten eindeutig zugreifen zu können, werden diesen Daten Adressen zugeordnet.

Ähnliche Präsentationen


Präsentation zum Thema: "Pointer. Grundsätzliches: Im Arbeitsspeicher werden Daten gespeichert. Um auf die Daten eindeutig zugreifen zu können, werden diesen Daten Adressen zugeordnet."—  Präsentation transkript:

1 Pointer

2 Grundsätzliches:

3 Im Arbeitsspeicher werden Daten gespeichert. Um auf die Daten eindeutig zugreifen zu können, werden diesen Daten Adressen zugeordnet. Diese sind fest eingebrannt und können nicht durch ein Programm verändert werden. Verändert werden können nur die Daten.

4 Vergleich: Jedes Haus hat eine feste Adresse, die von einem Amt fest vorgegeben werden und vom Hauseigentümer nicht verändert werden dürfen. Nur die in jedem Haus wohnenden Menschen können geändert werden (z.B. Wohnungswechsel).

5 Man kann sich einen Arbeitsspeicher schematisch wie folgt vorstellen:

6 Ausschnitt aus einem Arbeitsspeicher AdresseWert 0... 1 2 3 4 Fest eingebrannte, unveränderliche Werte veränderliche Werte (die durch ein Programm geändert werden können). Wenn nichts anderes angegeben wird, besteht der Wert immer aus 1 Byte. Also ist 1 Byte die kleinste adressierbare Speichereinheit.

7 Durch die Deklaration einer Variable wird im Arbeitsspeicher an einer bestimmten Adresse Platz reserviert. Wird zusätzlich bei der Deklaration die Variable noch z.B. mit 5 initialisiert, bekommt der Wert an dieser Adresse 5 zugewiesen. Wird die Variable nicht initialisiert, ist der Wert an dieser Adresse unbestimmt (undefiniert).

8 Bitte folgendes Programm abschreiben

9 ... int x = 5; int *ptr; ptr = &x; *ptr = 13; 01235x... Programm- Ausschnitt Arbeitsspeicher - Ausschnitt Was veranlasst diese Anweisung im Arbeitsspeicher ? Es wird im Arbeitsspeicher an einer bestimmten Adresse Platz für eine integer-Zahl reserviert und die Zahl 5 der Variablen x zugewiesen. Auf die (Anfangs)Adresse dieses Speicherbereichs hat der Programmierer keinen Einfluß. Diese legt der Compiler bzw. Programmlader fest. AdresseWert

10 ... int x = 5; int *ptr; ptr = &x; *ptr = 13; 01235x... 04560815ptr... Programm- Ausschnitt AdresseWert Inhalt von Adresse von Deklaration eines Pointers: d.h. Wert von ptr ist eine Adresse Compiler speichert hier in Wirklichkeit die Variablen direkt hintereinander ab (Speicher wird nicht fragmentiert). Arbeitsspeicher - Ausschnitt Wert undefiniert: wir nehmen diesen Wert einfach mal an.

11 ... int x = 5; int *ptr; ptr = &x; *ptr = 13; 01235x... 04560815ptr... Programm- Ausschnitt AdresseWert Arbeitsspeicher - Ausschnitt

12 ... int x = 5; int *ptr; ptr = &x; *ptr = 13; 01235x... 04560123ptr... Programm- Ausschnitt AdresseWert Arbeitsspeicher - Ausschnitt

13 ... int x = 5; int *ptr; ptr = &x; *ptr = 13; 01235x... 04560123ptr... Programm- Ausschnitt 0123 AdresseWert Arbeitsspeicher - Ausschnitt

14 ... int x = 5; int *ptr; ptr = &x; *ptr = 13; 012313x... 04560123ptr... Programm- Ausschnitt 0123 AdresseWert Arbeitsspeicher - Ausschnitt

15 Ein Pointer ist eine Variable, deren Wert die Adresse eines Speicherplatzes (z.B.einer Variable) ist. Merke:

16 Ein Pointer ist also ein Verweis. Man sagt dazu auch Zeiger, Referenz, Link

17 Beispiel:

18 Bitte folgende Aufgabe 1 in Gruppen zu je zwei Leuten lösen (siehe Aufgabenblatt oder folgende Folie)

19 ... int a = 7; int b = 3; int c = 5; int *ptr; ptr = &a; a = a + b + c; 013507a... 024603b... 035705c... 0468004711ptr... Aufgabe: Welchen Wert hat *ptr nach Programmende ? Wert undefiniert: wir nehmen diesen Wert einfach mal an.

20 ... int a = 7; int b = 3; int c = 5; int *ptr; ptr = &a; a = a + b + c; 013507a... 024603b... 035705c... 0468004711ptr...

21 int a = 7; int b = 3; int c = 5; int *ptr; ptr = &a; a = a + b + c; 013507a... 024603b... 035705c... 0468001350ptr...

22 int a = 7; int b = 3; int c = 5; int *ptr; ptr = &a; a = a + b + c; 013507a... 024603b... 035705c... 0468001350ptr...

23 int a = 7; int b = 3; int c = 5; int *ptr; ptr = &a; a = a + b + c; 0135015a... 024603b... 035705c... 0468001350ptr... Welchen Wert hat *ptr 15 01350

24 Beispiel:

25 Bitte folgende Aufgabe 2 in Gruppen zu je zwei Leuten lösen (siehe Aufgabenblatt oder folgende Folie)

26 ... float e = 3.1; float f = 2.7; float *p; p = &e; *p = f +*p; 013503.1e... 024602.7f... 035700007p... Aufgabe: Welchen Wert hat e nach Programmende ? Wert undefiniert: wir nehmen diesen Wert einfach mal an.

27 ... float e = 3.1; float f = 2.7; float *p; p = &e; *p = f +*p; 013503.1e... 024602.7f... 035700007p...

28 float e = 3.1; float f = 2.7; float *p; p = &e; *p = f +*p; 013503.1e... 024602.7f... 0357001350p...

29 float e = 3.1; float f = 2.7; float *p; p = &e; *p = f +*p; 013503.1e... 024602.7f... 0357001350p... 01350 2.7 01350 3.1

30 ... float e = 3.1; float f = 2.7; float *p; p = &e; *p = f +*p; 013505.8e... 024602.7f... 0357001350p... Welchen Wert hat e 5.8 01350 2.7 01350 3.1

31 Pointer und Felder

32 ... int v[3] = {20,5,10};... 013820v[0] ?5v[1] ?10v[2]... Aufgabe: Wie heißen die Adressen von v[1] und v[2] Tipp: Debugger von Visual C++ benutzen

33 Bitte folgende Aufgabe 3 in Gruppen zu je zwei Leuten lösen (siehe Aufgabenblatt oder folgende Folie)

34 ... int v[3] = {20,5,10};... 013820v[0] 01425v[1] 014610v[2]...

35 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0 0 2 0 0 0 0 5 0 0 1 0 daß die Zahl 20 vier Byte, die Zahl 5 vier Byte und die Zahl 10 auch 4 Byte belegt... Die Darstellung rechts ist eine Abkürzung für die Darstellung links (folgt gleich) und bedeutet... 013820 01425 014610 int braucht 4 Byte. Wie die Zahlen (20 bzw. 5 bzw. 10) jeweils auf die 4 Byte verteilt wird, ist für uns uninteressant

36 Bitte Aufgabe 4 in Gruppen zu je zwei Leuten lösen (siehe Aufgabenblatt oder folgende Folie)

37 ... double d[3] = {3.1,2.7,6.2};... 01003.1d[0] ?2.7d[1] ?6.2d[2]... Aufgabe: Wie heißen die Adressen von v[1] und v[2] Tipp: Debugger von Visual C++ benutzen

38 ... double d[3] = {3.1,2.7,6.2};... 01003.1d[0] 01082.7d[1] 01166.2d[2]...

39 Ergebnis Die Adresse hängt von der Grösse des Datentyps ab.

40 Beispiel: Wie entwickeln sich die Werte (in der Tabelle) der folgenden Variablen dynamisch während des Programmablaufs ?

41 int v[3] = {10,20,30}; int *p,*q,*r; 013810v[0] 014220v[1] 014630v[2]... 04710815p 05900345 q p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3; *(r-2)= 50; q = r-2; 06340765 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); Werte undefiniert: wir nehmen diesen Wert einfach mal an.

42 013810v[0] 014220v[1] 014630v[2]... 04710138p 05900345 q *(r-2)= 50; q = r-2; 06340765 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3;

43 013810v[0] 014220v[1] 014630v[2]... 04710138p 05900345 q *(r-2)= 50; q = r-2; 06340765 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3;

44 013810v[0] 014220v[1] 014630v[2]... 04710138p 05900142 q *(r-2)= 50; q = r-2; 06340765 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3;

45 013810v[0] 014220v[1] 014630v[2]... 04710138p 05900142 q *(r-2)= 50; q = r-2; 06340765 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3;

46 013810v[0] 014220v[1] 014630v[2]... 04710138p 05900142 q *(r-2)= 50; q = r-2; 06340146 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3;

47 013810v[0] 014220v[1] 014630v[2]... 04710138p 05900142 q q = r-2; 06340146 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3; 0138 + 1 = 0139 *(r-2)= 50; Wo würde die 3 abgespeichert werden, wenn der Compiler so rechnen würde ? Schauen wir uns den Arbeitsspeicher genauer an...

48 0138v[0] 0139 v[1] 0140 0141 0142 q = r-2; 0143 *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3; 0138 + 1 = 0139 *(r-2)= 50; 0144 0145 0 0 1 0 0 0 2 0 Wo würde die 3 abgespeichert werden? Schauen wir uns den Arbeitsspeicher genauer an... int braucht 4 Byte. Wie die Zahl (10 bzw. 20) auf die 4 Byte verteilt wird, ist für uns uninteressant

49 0138v[0] 0139 v[1] 0140 0141 0142 q = r-2; 0143 *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3; 0138 + 1 = 0139 *(r-2)= 50; 0144 0145 0 0 1 0 0 0 2 0 ab der Adresse 0139 werden 4 Byte abgespeichert.

50 0138v[0] 0139 v[1] 0140 0141 0142 q = r-2; 0143 *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3; 0138 + 1 = 0139 *(r-2)= 50; 0144 0145 0 0 0 2

51 0138v[0] 0139 v[1] 0140 0141 0142 q = r-2; 0143 *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3; 0138 + 1 = 0139 *(r-2)= 50; 0144 0145 0 0 3 0 0 0 2 0 Es wird nicht ein Speicherblock, sondern (Teile) zweier Speicherblöcke (v[0] und v[1]) überschrieben: zwei Zahlen "beschädigt" (versaut) Deswegen rechnet der Compiler bei Adressrechnungen wie folgt..

52 013810v[0] 014220v[1] 014630v[2]... 04710138p 05900142 q q = r-2; 06340146 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3; 0138 + 1 *4 = 0142 *(r-2)= 50; !

53 013810v[0] 01423v[1] 014630v[2]... 04710138p 05900142 q *(r-2)= 50; q = r-2; 06340146 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3; 0138 + 1 *4 = 0142

54 Bitte diese angefangene Aufgabe (= Aufgabe 5 im Aufgabenblatt) vollends selbständig lösen.

55 013810v[0] 01423v[1] 014630v[2]... 04710138p 05900142 q *(r-2)= 50; q = r-2; 06340146 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3; 0146-2*4 = 0138

56 013850v[0] 01423v[1] 014630v[2]... 04710138p 05900142 q *(r-2)= 50; q = r-2; 06340146 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3;

57 013850v[0] 01423v[1] 014630v[2]... 04710138p 05900142 q q = r-2; 06340146 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3; *(r-2)= 50; // 0146-2*4=0138

58 013850v[0] 01423v[1] 014630v[2]... 04710138p 05900138 q *(r-2)= 50; q = r-2; 06340146 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3;

59 013850v[0] 01423v[1] 014630v[2]... 04710138p 05900138 q *(r-2)= 50; q = r-2; 06340146 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3; //*0138+*(0138+1 4)

60 013850v[0] 01423v[1] 014653v[2]... 04710138p 05900138 q *(r-2)= 50; q = r-2; 06340146 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3;

61 013850v[0] 01423v[1] 014653v[2]... 04710138p 05900138 q *(r-2)= 50; q = r-2; 06340146 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3;

62 013850v[0] 01423v[1] 014653v[2]... 04710146p 05900138 q *(r-2)= 50; q = r-2; 06340146 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3;

63 013850v[0] 01423v[1] 014653v[2]... 04710146p 05900138 q *(r-2)= 50; q = r-2; 06340146 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3; 0146-2 4=01380138+1 4=0142 0146

64 013850v[0] 01423v[1] 0146106v[2]... 04710146p 05900138 q *(r-2)= 50; q = r-2; 06340146 r *r = *p + *(q+1); p = r; *p = *p + *(q+1) + *(r-2); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3;

65 Noch ein paar Infos:

66 Der Wert eines Pointers wird mit %p ausgegeben. Siehe folgendes Beispiel:

67 int main (){ int zahl=5; int *ptr; ptr = &zahl; printf("Adresse=%p Inhalt=%d", ptr, *ptr); return 0; }

68 Warum macht das folgende Programm während der Laufzeit Probleme?

69 int main (){ int *ptr; *ptr = 4711; return 0; } Die Variable ist nicht initialisiert. Deshalb steht in ptr eine uns unbekannte Adresse. An dieser Adresse wurde aber kein Speicher reserviert. Deshalb könnte an dieser Adresse ein Teil des Betriebssystems stehen. Der Inhalt dieser Adresse ist also nicht reservierter Speicher. Auf diesen wird zugegriffen. Moderne Prozessoren merken dies und deshalb wird auf dem Bildschirm eine entsprechende Meldung ausgegeben. Konkretes Beispiel: Siehe nächste Folie!

70 int main (){ int *ptr; *ptr = 4711; return 0; } 0815 ptr... 0912... Teil des Syst. Betr. Wert undefiniert: wir nehmen diesen Wert einfach mal an. Was steht an der Adresse 0912 im Arbeitsspeicher ? Der Programmierer weiß es nicht, denn er hat an dieser Adresse keinen Speicherplatz reservieren lassen und diesen entsprechend belegt. In einem schlimmen Fall könnte an der Adresse 0815 zum Beispiel... ein Teil des Betriebssystems stehen !

71 int main (){ int *ptr; *ptr = 4711; return 0; } 0815 ptr... 0912... Wert undefiniert: wir nehmen diesen Wert einfach mal an. Was steht an der Adresse 0912 im Arbeitsspeicher ? Der Programmierer weiß es nicht, denn er hat an dieser Adresse keinen Speicherplatz reservieren lassen und diesen entsprechend belegt. In einem schlimmen Fall könnte an der Adresse 0815 zum Beispiel... ein Teil des Betriebssystems stehen ! 4 7 1 1


Herunterladen ppt "Pointer. Grundsätzliches: Im Arbeitsspeicher werden Daten gespeichert. Um auf die Daten eindeutig zugreifen zu können, werden diesen Daten Adressen zugeordnet."

Ähnliche Präsentationen


Google-Anzeigen