Friedrich-Alexander-Universität Erlangen-Nürnberg Schriftliche Prüfung zur Vorlesung "Einführung in die Programmierung für Ingenieure (C)" Aufgabe1 Aufgabe2 Aufgabe3 Aufgabe4 Aufgabe5 Gesamt 40 10 10 6 14 80 Erlangen, 27.01.1999 · Die Bearbeitungszeit beträgt 120 Minuten. · Es sind keine Hilfsmittel zugelassen. Aufgabe 1: (40 Punkte) Schreiben Sie ein Programm bsort das mit Hilfe des "Bubble-Sort"-Algorithmus ein Array (= Feld) von ganzen Zahlen aufsteigend sortiert. Beim Aufruf soll man dem Programm auf der Kommandozeile mitteilen können, wieviele Zahlen einzulesen sind und ob die Summe aller Zahlen (Option -s) und/oder deren Mittelwert (Option -m) ausgegeben werden sollen. Programmaufrufe könnten z.B. wie folgt aussehen: bsort -s 15 bsort 12 -m -s bsort -m -s Der erste Aufruf würde bedeuten, daß der Benutzer 15 Zahlen eingeben soll, die anschließend sortiert werden und deren Summe bei der Ausgabe angezeigt wird. Ihnen sind die untenstehende main-Funktion sowie die Deklarationen der benötigten Funktionen vorgegeben. Sie sollen nun die deklarierten Funktionen implementieren, sowie zu den Funktionen init_array und sort_array jeweils ein Struktogramm erstellen. (Achtung: Verwenden Sie keine globalen Variablen!) Beschreibung der einzelnen Funktionen: a) parse_ops: Bearbeitet die Kommandozeilenoptionen. Für jede vorhandene Option (-s und/oder -m) soll die jeweils entsprechende Variable (flag_s , flag_m) den Wert 1 erhalten, andernfalls 0. Wenn eine Zahl vorhanden ist wird num auf den entsprechenden Wert gesetzt, ansonsten wird 10 eingestellt. Bei Fehlaufrufen (z.B. wenn die Zahl<=0 ist, etc.) soll das Programm eine Fehlermeldung ausgeben und terminieren. Zur Umwandlung einer Ziffernfolge in einen Integer-Wert kann die Funktion int atoi(char *str) verwendet werden (wobei str einen Zeiger auf den zu konvertierenden String darstellt). Hinweis: Falls str keine Zahl repräsentiert liefert atoi den Wert 0. b) init_array: Hier muß Speicher für das Array beschafft werden. (Falls hierbei etwas schiefgeht, muß das Programm natürlich entsprechend reagieren.) Anschließend sollen vom Benutzer über die Standardeingabe die Werte in das Array eingegeben werden. Die Funktion liefert als Ergebnis einen Zeiger auf das Array. (Zuerst Struktogramm erstellen!) c) sort_array: Die Werte im Array werden sortiert, indem das Array wiederholt von vorne durchlaufen wird und je zwei benachbarte Werte ihren Platz tauschen, falls der erste größer als der zweite ist. So steigt in einem Durchlauf das größte Element wie eine "Blase im Wasser" ans Ende des Arrays. Das wird wiederholt, bis in einem Durchlauf keine Elemente mehr getauscht werden mußten. (Struktogramm nicht vergessen!) d) print_array: Funktion zum Ausgeben aller Zahlen des Feldes und ggf. deren Summe (Ganzzahl) und Mittelwert (Fließkommazahl), falls die entsprechenden Optionen angegeben waren (falls eine Option nicht gesetzt ist, soll natürlich auch die entsprechende Ausgabe unterbleiben, die Berechnung des Wertes kann aber dennoch erfolgen). Hinweis: Es bietet sich an, die Summe während der Ausgabe der Arrayelemente zu berechnen. e) swap: Funktion zum Tauschen zweier Integerwerte. f) main: Ergänzen Sie die main-Funktion so, daß der dynamisch belegte Speicher wieder freigegeben wird. #include #include void parse_ops(int argc, char *argv[], int *num, int *flag_s, int *flag_m); int *init_array(int num); void sort_array(int *arr, int num); void print_array(int *arr, int num, int flag_s, int flag_m); void swap(int *a, int *b); int main(int argc, char *argv[]) { int num; int *arr; int flag_s, flag_m; parse_ops(argc, argv, &num, &flag_s, &flag_m); arr = init_array(num); sort_array(arr, num); print_array(arr, num, flag_s, flag_m); /* Speicher freigeben (Teilaufgabe f): */ return 0; } Aufgabe 2: (10 Punkte) Markieren und verbessern Sie die Fehler (nicht mehr als 20!) in dem untenstehenden Programm, welches den kürzesten Abstand von Erlangen zu einem beliebigen Ort auf dem Globus berechnet. Dazu müssen der Name des Ortes und vor allem seine Koordinaten (Breiten- und Längengrad; östliche Länge und südliche Breite sind negativ!) Angegeben werden. Falsch erkannte Fehler werden negativ gewertet! #include #include #define ERD_RAD 6371.221; #define DGR 0.017453; #define NAMELEN 30 struct ort { oname [NAMELEN], double breite, double laenge } int moin() { double dist = 1.0; struct ort erl = ( "Erlangen", 49.36, -11.02 ); struct ort ort = { '', 0.0, 0.0 }; struct ort *o = &ort; while(dist != 0.0) do /* Abbruch: Koordinaten von { Erlangen eingeben! */ printf("Ortsname: "); scanf(%s , o->oname); printf("Breitengrad: "); scanf("%lf", &o->breite); printf("Laengengrad: "); scanf("%lf", &o->laenge); if ((o->breite==erl.breite) & (o->laenge==erl.laenge)) dist = 0.0; else { bgl = sin(DGR * erl->breite) * sin(DGR * o->breite) + cos(DGR * erl->breite) * cos(DGR * o->breite) * cos(DGR * (erl.laenge - o.laenge); dist = ERDRAD * acos(bgl); } printf("Abstand zwischen %s und %s: %lf km\n"; erl.oname, o->oname, dist); } } Aufgabe 3: (10 Punkte) Was gibt das folgende Programm ey in Zeile 12 aus, wenn es wie folgt aufgerufen wird: ey ha ? Geben Sie die Inhalte der verwendeten Variablen nach jeder ausgeführten Anweisung an! Verwenden Sie dazu die untenstehende Tabelle! 1 #include 12 printf("count: %d, string: %s\n", j, a); 2 void f(char *a, char *b); 13 return j; 3 int main(int argc, char *argv[]) 14 } 4 { 15 void f(char *a, char *b) 5 int i, j=-1; 16 { 6 char a[256]; 17 while(*b) 7 for(i=0; i=2 Falls der Funktion ein ungültiger Wert für n übergeben wird, soll dies durch Rückgabe des Wertes -1 ausgedrückt werden. Aufgabe 5: (14 Punkte) a) Welches unerwartete Verhalten kann bei folgendem Programmstück auftreten, und warum ist dies so (nur den Grundgedanken erwähnen)? float f; for ( f = 0.1; f <= 1.0; f = f + 0.1 ) printf ( "%f\n", f); b) Erstellen Sie folgende Strukturen: · Personendaten mit Vor- und Nachname (jeweils maximal 24 Zeichen), sowie Geburtsdatum (10 Zeichen). · Studentendaten, bestehend aus Personendaten, Matrikel- nummer (Ganzzahl) und Studienfach (maximal 18 Zeichen). Die Studentendaten sollen in einer verketteten Liste verwaltet werden. Kreuzen Sie bei der folgenden Teilaufgabe alle wahren Aussagen an. Es können pro Teilaufgabe mehrere Antworten richtig sein! Falsche Antworten zählen negativ. c) Welche Aussagen gehören zur Definition des Begriffs "Algorithmus"? o endliche Beschreibung o eindeutige Operationsfolge; es steht fest, welches der jeweils nächste Schritt ist o muß in einer Programmiersprache formuliert sein o Zeichen werden durch Zahlen codiert o dynamische Speicherverwaltung für verwendete Daten Die Teilaufgaben d) bis f) beziehen sich auf die unten stehenden Programmodule, die zu einem lauffähigen Programm zusammengefügt werden (z.B. durch den Compileraufruf cc -Aa -o prog prog.c mod.c). Datei prog.c: | Datei mod.h | Datei mod.c | | 1 #include "mod.h" | 1 extern int c; | 1 #include "mod.h" 2 | 2 | 2 3 static int a; | 3 int f(int b); | 3 static int b; 4 static int b = 0; | | 4 int c; 5 +-------------------| 5 6 int main() | 6 int f(int b) 7 { | 7 { 8 int a = 0; | 8 static int c = 0; 9 c = 0; | 9 a += b; 10 b = f(b); | 10 b = 5; 11 f(b); | 11 c += b; 12 if(b > 5) { | 12 return c; 13 int c = a++; | 13 } 14 printf("a=%d c=%d\n", a, ++c); | 15 c++; | 16 } | 17 printf("a=%d c=%d\n", a, c); | 18 return ++a; | 19 } | Kreuzen Sie bei den folgenden Teilaufgaben alle wahren Aussagen an. Es können pro Teilaufgabe mehrere Antworten richtig sein! Falsche Antworten zählen negativ. d) o Zeile 13 in prog.c verursacht einen Fehler, da im umschließenden Block kein a bekannt ist. o Das ++ in Zeile 18 wirkt sich nicht mehr auf a aus, da durch return zuvor das Programm beendet wird. o In mod.c kann in Zeile 9 nicht auf a zugegriffen werden; es resultiert ein Compilerfehler. o Zeile 8 in prog.c teilt der main()-Funktion mit, daß sie das a aus Zeile 3 der selben Datei mit 0 initialisieren soll. e) o Zeile 3 in mod.c legt eine modulglobale Variable b an, auf die aber nirgends zugegriffen wird. o Zeile 10 in prog.c ist fehlerhaft, da eine Vari- able (hier b) nicht gleichzeitig auf der linken und rechten Seite einer Zuweisung stehen darf. o Durch die Zeilen 4 (prog.c) und 3 (mod.c) wird ein Compiler-Fehler verursacht, da nicht zwei static-Variablen mit gleichem Namen definiert werden können. o Die Anweisung in mod.c, Zeile 10 ändert weder das in Zeile 3 der selben Datei definierte b, noch das b in prog.c, Zeile 4. o In Zeile 11 von prog.c wird der Rückgabewert der Funktion f() nicht verwendet, was zu einem Compiler-Fehler führt. f) o In Zeile 13 in prog.c darf kein neues c definiert werden, da bereits ein globales c existiert (mod.c Zeile 4) und durch die erste Zeile der HeaderDatei überall sichtbar gemacht wird. o In Zeile 9, prog.c kann der Wert von c des Moduls mod.c (Zeile 4) auf 0 gesetzt werden, da die erste Zeile der Header-Datei c überall sichtbar macht. o Bei jedem Aufruf der Funktion f() wird zuerst c auf den Wert 0 gesetzt (mod.c, Zeile 8), anschließend um 5 erhöht (Zeilen 10 und 11) so daß immer 5 als Rück- gabewert der Funktion geliefert wird. o printf() in main(), Zeile 14 gibt für a und c den gleichen Wert aus. o Zeile 15 in prog.c hat keinen Einfluß auf das globale c (mod.c, Zeile 4).