HS Ravensburg-Weingarten Schriftlich Prüfung Programmieren Prof. Dr. M. Zeller Datum, Zeit Aufgabenblätter erreichbare Punktzahl zugelassene Hilfsmittel 18. Juli 2005, 08:00 – 10:00 Uhr (120 min) 12 Seiten (einschl. Deckblatt) 58 A (s. Prüfungsplan) Studiengang Prf. Nr. Raum AI 1804 C004 IK 2138 C004 WI 4004 D002 Matrikelnummer: Name: 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! Falls Sie es wünschen, dass Ihr Prüfungsergebnis auf einer Liste mit Matrikelnummern und Zensuren ausgehängt bzw. per Internet veröffentlicht wird, unterschreiben Sie bitte folgende Erklärung. Ich bin damit einverstanden, dass mein Klausurergebnis auf diese Weise veröffentlicht wird. Unterschrift: Bitte haben Sie dafür Verständnis, dass aus Gründen das Datenschutzes keine telefonischen Auskünfte gegeben werden können. Vom Prüfer auszufüllen: Aufgabe Max. Punkte Punkte 1 13 2 6 3 7 4 22 5 10 Summe 58 HS Ravensburg-Weingarten, Prof. Dr. M. Zeller Prüfung Programmieren SS05 Name: Seite 2 (12) 18. Juli 2005 Mat. Nr: Vorbemerkung 1. 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 weniger als die Hälfte der Punkte für die Note 4,0. Tipp: Aufgabe 2 ist m. E. relativ schwierig – evtl. sollten Sie sie zuletzt bearbeiten. 2. Bitte nehmen Sie sich – sofern noch nicht geschehen – in den nächsten Tagen ein paar Minuten Zeit und bewerten Sie die Vorlesung und das Praktikum Programmieren. Die Zugangsdaten zum Umfragesystem der FH wurden Ihnen vor einigen Wochen (28.06.2005) per E-Mail zugesendet. Aufgabe 1 Die Funktion countChar() zählt bestimmte Buchstaben in einem String. Die Funktion hat drei Parameter: ⊲ start: Der Wert dieses Parameter gibt die Stelle im String line an, ab dem die Funktion zählen soll. ⊲ cntChar: Der Vergleichsbuchstabe ⊲ line: Der String in dem die Funktion suchen soll Die Funktion soll im String line nach dem Buchstaben cntChar suchen, aber erst ab der durch start angegebenen Stelle. Wenn start den 4 hat und cntChar den Wert ’a’, soll die Funktion feststellen, wie oft der Buchstabe ’a’ ab dem 4.(!) Buchstaben des Strings line vorkommt. Die Funktion zählt also, wie oft der Buchstabe cntChar im Rest von line enthalten ist und gibt diesen Wert zurück (s. Bsp. unten). Das Programm: #include <s t d i o . h> int countChar ( int s t a r t , char cntChar , char l i n e [ ] ) { : } int main ( void ) { char t e s t C h a r = ’ a ’ ; int r e s u l t ; r e s u l t = countChar ( 4 , t est Cha r , ”aabaabab ” ) ; p r i n t f ( ”\n e s s i n d %d Buchstaben %c e n t h a l t e n \n ” , r e s u l t , t e s t C h a r ) ; return 0 ; } Ausgabe des Programms: es sind 3 Buchstaben a enthalten HS Ravensburg-Weingarten, Prof. Dr. M. Zeller Prüfung Programmieren SS05 Name: 1.1 Seite 3 (12) 18. Juli 2005 Mat. Nr: (5 Punkte) Vervollständigen Sie die Funktion. Sie dürfen annehmen, dass der String line stets mehr als start Buchstaben enthält. int countChar ( int s t a r t , char cntChar , char l i n e [ ] ) { } 1.2 switch-Anweisung (4 Punkte) Ersetzen Sie folgende switch-Anweisung durch äquivalente if-Anweisungen. Die Variable testChar ist definiert (Datentyp char). switch-Anweisung: switch ( t e s t C h a r ){ case ’ a ’ : p r i n t f ( ”\n found an ’ a ’ ” ) ; break ; case ’ b ’ : p r i n t f ( ”\n found a ’ b ’ ” ) ; default : p r i n t f ( ”\n found n o t h i n g ” ) ; } Äquivalentes Programmstück mit if-Anweisung(en): i f ( t e s t C h a r == ’ a ’ ){ HS Ravensburg-Weingarten, Prof. Dr. M. Zeller Prüfung Programmieren SS05 Name: 1.3 Seite 4 (12) 18. Juli 2005 Mat. Nr: if-Anweisung (4 Punkte) Gegeben ist folgende Formel der Aussagenlogik: (a > b) ∧ (b = c) Schreiben Sie eine if-Anweisung, die diesen Ausdruck auswertet und entsprechend verzweigt. D. h. wenn die Formel den Wert true liefert, soll das Programmstück den String “true“ auf dem Bildschirm ausgeben, ansonsten den String “false“. Die Variablen a, b und c sind als int definiert. if { p r i n t f ( ”\n t r u e ” ) ; } else { p r i n t f ( ”\n f a l s e ” ) ; } Schreiben Sie die if-Anweisung um, so dass kein !-Zeichen vor einer Klammer steht. Die Anweisung soll aber ebenfalls die oben gegebene logische Formel realisieren. if p r i n t f ( ”\n t r u e ” ) ; } else { p r i n t f ( ”\n f a l s e ” ) ; } { HS Ravensburg-Weingarten, Prof. Dr. M. Zeller Prüfung Programmieren SS05 Name: Seite 5 (12) 18. Juli 2005 Mat. Nr: Aufgabe 2 Gegeben ist folgendes C-Programm: #include <s t d i o . h> char mark = ’B ’ ; f l o a t boo ( int num , char ∗ t e s t ) { f l o a t r e s u l t = num / ∗ t e s t ; p r i n t f ( ”\n r e s u l t = %f ” , r e s u l t ) ; ∗ t e s t = mark ; t e s t = NULL ; return r e s u l t ; } char f a r ( char mark , int v a l u e s [ ] ) { f l o a t t e s t = boo ( v a l u e s [ 1 ] , &mark ) ; p r i n t f ( ”\n t e s t = %f , mark = %c ” , t e s t , mark ) ; i f ( test > 0.5){ values [ 1 ] = 99; } else { v a l u e s [ 1 ] = −1; } return mark + 1 ; } int main ( void ) { char mark = ’ a ’ ; int numbers [ ] = { 1 , 2 , 3 , 4 } ; int i ; mark = f a r ( mark , numbers ) ; p r i n t f ( ”\n main : mark = %c \n ” , mark ) ; for ( i = 0 ; i < 4 ; i ++){ p r i n t f ( ” %d , ” , numbers [ i ] ) ; } return 0 ; } Der ASCII-Code von ’a’ ist 97, der von ’A’ ist 65. 2.1 (6 Punkte) Welche Ausgabe erzeugt das Programm? HS Ravensburg-Weingarten, Prof. Dr. M. Zeller Prüfung Programmieren SS05 Name: Seite 6 (12) 18. Juli 2005 Mat. Nr: Aufgabe 3 Eine Funktion test() erhält drei int-Werte als Parameter. Die Funktion soll die Summe der drei Parameter berechnen und den Durchschnitt. Außerdem soll die Funktion prüfen, ob alle drei Parameter gleich groß sind. Die Funktion soll drei Werte an die aufrufende Funktion zurückliefern: ⊲ die Summe als int-Wert ⊲ der Durchschnitt als float-Wert ⊲ ein char-Wert, der angibt ob alle drei Parameter gleich groß sind (’g’ für gleich groß, ’u’ für ungleich). 3.1 (7 Punkte) Definieren Sie eine geeignete Datenstruktur für den Rückgabewert der Funktion test() und ergänzen Sie die Funktion testResult(). struct t e s t R e s u l t { }; typedef struct t e s t R e s u l t T RESULT; T RESULT t e s t ( int num1 , int num2 , int num3 ) { T RESULT r e s u l t ; return r e s u l t ; } HS Ravensburg-Weingarten, Prof. Dr. M. Zeller Prüfung Programmieren SS05 Name: Mat. Nr: Aufgabe 4 Gegeben ist folgendes Programm: #include <s t d i o . h> struct p er s Data { char name [ 3 0 ] ; int matrNr ; char s t d g a n g [ 3 0 ] ; }; typedef struct p er s Data PERS DATA ; struct e r g e b n i s { char f a c h [ 1 0 ] ; f l o a t bewertung ; struct e r g e b n i s ∗ r e s t ; }; typedef struct e r g e b n i s ERGEBNIS ; struct s t u d e n t { PERS DATA p e r s o n ; ERGEBNIS ∗ noten ; }; typedef struct s t u d e n t STUDENT; void p r i n t S t u d (STUDENT s t u d e n t ){ : : } int main ( void ){ PERS DATA p e r s = { ”Anna ” , 12345 , ”AI ” } ; ERGEBNIS e r g 1 = { ”PROG” , 1 . 7 , NULL} ; ERGEBNIS e r g 2 = { ”MATH1” , 2 . 7 , NULL} ; ERGEBNIS e r g 3 = { ”ENGL” , 3 . 3 , NULL} ; ERGEBNIS e r g 4 = { ”INET1” , 2 . 0 , &e r g 1 } ; STUDENT s tu d = { p er s , &e r g 2 } ; e r g 2 . r e s t = &e r g 4 ; e r g 1 . r e s t = &e r g 3 ; p r i n t S t u d ( s tu d ) ; p r i n t f ( ”\n ” ) ; return 0 ; } Seite 7 (12) 18. Juli 2005 HS Ravensburg-Weingarten, Prof. Dr. M. Zeller Prüfung Programmieren SS05 Name: 4.1 Seite 8 (12) 18. Juli 2005 Mat. Nr: (4 Punkte) Skizzieren Sie die Datenstruktur, die in der Funktion main() angelegt wird. Zeichnen Sie für jede Variable, die eine Struktur darstellt ein Kästchen, für jede Komponente der Struktur ein “Fach“ innerhalb des Kästchens. Zeichnen Sie für jeden Pointer einen Pfeil. Es genügt, wenn Sie die Namen der Variablen und die Namen der Komponenten eintragen. Sie müssen nicht für jede Komponenten den Wert eintragen. Beispiel für ein Variable name der Variable Komponente Komponente : : : 4.2 (5 Punkte) Die folgenden Ausdrücke bezeichnen entweder einen Datentyp oder eine Variable. Kreuzen Sie jeweils an, ob es sich bei dem Ausdruck um einen Typ oder um eine Variable handelt. Wenn es sich um eine Variable handelt, so geben Sie auch den Typ der Variablen an. Ausdruck ERGEBNIS pers.std_gang erg1.bewertung &pers PERS_DATA Typ Variable wenn Variable, welcher Typ? HS Ravensburg-Weingarten, Prof. Dr. M. Zeller Prüfung Programmieren SS05 Name: 4.3 Seite 9 (12) 18. Juli 2005 Mat. Nr: (5 Punkte) Ergänzen Sie die Funktion printStud() gemäß dem vorgegebenen Prototyp. Die Funktion soll zu einem Studenten folgendes auf dem Bildschirm ausgeben: ⊲ Name und Matrikelnummer ⊲ zu jedem gespeicherten Prüfungsergebnis den Namen des Faches und die Note Die Datenstruktur darf dabei nicht verändert werden. void p r i n t S t u d (STUDENT s t u d e n t ){ } 4.4 (5 Punkte) Nehmen Sie an, die Prüfungsergebnisse eines Studenten werden in einem Array gespeichert ERGEBNIS ergebnisse[]; bis sie auf eine Datei geschrieben werden. Ergänzen Sie die Funktion saveErgs() gemäß dem unten angegebenen Rahmen. Die Funktion soll folgendes leisten: ⊲ Sie öffnet eine Datei. Der Datei-Name ist der Wert des Parameters fileName. ⊲ Sie schreibt so viele Ergebnisse aus dem Array in die Datei, wie im Parameter cnt angegeben. ⊲ Sie schließt die Datei wieder. Beispiel: Bei einem Aufruf saveErgs(ergebnisse, 3, ”myFile.dat”); soll die Funktion die ersten 3 Ergebnisse aus dem Array ergebnisse in die Datei myFile.dat schreiben. HS Ravensburg-Weingarten, Prof. Dr. M. Zeller Prüfung Programmieren SS05 Name: Seite 10 (12) 18. Juli 2005 Mat. Nr: void s a v e E r g s (ERGEBNIS e r g [ ] , int cnt , char f i l e N a m e [ ] ) { int saveCnt ; FILE ∗ o u t F i l e = f o pen ( . . . . . . , if ( . . . . . . . . . .){ p r i n t f ( ”\n can ’ t open f i l e %s ” , } saveCnt = f w r i t e ( . . . , . . .); . . . . . . ); . . . . . ., . . ., . . . . . .); fclose ( . . .); return ; } Wie können/sollten Sie prüfen, ob ein Schreibvorgang erfolgreich war? 4.5 (3 Punkte) Das Programm soll nun dynamische Speicherverwaltung einsetzen. Im folgenden Programmfragment sind die Variablen myName, myNum, myStdgang, myFach und myNote passend definiert und mit Werten belegt. Das Programmfragment soll die Daten eines Studenten, der genau eine Prüfung geschrieben hat, in einer dynamischen Variable anlegen. STUDENT ∗myStud = (STUDENT ∗ ) m a l l o c ( s i z e o f (STUDENT) ) ; s t r n c p y ( myStud−>p e r s o n . name , myName, 3 0 ) ; myStud−>p e r s o n . matrNr = myNum; s t r n c p y ( myStud−>p e r s o n . st d g a ng , myStdgang , 3 0 ) ; myStud−>noten−>bewertung = myNote ; s t r n c p y ( myStud−>noten−>f a ch , myFach , 1 0 ) ; Enhält das Programmfragment einen grundsätzlichen Fehler? Wenn ja, welchen, wie lässt er sich beheben? HS Ravensburg-Weingarten, Prof. Dr. M. Zeller Prüfung Programmieren SS05 Name: Seite 11 (12) 18. Juli 2005 Mat. Nr: Aufgabe 5 Folgendes Programm mit einer rekursiven Funktion ist gegeben: #include <s t d i o . h> void bar ( int s t a r t , int i f ( s t a r t >= end ) { return ; } p r i n t f ( ”\n bar : %c , bar ( s t a r t + 1 , end , bar ( s t a r t , end − 1 , return ; } end , char l i n e [ ] ) { %c ” , l i n e [ s t a r t ] , l i n e [ end ] ) ; line ); line ); int main ( void ) { bar ( 2 , 5 , ” a b c d e f ” ) ; p r i n t f ( ”\n ” ) ; return 0 ; } 5.1 (5 Punkte) Welche Ausgabe erzeugt das Programm? Ergänzen Sie die folgenden Zeilen; die ersten 5 Zeilen genügen. bar: bar: bar: bar: bar: bar: XXX bar: XXX 5.2 (5 Punkte) Gegeben ist die Definition einer rekursiven Funktion: f oo(0) = 1 HS Ravensburg-Weingarten, Prof. Dr. M. Zeller Prüfung Programmieren SS05 Name: Seite 12 (12) 18. Juli 2005 Mat. Nr: f oo(k) = 1 + f oo(k − 1)/k k∈N Schreiben Sie eine rekursiven Funktion in C, die die Funktion f oo() realisiert. f l o a t f o o ( int k ) { }