Programmieren II Programmieren II Organisatorisches: Klausur Programmierung II • Sommersemester 2007 • Steffen Lange wie im letzten Semester mit Papier und Stift – an kleinen Beispielen nachweisen, daß Sie die Grundkonzepte verstanden haben und anwenden können geplanter Termin – 09.Juli 2006, 10:00 – 11:45 Uhr Hinweis: • davor gibt es wieder ein Blatt mit klausurrelevanten Aufgaben • letzter Vorlesungstermin: Hörsaalübung zu diesen Aufgaben 1/1 Programmieren II 1/2 Programmieren II Organisatorisches: Praktikum • • • • Organisatorisches: Praktikum Ausgabe der Aufgabenstellung Vorbesprechung in der Vorlesung; separater Foliensatz (wie gehabt) selbständig zu Hause oder in den Labors – Entwurf – Ausarbeitung des Programms inklusive Eintippen – setzt Editor voraus, aber nicht unbedingt Compiler im Praktikum – Übersetzung, Inbetriebnahme, Test mit MS Visual C++ – Vorführung und Erläuterung durch Sie – Abnahme und Testat durch Betreuer (die innere Struktur interessiert mehr als die Funktion nach außen !) 1/3 • • • • Teilnahme an Praktikumsterminen ist Pflicht Æ Testat gibt es nur zum jeweiligen Termin !!! Bewertung: erfolgreich / nicht erfolgreich Æ keine Noten Erfolgreiche Teilnahme am Praktikum ist Zulassungsvoraussetzung für Klausur: Æ 5 von 6 Praktikumsübungen müssen testiert sein Gruppeneinteilung, Termine im Internet 1/4 Programmieren II Programmieren II Organisatorisches: Praktikum • • Literaturempfehlungen Gruppenarbeit: jeweils 2 bis 3 StudentInnen an einem PC – erarbeiten gemeinsam ein Programm, aber jede(r) muß eine Kopie besitzen – keine Arbeitsteilung: jede(r) muß alles beherrschen – gemeinsame Vorbereitung ist empfehlenswert Abschreiben und Kopieren hilft nicht – Programmieren lernt man nur durch eigenes Üben • • • • • • Bjarne Stroustrup, The C++ Programming Language, AddisonWesley, Reading, MA, 1997 D.M. Capper, Introducing C++ for Scientists, Engineers and Mathematicians, Spinger, London, 2001 Robert Sedgewick, Algorithmen in C++, Pearson Studium, München, 2002 Peter Prinz, Ulla Kirch-Prinz, C++ Lernen und professionell anwenden, mitp-Verlag, 2002 Jürgen Wolff von Gudenberg, Objektorientiert Programmieren von Anfang an, Spektrum Akademischer Verlag, Heidelberg, 1996. Klaus Schmaranz, Softwareentwicklung in C++, Springer-Verlag, Berlin, 2002. 1/5 Programmieren II 1/6 Programmieren II Fahrplan Einordnung im Mittelpunkt: Konzepte, Ideen, ... der objektorientierten Programmierung Klassen, Objekte, Methoden ... Vererbung, Klassenhierarchien ... Polymorphismus ... Abstrakte Klassen ... klassische prozedurale Programmierung Algorithmische Ideen ... Effiziente Datenstrukturen ... Objektorientiertes Design ... zwei Rollen einnehmen: • Benutzer von Klassen(bibliotheken) • Programmierer von Klassen(bibliotheken) 1/7 • • • Trennung von Daten und Funktionen Strukturierung der Daten Strukturierung des Programms; Nutzung von Funktionen (Unterprogramme/Prozeduren) • Konsequenzen • Verantwortlichkeiten für „korrekte“ Initialisierung, Funktionsaufrufe mit „korrekten“ Daten • Änderung der Darstellung der Daten hat Anpassung der verwendeten Funktionen zur Folge 1/8 Programmieren II Programmieren II Einordnung Beispiel objektorientierte Programmierung • • • • • relevante Daten: Objekte (Instanzen einer Klasse) im Mittelpunkt Objekte bilden Einheit aus Daten (Attributen, Eigenschaften) und Methoden (Funktionen, Fähigkeiten) Informationsaustausch zwischen Objekten erfolgt über „Nachrichten“ zur Aktivierung der entsprechenden „Fähigkeiten“ Programmablauf = Austausch + Reaktion auf Botschaften • Darstellung von nicht-negativen rationalen Zahlen relevante Funktionen: Hoffnungen • geringere Fehleranfälligkeit (Kontrolle) • gute Wiederverwendbarkeit (Kapselung, Selbstverwaltung) • geringer Wartungsaufwand („schmale“ Schnittstellen) • • kürzen addieren • auf dem Bildschirm ansehen Hilfsfunktion: ggT() 1/9 Programmieren II Programmieren II Beispiel: prozedurale Programmierung #include <iostream> using namespace std; Beispiel: prozedurale Programmierung int main(){ bruch mb; mb.zaehler = 36; mb.nenner = 24; display(mb); mb = kuerzen(mb); display(mb); return(0); } Deklaration der Daten struct bruch { int zaehler; int nenner; }; bruch kuerzen ( bruch ); int ggt ( int, int ); void display ( bruch ); 1/10 Problem: zu verhindern, daß der Zähler gleich 0 ist Deklaration der Funktionen 1/11 1/12 Programmieren II Programmieren II Beispiel: prozedurale Programmierung Einschub: Bestimmung des GGT Euklidscher Algorithmus (Hintergrund) void display(bruch aktuell) { cout << "Der Bruch hat den Zaehler: " << aktuell.zaehler << endl; cout << "Der Bruch hat den Nenner: " << aktuell.nenner << endl; } bruch kuerzen(bruch aktuell){ int help; help = ggt(aktuell.zaehler,aktuell.nenner); aktuell.zaehler = aktuell.zaehler / help; aktuell.nenner = aktuell.nenner / help; return(aktuell); } es seien a, b natürliche Zahlen • ggt(a,b) = c, falls c die größte Zahl ist, mit: c teilt a und c teilt b Hinweis: falls b = 0, so ist c = a !!! Beobachtung: Es seien a, b natürliche Zahlen und r = a%b. Dann gilt: { t | t teilt a und t teilt b } = { s | s teilt b und s teilt r } Konsequenz: 1/13 ggt(a,b) = ggt(b,r) 1/14 Hinweis: ggt bezeichnet eine Funktion zur Bestimmung des größten gemeinsamen Teilers Programmieren II Programmieren II Einschub: Bestimmung des GGT Beispiel: objektorientierte Programmierung Euklidscher Algorithmus (Realisierungen) #include <iostream> using namespace std; int ggt_rec (int a, int b) { if ( b == 0) return(a); else ggt_rec(b,a%b); } int ggt(int, int); int ggt (int a, int b) { int rest = a%b; while ( rest != 0 ) { a = b; b = rest; rest = a%b; } return (b); } class bruch { private: int zaehler; int nenner; public: bruch (int, int) ; void kuerzen () ; void display (); }; 1/15 Deklaration der Attribute Deklaration der Methoden 1/16 Programmieren II Programmieren II Beispiel: objektorientierte Programmierung Beispiel: objektorientierte Programmierung ein Konstruktor für Objekte der Klasse Bruch Objekt vom Typ Bruch int main(){ bruch mb(36,24); mb.display(); mb.kuerzen(); mb.display(); return(0); } bruch::bruch(int Z, int N) { if (N != 0) { zaehler = Z; nenner = N; } else { zaehler = 0; nenner = 1; } } Methoden für dieses Objekt aufrufen garantiert, daß der Nenner immer ungleich 0 ist ein anderer Konstruktor für Objekte der Klasse Bruch bruch::bruch(int Z) { zaehler = Z; nenner = 1; }; } bruch mb1(10); 1/17 Programmieren II 1/18 Programmieren II Beispiel: objektorientierte Programmierung Relevante Grundbegriffe void bruch::display() { cout << "Der Bruch hat den Zaehler: " << zaehler << endl; cout << "Der Bruch hat den Nenner: " << nenner << endl; } void bruch::kuerzen() { int help; help = ggt(zaehler,nenner); zaehler = zaehler / help; nenner = nenner / help; } int ggt(int a, int b) { int teiler = a%b; while (teiler != 0) { a = b; b = teiler; teiler = a%b; } return (b); } • • • • • • • • • 1/19 Klassen, Datenstruktur Datenkapselung statisches und dynamisches Erzeugen von Objekten eigenständige Zustandsverwaltung abstrakte Datentypen parametrisierte Datentypen modulares Programmieren Vererbung ... 1/20