Platz für Aufkleber
2. Klausur zu den Lehrveranstaltungen
Grundlagen der Programmierung
& Datenverarbeitung
WS 2019/20
25. September 2020
Hinweise: Bitte lesen!
• Diese Klausur umfasst 8 Aufgaben und 32 Seiten. Überprüfen Sie Ihre Klausur bitte auf Vollständigkeit!
Die Heftklammer der Klausur darf nicht entfernt werden.
• Schreiben Sie bitte zuerst Ihren Namen auf jedes Blatt dieser Klausur und ggf. auf weitere von
Ihnen benutzte Zusatzblätter!
• Es sind keine Hilfsmittel außer Fremdsprachenwörterbucher erlaubt.
• Alle elektronischen Geräte (Handy, Smartphone, PDA, Smartwatches,. . . ) sind auszuschalten. Eingeschaltete
Geräte werden als Täuschungsversuch gewertet.
• Nehmen Sie sich Zeit, die Klausuraufgaben vollständig durchzulesen. Sie können insgesamt 120
Punkte erreichen; mit 60 Punkten haben Sie auf jeden Fall bestanden. Die Bearbeitungszeit beträgt
120 Minuten.
• Sollten Sie mehr als eine Lösung für eine Aufgabe anfertigen, kennzeichnen Sie die Lösung, die
bewertet werden soll. Aufgaben mit zwei Lösungen werden nicht gewertet!
• Verwenden Sie keine Bleistifte, keine Rotstifte, keine Korrekturflüssigkeiten (z. B. Tipp-Ex) und
keine Korrekturroller.
Viel Erfolg bei der Bearbeitung der Aufgaben!
A1 A2 A3 A4 A5 A6 A7 A8 P
15 15 15 15 15 15 15 15 120
http://www.hni.uni-paderborn.de/alg/lehre/ 1 / 32
Grundlagen der Programmierung & Datenverarbeitung WS 2019/20, 2. Klausur
Aufgabe 1 – Zusicherungen & Typkonvertierung (7 + 8 = 15 Punkte)
a) Das folgende Programm fragt den Benutzer nach der Eingabe einer ganzen Zahl und gibt entsprechend
dieser Zahl eine oder mehrere Ausgaben aus. Tragen sie in die Tabelle ein, für welche Werte von
i die jeweilige Ausgabe erzeugt wird.
Hinweis: Zur Angabe des Wertebereichs sind sowohl mathematische als auch sprachliche Beschreibungen
zulässig. Es muss immer der komplette Wertebereich angegeben werden! Sie können davon ausgehen,
dass die eingegebene Zahl immer ganzzahlig ist.
1 cout << "Bitte eine ganze Zahl eingeben: ";
2 int i;
3 cin >> i;
4 if ( i<42 ) {
5 cout << "A" << endl;
6 if( (i%2) == 0 ){
7 cout << "B" << endl;
8 }
9 }
10 else if( (i%2) == 0 ) {
11 cout << "C" << endl;
12 }
13 if( i>11 ) {
14 cout << "D" << endl;
15 if( i>22 && i<=25 ) {
16 cout << "E" << endl;
17 }
18 else if( i<32 || i==7 ) {
19 cout << "F" << endl;
20 }
21 } else {
22 cout << "G" << endl;
23 if( i==9 ) {
24 cout << "H" << endl;
25 }
26 }
http://www.hni.uni-paderborn.de/alg/lehre/ 2 / 32
Name, Vorname: Matrikelnummer:
Ausgabe Bedingung für i
A (Beispiel) i ist kleiner 42
Grundlagen der Programmierung & Datenverarbeitung WS 2019/20, 2. Klausur
b) Bestimmen Sie den Typ der folgenden beiden Ausdrücke, indem Sie den dazu gehörigen Syntaxbaum
angeben. Zeichnen Sie dazu so, wie aus der Vorlesung bekannt, den Baum für den entsprechenden
Ausdruck und schreiben Sie an jeden Knoten den entsprechenden Datentyp. Schreiben Sie auch an die
Blätter des Baums den Datentyp. Das Ergebnis des Ausdrucks braucht nicht berechnet und aufgeschrieben
werden.
float f = 2.5f;
short s = 1000;
int i = 12;
double d = 0.0;
1.) d * 2.0f + (float)42
2.) i > f || s*(int)’E’
http://www.hni.uni-paderborn.de/alg/lehre/ 4 / 32
Name, Vorname: Matrikelnummer:
(Zusätzlicher Platz zur Lösung von Aufgabe 1b)
http://www.hni.uni-paderborn.de/alg/lehre/ 5 / 32
Grundlagen der Programmierung & Datenverarbeitung WS 2019/20, 2. Klausur
Aufgabe 2 – Schleifen & Programmsimulation (5 + 5 + 5 = 15 Punkte)
a) Programmieren Sie eine for-Schleife welche die Zahlen x = zahl1, . . . , zahl2 ausgibt. Für eine
Zahl die ohne Rest durch 7 teilbar ist, soll an Stelle der Zahl ein “nein“ ausgegeben werden. Die Variablen
zahl1 und zahl2 speichern zwei Zahlen, die vom Benutzer eingeben werden. Die Ausgabe des
Programm für zahl1 = 7 und zahl2 = 15 sieht also wie folgt aus:
Programmierausgabe
Zahl1 ? 7
Zahl2 ? 15
nein 8 9 10 11 12 13 nein 15
Vervollständigen Sie das nachfolgende Programm:
i n t z a hl 1 , z a h l 2 ;
c o ut << " Z a hl 1 ? " ; c i n >> z a h l 1 ;
c o ut << " Z a hl 2 ? " ; c i n >> z a h l 2 ;
http://www.hni.uni-paderborn.de/alg/lehre/ 6 / 32
Name, Vorname: Matrikelnummer:
b) Das folgende Programm berechnet die Quersumme einer Zahl. Formen Sie das angegebene Programmfragment
so um, dass statt der for-Schleife eine while-Schleife verwendet wird. Die Funktionalität,
die einzelnen Berechnungsschritte mit der Variablen zahl und die Ausgabe des modifizierten
Programms sollen identisch zum ursprünglichen Programm sein.
i n t z a h l = 3 6 5;
i n t q u e r = 0 ;
f o r ( i n t i = z a h l ; i > 0; i = i / 1 0 ) {
q u e r = q u e r + i %10;
}
c o ut << " Die Quersumme i s t "<< q u e r ;
Programmierausgabe:
Die Quersumme ist 14
http://www.hni.uni-paderborn.de/alg/lehre/ 7 / 32
Grundlagen der Programmierung & Datenverarbeitung WS 2019/20, 2. Klausur
c) Schreiben Sie ein Programm für das Trinkspiel Böse7. Dabei wird der Reihe nach in ganzen Schritten
hochgezählt. Jedes Mal wenn
• die Zahl eine Sieben als Ziffer enthält,
• die Zahl durch Sieben teilbar ist,
• oder die Quersumme der Zahl durch Sieben teilbar ist
muss nein gesagt werden.
Erweitern Sie das unten angegebene Programm so, dass das Programm von 1 bis zu dem vom Benutzer
eingegebenen Maximum hochzählt und jede Zahl ausgibt. Für jede Zahl, auf welche die oben genannte
Regel der Bösen7 zutrifft, soll anstelle der Zahl ein "nein" ausgegeben werden.
Programmierausgabe
Bitte Maximum bis zu dem gespielt werden soll eingeben: 23
1 2 3 4 5 6 nein 8 9 10 11 12 13 nein 15 nein nein 18 19 20 nein 22 23
TIPP: Bilden Sie eine äußere Schleife für das Hochzählen der Zahlen und eine innere Schleife um die
Quersumme zu ermitteln und zu prüfen ob eine 7 in der Zahl vorkommt.
Vervollständigen sie das Nachfolgende Programm:
i n t maximum ;
c o ut << " B i t t e Maximum b i s zu dem g e s p i e l t we rden s o l l ei n g e b e n : " ;
c i n >> maximum ;
http://www.hni.uni-paderborn.de/alg/lehre/ 8 / 32
Name, Vorname: Matrikelnummer:
Aufgabe 3 – Zeiger (8 + 7 = 15 Punkte)
a) Dieses Programm soll die Reihenfolge der Werte in einem gegebenen Integer-Array arr spiegeln.
Initial könnte das Array die folgenden Zahlen enthalten:
{ 4 2 , 1 3 3 7 , 6 9 , 0 , 2 4 , 2 5 , 1 0 1 , 1 2 3 4 5 , 1 3 , 13}
Nach Ablauf des Programms stehen die Zahlen dann in der nachfolgenden (gespiegelten) Reihenfolge
im Array:
{ 1 3 , 1 3 , 1 2 3 4 5 , 1 0 1 , 2 5 , 2 4 , 0 , 6 9 , 1 3 3 7 , 42}
Implementieren Sie ausschließlich mithilfe der vorgegebenen Variablen und Zeigern eine Lösung, die
für eine beliebige Arraylänge größer Null und beliebige Integer-Werte im Array funktioniert. Vermeiden
Sie die Nutzung von eckigen Klammern, verwenden Sie stattdessen Zeigerarithmetik.
Tipp: ‘Durchlaufen’ Sie das Array mit den beiden Zeigern von unterschiedlichen Seiten aus bis hin zur
Mitte und tauschen Sie dabei die Werte unter Zuhilfenahme von save.
//Arraylänge: Alle Werte größer gleich 1 sind möglich
int len = 10;
//Array mit Beispielwerten
int arr[len] = {42, 1337, 69, 0, 24, 25, 101, 12345, 13, 13};
int save;
int* pl = NULL;
int* pr = NULL;
http://www.hni.uni-paderborn.de/alg/lehre/ 9 / 32
Grundlagen der Programmierung & Datenverarbeitung WS 2019/20, 2. Klausur
b) In dem folgenden Programm werden einige Berechnungen unter Verwendung von Zeigern durchgeführt.
Vollziehen Sie den Verlauf des Programms nach und füllen Sie für jeden Besuch einer markierten
Stelle einen Eintrag in der Programmsimulationstabelle aus.
• Wenn die Variable zu dem Zeitpunkt nicht lebt, tragen Sie einen Strich ein ‘—’.
• Wenn die Variable lebt, aber der Wert unbekannt ist (weil die Variable noch nicht initialisiert
wurde), tragen Sie ein ‘?’ ein.
• Wenn die Variable lebt und man den Wert der Variable direkt angeben kann, tragen Sie ihn ein.
• Wenn die Variable lebt, es sich bei dem Typ der Variable um einen Zeiger handelt und der Wert
bekannt ist, dann zeichnen Sie einen Pfeil von dem Kästchen der Variable zu dem Kästchen der
referenzierten Variable.
• Es sind nicht für alle Variablen Kästchen vorhanden (Variable i). Für Variablen ohne Kästchen
brauchen Sie keine Eintragung vorzunehmen.
• Nicht benötigte Blöcke können durchgestrichen werden. Es werden nicht alle abgedruckten Blöcke
benötigt.
int numbers[4];
for(int i=1; i<4; i++){
numbers[i] = i + 1;
} // STELLE 1
int *pta = numbers;
int *ptb = pta + 3; // STELLE 2
*pta = *ptb + 7;
pta = pta + *(numbers + 2); // STELLE 3
if(pta > ptb){
*(numbers + 1) = numbers[1];
numbers[2] = *(numbers + 1);
numbers[1] = numbers[2];
} else if (pta == ptb){
pta = pta - 2;
*ptb = *pta + numbers[0];
ptb = &numbers[2];
} else {
pta=&(*ptb);
pta--;
numbers[2] = *pta + 2;
} // STELLE 4
pta[2] = *pta + 46; // STELLE 5
http://www.hni.uni-paderborn.de/alg/lehre/ 10 / 32
Name, Vorname: Matrikelnummer: STELLE
numbers[0]
pta numbers[1]
ptb numbers[2]
numbers[3] STELLE
numbers[0]
------------------------------------------ pta numbers[1]
ptb numbers[2]
STELLE numbers[3]
numbers[0]
pta numbers[1] ------------------------------------------
ptb numbers[2]
numbers[3] STELLE
numbers[0]
------------------------------------------ pta numbers[1]
ptb numbers[2]
STELLE numbers[3]
numbers[0]
pta numbers[1] ------------------------------------------
ptb numbers[2]
numbers[3] STELLE
numbers[0]
pta numbers[1]
ptb numbers[2]
numbers[3] http://www.hni.uni-paderborn.de/alg/lehre/ 11 / 32
Grundlagen der Programmierung & Datenverarbeitung WS 2019/20, 2. Klausur STELLE
numbers[0]
pta numbers[1]
ptb numbers[2]
numbers[3] STELLE
numbers[0]
------------------------------------------ pta numbers[1]
ptb numbers[2]
STELLE numbers[3]
numbers[0]
pta numbers[1] ------------------------------------------
ptb numbers[2]
numbers[3] STELLE
numbers[0]
------------------------------------------ pta numbers[1]
ptb numbers[2]
STELLE numbers[3]
numbers[0]
pta numbers[1] ------------------------------------------
ptb numbers[2]
numbers[3] STELLE
numbers[0]
pta numbers[1]
ptb numbers[2]
numbers[3] http://www.hni.uni-paderborn.de/alg/lehre/ 12 / 32
Name, Vorname: Matrikelnummer:
(Diese Seite ist frei, kann aber als zusätzlicher Platz zur Lösung von anderen Aufgaben genutzt werden)
http://www.hni.uni-paderborn.de/alg/lehre/ 13 / 32
Grundlagen der Programmierung & Datenverarbeitung WS 2019/20, 2. Klausur
Aufgabe 4 – Funktionen (15 Punkte)
In dieser Aufgabe soll ein Programm erstellt werden, welches eine positive komplexe Zahl der Form
z = a + i · b in die Polardarstellung der Form z = r · e
iφ umwandelt, wobei r der Betrag und φ das
Argument der komplexen Zahl im Bogenmaß ist. Anschließend soll die Polardarstellung auf der Konsole
ausgegeben werden.
Wir benötigen zunächst eine Funktion um eine Zahl einzulesen. Definieren Sie dazu im folgenden Kasten
eine Funktion eingabe, die keine Parameter besitzt. Die Funktion liest einen float-Wert vom
Benutzer ein und gibt das Ergebnis als Funktionswert an die aufrufende Stelle zurück.
Definieren Sie im folgenden Kasten eine Funktion berechne_betrag, die zwei Call-by-Value Parameter
a und b vom Typ float besitzt.
Um die Wurzel einer Zahl x zu ziehen, verwenden Sie kommentarlos die Library-Funktion sqrt(x).
Definieren Sie im folgenden Kasten eine Funktion berechne_argument, die zwei Call-by-Reference
Parameter a und b vom Typ float besitzt und keinen Funktionswert zurück liefert. Die Funktion
berechnet den Parameter φ = arctan ( b
a
) der komplexen Zahl z = a + i · b und schreibt den Wert des
Parameters φ in die Call-by-Reference Parameter Variable a. Um den arctan einer Zahl x zu berechnen
verwenden Sie kommentarlos die Library-Funktion atan(x).
http://www.hni.uni-paderborn.de/alg/lehre/ 14 / 32
Name, Vorname: Matrikelnummer:
Definieren Sie im folgenden Kasten eine Funktion ausgabe, die zwei Call-by-Value Parameter r und
phi besitzt und keinen Funktionswert zurück liefert. Die Funktion gibt die komplexe Zahl in Polardarstellung
auf der Konsole aus.
Beispiel: Für r=1.5 und phi=2.5 sieht die Ausgabe wie folgt aus: 1.5 ∗ exp(i ∗ 2.5)
Schreiben Sie im folgenden Kasten das Hauptprogramm (main-Funktion), dass die zu Beginn dieser
Aufgabe beschriebene Funktionalität besitzt. Verwenden Sie dazu die oben definierten Funktionen!
http://www.hni.uni-paderborn.de/alg/lehre/ 15 / 32
Grundlagen der Programmierung & Datenverarbeitung WS 2019/20, 2. Klausur
Aufgabe 5 – Klassen (10 + 5 = 15 Punkte)
a) Gegeben ist die nachfolgende Implementierung einer Datenstruktur: Die Datenstruktur erlaubt das
Speichern von Matrikelnummer und Name von Studierenden. Zur Verwaltung und Speicherung der Daten
dient die Struktur studiTyp. Die Speicherung der Daten erfolgt mit der Funktion einfuegen(..).
Es können auch alle gespeicherten Daten mit Hilfe der Funktion alleAusgeben(..) ausgegeben werden.
Die Datenstruktur wurde mit Hilfe einer Struktur und geeigneten Funktionen implementiert.
const int maxStudis = 100;
struct studiTyp {
string* name;
int* matrNr;
int anzahlStudis;
};
studiTyp* initDatenstruktur() {
studiTyp* studis = new studiTyp;
studis->name = new string[maxStudis];
studis->matrNr = new int[maxStudis];
studis->anzahlStudis = 0;
return studis;
}
void einfuegen(studiTyp* studis, string name, int matrNr) {
if (studis->anzahlStudis < maxStudis) {
studis->name[studis->anzahlStudis] = name;
studis->matrNr[studis->anzahlStudis] = matrNr;
studis->anzahlStudis = studis->anzahlStudis + 1;
}
}
void alleAusgeben(studiTyp* studis) {
for(int i=0; i