Aufgabe 1: (31 Punkte) Schreiben Sie ein Programm telefon zum Erstellen eines Telefonbuches, bestehend aus einer beliebigen Anzahl von Einträgen. Für jeden Eintrag sollen folgende Daten erfasst werden - Nachname (max. 24 Buchstaben lang) - Vorname (max. 24 Buchstaben lang) - Telefonnummer (als Zahl). Das Programm wird folgendermassen aufgerufen telefon -o Ausgabedatei und arbeitet dann wie folgt beschrieben: - Aufrufparameter auswerten, bei falschem Aufruf Fehlermeldung (-o steht für "output" und muß immer mit angegeben werden) - Jetzt werden vom Benutzer Einträge entgegengenommen. Dies wird von der Funktion erfasse_eintraege erledigt, die folgendes tut: · mit Hilfe der Funktion neuer_eintrag wird eine Datenstruktur zur Speicherung der Telefondaten erzeugt · diese Struktur wird mit Hilfe der Funktion erfasse_daten gefüllt · anschließend wird diese Struktur vorne in eine verkettete Liste solcher Strukturen eingehängt (das wird nicht durch erfasse_daten erledigt, sondern muss in der Funktion erfasse_eintraege erfolgen!) · dies wird wiederholt, bis erfasse_daten das Ende der Eingabe meldet. - Nun werden alle Einträge nach Nachnamen sortiert (mit der Funktion sortiere_eintraege) - Schliesslich werden alle in der Liste gespeicherten Telefondaten mit Hilfe der Funktion speichere_eintraege in die angegebene Ausgabedatei gespeichert. Auf den folgenden Seiten finden Sie ein Gerüst für das beschriebene Programm. In den Kommentaren sind die Aufgaben der einzelnen, zu ergänzenden Programmteile beschrieben. #include #include #include /* * Deklaration der Struktur für Einträge ins Telefonverzeichnis */ struct eintrag { __________________________________________________________ __________________________________________________________ __________________________________________________________ struct eintrag *naechster; }; /* * Deklaration von Funktionen, die bei der Programmierung von * main benötigt werden und die im Rahmen dieser Aufgabe * (zusätzlich zu main) zu programmieren sind (ab Seite 6) */ struct eintrag *neuer_eintrag(); struct eintrag *erfasse_eintraege(); void speichere_eintraege(struct eintrag *, char *); /* * Deklaration von Funktionen, die bei der Programmierung von * main benötigt werden, die aber nicht selbst programmiert * werden müssen */ /* erfasse_daten: liefert 0 am Ende der Eingabe, sonst 1 */ int erfasse_daten(struct eintrag *); /* sortiere_eintraege: Liefert einen Zeiger auf das erste */ /* Element der sortierten Liste */ struct eintrag *sortiere_eintraege(struct eintrag *); /* * Funktion main */ int main(int argc, char *argv[]) { /* Variablendefinitionen */ __________________________________________________________ __________________________________________________________ __________________________________________________________ /* * Überprüfen der Kommandozeile; * Hinweis: int strcmp(char *, char *) liefert 0, wenn die * übergebenen Zeichenketten gleich sind, ungleich 0 sonst */ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ /* * Einträge vom Benutzer entgegennehmen */ __________________________________________________________ /* * Einträge nach Nachnamen sortieren */ __________________________________________________________ /* * Liste in Ausgabedatei speichern */ __________________________________________________________ return 0; } /* * Funktion erfasse_eintraege zum wiederholten Einlesen von * Telefonbucheinträgen. Gibt Zeiger auf den Anfang der hier * erzeugeten verketteten Liste der Einträge zurück. */ struct eintrag *erfasse_eintraege() { __________________________________________________________ __________________________________________________________ /* * Struktur für Einträge erzeugen, Daten erfassen, * vorne in Liste einketten, ... */ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ } /* * Funktion neuer_eintrag zum Erzeugen eines neuen Telefonbuch- * eintrags (wenn beim Reservieren des Speichers ein Fehler * auftritt, gibt diese Funktion eine Fehlermeldung aus und * beendet das Programm). * Die neue Struktur soll nicht initialisiert werden! */ struct eintrag *neuer_eintrag() { __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ } /* * Funktion speichere_eintraege * öffnet zuerst die übergebene Datei * - wenn hierbei ein Fehler auftritt, wird eine entsprechende * Meldung ausgegeben und das Programm abgebrochen * anschliessend wird für jedes Listenelement eine Zeile in der Form * "Nachname Vorname Telefonnummer" * in die Datei geschrieben */ void speichere_eintraege(struct eintrag *telbuch, char *datei) { FILE *fp; __________________________________________________________ __________________________________________________________ /* Ausgabedatei öffnen */ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ /* Telefonbuch (Liste der Einträge) ausgeben */ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ __________________________________________________________ } Aufgabe 2: (8 Punkte) Markieren und verbessern Sie die Fehler in dem untenstehenden Programm, das den Benutzer nach einer Laufzeit, einem Zinssatz sowie einer monatlichen Sparrate fragt und daraus Zinsen und Zinseszinsen berechnet. (Sie können davon ausgehen, daß max. 8 Fehler im Programm versteckt sind.) Falsch erkannte Fehler werden negativ gewertet! #include /* Default: Zinsgutschrift am #define DEFAULT_WERTSTELLUNG 3; Quartalsende (alle 3 Monate) */ int parseargs(int argc, char *argv[]); int main(int argc, char *argv[]) { int m, monate, wertstellung; double zins, zinssatz, betrag; wertstellung = parseargs(argc, *argv); printf("Laufzeit (Monate): "); scanf("%d", monate); printf("Zinssatz (in %): "); canf("%lf", &zinssatz); printf("Betrag: "); scanf("%lf", &betrag); zins = 0.0; for(m=0; m 2 #define LEN 5 3 4 int main(int argc, char *argv[]) 5 { 6 int i; 7 char *zk, erg[LEN]; 8 for (i=0; argv[i] != NULL ; i++) { 9 zk = argv[i]; erg[i] = zk[0]; 10 } 11 erg[i] = '\0'; 12 printf("%s\n", erg); 13 return 0; 14 } +-------++-------+----------+------------------------------------+ | Zeile || i | zk | erg | | || | | erg[0] erg[1] erg[2] erg[3] erg[4] | +-------++-------+----------+------------------------------------+ | || | | | +-------++-------+----------+------------------------------------+ | || | | | +-------++-------+----------+------------------------------------+ | || | | | +-------++-------+----------+------------------------------------+ | || | | | +-------++-------+----------+------------------------------------+ | || | | | +-------++-------+----------+------------------------------------+ | || | | | +-------++-------+----------+------------------------------------+ | || | | | +-------++-------+----------+------------------------------------+ | || | | | +-------++-------+----------+------------------------------------+ | || | | | +-------++-------+----------+------------------------------------+ | || | | | +-------++-------+----------+------------------------------------+ | || | | | +-------++-------+----------+------------------------------------+ | || | | | +-------++-------+----------+------------------------------------+ | || | | | +-------++-------+----------+------------------------------------+ | || | | | +-------++-------+----------+------------------------------------+ | || | | | +-------++-------+----------+------------------------------------+ Aufgabe 4: (6 Punkte) Sie benötigen für eine Berechnung die Fibonacci-Zahlen. Ein kurzer Blick in ein 24-bändiges Standardlexikon liefert folgende (hier leicht abgeänderte) Definition: "Fibonacci-Folge, nach L. FIBONACCI die Folge der Zahlen 1, 1, 2, 3, 5, 8, 13, ... , wobei jedes Glied gleich der Summe der beiden vorangehenden Glieder ist; allgemein: a(n) = a(n-2) + a(n-1) mit a(1) = a(2) = 1." Schreiben Sie eine rekursive Funktion namens fib, die bei gegebenem n die entsprechende Fibonacci-Zahl berechnet (Fehlerabfragen sind nicht nötig). Aufgabe 5: (5 Punkte) a) Betrachten Sie das folgende Programmstück? float f = 10.0; f = f / 100.0; f = f * 10.0; Welchen Wert erwartet der "unerfahrene" Programmierer in der Variablen f nach Ausführung der letzten Zeile? Womit dagegen rechnen Sie, und warum ist das so? b) Was ist der Unterschied zwischen einer Funktionsdefinition und einer Funktions-deklaration (Prototyp)? Warum werden Funktionsdeklarationen benötigt?