Hochschule Ravensburg-Weingarten Schriftliche Prüfung Programmieren Prof. Dr. M. Zeller Datum, Zeit, 10:30 12:00 Uhr(90 min) Aufgabenblätter 15 Seiten(einschl. Deckblatt) erreichbare Punktzahl 61 zugelassene Hilfsmittel A(s. Prüfungsplan) Studiengang Prf. Nr. Raum AI 3600 C004 EI 2210 C004 WI 4104b C004 Name, Vorname: Matrikelnummer: Hinweise: Schreiben Sie bitte Name und Matrikelnummer auf jedes Aufgabenblatt. Schreiben Sie Ihre Lösung zu den Aufgaben auf den freien Platz, direkt anschließend an die Fragestellungen. Wenn Sie zusätzliche Blätter verwenden, so schreiben Sie bitte Name und Matrikelnummer auf jedes Blatt. Schreiben Sie lesbar! Vom Prüfer auszufüllen: Aufgabe 1 2 3 4 Summe Max. Punkte 12 6 31 12 61 Punkte
Seite 2 (15) Vorbemerkung Die Klausur ist ziemlich umfangreich. Lassen Sie sich nicht verunsichern, Sie benötigen nicht alle Punkte für die Note 1,0; Sie benötigen wenigerals diehälfte derpunktefür dienote4,0. Bei den gezeigten Programmen ist/sind die Zeile(n) #include... nicht abgedruckt. Dies dient dazu, Platz zu sparen; gehen Sie davon aus, dass die Programme jeweils alle notwendigen Bibliotheken einbinden. Aufgabe 1 Gegeben ist ein Programm, das neben der Funktion main() vier weitere Funktionen enthält. float posaverage( int [], int ); int diffsquaresum( int [], int ); int exchangecontent (char [], char []); int printpermutation(char [], int [], int ); int main (void){ char alphabet [] = "daecb" ; char word[] = "xyz12345" ; int mix[] = {1, 4, 3, 0, 2, 0; int result ; int values [] = {1, 4, 3, 8, 2, 1, 5; float average ; average = posaverage(values, 7); printf ("\n posaverage: %5.2f\n", average ); result = diffsquaresum(mix, 6); printf ("\n diffsquaresum: %i\n", result ); printf ("\n alphabet : %s, word: %s", alphabet, word); result = exchangecontent (alphabet, word); printf ("\n alphabet : %s, word: %s", alphabet, word); printf ("\n %i\n", result ); printf ("\n printpermutation \n " ); result = printpermutation(alphabet, mix, 6); printf ("\n %i\n", result ); return 0;
Seite 3 (15) Ein Beispiel für einen Programmlauf: posaverage: 2.67 diffsquaresum: 27 alphabet: daecb, word: xyz12345 alphabet: xyz12, word: daecb result: 5 printpermutation y21xzx result: 0 1.1 (3 Punkte) Die Funktion float posaverage(int values[], int length) berechnet den Durchschnitt aller positiven Zahlen im Array values. Dabei werden nur die ersten length Elemente des Arrays betrachtet. Vervollständigen Sie die Funktion float posaverage(int values[], int length), definieren Sie dabei keine zusätzlichen Variablen, verwenden Sie keine existierenden Funktionen. float posaverage( int values [], int length ){ int sum = 0; int numcount = 0; int i ; for( i = 0; i < length ; i ++){ if (values[ i ] > 0){ sum +=values[ i ]; numcount++; return ( float ) sum/numcount;
Seite 4 (15) 1.2 (3 Punkte) Die Funktion int diffsquaresum(int values[], int length) berechnet folgenden Wert: Für alle Index-Werte i zwischen 1 und length berechnet die Funktion die Differenz zwischen values[i-1] und values[i]. Dieser Wert wird dann quadriert. Die Funktion summiert alle quadrierten Differenzen auf und gibt diesen Wert als Rückgabewert zurück. Ein Beispiel: Formal: 1 4 3 0 2 0 3-1 -3 2-2 9 1 9 4 4 i<length i=1 (values[i] values[i 1]) 2 27 Vervollständigen Sie die Funktion int diffsquaresum(), definieren Sie dabei keine zusätzlichen Variablen, verwenden Sie keine existierenden Funktionen. int diffsquaresum( int values [], int length ){ int sum = 0; int diff = 0; int i = 0; for ( i = 1; i < length ; i = i + 1){ diff = values[ i ] values[i 1]; sum = sum + diff diff ; return sum;
Seite 5 (15) 1.3 (3 Punkte) Die Funktion int exchangecontent(char stringa[], char stringb[]) vertauscht den Inhalt der beiden Arrays. Das Wort, das vor dem Funktionsaufruf im Arrays stringa steht, steht danach in stringb und umgekehrt. Allerdings begrenzt das kürzere der beiden Wörter den Vorgang. Nach dem Funktionsaufruf sind also beide Wörter nur noch so lang, wie das kürzere der beiden. Beide Wörter müssen mit einem 0-Byte abgeschlossen sein. Der Rückgabewert gibt an, wie viele Buchstaben ausgetauscht worden sind, d. h. wie lang das kürzere der beiden Wörter war. Vervollständigen Sie die Funktion int exchangecontent(), definieren Sie dabei keine zusätzlichen Variablen, verwenden Sie keine existierenden Funktionen. int exchangecontent (char stringa [], char stringb []){ char tmp; int i= 0; while (( stringa[ i ]!= 0) && ( stringb[ i ]!= 0)){ tmp = stringa[ i ]; stringa[ i ] = stringb[ i ]; stringb[ i ] = tmp; i = i +1; stringa[ i ] = 0; stringb[ i ] = 0; return i ;
Seite 6 (15) 1.4 (3 Punkte) Die Funktion int printpermutation(char charset[], int perm[], int length) zeigt die Buchstaben des Arrays charset in einer Reihenfolge an, die durch das Array perm gegeben ist. Der Parameter length gibt an, wie viele Buchstaben ausgegeben werden sollen. Die Funktion durchläuft die ersten length Werte des Arrays perm. Wenn die Funktion im Arrays permden Wert n vorfindet, so gibt sie den n + 1-en Wert des Arrays charset aus. Jeder Wert des Arrays perm dient also als Index in das Array charset. Es gelten folgende Einschränkungen: Wenn der Wert n kleiner als 0 ist, kehrt die Funktion mit dem Rückgabewert-1 zurück. Wenn der Wert n größeroder gleich lenchar ist, kehrt die Funktion mit dem Rückgabewert-2 zurück. Ein Beispiel: Ausgabe: a b c d e d 1 4 3 0 2 0 perm d a e c b charset Vervollständigen Sie die Funktion int printpermutation(), definieren Sie dabei keine zusätzlichen Variablen, verwenden Sie keine existierenden Funktionen. int printpermutation(char charset [], int perm[], int length ){ int i ; int lenchar = strlen ( charset ); for ( i = 0; i < length ; i = i +1){ if (perm[ i ] < 0){ return 1; if (perm[ i ] >= lenchar){ return 2; printf ( "%c", charset[perm[ i ]]); return 0;
Seite 7 (15) Aufgabe 2 Gegeben ist folgendes C-Programm: char flag = C ; float oops(char dummy, int value1 ){ float result = value1 / dummy; printf ("\n result = %5.2f ", result ); dummy = flag ; dummy = NULL; return result ; char bar(char flag, int values []){ float dummy = oops(&flag, values [1]); printf ("\n dummy = %5.2f, flag = %c ", dummy, flag ); if (dummy > 0.5){ values[1] = 1; else { values[1] = 22; return flag 1; int main(void){ char flag = b ; int nums [] = {1, 2, 3, 4; int i ; flag = bar(flag, nums); printf ("\n main: flag = %c \n", flag ); for( i = 0; i < 4; i ++){ printf (" %d, ", nums[ i ]); return 0; Der ASCII-Codevon b ist98, dervon C ist67. 2.1 (6 Punkte) Welche Ausgabe erzeugt das Programm?
Seite 8 (15) result = 0.00 dummy = 0.00, flag = C main: flag = B 1, 22, 3, 4,
Seite 9 (15) Aufgabe 3 Gegeben ist folgendes Programm: #define LENGTH 20 struct person{ cha r lastname[length]; short idnum; ; typedef struct person PERSON; typedef PERSON PERSON_PTR; struct bus{ int idnum; struct bus follow ; char name[length]; struct person driver ; ; typedef struct bus BUS; typedef BUS BUS_PTR; int main (void){ PERSON driver1 = {"Enekoro", 4; PERSON driver2 = {"Geradaks", 7; PERSON driver3 = {"Impoleon", 8; PERSON driver4 = {"Tornupto", 1; PERSON driver5 = {"Miltank", 2; BUS bus1 = {1, NULL, "NAG 502N", driver2 ; BUS bus2 = {2, NULL, "Neoplan", driver5 ; BUS bus3 = {3, &bus2, "Setra GTi", driver1 ; BUS bus4 = {4, &bus1, "Citaro LE", driver4 ; BUS bus5 = {5, &bus3, "FBW LN 40", driver3 ; BUS_PTR busptr1 ; FILE busfile ; bus1. follow = &bus5 ; busptr1 = createbus (4, "Post", driver1 ); printbuses(busptr1 ); busfile = openfilerw("bus. data" ); savebus(busptr1, busfile ); rewind( busfile ); readbus(&bus2, busfile ); printbuses(&bus2 ); return 0;
Seite 10 (15) Folgende Funktionen sind in dem Programm definiert: void printdriver (PERSON_PTR); void printbuses(bus_ptr); BUS_PTR createbus (int, char[], PERSON); FILE openfilerw(char []); int savebus(bus_ptr, FILE ); int readbus(bus_ptr, FILE ); 3.1 (3 Punkte) Skizzieren Sie die Datenstruktur, die durch die Variablen driver1, driver2...driver5 und die Variablen bus1, bus2...bus5 gebildet wird. Zeichnen Sie für jede Struktur ein Kästchen und für jeden Pointer einen Pfeil. Schreiben Sie zu jeder Struktur den Namen der Variable. bus4 bus1 bus5 bus3 bus2 follow follow follow follow follow NULL driver4 driver2 driver3 driver1 driver5
Seite 11 (15) 3.2 (6 Punkte) Die folgenden Ausdrücke bezeichnen entweder einen Datentyp oder eine Variable.KreuzenSiejeweilsan,obessichbeidemAusdruckumeinenTypoder umeinevariablehandelt.wennessichumeinevariablehandelt,sogebensie auch dentypdervariablen an. Ausdruck Typ Variable wenn Variable, welcher Typ? bus2.idnum X int bus4.follow X BUS * busptr->name X char [] BUS_PTR X driver5.idnum X short busptr1->driver X PERSON FILE * X 3.3 (1 Punkt) Die Funktion void printdriver(person_ptr) soll die ID-Nummer (idnum) und den Namen des Fahrers (lastname) auf dem Bildschirm ausgeben. Ergänzen SiedieFunktionan denmit... gekennzeichnetenstellen. void printdriver (PERSON_PTR driver ){ printf ("\n Driver ID: %d, ", driver >idnum); printf (" %s \n", driver >lastname); return ; 3.4 (4 Punkte) Die Funktion void printbuses(bus_ptr bus) soll alle Busse durchlaufen, die über den Pointer bus erreichbar sind. Zu jedem Bus soll der Name und die ID-Nummer des Busses ausgegeben werden, sowie die ID-Nummer und der NamedesFahrers.ErgänzenSiedieFunktionandenmit... gekennzeichneten Stellen. void printbuses(bus_ptr bus){ while (bus!= NULL){ // 1 printf ("\n Bus ID: %d, %s", bus >idnum, bus >name); // 1 printdriver(&bus >driver ); // 1 bus= bus >follow ; // 1 return ;
Seite 12 (15) 3.5 (5 Punkte) Die Funktion BUS_PTR createbus(int id, char textid[], PERSON driver) soll eine dynamische Variable vom Typ BUS erzeugen. Die Komponeten der Struktur sollen mit den als Parameter angegebenen Werten belegt werden, der Verkettungs-Pointer soll den Wert NULL erhalten. Der Programmcode soll keine Zahl enthalten. Ergänzen Sie die Funktion an den mit... gekennzeichneten Stellen. BUS_PTR createbus ( int id, char textid [], PERSON driver ){ BUS_PTR bus = (BUS_PTR) malloc( sizeof (BUS)); // 2 if (bus == NULL){ // 0,5 return NULL; bus >idnum = id ; // 0,5 strncpy(bus >name, textid, LENGTH); // 1 bus >driver = driver ; // 0,5 bus >follow = NULL; // 0,5 return bus; 3.6 (3 Punkte) Die Funktion FILE openfilerw(char filename[]) soll eine Datei öffnen. Der Name derdateiwirdalsparameterandiefunktionübergeben.diedateisollnachdemöffnen leer sein. Wenn die Datei vor dem Öffnen noch nicht existiert, soll sie angelegt werden. Die Datei soll zum Lesen und Schriben geöffnet sein. War das Öffnen erfolgreich, so gibt die Funktion einen File-Pointer zurück, ansonsten beendet sich das Programm. Ergänzen Sie die Funktion an den mit... gekennzeichneten Stellen. FILE openfilerw(char filename []){ FILE fileptr = fopen(filename, "w+b" ); // 2 if ( fileptr == NULL){ // 0,5 exit ( 1); return fileptr ; // 0,5
Seite 13 (15) 3.7 (5 Punkte) Die Funktion int savebus(bus_ptr bus, FILE busfile) schreibt die Daten der Struktur aufdie derpointer buszeigtaufdenstream busfile.es sollendie Datengenau einer Struktur-Variable geschrieben werden. Wenn das Schreiben erfolgreich war, gibt die Funktion die Anzahl der geschriebenen Datensätze zurück(hier also den Wert 1), ansonsten beendet sich das Programm. Ergänzen Sie die Funktion an den mit... gekennzeichneten Stellen. int savebus(bus_ptr bus, FILE busfile ){ int savecount; savecount = fwrite (bus, sizeof (BUS), 1, busfile ); // 2,5 if (savecount!= 1){ // 1 exit ( 2); // 0,5 return savecount; Kann ein Aufruf der Funktion fwrite() in diesem Programm mehr als eine Struktur- Variable schreiben, z. B. die Variable bus5 und die zwei nachfolgenden, verketteten Variablen? Wenn ja, wie lautet der Aufruf von fwrite(), wenn nein. warum nicht? 3.8 (3 Punkte) Die Funktion int readbus(bus_ptr bus, FILE busfile) liest Daten aus dem Stream busfile und speichert sie in der Struktur, auf die der Pointer bus zeigt. Wenn das Lesen erfolgreich war, gibt die Funktion die Anzahl der gelesenen Datensätze zurück (hier also den Wert 1), ansonsten beendet sich das Programm. Ergänzen Sie die Funktion andenmit... gekennzeichneten Stellen. int readbus(bus_ptr bus, FILE busfile ){ int readcount ; readcount = fread (bus, sizeof (BUS), 1, busfile ); // 2 if (readcount!= 1){ // 0,5 exit ( 3); return readcount ; // 0,5 3.9 (1 Punkte) Welche Ausgabe erzeugt das Programm in der letzten Ausgabe-Anweisung der Funktion main():printbuses(&bus2);? Bus ID:4, Post Driver ID: 4,Enekoro
Seite 14 (15) Aufgabe 4 Gegeben ist folgendes Programm: int foo( int k, int n){ int result = 1; if (k <= 1){ return 1; printf ("\n k: %2i, n: %2i ", k, n); result = foo(k/n, n+1) + foo(k/n, n+1); return result ; int main(void){ int result = foo(20, 2); printf ("\n foo(20, 2): %2i \n", result ); return 0; 4.1 (7 Punkte) Welche Ausgabe erzeugt das Programm? Ergänzen Sie die folgenden Zeilen an den mit... gekennzeichneten Stellen. Es genügen die ersten 5 Zeilen der Ausgabe. k: 20, n: 2 k: 10, n: 3 k: 3, n: 4 k: 3, n: 4 k: 10, n: 3 k: 3, n: 4 k: 3, n: 4 foo(20, 2): 8
Seite 15 (15) 4.2 (5 Punkte) Gegebenist diedefinition einerrekursivenfunktion rab(p)mit p N 0 : rab(p) = rab(p 1)/rab(p 2) + p für p > 1 und p gerade rab(p 1) p/2 für p > 1 und p ungerade 2 sonst Schreiben Sie eine rekursiven Funktion in C, die die Funktion rab(p) realisiert. int rab( int p){ int rab( int p){ if (p <= 1){ return 2; if (p%2 == 0){ return rab(p 1)/rab(p 2) + p ; if (p%2 == 1){ return rab(p 1) p/2; return 1;