Universität Ulm - Abteilung Angewandte Informationsverarbeitung
9.Übungsblatt (09.12.00 bis 16.01.01)
zur Vorlesung Allgemeine Informatik III (WS 00/01)


ACHTUNG ERGÄNZUNG BEI AUFGABE 3 NOTWENDIG (s.u.)!!!


Erweitern Sie die Lösung von Blatt 7 noch ein 8.Mal!

(Nein :-)))) keine Panik -- das ist nur ein Scherz )

Bruchrechnen. Wir rechnen jetzt mal mit Brüchen. Das sollte gehen, da die meisten von Ihnen ja bereits im 3.Semester sind. Für Erstsemester wäre das noch zu schwierig ...
 

Aufgabe 1 (10 Punkte)

Schreiben Sie ein einzelnes kleines nettes C-Modul bruch.c, das rationale Brüche dividieren, multiplizieren, heilen, addieren und subtrahieren kann. Selbstverständlich ist das Ergebnis immer ein gekürzter Bruch.

Hier die Funktionen, die das Modul exportieren soll:

BRUCH *create_bruch(int z, int n); /* erzeugt einen Bruch und initialisiert Zaehler und Nenner */
void free_bruch(BRUCH *a);         /* gibt ein erzeugtes Bruchobjekt wieder frei   */
BRUCH *add_bruch(BRUCH *a, BRUCH *b);/* addiert zwei Brueche und erzeugt einen Bruch, der das Ergebnis traegt */
BRUCH *sub_bruch(BRUCH *a, BRUCH *b); /* raten sie mal, was diese Funktion macht ... */
BRUCH *mult_bruch(BRUCH *a, BRUCH *b); /* ... und diese hier ... */
BRUCH *div_bruch(BRUCH *a, BRUCH *b);  /* und die hier ??? toll, gell? */
BRUCH *heal_bruch(BRUCH *a);          /* :-) das müssen nur Medizinstudenten implementieren ... */

Den Datentyp  BRUCH sollen Sie sich selbst überlegen. Bitte zerlegen Sie das Programm unbedingt in bruch.h und bruch.c.
 

Aufgabe 2 (5 Punkte)

Schreiben Sie ein Programm main.c, das testet, ob ihre Bruchroutinen bei Belastung in die Brüche geht oder nicht. (Also einfach ein paar Testroutinen in main schreiben und die ggf. gefundenen Fehler beheben, ok?).
Schreiben Sie dann ein makefile, dass die Abhängigkeiten der Module abbildet und compilieren Sie Ihr Programm via make.
 

Aufgabe 3 (5 Echtpunkte für Fleissige)

Eigentliche wäre ja eine Art Taschenrechner für Brüche nett. Schön wäre es, wenn

    main 13/104 + 7/112 + 3/48

sofort 1/4 als Ergebnis ausspucken würde... hier steht aber noch einer einfachen Implementierung das Problem des Vorrangs entgegen:
Bei

    main 13/104 + 7/112 * 3/48

muss natürlich * vor + gelten --- das macht die Sache a little bit complicated. Deshalb wechseln wir einfach zur Umgekehrten Polnischen Notation (UPN).

        main 13/104  7/112  3/48  *+

Das heißt, dass erst die Operanden und dann die Operatoren angegeben werden: jeweils n Operanden werden von (n-1) Operatoren gefolgt. Alle Operatoren stehen in einem kompletten String (hier: "*+"). Die Operatoren werden von links nach rechts (erst *, dann +) angewandt, die Operanden von rechts nach links abgearbeitet: Auf  7/112 und 3/48 wird der Operand * angewandt, also 7/112 * 3/48 und auf das Ergebnis 1/256 und der Zahl 13/104 wird dann der zweite angegebene Operator + angewandt: 1/256 + 13/104 ergibt dann das Endergebnis 33/256.
Obacht: auf der Shell darf man nicht einfach den * angeben, da der sonst als "alle Dateinamen" interpretiert wird. Hier muss man dann den Stern mit Anführungszeichen versehen:   main 13/104  7/112  3/48  "*+"   klappt richtig!

Um alle Möglichkeiten zu berücksichtigen, kann es mehrere Folgen von Operanden und Operatoren auf der Kommandozeile geben:
Aus (1/4 + 1/8) * (1/3 + 1/2) wird in der UPN     main 1/4 1/8 "+" 1/3 1/2 "+*"

Erweitern Sie die Module main.c und bruch.c so, dass die Aufgabe gelöst wird! Sie können auch eine Lösung über geklammerte Ausdrücke implementieren: main ( 1/4 "+" 1/8 ) * ( 1/3 + 1/2 )