# Aufgaben zur UE
Einführung in die Programmierung

Legen Sie alle Programme so aus, dass der Benutzer die geforderten Berechnungen beliebig oft durchführen kann, ohne das Programm jedes mal neu zu starten.
Die mit einem Plus gekennzeichneten Aufgaben entsprechen den Aufgaben aus der Woche VII (Kapitel 5A). Diesmal sind die Programme aber unter Verwendung von Klassen und ohne Zuhilfenahme von globalen Variablen zu erstellen. Überlegen Sie, welche Klassen Sie verwenden wollen, sowie deren Instanzvariablen und Methoden. Mögliche Klassenkandidaten sind in der Angabe angeführt.
Anspruchsvollere Aufgaben sind mit einem Stern gekennzeichnet.

##
7. Klassen - Einführung; Exkurs: Stack

Erstellen Sie C++ Programme für folgende Problemstellungen:

1. + Wie Beispiel 1 aus Woche VII (Kapitel 5A). Mögliche Klassenkandidaten: Brett, Lager

2. + Wie Beispiel 2 aus Woche VII (Kapitel 5A). Mögliche Klassenkandidaten: Auto, Garage

3. + Wie Beispiel 3 aus Woche VII (Kapitel 5A). Mögliche Klassenkandidaten: Album, Sammlung

4. + Wie Beispiel 4 aus Woche VII (Kapitel 5A). Mögliche Klassenkandidaten: Drink, Rezept, Bar

5. Schreiben Sie eine Klasse, deren Objekte ein Sparschwein repräsentieren. In dieses Sparschwein können nur Münzen im Wert von 1 Cent, 5 Cent und 10 Cent geworfen werden. Implementieren Sie zumindest die Methoden leeren (Setzt den Inhalt des Sparschweins auf 0), einwerfen (ermöglicht es, Münzen in das Sparschwein einzuwerfen) und print (gibt den Inhalt des Sparschweins in der Form z.B.: "2*1Cent + 1*5Cent+3*10Cent = 37Cent" aus)
   Schreiben Sie
   - die nötigen Konstruktoren, damit folgende Definitionen von Objekten möglich sind (unter der Annahme, dass die Klasse den Namen Sparschwein hat):
     Sparschwein a; // erzeugt ein leeres Sparschwein
     Sparschwein b=10; // erzeugt ein Sparschwein mit 10 Eincentmünzen als Inhalt
     Sparschwein c(2,3,4); // erzeugt ein Sparschwein mit 2 Eincent-, 3 Fünfcent- und 4 Zehncentmünzen als Inhalt
   - Die Vergleichsoperatoren <, >, ==, !=, die jeweils den Inhalt zweier Sparschweine vergleichen
   Schreiben Sie ein Hauptprogramm, das mindestens zwei Instanzen Ihrer Klasse verwendet und die Verwendung der verschiedenen Methoden illustriert.

6. Schreiben Sie eine Klasse, deren Objekte eine Ampel repräsentieren. Die Ampel hat die Zustände grün, grün blinkend, gelb, rot, rot+gelb in der üblichen Reihenfolge. Zusätzlich gibt es noch den Zustand gelb blinkend. Implementieren Sie zumindest die Methoden anschalten (versetzt die Ampel in den Zustand gelb blinkend), weiter (geht in den nächstfolgenden Zustand über; dabei ist der Folgezustand von gelb blinkend gleich rot) und print (gibt den aktuellen Zustand der Ampel aus).
   Schreiben Sie
   - die nötigen Konstruktoren, damit folgende Definitionen von Objekten möglich sind (unter der Annahme, dass die Klasse den Namen Ampel hat):
     Ampel a; // erzeugt eine Ampel im Zustand gelb blinkend
     Ampel b = AktZustand; // erzeugt eine Ampel in dem Zustand, der durch AktZustand vorgegeben wird
   - Einen Operator ++, der das Fortschalten der Ampel bewirkt
   Schreiben Sie ein Hauptprogramm, das mindestens zwei Instanzen Ihrer Klasse verwendet und die Verwendung der verschiedenen Methoden illustriert.
   Anmerkung: Der Operator ++ kann in C++ sowohl in Postfix- (a++), als auch in Prefixform (++a) verwendet werden. Bei der Definition der Methoden zum Überladen des Operators ++ gibt es daher zwei verschiedene Möglichkeiten:
   void operator++() definiert die Prefixform
   void operator++(int) definiert die Postfixform
   Der zusätzliche Parameter bei der Postfixform unterscheidet nur zwischen den beiden Möglichkeiten und hat sonst keinerlei Verwendung. Für die Lösung des Beispiels brauchen Sie nur eine der beiden Möglichkeiten zu implementieren. Statt void kann bei Bedarf natürlich auch ein passender Typ für das Ergebnis der Operation gewählt werden.

7. Schreiben Sei eine Klasse, deren Objekte Spielkarten repräsentieren. Die möglichen Kartenwerte sind (in aufsteigender Reihenfolge) 10, Bube, Dame, König und As. Die möglichen Farben (ebenfalls aufsteigend) Pik, Treff, Karo und Herz. Eine Karte sticht, wenn entweder ihr Farbenwert höher ist, oder bei gleichen Farben ihr Kartenwert höher ist. Schreiben Sie
   - die nötigen Konstruktoren, damit folgende Definitionen von Objekten möglich sind (unter der Annahme, dass die Klasse den Namen Karte hat):
     Karte a; // erzeugt Herz As
     Karte b = Bube; // erzeugt Herz Bube
     Karte c(Zehn, Herz);
   - Die Vergleichsoperatoren <, >, ==, !=, die jeweils zwei Karten vergleichen. Dabei ist a>b, fall a b nach obigen Regeln sticht.
   Schreiben Sie ein Hauptprogramm, das mindestens zwei Instanzen Ihrer Klasse verwendet und die Verwendung der verschiedenen Methoden illustriert.

8. Schreiben Sie eine Klasse, deren Objekte rationale Zahlen repräsentieren. Dabei sollen die Zahlen nicht in der üblichen Kommaschreibweise gespeichert werden (z.B.: 0.33333), sondern in der Form Zähler/Nenner (also etwa 1/3). Implementieren Sie zumindest die Methoden init (setzt den Wert der rationalen Zahl, indem Zähler und Nenner gesetzt werden), kuerzen (kürzt den dargestellten Wert auf den kleinstmöglichen Nenner, so dass etwa aus der Darstellung 3/9 die gleichwertige Darstellung 1/3 wird), wert (retourniert den aktuellen Wert des Bruches als double Wert) und print (gibt den Bruch in der Form z.B.: "3/9" aus)
   Schreiben Sie
   - die nötigen Konstruktoren, damit folgende Definitionen von Objekten möglich sind (unter der Annahme, dass die Klasse den Namen Q hat):
     Q a; // erzeugt eine rationale Zahl mit dem Wert Null
     Q b=10; // erzeugt eine rationale Zahl mit dem Wert 10
     Q c(1,2); // erzeugt eine rationale Zahl mit dem Wert 0,5
   - Die Operatoren +, -, * und /, die jeweils rationale Zahlen addieren, subtrahieren, multiplizieren und dividieren
   Schreiben Sie ein Hauptprogramm, das mindestens zwei Instanzen Ihrer Klasse verwendet und die Verwendung der verschiedenen Methoden illustriert.

9. Die Klasse SafeInt dient zur Darstellung von ganzen Zahlen. Die einzelnen Operationen sind dabei analog zum vordefinierten Datentyp int definiert. Im Unterschied zu int sollen SafeInt-Operationen weitgehend abgesichert werden. D.h. falls das Ergebnis einer SafeInt-Operation nicht definiert ist (Über-/Unterlauf, Division durch 0, etc.) soll das Ergebnisobjekt dies „wissen“ und bei weiteren Operationen oder einer Ausgabe berücksichtigen. Implementieren und testen Sie zumindest die folgenden Methoden:
   SafeInt::SafeInt() // mit 0 initialisieren
   SafeInt::SafeInt(int)
   SafeInt SafeInt::operator+(SafeInt)
   SafeInt SafeInt::operator-(SafeInt)
   SafeInt SafeInt::operator*(SafeInt)
   SafeInt SafeInt::operator/(SafeInt)
   void SafeInt::print()

10. Die Klasse N0 dient zur Darstellung von natürlichen Zahlen mit bis zu 70 Stellen (Interne Darstellung als char Array). Zusätzlich zum Wert enthält jedes Objekt der Klasse N0 auch einen Status, der festlegt ob der im char Array dargestellte Wert gültig ist, oder nicht. Implementieren und testen Sie zumindest die folgenden Methoden:
    N0::N0() // mit 0 initialisieren
    N0::N0(int)
    N0 N0::operator+(N0)
    N0 N0::operator-(N0)
    N0 N0::operator*(N0)
    N0 N0::operator/(N0)
    void N0::print()
    Falls bei den arithmetischen Operationen (+ - * /) Überläufe entstehen, so wird ein Objekt mit dem Status ungültig retourniert. Bei der Ausgabe wird für ungültige Objekte der String "ungültig" ausgegeben.

11. Die Klasse Vektor dient zur Darstellung von Vektoren im R3. Implementieren und testen Sie zumindest die folgenden Methoden:
    Vector::Vector() // mit (0,0,0) initialisieren
    Vector::Vector(double, double, double)
    Vector Vector::operator+(Vector)
    Vector Vector::operator-(Vector)
    double Vector::operator*(Vector) //Skalarprodukt
    Vector Vector::operator/(Vector) //Vektorprodukt
    double Vector::norm() //Betrag(Länge) void Vector::print()

12. Implementieren Sie eine Klasse Kurs zur Verwaltung der Teilnehmer (maximal 20) einer Lehrveranstaltung. Realisieren Sie einen Konstruktor, mit dem der Titel der Lehrveranstaltung festgelegt werden kann und weiters Methoden zur Eingabe von Namen und Matrikelnummern für die einzelnen Studentinnen, die über eine Ihnen zugewiesene Nummer (d.h. einen Index) identifiziert werden. Es muss (über geeignete Methoden) möglich sein, für jede einzelne Studentin die Ergebnisse von (maximal 10) Beurteilungen (i.e. erreichte Punkte bei Tests) zu speichern und den Durchschnitt der erreichten Punkte pro Studentin und pro Kurs zu errechnen. Definieren Sie einen geeignete Methode, die eine Ergebnisliste für den gesamten Kurs druckt.
    Anmerkungen: Für alle Strings sind Charakter-Felder fixer Größe zu vereinbaren.
    Zum Testen der Klasse muss ein geeignetes Testprogramm erstellt werden.

13. Die Klasse Geheim dient zum Speichern von wichtigen Informationen, die mit Passworten geschützt werden können. Jedes Objekt enthält außer der zu speichernden Zeichenkette noch eine zweite Zeichenkette, das Passwort. Ist das Passwort leer, so ist das Objekt offen, ansonst ist es gesperrt. Implementieren und testen Sie zumindest die folgenden Methoden:
    Geheim::Geheim(char inhalt[]) // offenes Objekt mit inhalt als Information
    Geheim::Geheim(char inhalt[], char passwort[]) // mit passwort geschütztes Objekt
    bool Geheim::lock(char passwort[]) // sperrt ein Objekt mit passwort. Das darf nur funktionieren, wenn das Objekt vorher offen war. Sonst muß diese Funktion false liefern und das Objekt unverändert lassen.
    bool Geheim::unlock(char passwort[]) // entsperrt ein Objekt, falls dass passwort korrekt ist. Ansonst wird false zurückgeliefert.
    Geheim Geheim::operator+(Geheim) //funktioniert nur, wenn die beiden zu verknüpfenden Objekte offen sind. Dann werden die beiden Zeichenketten im Ergebnisobjekt einfach aneinandergehängt. Andernfalls wird ein leeres Objekt retourniert.
    int Geheim::len() //Länge der Zeichenkette. Liefert 0 für gesperrte Objekte
    void Geheim::print() //Gibt die Information aus. Für gesperrte Objekte wird nichts ausgegeben.

14. Erweitern Sie die Klasse Complex und schreiben Sie den nötigen Programmcode, sodass das folgende Programm das erwartete Ergebnis bringt.
    Soweit wie möglich, verwenden Sie Methoden und nicht globale Funktionen.
    #include <iostream.h>
    #include "Complex.h"
    int main() {
    Complex c1(2),c2(3,-4);
    double d1=2, d2(3);
    c2.print(); cout << " ist " << (c2==d2 ? "" : "nicht ") << "gleich ";
    cout << d2 << endl;
    c1.print(); cout << " ist " << (c1!=d1 ? "nicht " : "") << "gleich ";
    cout << d1 << endl;
    cout << d1 << " ist " << (d1==c1 ? "" : "nicht ") << "gleich ";
    c1.print(); cout << endl;
    cout << d2 << " ist " << (d2!=c2 ? "nicht " : "") << "gleich ";
    c2.print(); cout << endl;
    cout << "Die konjugiert komplexe Zahl zu "; c2.conj().print();
    cout << " ist "; c2.print(); cout << endl;
    return 0;
    }

15. * Implementieren Sie eine Klasse Stack, wie in der VO vorgestellt. Verwenden Sie diese Klasse, um die Ackermann Funktion (Übungsbeispiel 9 von Woche VII; Kapitel 5A) iterativ (also nur mit Verwendung von Schleifen und ohne Rekursion) zu lösen.