1 / 37

Zeiger bei Matrizen

Einführung in die Programmiersprache C 4.Tag Institut für Mathematische Optimierung - Technische Universität Braunschweig. Zeiger bei Matrizen. Es kann nötig sein, eine Matrix zu kopieren, um bei Veränderungen noch auf die Originaldaten zurückgreifen zu können. Das geht nicht so:

kemp
Download Presentation

Zeiger bei Matrizen

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Einführung in die Programmiersprache C4.TagInstitut für Mathematische Optimierung -Technische Universität Braunschweig

  2. Zeiger bei Matrizen Es kann nötig sein, eine Matrix zu kopieren, um bei Veränderungen noch auf die Originaldaten zurückgreifen zu können. Das geht nicht so: double **mat,**copy; ... copy=mat; Hier werden nicht die Inhalte der Matrix kopiert, sondern nur der Zeiger auf den Beginn des Speicherbereichs. Veränderungen von Einträgen von mat führen auch zur Veränderung der Einträge von copy. Institut für Mathematische Optimierung – Technische Universität Braunschweig

  3. Zeiger bei Matrizen Institut für Mathematische Optimierung – Technische Universität Braunschweig

  4. Andere Operationen Sollen hingegen zwei Matrizen oder Zeilen von Matrizen getauscht werden, so können auch nur die Zeiger getauscht werden: double **mat; **copy, **temp1, *temp2; ... temp1 = mat; mat = copy; copy = temp1; ... temp2 = mat[17]; mat[17] = mat[43]; mat[43] = temp2;

  5. Lösung Die Inhalte müssen elementweise kopiert werden. Dabei müssen die Matrixdimensionen jeweils gleich sein und Speicher für beide Matrizen besorgt werden: double **mat, **copy; mat=alloc_matrix(zeilen,spalten); copy=alloc_matrix(zeilen,spalten); for... for... copy[i][j]=mat[i][j]; Institut für Mathematische Optimierung – Technische Universität Braunschweig

  6. Speicher für Matrizen freigeben Der für Matrizen besorgte Speicher muss iterativ wieder freigegeben werden: voidfreeintmatrix(int **matrix, intzeile) { int i; for(i=0;i<zeile;i++) free(matrix[i]); free(matrix); } Institut für Mathematische Optimierung – Technische Universität Braunschweig

  7. Aufgabe Schreiben Sie zwei Funktionen, die dynamisch Speicher reservieren und diesen zurückgeben. Eine Funktion soll dabei Speicher für ein eindimensionales Feld (array) freigeben und die andere Speicher für ein mehrdimensionales Feld (Typ Matrix). Implementieren Sie außerdem eine Funktion, die den für mehrdimensionale Felder besorgten Speicher wieder freigibt. Überlegen Sie hierbei welche Parameter Sie den Funktionen übergeben müssen. Institut für Mathematische Optimierung – Technische Universität Braunschweig

  8. Zeigerarithmetik Eine weitere Möglichkeit mit Zeigern zu arbeiten ist die Zeigerarithmetik. Zur Verdeutlichung hier ein kleines Beispiel. Bei dem Feld: inta[]={1,2,3}; zeigt a auf a[0] und a+1 zeigt auf a[1]. Statt scanf(" %d",&a[1]); kann man also scanf(" %d",a+1); schreiben, um den zweiten Wert des arrays zu ändern. Institut für Mathematische Optimierung – Technische Universität Braunschweig

  9. Zeigerarithmetik Konsequenterweise gibt es auch a++, ++a, a-- und --a. Die Anweisungen: int*p; int a[]={1,2,3,4}; for (p=a; *p != 4; p++) printf(" %d", *p); sind äquivalent zu: inti; int a[]={1,2,3,4}; for (i=0; a[i] != 4; i++) printf(" %d", a[i]); Institut für Mathematische Optimierung – Technische Universität Braunschweig

  10. Zeigerarithmetik bei Matrizen Bei Matrizen sieht das noch etwas komplizierter aus: double **mat; mat=alloc_matrix(2,2); mat[0][0]=1.0; mat[0][1]=2.0; mat[1][0]=3.0; mat[1][1]=4.0; Institut für Mathematische Optimierung – Technische Universität Braunschweig

  11. Zeigerarithmetik bei Matrizen printf("mat[0][0] = %f\n",mat[0][0]); printf("mat[1][1] = %f\n",mat[1][1]); printf("**mat = %f\n",**mat); printf("*(*mat+1) = %f\n",*(*mat+1)); printf("*(*(mat+1) ) = %f\n",*(*(mat+1))); printf("*(*(mat+1)+1) = %f\n",*(*(mat+1)+1)); Institut für Mathematische Optimierung – Technische Universität Braunschweig

  12. Aufgabe Schreiben Sie eine 3x3 Matrix sukzessive mit den Werten 1,2,3,… voll. D.h. Zeile 1 enthält die Einträge 1,2,3, Zeile 2 die Einträge 4,5,6 und Zeile 3 die Einträge 7,8,9. Geben Sie darauf per Zeigerarithmetik die komplette Matrix am Bildschirm aus. Institut für Mathematische Optimierung – Technische Universität Braunschweig

  13. Strukturen Objekte verschiedenen Datentyps können zu einem neuen Datentyp kombiniert werden. Beispiel: structstudent { char[100] vorname; char[100] nachname; intmatrikelnummer; char[100] studienfach; }; Definiert den Datentyp structstudent. Institut für Mathematische Optimierung – Technische Universität Braunschweig

  14. Aufbau einer Struktur struct Name { Deklaration1; Deklaration2; ... DeklarationN; }; Institut für Mathematische Optimierung – Technische Universität Braunschweig

  15. Zugriff auf Strukturelemente /* Definition von "Koordinaten": */ struct Koordinaten { double x; double y; double z; }; /* Deklaration einer Variable dieses Typs: */ struct Koordinaten p; p.x=3.0; p.y=p.x; /* Zugriff auf die Elemente: */ p.z=0; Institut für Mathematische Optimierung – Technische Universität Braunschweig

  16. Zuweisungen und Vergleiche Man kann Strukturen als Ganzes zuweisen, aber Vergleiche sind nicht als Ganzes erlaubt. struct Koordinaten p1, p2; p1 = p2; /* Zuweisung */ if (p1==p2) ... /* <-- Fehler */ Die if-Bedingung ist in dieser Form nicht erlaubt, sondern es müssten alle Komponenten der Struktur gesondert auf Gleichheit überprüft werden. Institut für Mathematische Optimierung – Technische Universität Braunschweig

  17. Strukturen und Zeiger Eine Struktur darf sich nicht selbst als Element enthalten, aber sie darf einen Zeiger auf eine Variable vom Typ der eigenen Struktur enthalten. structknoten { int wert; struct knoten *naechster; }; Die Struktur knoten enthält einen Zeiger auf eine Struktur vom Typ knoten. Darüberhinaus können in jeder Struktur andere Strukturen verwendet werden. Institut für Mathematische Optimierung – Technische Universität Braunschweig

  18. Zugriff auf Strukturzeigerinhalte Auf die einzelnen Datenelemente einer Struktur zuzugreifen, deren Adresse man durch eine Zeigervariable kennt, kann auf verschiedene Arten geschehen: struct knoten *p; (*p).wert=0; /* 1. Art */ p[0].wert=0; /* 2. Art */ p->wert=0; /* 3. Art */ Institut für Mathematische Optimierung – Technische Universität Braunschweig

  19. Strukturen als Parameter Strukturen können als Parameter verwendet werden: struct knoten { int wert; struct knoten *naechster; }; void ausgabewert(struct knoten p) { printf("%i\n",p.wert); } Dabei werden sie als Kopie übergeben (call-by-value). Institut für Mathematische Optimierung – Technische Universität Braunschweig

  20. Besser … struct knoten *p; p->wert=0; // p[0].wert=0; oder (*p).wert=0; ausgabewert(p); … void ausgabewert(struct knoten *p) { printf("%i\n",p->wert); } Verwendung von einem Zeiger (call-by-reference). Institut für Mathematische Optimierung – Technische Universität Braunschweig

  21. Strukturen als Rückgabewert Strukturen können auch als Rückgabewert verwendet werden: struct knoten { int wert; struct knoten *naechster; }; struct knoten generate() { struct knoten result; ... returnresult; } Institut für Mathematische Optimierung – Technische Universität Braunschweig

  22. Eigene Datentypen Mit dem Schlüsselwort typedef kann man Datentypen mit einem eigenen Namen versehen. Mit: structknoten_s { int wert; structknoten_s *naechster; }; typedefstructknoten_s knoten; kann man eine Variable vom Typ structknoten_s jetzt durch knoten p; deklarieren und das mitunter lästige struct weglassen. Institut für Mathematische Optimierung – Technische Universität Braunschweig

  23. Verkürzte Schreibweise • Verkürzte Schreibweise durch Kombination der Deklarationen: typedefstructknoten_s { int wert; structknoten_s *naechster; } knoten; • Andere Anwendungsbeispiele für typedef: typedefunsignedintuint; typedef double real; /* typedeffloat real; */ (leichter Wechsel zwischen float und double) Institut für Mathematische Optimierung – Technische Universität Braunschweig

  24. Einfach verkettete Listen Mit Hilfe von Strukturen lassen sich Listen erzeugen. Jedes Element (Knoten) der Liste hat einen Zeiger auf seinen Nachfolger. Das erste Element wird Kopf genannt, das letzte Element hat NULL als Nachfolger: Institut für Mathematische Optimierung – Technische Universität Braunschweig

  25. Elemente einfügen Um ein neues Element nach einem Listenelement einzufügen, müssen die Nachfolgezeiger geändert werden: Institut für Mathematische Optimierung – Technische Universität Braunschweig

  26. Elemente einfügen Die Anweisungen dazu sind: knoten *kopf, *vorgaenger, *neuer_knoten; neuer_knoten->naechster=vorgaenger->naechster; vorgaenger->naechster=neuer_knoten; Institut für Mathematische Optimierung – Technische Universität Braunschweig

  27. Elemente am Kopf einfügen Folgende Anweisungen hängen ein neues Element am Kopf an die Liste an: knoten *kopf, *neuer_knoten; neuer_knoten->naechster = kopf; kopf = neuer_knoten; Institut für Mathematische Optimierung – Technische Universität Braunschweig

  28. Elemente entfernen Beim Entfernen eines Elementes muss wiederum der Zeiger des Vorgängerelementes geändert werden. Institut für Mathematische Optimierung – Technische Universität Braunschweig

  29. Elemente entfernen Die Anweisungen dazu sind: knoten *kopf, *vorgaenger, *zu_loeschen; vorgaenger->naechster = zu_loeschen->naechster; free(zu_loeschen); oder beim Entfernen des ersten Elements: kopf = zu_loeschen->naechster; free(zu_loeschen); Institut für Mathematische Optimierung – Technische Universität Braunschweig

  30. Durchlaufen einer Liste Listen können z.B. mittels For-Schleife durchlaufen werden: knoten *p; intmax_wert; ... max_wert = head->wert; for (p=head; p!=NULL; p=p->naechster) { if (p->wert > max_wert) max_wert = p->wert; } Institut für Mathematische Optimierung – Technische Universität Braunschweig

  31. Rekursion Ruft eine Funktion sich selbst auf, so wird das Rekursion genannt. Diese muss immer eine Abbruchbedingung haben. Beispiel: #include <stdio.h> voidprintnumbers(int a) { printf("%d ",a); if (a > 0) printnumbers(a-1); } intmain() { printnumbers(10); return 0; }

  32. Schlechtes Beispiel für eine Rekursion Berechnung der Fakultät einer Zahl: unsignedintfakultaet(unsignedint); intmain() { printf("%u\n",fakultaet(5)); return 0; } Institut für Mathematische Optimierung – Technische Universität Braunschweig

  33. Schlechtes Beispiel für eine Rekursion unsigned int fakultaet(unsigned int n) { if(n>0) return n*fakultaet(n-1); /* n!=n*(n-1)!*/ else return 1; /* 0!=1 */ } Institut für Mathematische Optimierung – Technische Universität Braunschweig

  34. Besser: Iterative Lösung intmain() { int n=5,i,fakultaet=1; for(i=2;i<=n;i++) fakultaet*=i; /* fakultaet=fakultaet*i; */ printf("%d\n",fakultaet); return 0; } Institut für Mathematische Optimierung – Technische Universität Braunschweig

  35. Bäume Analog zu Listen lassen sich auch baumartige Daten- strukturen erzeugen: Institut für Mathematische Optimierung – Technische Universität Braunschweig

  36. Traversierung von Bäumen Sollen alle Knoten eines Baumes abgearbeitet werden, wird oft Rekursion verwendet. Beispiel: double maxwert; // globale Variable void traverse(knoten* r) { if (r->wert > maxwert) maxwert = r->wert; if (r->rechts!=NULL) traverse(r->rechts); if (r->links!=NULL) traverse(r->links); }

  37. Nochmal ohne globale Variable int traverse(knoten* r) { double h; double maxwert; maxwert = r->wert; if (r->rechts!=NULL) { h = traverse(r->rechts); if (h > maxwert) h = maxwert; } if (r->links!=NULL) { h = traverse(r->links); if (h > maxwert) h = maxwert; } }

More Related