Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 5 Claudio Moraga; Gisbert Dittrich FBI Unido

Ähnliche Präsentationen


Präsentation zum Thema: "EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 5 Claudio Moraga; Gisbert Dittrich FBI Unido"—  Präsentation transkript:

1 EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 5 Claudio Moraga; Gisbert Dittrich FBI Unido

2 Kap 5: ZeigerVorl EINI-I" Gliederung Kapitel 5 Zeiger –Grundbegriffe –Zeiger und Felder –Beispiel: Zeichenketten –Funktionen als Parameter –Mehrdimensionale Felder

3 Kap 5: ZeigerVorl EINI-I" Variable hat: –Namen –Typ u.a. Wertebereich, aus dem Werte angenommen werden –Wert (aus dem Wertebereich oder "undefiniert") ist realisiert im Speicher durch: –Speicherplatz, der hat : Adresse Anmerkung: Nicht immer alle Angaben verfügbar !

4 Kap 5: ZeigerVorl EINI-I" Variable Anmerkungen: –Adresse: Eindeutiger Identifikator des Speicherplatzes –Größe des Speicherplatzes abhängig vom Typ der Variablen. –Bildliche Darstellungen: oder auch: Wert Adresse Name Typ nicht explizit angegeben ! Wert Adresse Name -99 B 123 Beispiel: Speicherplatz

5 Kap 5: ZeigerVorl EINI-I" Grundbegriffe Zeiger Neu: Adressen können jetzt Werte von Variablen sein !! (Typisiert!) Zeiger: –Vereinbarung: T *var ; –var ist Variablenname, der Adressen von Variablen vom Typ "T" annimmt. Typ int -99 B var Beispiel:

6 Kap 5: ZeigerVorl EINI-I" Grundbegriffe Zeiger -99 B var Beispiel: Gängige alternative Darstellung: -99 B var Beispiel: -99 B 1230 var -99 B var -99 var -99 B 1230 var Beispiel:

7 Kap 5: ZeigerVorl EINI-I" Grundbegriffe Zeiger Sei var Variablenname: &var liefert die Adresse von var Sei wo Name eines Zeigers (Speicherreferenz), so liefert *wo die Variable, auf die wo zeigt. Referenzen sind typisiert: es wird angegeben, welcher Typ sich hinter einer Adresse verbirgt (z. B. Referenz auf einen Wert vom Typ int ).

8 Kap 5: ZeigerVorl EINI-I" Beispiele &k ist die Adresse der ganzen Zahl k, t ist als Zeiger auf eine Variable vom Typ float definiert, beinhaltet also eine Adresse adr einer derartigen Variablen *t = speichert damit den Wert unter dieser Adresse adr int k; float *t;

9 Kap 5: ZeigerVorl EINI-I" Beispiele Definiert seien int A=1, B=-99; Nach ZeigerA = &A hat ZeigerA also als Wert die Adresse der Variablen A : -99 B 1 A ZeigerA int *ZeigerA, *ZeigerB; D.h.: die Variablen ZeigerA und ZeigerB enthalten Adressen ganzer Zahlen. ZeigerBZeigerA

10 Kap 5: ZeigerVorl EINI-I" Beispiele (Forts.) -99 B A ZeigerA Nach *ZeigerA = B enthält der Speicherplatz, dessen Adresse ZeigerA ist, den Wert von B, also: -99 B 1 A ZeigerA Situation nach: B = B * B; 9801 B -99 A ZeigerA ZeigerB ZeigerB = &B; *ZeigerA = *ZeigerB; 9801 B A ZeigerA Es gilt *ZeigerA == 1

11 Kap 5: ZeigerVorl EINI-I" Merke *ZeigerA spricht den Speicherplatz an, auf den ZeigerA zeigt: weil ZeigerA eine Referenz ist, gibt *ZeigerA den Inhalt dieser Referenz an (man spricht von Dereferenzieren: von der Referenz/Adresse zum dadurch bez. Speicherplatz übergehen) &B auf der linken Seite einer Zuweisung ist illegal: die Adressen werden von Compiler oder vom Laufzeitsystem gesetzt, aber nicht vom Benutzer

12 Kap 5: ZeigerVorl EINI-I" Vertausche zwei Werte Was geschieht in Tausch ? void Tausch (int a, int b) { int temp; temp = a; a = b; b = temp; } Der Tausch bleibt lokal auf die Funktion beschränkt (wg. call by value) Beispiel

13 Kap 5: ZeigerVorl EINI-I" Beispiel Was geschieht in AdrTausch ? void AdrTausch(int *p, int *q) { int temp; temp = *p; *p = *q; *q = temp; } temp nimmt den Inhalt von * p auf Der Inhalt von * q wird als Inhalt von * p gespeichert Der Inhalt von * q ist der in temp gespeicherte Wert

14 Kap 5: ZeigerVorl EINI-I" Beispiel (Bildchen) 30 p -121 q undef temp temp = *p; *p = *q; Dadurch ist sog. call by reference möglich *q = temp; 30 p -121 q 30 temp -121 p q 30 temp -121 p 30 q temp

16 Kap 5: ZeigerVorl EINI-I" void Tausch (int a, int b) { int temp; temp = a; a = b; b = temp; } void AdrTausch (int *p, int *q) { int temp; temp = *p; *p = *q; *q = temp; } Ausführen

17 Kap 5: ZeigerVorl EINI-I" Felder und Zeiger Sei deklariert int a[10], x, *pa; Dann: pa = &a[0] setzt pa als Zeiger auf das erste Element von a x = *pa würde also a[0] nach x kopieren.

18 Kap 5: ZeigerVorl EINI-I" Felder und Zeiger pa+1,..., pa+9 zeigen auf die Elemente a[1],...,a[9] –es gilt also *(pa+i) = a[i] für i = 0,..., 9 Allgemein: ist deklariert T *p;(p ist also ein Zeiger auf Elemente vom Typ T ), dann bezeichnet p+i das Element vom Typ T, das von p um i*sizeof(T) entfernt liegt.

19 Kap 5: ZeigerVorl EINI-I" Felder und Zeiger pa ist eine Zeiger-Variable, a ist ein Feld mit Elementen vom Typ int, also sind z. B. a=pa, a++ illegal. Bei Funktionsaufrufen werden Felder als aktuelle Parameter als Zeiger auf das jeweils erste Element interpretiert! Damit erklärt sich, daß Kopiere korrekt funktioniert.

20 Kap 5: ZeigerVorl EINI-I" Felder und Zeiger void strcpy (char nach[ ], char von[ ]) { int i = 0; while ((nach[i] = von[i]) ! = '\0') i++; } Kopiert bekanntlich die Zeichenkette von in die Zeichenkette nach. Die Zeichenketten werden als Felder dargestellt.

21 Kap 5: ZeigerVorl EINI-I" Felder und Zeiger void strcpy (char *s, *t) { while ((*s++ = *t++) ! = '\0' ); } *s++ dereferenziert s und schaltet die Adresse dann um sizeof(char) weiter [also zu lesen (*s)++ ].

22 Kap 5: ZeigerVorl EINI-I" Felder und Zeiger merke: ( *s++ = *t++) ! = '\0' liefert den Wert 0, falls das Ende der Zeichenkette t erreicht ist (dann soll ja auch die while -Schleife abbrechen) die eigentliche Arbeit findet in dieser Zuweisung statt, daher ist der Anweisungsblock in der while -Schleife leer.

23 Kap 5: ZeigerVorl EINI-I" Vergleich von Zeichenketten Sind a und b Zeichenketten, so soll der ganzzahlige Wert strcmp(a, b) den lexikographischen Vergleich von a und b ermöglichen. Es soll gelten: –strcmp(a, b) ist negativ, wenn a kleiner als b ist, –strcmp(a, b) ist Null, wenn a gleich b ist, –strcmp(a, b) ist positiv, wenn a größer als b ist,

24 Kap 5: ZeigerVorl EINI-I" Vergleich von Zeichenketten int strcmp (char *s, char *t) { int k = 1; for (;*s == *t; s++, t++) if (*s == '\0') k = 0; if (k > 0) k = (*s - *t); return k; } Die Zeichenketten werden durchlaufen, solange sie identische Zeichen haben tritt dabei das Ende einer Kette auf, sind sie identisch sonst wird die Differenz berechnet

25 Kap 5: ZeigerVorl EINI-I" Vergleich von Zeichenketten Version mit Feldern int strcmp (char s[], char t[]) { int i = 0, k = 1; while (s[i] == t[i]) if (s[i++] == '\0') k = 0; if (k > 0) k =(s[i] - t[i]); return k; } Felder und Zeiger

26 Kap 5: ZeigerVorl EINI-I" // K5-P2: Zeiger und Felder // // Demonstriert Zeiger und Felder // #include main(){ int v1[10]; int i; // Feld v1 initialisieren cout << "ursprüngliches Feld v1:\n"; for (i=0;i<10;i++) { v1[i] = i; cout << v1[i] << " "; }

27 Kap 5: ZeigerVorl EINI-I" cout << "\n\n" << "kopiertes Feld z1:\n"; // kopieren und Ausgabe ueber Zeiger int *z1; z1 = v1; for (i=0;i<10;i++){ cout << *z1 << " "; z1=z1+1; } cout << '\n'; } Ausführen

28 Kap 5: ZeigerVorl EINI-I" v1... int v1[10]; int *z1; z1 z1 = v1; Zur Erinnerung v1... Adr. v1[0] v1[9] z1 = z1+1;

29 Kap 5: ZeigerVorl EINI-I" #include main(){ int v1[10]; int i; cout << "ursprüngliches Feld v1:\n"; for (i=0;i<10;i++) { v1[i] = i; cout << v1[i] << " "; } cout << "\n\n" << "kopiertes Feld z1:\n"; int *z1; z1 = v1; for (i=0;i<10;i++){ cout << *z1 << " "; z1=z1+1; } cout << '\n'; } // Feldname als Zeiger

30 Kap 5: ZeigerVorl EINI-I" Funktionen als Parameter In C++ nicht direkt möglich. Wohl aber: Übergabe eines Zeigers auf eine Funktion Zeiger auf Funktionen Beachte: int (*f)() im Vergleich zu int *f(): int (*f)(): Zeiger auf eine Funktion ohne Argumente mit Rückgabe Wert int int *f(): Funktion ohne Argument, die einen Zeiger auf int zurückgibt

31 Kap 5: ZeigerVorl EINI-I" Zeiger auf Funktionen; Namen von Funktionen Funktionsname Speicherbereich, wo das Programm der Funktion abgespeichert ist Adr. BspFunktion char BspFunktion(char, char); // Funktionsprototyp char (*z)(char, char); z z = BspFunktion; cout << (*z)(A, B) << endl; // Funktionsaufruf über z // Übergabe der Adresse der Funktion // Zeiger auf Funktion gleicher Art

32 Kap 5: ZeigerVorl EINI-I" #include int max(int x, int y){ int min(int x, int y){ int k ; if (x > y) k = x; if (x < y) k = x; else k = y; return k; } main ( ) { int a = 1936, b = 6391; int (*f)(int, int); //Zeiger auf Funktion while(1) { char c; cout <<"(max = 1),(min = 0),(abbruch = sonst)?\n"; cin >> c; if (c == '1') f = max; //Zuweisung von max else if (c == '0') f = min; //Zuweisung von min else break; cout << (*f)(a,b) << '\n';}}

33 // Zeiger auf Funktionen // // Demonstriert Zeiger auf Funktionen // #include int sum1(int); int sum2(int); int Summiere(int (*f)(int)); main() { cout << "\terste Summe: " << Summiere(sum1) << "\n\n"; cout << "\tzweite Summe: " << Summiere(sum2) << endl; } // Funktionsprototypen

34 Kap 5: ZeigerVorl EINI-I" int sum1(int n) { int i, s = 0; for(i = 0; i < n; i++) s = s + 1; return s; } int sum2(int n) { int i, s = 0; for(i = 0; i < n; i++) s = s - 2; return s; } int Summiere(int (*f)(int)) { int lauf, sum=0; for (lauf = 0; lauf < 7; lauf++) { cout << "(*f)(" << lauf << ") = " << (*f)(lauf) << endl; sum = sum + (*f)(lauf); } return sum; } Ausführen

35 Kap 5: ZeigerVorl EINI-I" Mehrdimensionale Felder In C++ sind mehrdimensionale Felder möglich (Details später). Beispiel: int matrix [3][7] –beschreibt eine Matrix mit drei Zeilen und sieben Spalten, deren Elemente vom Typ int sind, –Beachte: int matrix [3][7] beschreibt 7 Elemente vom Typ int matrix [3]. –int matrix [3, 7] ist in C++ syntaktisch nicht legal.


Herunterladen ppt "EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 5 Claudio Moraga; Gisbert Dittrich FBI Unido"

Ähnliche Präsentationen


Google-Anzeigen