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

Slides:



Advertisements
Ähnliche Präsentationen
Einführung in die Programmiersprache C/C++
Advertisements

Programme in C++.
Imperative Programmierung
Forschungszentrum caesar
der Universität Oldenburg
der Universität Oldenburg
Sequentielle Liste - Array
Christos, Kornelia, Jan Christos, Kornelia, Jan Entwicklungsumgebung Versteht unseren Java Programm Code Versteht unseren Java Programm.
Indirekte Adressierung
FH-Hof Indirekte Adressierung Richard Göbel. FH-Hof Einfache Speicherung von Daten Eine "einfache" Deklaration definiert direkt eine Speicherplatz für.
Das Halteproblem. Gibt es einen Algorithmus, mit dem man für jedes beliebig vorgegebene Programm R und für jede beliebig vorgegebene Eingabe E entscheiden.
Algorithmus. Ein Kochrezept, zum Beispiel: Kartoffelbrei.
SWITCH - Anweisung.
SWITCH - Anweisung.
Datentyp- umwandlung. Literale sind: Bezeichner mit einem festen Wert wie z.B:
Strukturen. In einer Struktur kann eine beliebige Anzahl von Komponenten (Daten) mit unterschiedlichen Datentypen (im Gegensatz zu Feldern) zusammengefaßt.
ARRAY oder FELD oder VEKTOR
Dynamischer Speicher. Ein Vergleich aus dem täglichen Leben...
Ein Beispiel in Java.
Dynamisches Array als "verkettete Liste". Ein Vergleich.
Dynamischer Speicher und Struktur
Pointer. Grundsätzliches: Im Arbeitsspeicher werden Daten gespeichert. Um auf die Daten eindeutig zugreifen zu können, werden diesen Daten Adressen zugeordnet.
Klassenvariable. Da man für jede Kuh bzw. jede Henne auf dem Markt den gleichen Preis für ein Liter Milch, bzw. den gleichen Preis für ein Ei bekommt,
Konstruktoren.
Objekte werden als Adressen (Referenzen) übergeben. Dies führt manchmal zu unerwarteten Ergebnissen...
Parameterübergabe von zweidimensionalen Feldern in Funktionen.
Polymorphie (Vielgestaltigkeit)
Assoziationen (Beziehungen). Zwischen Objekten kann es eine Beziehung geben.
Polymorphie (Vielgestaltigkeit)
Objekte und Arbeitsspeicher
V AdresseWert public static void main(...){ int[] v; v=new int[2]; } Was veranlasst diese Anweisung im Arbeitsspeicher ? Es wird im Arbeitsspeicher.
Interface bzw. Schnittstelle anschaulich: Hüllenklasse
FOR Anweisung.
Der Präprozessor. Bevor der Compiler das Programm in Maschinencode übersetzt (nur dieser kann von der CPU, dem Herz des Computers, bearbeitet werden)
Dynamischer Speicher. In einer Funktion wird z.B. mit der Deklaration int i; Speicher auf dem sogenannten Stack reserviert. Wenn die Funktion verlassen.
ARRAY oder FELD oder VEKTOR
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 5 Claudio Moraga; Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
EDV1 - Komplexe Datentypen
Wichtige Fachausdrücke in C
Programmieren mit MS Small Basic
Einführung in die Programmiersprache C 1
Informatik Grundlagen, WS04, Seminar 11
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 1 Algorithmen und Datenstrukturen SS 2005 Mag.Th. Hilpold u. Dr. A.Stritzinger Institut.
Programmierung 1. Einführung Seite 1
Variablenkonzept Klassisch, in Java Basistyp
Datenablage der Stadt Winterthur
Programmieren in C Grundlagen C 2
Hochschule Fulda – FB ET Sommersemester 2014
Paul, Morten, Yannick Blue J. Entwicklungsumgebung  versteht Java Programmcode  Für die Entwicklung eigener Software  Durch die Programmierung.
Polymorphie (Vielgestaltigkeit). Wenn eine Methode, wie z.B. print für verschiedene Programmteile steht (und z.B. einmal Objekte verschiedener Klassen.
early binding (frühe Bindung) late binding (späte Bindung)
Erweiterte Zuweisungskompatibilität. Wie kann man Objekte verschiedener Klassen einer Klassenhierarchie einander zuweisen ?
Pool Informatik, Sj 11/12 GZG FN W.Seyboldt 1 Pool Informatik 5 GZG FN Sj. 11/12 Kopieren, Daten, Programme.
Funktionen. Aufgabe : Eingabe zweier Zahlen ---> Minimum bestimmen Dann nochmals Eingabe zweier Zahlen ---> Minimum bestimmen.
Dynamisches Array als "verkettete Liste". Ein Vergleich.
Funktionen, Felder und Parameter- übergabe. Funktionsaufruf mit Feld als Parameter: Parameter = Name des Feldes.
Tutorium Software-Engineering SS14 Florian Manghofer.
Tutorium Software-Engineering SS14 Florian Manghofer.
Tutorium Software-Engineering SS14 Florian Manghofer.
Funktionen (Zweck und Eigenschaften) Funktionen sind Unterprogramme, die einen bestimmten Zweck erfüllen Sie zerlegen Probleme in kleine, abgeschlossene.
Strukturen (Eigenschaften) Strukturen dienen zur Zusammenfassung mehrerer Komponenten verschiedener Typen zu einer Einheit, die dann mit gemeinsamen Namen.
Konstruktoren.
Präsentation Binär.
ARRAY oder FELD oder VEKTOR
Dynamisches Array als "verkettete Liste"
Arrays in Java Ein Array ist eine Variable, die aus einer An-zahl von Elementen des gleichen Datentyps besteht, die aufeinanderfolgend im Speicher liegen.
Es gibt Klassen, die mit der Entwicklungsumgebung ausgeliefert werden
Arrays in C Ein Array ist eine Variable, die aus einer Anzahl von Elementen des gleichen Datentyps besteht, die aufeinanderfolgend im Speicher liegen.
Datentyp- umwandlung.
 Präsentation transkript:

Pointer

Grundsätzliches:

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.

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).

Man kann sich einen Arbeitsspeicher schematisch wie folgt vorstellen:

Ausschnitt aus einem Arbeitsspeicher AdresseWert 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.

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).

Bitte folgendes Programm abschreiben

... 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

... int x = 5; int *ptr; ptr = &x; *ptr = 13; 01235x ptr... 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.

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

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

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

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

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

Unterschied Pointer und " normaler " Wert im Arbeitsspeicher. Dazu ein Beispiel aus dem " Alltag " : Bei Absitzen einer Gefängnisstrafe muß sich eine Person ( " normaler " Wert) in der Zelle (Teil des Arbeitsspeicher) befinden. Es ist nicht zulässig, statt einer Person ( " normaler " Wert) eine Telefonnumer (Adresse) zu hinterlegen.

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

Beispiel:

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

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

... int a = 7; int b = 3; int c = 5; int *ptr; ptr = &a; a = a + b + c; a b c ptr...

int a = 7; int b = 3; int c = 5; int *ptr; ptr = &a; a = a + b + c; a b c ptr...

int a = 7; int b = 3; int c = 5; int *ptr; ptr = &a; a = a + b + c; a b c ptr...

int a = 7; int b = 3; int c = 5; int *ptr; ptr = &a; a = a + b + c; a b c ptr... Welchen Wert hat *ptr

Beispiel:

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

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

... float e = 3.1; float f = 2.7; float *p; p = &e; *p = f +*p; e f p...

float e = 3.1; float f = 2.7; float *p; p = &e; *p = f +*p; e f p...

float e = 3.1; float f = 2.7; float *p; p = &e; *p = f +*p; e f p

... float e = 3.1; float f = 2.7; float *p; p = &e; *p = f +*p; e f p... Welchen Wert hat e

Pointer und Felder

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

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

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

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 int braucht 4 Byte. Wie die Zahlen (20 bzw. 5 bzw. 10) jeweils auf die 4 Byte verteilt wird, ist für uns uninteressant. Falls es jemand interessiert (nächste Folie)

Dualdarstellung (als 4 Byte) von 20 ist: Das 1. Byte kommt nach... Das 2. Byte kommt nach... Das 3. Byte kommt nach... Das 4. Byte kommt nach... Aufgabe: Bestimmen Sie die restlichen Bytes dieser Tabelle

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

... double d[3] = {3.1,2.7,6.2}; d[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

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

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

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

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

013810v[0] v[1] v[2] p q *(r-2)= 50; q = r-2; 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;

013810v[0] v[1] v[2] p q *(r-2)= 50; q = r-2; 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;

013810v[0] v[1] v[2] p q *(r-2)= 50; q = r-2; 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;

013810v[0] v[1] v[2] p q *(r-2)= 50; q = r-2; 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;

013810v[0] v[1] v[2] p q *(r-2)= 50; q = r-2; 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;

013810v[0] v[1] v[2] p q q = r-2; 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; = 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...

0138v[0] 0139 v[1] 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; = 0139 *(r-2)= 50; 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

0138v[0] 0139 v[1] 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; = 0139 *(r-2)= 50; ab der Adresse 0139 werden 4 Byte abgespeichert.

0138v[0] 0139 v[1] 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; = 0139 *(r-2)= 50;

0138v[0] 0139 v[1] 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; = 0139 *(r-2)= 50; 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..

013810v[0] v[1] v[2] p q q = r-2; 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; *4 = 0142 *(r-2)= 50; !

013810v[0] 01423v[1] v[2] p q *(r-2)= 50; q = r-2; 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; *4 = 0142

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

013810v[0] 01423v[1] v[2] p q *(r-2)= 50; q = r-2; 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; *4 = 0138

013850v[0] 01423v[1] v[2] p q *(r-2)= 50; q = r-2; 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;

013850v[0] 01423v[1] v[2] p q q = r-2; 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; // *4=0138

013850v[0] 01423v[1] v[2] p q *(r-2)= 50; q = r-2; 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;

013850v[0] 01423v[1] v[2] p q *(r-2)= 50; q = r-2; r *r = *p + *(q+1); int v[3] = {10,20,30}; int *p,*q,*r; p = &v[0]; q = &v[1]; r = &v[2]; *(p+1)= 3; *4 0146

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

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

013850v[0] 01423v[1] v[2] p q *(r-2)= 50; q = r-2; 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;

013850v[0] 01423v[1] v[2] p q *(r-2)= 50; q = r-2; 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;

013850v[0] 01423v[1] v[2] p q *(r-2)= 50; q = r-2; 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;

013850v[0] 01423v[1] v[2] p q *(r-2)= 50; q = r-2; 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;  4=  4=

013850v[0] 01423v[1] v[2] p q *(r-2)= 50; q = r-2; 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;

Noch ein paar Infos:

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

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

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

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!

int main (){ int *ptr; *ptr = 4711; return 0; } 0815 ptr 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 0912 zum Beispiel... ein Teil des Betriebssystems stehen !

int main (){ int *ptr; *ptr = 4711; return 0; } 0815 ptr 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 !