Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 1 Programmierkurs Java Vorlesung am FB Informatik der Universität Oldenburg Vorlesung 7 Dietrich.

Ähnliche Präsentationen


Präsentation zum Thema: "Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 1 Programmierkurs Java Vorlesung am FB Informatik der Universität Oldenburg Vorlesung 7 Dietrich."—  Präsentation transkript:

1 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 1 Programmierkurs Java Vorlesung am FB Informatik der Universität Oldenburg Vorlesung 7 Dietrich Boles

2 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 2 Gliederung von Vorlesung 7 Speicherverwaltung –Stack –Zeiger –Heap Inkarnationen –von Funktionen –von Variablen Rekursion –Definitionen –rekursive Prozeduren –rekursive Funktionen –Endlosrekursion Backtracking Beispielprogramme

3 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 3 Speicherverwaltung Programmcode Statische Daten Stack Heap globale Variablen lokale Variablen Daten unter Programmkontrolle Programm- speicher

4 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 4 Stack Verwaltung durch Laufzeitsystem Arbeitet nach dem Prinzip last-in-first-out Verwaltung von Funktionsaktivierungen Speicherbereich für lokale Variablen int a float b void main(): int a float b void main(): int a char b void p(): p(); int a float b void main(): return; Stack

5 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 5 Heap Programmkontrollierte Verwaltung Speicherzuweisung per Anweisung (new/delete) Zugriff über Zeiger-Variablen (Referenz-Variablen) Unterstützung durch Laufzeitsystem (Garbage Collection,...) Heap int a new int (a); Heap int a delete (b); char b

6 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 6 Zeiger Gibt es in Java so nicht, aber Grundlage für Objektrepräsentation Datentyp ADDRESS ADDRESS-Variablen: Speicherung von Speicheradressen ADDRESS v double v Stack oder Heap Heap Stack oder Heap Heap

7 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 7 Zeiger ADDRESS(double) v, w; // Anlegen zweier ADDRESS- // Variablen auf dem Stack v = new double(); // Speicherplatzzuweisung (Heap) w = new double(); // v und w enthalten als Werte // Speicheradressen *v = ; // Zuweisung eines Wertes an die // Speicheradresse, auf die v zeigt *w = *v ; // dito für w (Dereferenzierung) v = w // v und w zeigen nun auf denselben // Speicherplatz delete v; // Speicherplatzfreigabe delete w;

8 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 8 Inkarnation Funktionsinkarnationen –beim Aufruf einer Funktion f ensteht eine Inkarnation von f –zur Inkarnation einer Funktion gehören: ein Ausführungspunkt Speicherplätze für funktionslokale Variablen –eine Inkarnation wird vernichtet, wenn die Funktion verlassen wird –Blockanweisungen entsprechen namenlosen Funktionen, entsprechend gilt der Inkarnationsbegriff auch hier Variableninkarnationen –wird während der Programmausführung die Definitionsanweisung einer Variablen v erreicht, entsteht eine Inkarnation (Instanz) von v –die Inkarnation von v wird vernichtet, sobald die Lebensdauer von v beendet ist

9 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 9 Inkarnation Aktionen beim Aufruf einer Funktion –es wird auf dem Stack ein Aktivierungssegment (Speicherstück) angelegt –der aktuelle Zustand des Programms (Registerinhalte) wird im Aktivierungssegment gespeichert –im Aktivierungssegment werden Speicherbereiche für Parameter, lokale Variable und temporäre Daten reserviert Aktionen beim Verlassen einer Funktion –mit Hilfe der abgespeicherten Registerinhalte kann der Zustand des Programms von vor dem Funktionsaufruf wiederhergestellt werden –der Funktionswert wird an geeigneter Stelle abgelegt –das Aktivierungssegment wird zerstört

10 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 10 Inkarnation Schema: main(): f1(): f2(int j): int i; int i; float x; f1(); f2(i); //... int j; return; f2(5+j); Stack main i i f1 i main i f1 i main i f1 i j main i f1 i j f2 j x j x

11 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 11 Rekursion Definition eines Problems, einer Funktion oder eines Verfahrens durch sich selbst bereits bekannt: –direkt rekursive Syntaxdiagramme: –indirekt rekursive Syntaxdiagramme: –Mathematik: :: true | false | ( ) ; ::=... | ; ::= while ( ) ; n! = 1 falls n = 0 n * (n-1)! sonst {

12 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 12 Rekursive Prozeduren und Funktionen Definition (Rekursion): Eine Funktion heißt rekursiv, wenn mindestens zwei Inkarnationen dieser Funktion zur gleichen Zeit bestehen können. Definition (direkte Rekursion): Eine Funktion heißt direkt rekursiv, wenn sich die Funktion selbst aufruft, d.h. wenn die zweite Inkarnation der Funktion durch die Funktion selbst erzeugt wird. Definition (indirekte Rekursion): Eine Funktion heißt indirekt rekursiv, wenn die zweite Inkarnation der Funktion nicht durch die Funktion selbst erzeugt wird. Definition (Rekursionstiefe): Anzahl der Inkarnationen einer Funktion minus 1

13 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 13 Rekursive Prozeduren Der Hamster soll bis zur nächsten Wand laufen! Iterative Lösung: Direkt rekursive Lösung: void zurMauer() { while (vornFrei()) vor(); } void zurMauerR() { if (vornFrei()) { vor(); zurMauerR(); }

14 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 14 Rekursive Prozeduren Der Hamster soll alle Körner auf dem aktuellen Feld einsammeln! Iterative Lösung: Direkt rekursive Lösung: void sammle() { while (kornDa()) nimm(); } void sammleR() { if (kornDa()) { nimm(); sammleR(); }

15 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 15 Rekursive Prozeduren Korrelation zwischen iterativen und rekursiven Prozeduren: void p() { while ( ) } void pR() { if ( ) { pR(); } void p1() { if ( ) { while ( ) } void p2() { if ( ) { if ( ) { while ( ) } } }

16 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 16 Rekursive Prozeduren Der Hamster soll bis zur nächsten Wand und dann zurück zur Ausgangsposition laufen! Iterative Lösung: void hinUndZurueck() { int anzahl = 0; while (vornFrei()) { vor(); anzahl++; } linksUm(); linksUm(); while (anzahl > 0) { vor(); anzahl--; }

17 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 17 Rekursive Prozeduren Der Hamster soll bis zur nächsten Wand und dann zurück zur Ausgangsposition laufen! Direkt rekursive Lösung: void hinUndZurueckR() { if (vornFrei()) { vor(); hinUndZurueckR(); vor(); } else { kehrt(); } void kehrt() { linksUm(); }

18 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 18 Rekursive Prozeduren Schema: main: hUZR (1.) hUZR (2.) hUZR (3.) hUZR(); vornFrei -> t vor(); hUZR(); -----> vornFrei -> t vor(); hUZR(); -----> vornFrei -> f kehrt(); <----- vor(); <----- vor(); <----- Befehlsfolge: vor(); vor(); kehrt(); vor(); vor();

19 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 19 Rekursive Prozeduren Der Hamster soll bis zur nächsten Wand und dann zurück zur Ausgangsposition laufen! Indirekt rekursive Lösung: void hinUndZurueckR() { if (vornFrei()) { laufe(); } else { linksUm(); linksUm(); } void laufe() { vor(); hinUndZurueckR(); vor(); }

20 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 20 Rekursive Funktionen Der Hamster soll die Anzahl an Schritten bis zur nächsten Mauer zählen! Iterative Lösung: Rekursive Lösung: int anzahlSchritteR() { if (vornFrei()) { vor(); return anzahlSchritteR() + 1; } else return 0; } int anzahlSchritte() { int anzahl = 0; while (vornFrei()) { vor(); anzahl++; } return anzahl; }

21 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 21 Rekursive Funktionen Schema: main: aSR (1.) aSR (2.) aSR (3.) i=aSR(); vornFrei -> t vor(); aSR() -----> vornFrei -> t vor(); aSR() -----> vornFrei -> f return 0; 0 <----- return 0 + 1; 1 <----- return 1 + 1; 2 <----- i=2;

22 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 22 Rekursive Funktionen mit lokalen Variablen Der Hamster soll die Anzahl an Körnern im Maul zählen! int anzahlKoernerR() { if (!maulLeer()) { gib(); int anz = anzahlKoernerR(); nimm(); // Vermeidung von Seiteneffekten! return anz + 1; } else return 0; } Stack aKR main anz aKR main anz aKR main anz aKR anz aKR anz aKR anz...

23 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 23 Rekursive Funktionen mit Parametern Der Hamster soll anz-Schritte nach vorne gehen! void vorR(int anz) { if ((anz > 0) && vornFrei()) { vor(); vorR(anz-1); } Stack vorR main anz=2 vorR main anz=2 vorR main anz=2 vorR anz=1 vorR anz=1 vorR anz=0...

24 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 24 Rekursive Funktionen / Endlosrekursion Endlosrekursion: Rekursionstiefe: im Prinzip unendlich! erzeugt im allgemeinen einen Laufzeitfehler: Stack overflow! Dem Java-Interpreter kann man die gewünschte Stackgröße mitteilen! void sammleR() { if (kornDa()) { sammleR(); nimm(); }

25 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 25 Rekursive Prozeduren und Funktionen Anmerkungen: –zu jedem rekursiv formulierten Algorithmus gibt es einen äquivalenten iterativen Algorithmus Vorteile rekursiver Algorithmen: –kürzere Formulierung –leichter verständliche Lösung –Einsparung von Variablen –teilweise sehr effiziente Problemlösungen (z.B. Quicksort) Nachteile rekursiver Algorithmen: –weniger effizientes Laufzeitverhalten (Overhead beim Funktionsaufruf) –Verständnisprobleme bei Programmiernanfängern –Konstruktion rekursiver Algorithmen gewöhnungsbedürftig

26 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 26 Backtracking-Verfahren Prinzip: –Versuch, eine Teillösung eines gegebenen Problems systematisch zu einer Gesamtlösung auszubauen –falls in einer gewissen Situation ein weiterer Ausbau einer vorliegenden Teillösung nicht mehr möglich ist (Sackgasse), werden eine oder mehrere der letzten Teilschritte rückgängig gemacht –die dann erhaltene reduzierte Teillösung versucht man auf einem anderen Weg wieder auszubauen –Wiederholung des Verfahrens, bis Lösung gefunden wird oder man erkennt, daß keine Lösung existiert Grundlage der Programmiersprache PROLOG! Bekannte Probleme: –Springerproblem –Acht-Damenproblem –Labyrinthsuche

27 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 27 Backtracking-Verfahren Aufgabe: Der Hamster steht am Eingang eines zyklenfreien Labyrinths, in dem er ein Korn finden und auf dem schnellsten Weg zurücktransportieren soll!

28 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 28 Backtracking-Verfahren boolean gefunden = false; void main() { sucheGeradeAb(); } void sucheGeradeAb() { if (kornDa()) { gefunden = true; nimm(); } if (!gefunden && linksFrei()) { linksUm(); vor(); sucheGeradeAb(); vor(); linksUm(); } if (!gefunden && rechtsFrei()) { rechtsUm(); vor(); sucheGeradeAb(); vor(); rechtsUm(); } if (!gefunden && vornFrei()) { vor(); sucheGeradeAb(); vor(); } else { kehrt(); }

29 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 29 Beispielprogramm 1 Berechnung der Fakultätsfunktion: public static int fakultaet(int n) { if (n <= 0) return 1; else return n * fakultaet(n-1); } n! = 1 falls n = 0 n * (n-1)! sonst { fak(3) = 3 * fak(2) 2 * fak(1) 1 * fak(0) 1 1 * 1 2 * 1 3 * 2 6

30 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 30 Beispielprogramm 2 Berechnung einer Fibonacci-Zahl: public static int fib(int n) { if (n <= 2) return 1; else return fib(n-1) + fib(n-2); } 1 falls n = 1 fib(n) = 1 falls n = 2 fib(n-1) + fib(n-2) sonst {

31 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 31 Beispielprogramm 3 McCarthy-Funktion: es gilt übrigens: mc(n) = 91 für 1 <= n <= 101 public static int mc(int n) { if (n > 100) return n - 10; else return mc(mc(n+11)); } n-10 falls n > 100 mc(n) = mc(mc(n+11)) sonst {

32 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 32 Beispielprogramm 4 Ackermann-Funktion: wächst sehr stark: ack(4,2) besitzt Stellen ack(4,4) ist größer als 10 hoch 10 hoch 10 hoch public static int ack(int n, int m) { if (n == 0) return m+1; else if (m == 0) return ack(n-1, 1); else return ack(n-1, ack(n,m-1)); } m + 1 falls n = 0 ack(n,m) = ack(n-1,1) falls m = 0 ack(n-1,ack(n,m-1)) sonst {

33 Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 33 Beispielprogramm 5 Türme von Hanoi: public class Hanoi { public static void main(String[] args) { int hoehe = Terminal.readInt(); verlegeTurm(hoehe, 1, 3, 2); } public static void verlegeTurm(int hoehe, int von, int nach, int ueber) { if (hoehe > 0) { verlegeTurm(hoehe-1, von, ueber, nach); Terminal.out.println(von nach); verlegeTurm(hoehe-1, ueber, nach, von); } } } Gegeben: 3 Pfosten mit n Scheiben Ziel: Lege alle n Scheiben von 1 nach 3 Restriktion 1: immer nur eine Scheibe bewegen Restriktion 2: niemals größere auf kleinere Scheibe 123


Herunterladen ppt "Programmierkurs Java Vorlesung 7 Dietrich Boles Seite 1 Programmierkurs Java Vorlesung am FB Informatik der Universität Oldenburg Vorlesung 7 Dietrich."

Ähnliche Präsentationen


Google-Anzeigen