Kapitel 4: Zeiger - Lehrstuhl 11 Algorithm Engineering

 Documents

 21 views
of 19
All materials on our website are shared by users. If you have any questions about copyright issues, please report us to resolve them. We are always happy to assist you.
Description
Wintersemester 2005/06 Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr.…
Share
Transcript
Wintersemester 2005/06 Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich Informatik Lehrstuhl für Algorithm Engineering Kapitel 4: Zeiger Inhalt ● Zeiger ● Zeigerarithmetik Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 2 Kapitel 4: Zeiger Caveat! ● Fehlermöglichkeiten immens groß! ● Falsch gesetzte Zeiger  Rechnerabstürze! Aber: ● Machtvolles Konzept ● Deshalb genaues Verständnis unvermeidlich! ● Dazu müssen wir etwas ausholen ... Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 3 Kapitel 4: Zeiger ● Speicherplätzen sind fortlaufende Nummern (= Adressen) zugeordnet ● Datentyp legt Größe eines Datenobjektes fest ● Lage eines Datenobjektes im Speicher bestimmt durch Anfangsadresse ● Zeiger = Datenobjekt mit Inhalt (4 Byte) ● Inhalt interpretiert als Adresse eines anderen Datenobjektes Zeiger Datenobjekt Adresse Inhalt Adresse Inhalt 4711 32760 32760 Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 4 Kapitel 4: Zeiger Zeiger Datenobjekt Adresse Inhalt Adresse Inhalt 4711 32760 32760 Adresse Inhalt Adresse Inhalt des des des des Zeigers Zeigers Objekts Objekts Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 5 Kapitel 4: Zeiger Beispiel: Visitenkarte Hugo Hase X-Weg 4 X-Weg 42 2 Zeiger Objekt Inhalt: Adresse X-Weg 42 Inhalt: Hugo Hase Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 6 Kapitel 4: Zeiger Zeiger: Wofür? ● Zeiger weiterreichen einfacher als Datenobjekt weiterreichen ● Zeiger verschieben einfacher / effizienter als Datenobjekt verschieben ● etc. Datendefinition Datentyp *Bezeichner; → reserviert 4 Byte für einen Zeiger, der auf ein Datenobjekt vom Typ des angegebenen Datentyps verweist Beispiel ● double Umsatz; „Herkömmliche“ Variable vom Type double double *pUmsatz; Zeiger auf Datentyp double Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 7 Kapitel 4: Zeiger Was passiert genau? reserviert 8 Byte für Datentyp double; double Umsatz; symbolischer Name: Umsatz; Rechner kennt jetzt Adresse des Datenobjektes reserviert 4 Byte für einen Zeiger, double *pUmsatz; der auf ein Datenobjekt vom Type double zeigen kann; symbolischer Name: pUmsatz Umsatz = 122542.12; Speicherung des Wertes 122542.12 an Speicherort mit symbolischer Adresse Umsatz holt Adresse des Datenobjektes, pUmsatz = &Umsatz; das an symbolischer Adresse Umsatz gespeichert ist; speichert Adresse in pUmsatz indirekte Wertzuweisung: *pUmsatz = 125000.; Wert 125000. wird als Inhalt an den Speicherort gelegt, auf den pUmsatz zeigt Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 8 Kapitel 4: Zeiger Zwei Operatoren: * und & ● *-Operator: - mit Datentyp: Erzeugung eines Zeigers double *pUmsatz; - mit Variable: Inhalt des Ortes, an den Zeiger zeigt *pUmsatz = 10.24; ● &-Operator: ermittelt Adresse des Datenobjektes pUmsatz = &Umsatz; Wie interpretiert man Datendefinition richtig? Man lese von rechts nach links! double *pUmsatz; 1. pUmsatz ist … 2. Zeiger auf … 3. Typ double Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 9 Kapitel 4: Zeiger Initialisierung Sei bereits double Umsatz; vorhanden: double *pUmsatz = &Umsatz; oder int *pINT = NULL; oder Nullpointer! Symbolisiert Adresse, int *pINT = 0; auf der niemals ein Datenobjekt liegt! Verwendung Nullzeiger: Zeiger zeigt auf Nichts! Er ist „leer“! Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 10 Kapitel 4: Zeiger Beispiele: double a = 4.0, b = 5.0, c; c = a + b; double *pa = &a, *pb = &b, *pc = &c; *pc = *pa + *pb; double x = 10.; double y = *&x; Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 11 Kapitel 4: Zeiger Typischer Fehler ● double *widerstand; *widerstand = 120.5; Dem Zeiger wurde keine Adresse zugewiesen! Er zeigt also irgendwo hin: a) Falls in geschützten Speicher, dann Abbruch wg. Speicherverletzung!  b) Falls in nicht geschützten Speicher, dann Veränderung anderer Daten! Folge: Seltsames Programmverhalten! Schwer zu erkennender Fehler!  Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 12 Kapitel 4: Zeiger Unterscheidung ● Konstante Zeiger char *text = “Hallo“; Aber: Es gibt int feld[] = { 2, 3, 4 }; Compiler- zeigt auf feste Adresse im Speicher, spezifische auf die Programmierer nicht verändernd zugreifen kann! Unterschiede! text → H a l l o \0 feld → 2 3 4 int *const cpFeld = feld; v.r.n.l.: cpFeld ist constanter Zeiger auf Datentyp int Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 13 Kapitel 4: Zeiger Unterscheidung ● Veränderliche Zeiger double x = 2.0, y = 3.0, z = 7.0, s = 0.0, *ptr; ptr = &x; s += *ptr; ptr = &y; s += *ptr; ptr = &z; s += *ptr; ptr nimmt nacheinander verschiedene Werte (Adressen) an s hat am Ende den Wert 12.0 ptr x y z Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 14 Kapitel 4: Zeiger Zeigerarithmetik Sei T ein beliebiger Datentyp in der Datendefinition T *ptr; und ptr ein Zeiger auf ein Feldelement eines Arrays von Typ T Dann bedeutet: ptr = ptr + 1; oder ++ptr; dass der Zeiger ptr auf das nächste Feldelement zeigt. Analog: ptr = ptr – 1; oder --ptr; Zeiger ptr zeigt dann auf das vorherige Feldelement Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 15 Kapitel 4: Zeiger Zeigerarithmetik Achtung: T val; T *ptr = &val; ptr = ptr + 2; In der letzten Zeile werden nicht 2 Byte zu ptr hinzugezählt, sondern 2 mal die Speichergröße des Typs T. Das wird auch dann durchgeführt wenn ptr nicht auf Array zeigt. Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 16 Kapitel 4: Zeiger Zeigerarithmetik int a[] = { 100, 110, 120, 130 }, *pa, sum = 0; pa = &a[0]; sum += *pa + *(pa + 1) + *(pa + 2) + *(pa + 3); struct KundeT { Größe des Datentyps KundeT: double umsatz; float skonto; 8 + 4 = 12 Byte }; KundeT Kunde[5], *pKunde; pKunde = &Kunde[0]; Sei pKunde == 10000 int i = 3; *pKunde = *(pKunde + i); Dann(pKunde + i) == 10036 Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 17 Kapitel 4: Zeiger Zeigerarithmetik char *quelle = “Ich bin eine Zeichenkette“; char ziel[100] , *pz; // Länge der Zeichenkette Kommentar char *pq = quelle; while (*pq != ‘\0‘) pq++; int len = pq – quelle; if (len < 100) { // Kopieren der Zeichenkette Kommentar pq = quelle; pz = ziel; while (*pq != ‘\0‘) { *pz = *pq; pz++; pq++; } später! } *pz = ‘\0‘; Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 18 Kapitel 4: Zeiger Zeiger auf Datenverbund (struct) struct punktT { int x , y; }; punktT punkt[1000]; punktT *ptr = punkt; punkt[0].x = 10; ptr->x = 10; punkt[2].x = 20;  (ptr + 2)->x = 20; punkt[k].x = 100; (ptr + k)->x = 100; (*ptr).x ist identisch zu ptr->x Rudolph: EINI (WS 2005/06) ● Kap. 4: Zeiger 19
Related Search
We Need Your Support
Thank you for visiting our website and your interest in our free products and services. We are nonprofit website to share and download documents. To the running of this website, we need your help to support us.

Thanks to everyone for your continued support.

No, Thanks