Kompaktkurs Einführung in die Programmierung Klausur Seite 1/10 Name, Vorname, Unterschrift: Matrikelnummer: Wichtig: Klausur Kompaktkurs Einführung in die Programmierung Dr. T. Weinzierl & M. Sedlacek 25. März 2011 Die Angabe besteht aus 10 Seiten prüfen Sie bitte Ihr Exemplar auf Vollständigkeit. Kennzeichen Sie jedes Blatt lesbar mit Ihrem Namen und dieses Deckblatt zusätzlich mit Ihrer Matrikelnummer und Unterschrift; trennen Sie die Heftung nicht auf. Bearbeiten Sie die Aufgaben auf den Angabenblättern. Sollte der Platz für einen Aufgabenteil nicht reichen, benutzen Sie bitte die Rückseite der Angabenblätter und machen Sie einen entsprechenden Vermerk bei der Aufgabe. Insgesamt können Sie 40+4 Punkte erreichen (4 Punkte Überhang), bei jeder Aufgabe ist die maximale Anzahl an erreichbaren Punkten angegeben. Zum Bestehen sind 17 Punkte erforderlich. Es ist alles außer elektronische Geräte als Hilfsmittel zugelassen. Eigene Funktionen dürfen in den folgenden Teilaufgaben weiterverwendet werden; von den Standardfunktionen sind, soweit nicht bei der Aufgabe anders angegeben, nur die zur Ausgabe zulässig (std::cout bzw. printf, was immer Ihnen davon lieber ist). Die Bearbeitungszeit beträgt 75 Minuten. Aufg. 1) 2) ) 4) Pkt. o /11 o /9 o /10 o /10(+4) Summe /40(+4) Note
Kompaktkurs Einführung in die Programmierung Klausur Seite 2/10 1 Warm Up (max. 11 Punkte) a) Was ist der Inhalt von a und b nach Ausführung dieser Anweisungen? int a = 0; int b = -; if (++a!= 0 && b == -) a = a + b; b = --a; a = b = b) Was ist die Ausgabe des folgenden Programmstücks? Achten Sie auf exakte Darstellung der Ausgabe (Zeilenumbrüche?), wie sie bei Ausführung sichtbar wird. int feld[5]; for(int i = 4; i >= 0; i--) feld[i] = i + i*i; for(int i = 0; i < 5; i++) std::cout << feld[i] << " "; 0 2 6 12 20 c) Was ist der Inhalt von a und b nach Ausführung dieser Anweisungen? int a = ; int b = 7; a ==? b == 4? b = : a = 4, b = - : (a = 8, b = ); a = 4 b = Seite 2/10
Kompaktkurs Einführung in die Programmierung Klausur Seite /10 d) Entscheiden Sie jeweils, ob die Anweisung in der Zeile der Kästchen korrekt ist (kompiliert) oder nicht (kompiliert nicht). Programm korrekt nicht korrekt int main() { float z = -4.5; int i = 0; char c = d ; double ***pppd; x double *pd = z; x int j = c-4; x z++; x c++ = ++i; x return 0; Seite /10
Kompaktkurs Einführung in die Programmierung Klausur Seite 4/10 2 Schleifen und Ausgabe (max. 9 Punkte) Im Folgenden soll eine Reihe von Funktionen realisiert werden, die ein Rautenmuster wie im Bild rechts druckt. Dabei soll die Höhe der Raute von einer Variablen hoehe abhängen. Im Bild rechts hat die Raute hoehe = 4, da sich die längste Zeile, von oben gezählt, an vierter Position befindet. Alle nachfolgenden Zeilen sind wieder stufenweise kürzer. # # # # # # # # # # # # # # # # # # # # # # # # # a) Schreiben Sie eine Funktion void drucke zeile(int len), die len mal das Zeichen # und abschließend einen Zeilenumbruch druckt. Hierbei soll noch nicht auf das Rautenmuster eingegangen werden. void d r u c k e z e i l e ( i n t l e n ) { f o r ( i n t i = 1 ; i <= l e n ; i ++) s t d : : c o u t << # ; s t d : : c o u t << s t d : : e n d l ; b) Schreiben Sie nun eine Funktion void raute(int hoehe), die die Raute linksbündig wie im Bild rechts druckt. Nehmen Sie hierzu Ihre Funktion aus Teilaufgabe a) zu Hilfe. Hinweis: Es sollen linksbündige Rauten beliebiger hoehe gedruckt werden können und nicht nur für hoehe = 4. void r a u t e ( i n t hoehe ) { i n t z e i c h e n = 1; f o r ( i n t z = 1 ; z <= 2 hoehe 1; z ++) { i f ( z <= hoehe ) { z e i c h e n += 2 ; d r u c k e z e i l e ( z e i c h e n ) ; e l s e { z e i c h e n = 2 ; # # # # # # # # # # # # # # # # # # # # # # # # # Seite 4/10
Kompaktkurs Einführung in die Programmierung Klausur Seite 5/10 d r u c k e z e i l e ( z e i c h e n ) ; c) Schreiben Sie nun eine Funktion void einruecken(int z), die z mal eine Leerposition (whitespace) druckt. Vervollständigen Sie anschließend Ihre Funktion void raute(int hoehe) aus Teilaufgabe b) so, dass die Raute in richtiger Form gedruckt wird. Hierzu müssen Sie ihre Funktion aus Teilaufgabe b) nochmals abschreiben und mit der Funktion void einruecken(int z) korrekt vervollständigen. Hinweis: Es sollen Rauten beliebiger hoehe gedruckt werden können und nicht nur für hoehe = 4. void e i n r u e c k e n ( i n t z ) { f o r ( i n t i = 1 ; i <= z ; i ++) s t d : : c o u t << ; void r a u t e ( i n t hoehe ) { i n t z e i c h e n = 1; f o r ( i n t z = 1 ; z <= 2 hoehe 1; z ++) { i f ( z <= hoehe ) { z e i c h e n += 2 ; e i n r u e c k e n ( hoehe z ) ; d r u c k e z e i l e ( z e i c h e n ) ; e l s e { z e i c h e n = 2 ; e i n r u e c k e n ( z hoehe ) ; d r u c k e z e i l e ( z e i c h e n ) ; Seite 5/10
Kompaktkurs Einführung in die Programmierung Klausur Seite 6/10 Rang-Eins-Matrizen und Ausgabe (max. 10 Punkte) Im Folgenden soll eine Reihe von Funktionen zur Ausgabe von Vektoren bzw. Matrizen sowie eine Funktion zur Erstellung einer Rang-Eins-Matrix realisiert werden. Eine Rang-Eins-Matrix ist eine Matrix, die aus der Multiplikation xy T zweier Vektoren x R n und y R n hervorgeht, d.h. für die Elemente der resultierenden Matrix gilt: ( xy T ) ij = x i y j. a) Skizzieren Sie grob das Speicherdiagramm bei der Ausführung folgenden Programmcodes. Skizzieren Sie ebenfalls Zeigerzuweisungen und fiktive Adressen neben den Speicherzellen. Hinweis: Es ist keine explizite Funktion gefordert, sondern nur ein grobes Speicherdiagramm, wie es in den Vorlesungen (und Übungen) benutzt wurde. int n = ; double **mtx = new double*[n]; for (int i = 0; i < n; i++) mtx[i] = new double[n]; mtx[0][2] = -7.0; mtx[2][1] = 5.0; Seite 6/10
Kompaktkurs Einführung in die Programmierung Klausur Seite 7/10 b) Schreiben Sie eine Funktion void drucke matrix(double **mtx, int zeilen, int spalten), oder mehrere ineinandergreifende Funktionen, zur Ausgabe einer korrekt initialisierten Matrix. Dabei soll die Matrix, die über ein mehrdimensionales Feld **mtx übergeben wird, in lesbarer Form ausgegeben werden, d.h. jede Zeile der Matrix soll in einer eigenen Zeile ausgegeben werden und zwischen den einzelnen Elementen sollen Leerzeichen stehen. void d r u c k e v e k t o r ( double vec, i n t e l e m e n t e ) { f o r ( i n t j = 0 ; j < e l e m e n t e ; j ++) s t d : : c o u t << vec [ j ] << ; s t d : : c o u t << s t d : : e n d l ; void d r u c k e m a t r i x ( double mtx, i n t z e i l e n, i n t s p a l t e n ) { f o r ( i n t i = 0 ; i < z e i l e n ; i ++) d r u c k e v e k t o r ( mtx [ i ], s p a l t e n ) ; c) Schreiben Sie eine Funktion double** rangeins(double* x, double* y, int n), die als Funktionswert die Rang-Eins-Matrix zu den entsprechenden Vektoren x und y liefert. Mit dem Parameter n werde die Länge der Vektoren x und y übergeben. Der Speicherplatz für die zu erzeugende Ergebnismatrix ist innerhalb der Funktion dynamisch (mit new) anzulegen, d.h. die Matrix soll innerhalb der Funktion, vor der eigentlichen Berechnung, korrekt als Nullmatrix initialisiert werden. double r a n g e i n s ( double x, double y, i n t n ) { double mtx = new double [ n ] ; f o r ( i n t i = 0 ; i < n ; i ++) mtx [ i ] = new double [ n ] ; f o r ( i n t i = 0 ; i < n ; i ++) f o r ( i n t j = 0 ; j < n ; j ++) mtx [ i ] [ j ] = x [ i ] y [ j ] ; return mtx ; Seite 7/10
Kompaktkurs Einführung in die Programmierung Klausur Seite 8/10 4 Stack und Listen (max. 10 (+4) Punkte) Ein Stack (Keller- oder Stapelspeicher) ist eine listenähnliche Datenstruktur, in die nur an einem Ende eingefügt oder gelöscht werden kann. Bildlich werden die Elemente übereinander gestapelt und in umgekehrter Reihenfolge vom Stapel genommen. Dies wird auch Last In First Out-Prinzip (LIFO) genannt. Dabei werden die Elemente immer vorne an die Liste angehängt. Das Bild rechts stellt einen Stack und die dazu korrespondierende Listenstruktur von drei Elementen dar. Im Folgenden sollen eine Reihe von Funktionen geschrieben werden, die auf einem Stack operieren. Hierbei soll keine ObjektOrientierung verwendet werden. Halten Sie sich an die vorgegebenen Funktionssignaturen! a) Definieren Sie einen rekursiven Strukturtyp struct stackelement, der nach dem Bild oben rechts ein Datum sowie einen Zeiger auf ein vorheriges Stackelement hat. s t r u c t s t a c k e l e m e n t { i n t d a t a ; s t r u c t s t a c k e l e m e n t prev ; ; 5 Stack 5 Liste NULL b) Schreiben Sie eine Funktion stackelement* push(stackelement* st, int data), die auf dem Stack ein neues Element ablegt. Dabei soll der Zeiger auf das oberste Element aktuell gehalten werden. Siehe als Beispiel Bild rechts. Sie können davon ausgehen, dass der übergebene Zeiger st bereits auf das oberste Stackelement zeigt. Oberstes Element Oberstes Element push(st,5) NULL 5 NULL Stack vorher Stack nachher stackelement* push(stackelement* st, int data) { ooooo//fügen Sie hier code ein s t a c k e l e m e n t push ( s t a c k e l e m e n t s t, i n t d a t a ) { s t a c k e l e m e n t new element = new s t a c k e l e m e n t ; new element >d a t a = d a t a ; new element >prev = s t ; return new element ; Seite 8/10
Kompaktkurs Einführung in die Programmierung Klausur Seite 9/10 c) Schreiben Sie eine Funktion int top(stackelement* st), die das Datum des obersten Stackelements zurückgibt. i n t t o p ( s t a c k e l e m e n t s t ) { return s t >d a t a ; d) Schreiben Sie eine Funktion stackelement* pop(stackelement* st), die das oberste Element des Stacks löscht und den Zeiger auf das neue oberste Element aktualisiert. Siehe als Beispiel Bild rechts. Für den Fall, dass der Stack leer ist, soll eine Fehlermeldung ausgegeben und NULL zurückgegeben werden. Oberstes Element 5 Stack vorher NULL Oberstes Element pop(st) Stack nachher s t a c k e l e m e n t pop ( s t a c k e l e m e n t s t ) { s t a c k e l e m e n t new head ; i f (! s t ) { s t d : : c o u t << pop ( ) a u f l eerem S t a c k i l l e g a l! << s t d : : e n d l ; return NULL; e l s e { new head = s t >prev ; d e l e t e s t ; return new head ; NULL e) Schreiben Sie eine Funktion die einen Stack übergeben bekommt und den gesamten Stack druckt. Dabei sollen die Elemente von oben nach unten ausgegeben werden. Das heißt, dass das zuletzt hinzugefügte Element als erstes gedruckt werden soll. void d r u c k e s t a c k ( s t a c k e l e m e n t s t ) { while ( s t!= 0) { s t d : : c o u t << t o p ( s t ) << s t d : : e n d l ; s t = s t >prev ; Seite 9/10
Kompaktkurs Einführung in die Programmierung Klausur Seite 10/10 f) Schreiben Sie nun eine objektorientierte Variante der Funktion pop(...), die das oberste Element des Stacks löscht, analog zu Teilaufgabe d). c l a s s S t a c k e l e m e n t { p u b l i c : S t a c k e l e m e n t ( ) { d a t a = 0 ; p r e v = NULL; t o p = NULL; S t a c k e l e m e n t ( i n t d a t a ) { d a t a = d a t a ; p r e v = NULL; t o p = t h i s ; void push ( i n t d a t a ) { S t a c k e l e m e n t new element = new S t a c k e l e m e n t ( d a t a ) ; new element >p r e v = t o p ; t o p = new element ; void p r i n t ( ) { S t a c k e l e m e n t s t = t o p ; while ( s t!= NULL) { s t d : : c o u t << s t >d a t a << s t d : : e n d l ; s t = s t >p r e v ; void pop ( ) { i f ( t o p == NULL) s t d : : c o u t << pop ( ) a u f l eerem S t a c k i l l e g a l! << s t d : : e n d l ; e l s e { S t a c k e l e m e n t tmp = t o p ; t o p = t o p >p r e v ; d e l e t e tmp ; p r i v a t e : i n t d a t a ; S t a c k e l e m e n t p r e v ; S t a c k e l e m e n t t o p ; ; Seite 10/10