Sie sind auf Seite 1von 28

Name, Vorname:

Matrikelnummer:

Name, Vorname: Matrikelnummer: 1. Klausur zur Lehrveranstaltung Grundlagen der Programmierung für Ingenieure II WS

1. Klausur zur Lehrveranstaltung

Grundlagen der Programmierung für Ingenieure II WS 2015/16

23. Februar 2016

Hinweise:

Bitte lesen!

Diese Klausur umfasst 10 Aufgaben und 28 Seiten. Überprüfen Sie Ihre Klausur bitte auf Voll- ständigkeit!

Schreiben Sie bitte zuerst Ihren Namen auf jedes Blatt dieser Klausur und ggf. auf weitere von Ihnen benutzte Zusatzblätter!

Es sind keine Hilfsmittel erlaubt.

) sind auszuschalten. Ein-

Alle elektronischen Geräte (Handy, Smartphone, PDA, Smartwatches,

geschaltete Geräte werden als Täuschungsversuch gewertet.

Nehmen Sie sich Zeit, die Klausuraufgaben vollständig durchzulesen. Sie können insgesamt 180 Punkte erreichen; mit 90 Punkten haben Sie auf jeden Fall bestanden. Die Bearbeitungszeit be- trägt 150 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

A9

A10

20

10

16

20

14

20

20

20

18

22

180

Aufgabe 1 – Zeiger

(10 + 10 = 20 Punkte)

a) Vervollständigen Sie das angegebene Programm um folgende Funktionalität, jedoch ohne dabei den []-Operator für den Zugriff auf Array-Elemente zu verwenden. Verwenden Sie stattdessen die Möglich- keiten der Zeigerarithmetik.

Funktionalität: Vom Benutzer wird zunächst ein Integer (ganze Zahl) namens anzahl eingelesen und danach dynamisch ein int-Array für anzahl viele Elemente angelegt. Danach werden vom Benutzer anzahl viele Integer Werte abgefragt und in dem Array gespeichert. Anschließend werden alle Integer Werte in gleicher Reihenfolge wie die Eingabe, durch Komma getrennt, auf der Konsole ausgegeben und anschließend das Array gelöscht.

Beispielausgabe: Eine Ausgabe des Programms bei Arraygröße 3 könnte wie folgt aussehen:

Wie

Geben

v i e l e Sie

Wert?

Wert?

Wert?

12

24

43

12 ,24 ,43 ,

Programm:

Zahlen ? 3

3

Zahlen

ein !

1 #include <iostream>

2 using namespace std;

3 int main() {

4 cout << "Wie viele Zahlen? ";

5 int anzahl;

6 cin >> anzahl;

7 if (anzahl <= 0) {

8 return 0;

9 }

10 cout << "Geben Sie " << anzahl << " Zahlen ein!" << endl;

anzahl << " Zahlen ein!" << endl; http://www.hni.uni-paderborn.de/alg/lehre/ 2 / 28

Name, Vorname:

Matrikelnummer:

Name, Vorname: Matrikelnummer: 11 return 0; 12 } http://www.hni.uni-paderborn.de/alg/lehre/ 3 / 28

11

return 0;

12

}

b) Vervollständigen Sie das nachfolgende Programmfragment indem Sie dynamisch zur Laufzeit Struk- turen vom Typ DatTyp erzeugen, so dass die folgende Speichersituation entsteht:

erzeugen, so dass die folgende Speichersituation entsteht: An Variablen bzw. Zeiger dürfen Sie ausschließlich dat1
erzeugen, so dass die folgende Speichersituation entsteht: An Variablen bzw. Zeiger dürfen Sie ausschließlich dat1
erzeugen, so dass die folgende Speichersituation entsteht: An Variablen bzw. Zeiger dürfen Sie ausschließlich dat1
erzeugen, so dass die folgende Speichersituation entsteht: An Variablen bzw. Zeiger dürfen Sie ausschließlich dat1
erzeugen, so dass die folgende Speichersituation entsteht: An Variablen bzw. Zeiger dürfen Sie ausschließlich dat1

An Variablen bzw. Zeiger dürfen Sie ausschließlich dat1 und dat2 verwenden und keine weiteren Va- riablen bzw. Zeiger anlegen. Sobald die oben angegebene Speichersituation erreicht wird, markieren Sie dieses durch einen Kommentar „// Speichersituation erreicht“. Geben Sie anschließend den verwendeten Speicher wieder frei.

1 int main() {

2 struct DatTyp{

3 int zahl;

4 DatTyp* zgr;

5 };

6 DatTyp* dat1;

7 DatTyp* dat2;

4 DatTyp* zgr; 5 }; 6 DatTyp* dat1; 7 DatTyp* dat2; 8 return 0; 9 }

8 return 0;

9 }

Name, Vorname:

Matrikelnummer:

Aufgabe 2 – Sichtbarkeit

(10 Punkte)

Heben Sie im folgenden Programm die Sichtbarkeit aller Variablen, Konstanten und formalen Parame- tern durch Linien neben dem Programmcode hervor – wie aus der Vorlesung und den Übungen bekannt. Wenn Variablen verdeckt sind, dann soll dies in den entsprechenden Bereichen durch eine gestrichelte Linie markiert werden.

#include <iostream> #include <cmath> #include <iomanip> using namespace std;

double c;

double h;

double berechneSeite(const double& a, const double& b) { return sqrt(a*a + b*b);

}

double berechneHoehe(const double& a, const double& c1) { return sqrt(a*a-c1*c1);

}

int main()

 

{

 

double c1;

 

{

 

double a = 20.; double b = 30.;

c

= berechneSeite(a, b);

c1 = (c*c+a*a-b*b)/(2*c);

h

= berechneHoehe(a, c1);

 

}

for(int i=0; i<(int)c; i++)

{

 

cout << setw(2) << (i+1) << ": "; int h;

if(i<=(int)(c1))

 

h

= (int)(::h/c1*i);

 

else

 

h

= (int)(::h-::h/(::c-c1)*(i-(int)(c1)));

 

for(int i=0; i<h; i++) cout << ’#’;

cout << endl;

 

}

return 0;

 

}

Aufgabe 3 – Schleifen

(10 + 6 = 16 Punkte)

a) Implementieren Sie die Funktion sucheKleinstePositiveZahl, welche in einem Array unsortierter ganzer Zahlen die kleinste positive Zahl bestimmt und zurück gibt. Hierbei nehmen wir an, dass 0 keine positive Zahl ist. Falls das Array keine positiven Zahlen beinhaltet, dann soll die Funktion 0 zurück geben. Die Ausgabe des folgenden Programms soll sein:

Kleinste

p o s i t i v e

Zahl

8

Kleinste

p o s i t i v e

Zahl

9

Keine

Programm:

p o s i t i v e

Zahl

dabei

1 #include <iostream>

2 using namespace std;

3 int sucheKleinstePositiveZahl(int *arr, int len) {

3 int sucheKleinstePositiveZahl( int *arr, int len) { 4 } 5 void print( int *arr, int

4 }

5 void print(int *arr, int len) {

6 int erg = sucheKleinstePositiveZahl(arr, len)

7 if (erg == 0)

8 cout << "Keine positive Zahl dabei" << endl;

9 else

10 cout << "Kleinste positive Zahl " << erg << endl;

11 }

12 int main() {

13 int zahlen1[10] = {13, -12, 17, -20, 8, 24, -14, 27, 0, 99};

14 int zahlen2[7] = {-12, 17, -20, 9, 24, -14, 27};

15 int zahlen3[3] = {-12, -20, -14};

16 print(zahlen1, 10);

17 print(zahlen2, 7);

18 print(zahlen3, 3);

19 return 0;

20 }

Name, Vorname:

Matrikelnummer:

b) Verwenden Sie das im Folgenden angegebene Programm Programmvariante A als Vorlage um die äquivalente Funktionalität in Programmvariante B zu implementieren. Hierbei soll Programmvariante B weder for noch do-while Schleifen verwenden, sondern ausschließlich while Schleifen benutzen.

Programmvariante A:

1

#include <iostream>

2

using namespace std;

3

4

int main() {

5

int arr1[10] = {12, 24, 23, 7, 19, 45, 18, 15, 2, 29};

6

int arr2[5];

7

8

for(int i=0; i<10; i=i+2)

9

arr2[i/2] = arr1[i];

10

11

int i=0;

12

do {

13

cout << arr2[i] << " ";

14

i++;

15

} while (i<5);

16

return 0;

17

}

Programmvariante B:

1

#include <iostream>

2

using namespace std;

3

4

int main() {

5

int arr1[10] = {12, 24, 23, 7, 19, 45, 18, 15, 2, 29};

6

int arr2[5];

7

return 0;

8

}

Aufgabe 4 – STL

(10 + 10 = 20 Punkte)

Im Folgenden finden Sie Programmfragmente, in welchen Container aus der STL verwendet werden. Ergänzen Sie diese Programmfragmente um die jeweils gesuchte Funktionalität.

a) Schreiben Sie ein Programmfragment, welches unter Verwendung von Iteratoren alle geraden Zahlen aus dem gegebenen Vektor zahlenVec ausgibt. Die Ausgabe soll sein: 2 8 20.

1

#include <iostream>

2

#include <vector>

3

using namespace std;

4

5

int main()

6

{

7

int zahlen[] = { 1, 3, 37, 3, 5, 17, 2, 8, 20, 15 };

8

vector<int> zahlenVec;

9

for (int i = 0; i < 10; ++i) { zahlenVec.push_back(zahlen[i]);

10

11

}

12

return 0;

13

}

Name, Vorname:

Matrikelnummer:

b) Ergänzen Sie das Programmfragment zu einem vollständigen Programm, welches unter Verwendung von count_if(begin, end, function) die Anzahl der ungeraden Zahlen in der angegebenen Liste zahlenList berechnet und ausgibt. Die Ausgabe soll sein: 7.

1

#include <iostream>

2

#include <list>

3

#include <algorithm>

4

using namespace std;

5

int main()

6

{

7

int zahlen[] = { 1, 3, 37, 3, 5, 17, 2, 8, 20, 15 };

8

list<int> zahlenList;

9

for (int i = 0; i < 10; ++i) { zahlenList.push_back(zahlen[i]);

10

11

}

12

return 0;

13

}

Name, Vorname:

Matrikelnummer:

Die Ausführung des angegebenen Programms führt auf der Konsole zu folgender Ausgabe:

The

Someone

Titanium

Wall

l i k e

You

Implementieren Sie die Datenstruktur mit gleichwertiger Funktionalität in Form einer Klasse: Für die Struktur SammlungTyp ist eine Klasse Sammlung zu programmieren. Die Klasse Sammlung enthält die Methoden cdHinzufuegen und cdAlleAusgeben. Implementieren Sie einen geeigneten Konstruktor und Destruktor für die Funktionen initSammlung und removeSammlung.

für die Funktionen initSammlung und removeSammlung . 1 int main() { 2 Sammlung meineCDs(10); 3

1 int main() {

2 Sammlung meineCDs(10);

3 meineCDs.cdHinzufuegen("The Wall");

4 meineCDs.cdHinzufuegen("Someone like You");

5 meineCDs.cdHinzufuegen("Titanium ");

6 meineCDs.cdAlleAusgeben();

7 return 0;

8 }

Aufgabe 6 – Polymorphismus

(6 + 6 + 8 = 20 Punkte)

Gegeben ist folgendes Programmfragment, bestehend aus mehreren Klassen:

1

#include <iostream>

2

using namespace std;

3

const double PI = 3;

4

5

class Geo {

6

public:

7

Geo() {

8

cout << "Geo erzeugt" << endl;

9

}

10

virtual ~Geo(){

11

cout << "Geo entfernt" << endl;

12

}

13

virtual double flaeche() = 0;

14

};

15

class Kreis : public Geo

16

{

17

double m_radius;

18

public:

19

Kreis(double radius)

20

: m_radius(radius) { }

21

virtual ~Kreis(){}

22

virtual double flaeche() {

23

return m_radius*m_radius*PI;

24

}

25

};

26

class Rechteck : public Geo

27

{

28

double m_a, m_b;

29

public:

30

Rechteck(double a, double b)

31

: m_a(a), m_b(b) {}

32

virtual ~Rechteck(){}

33

virtual double flaeche() {

34

return m_a * m_b;

35

}

36

double breite() { return m_a;}

37

double hoehe() { return m_b;}

38

};

a) Vervollständigen Sie die folgende main-Funktion, so dass zunächst sämtliche Flächeninhalte der Ob- jekte, jeweils getrennt durch Zeilenumbrüche, ausgegeben werden. Anschließend soll nacheinander der Speicher aller im Array forms gespeicherten Objekte freigegeben werden.

Name, Vorname:

Matrikelnummer:

1 int main() {

2 Geo *forms[3];

3 forms[0] = new Kreis(3);

4 forms[1] = new Rechteck(1,2);

5 forms[2] = new Rechteck(1,3);

= new Rechteck(1,2); 5 forms[2] = new Rechteck(1,3); 6 return 0; 7 } b) Das von

6 return 0;

7 }

b) Das von Ihnen vervollständigte Programm erzeugt bei Aufruf der main-Funktion an mehreren Stellen Ausgaben. Geben Sie diese Ausgabe an:

Ausgabe (Ein Feld pro ausgegebener Zeile)
Ausgabe (Ein Feld pro ausgegebener Zeile)

c) Schreiben Sie eine Klasse namens Quadrat, die von der vorgegebenen Klasse Rechteck erbt. Die Klasse soll folgende Eigenschaften haben:

Die Klasse soll keine Attribute besitzen.

Die Methode double Quadrat::flaeche() soll den korrekten Flächeninhalt zurückgeben.

Die Klasse soll eine zusätzliche Methode double Quadrat::umfang() haben, welche den Um- fang des Quadrats zurückgibt.

Hinweis: Sie können annehmen, dass die Klasse in der gleichen Datei wie der zuvor in dieser Aufgabe verwendete Programmcode steht.

der zuvor in dieser Aufgabe verwendete Programmcode steht. http://www.hni.uni-paderborn.de/alg/lehre/ 14 / 28

Programm:

1

#include <iostream>

2

#include <string>

3

#include "Schlange.h"

4

using namespace std;

5

6

int main() {

7

Schlange* SchlangeLinks = new Schlange();

8

Schlange* SchlangeRechts = new Schlange();

9

10

SchlangeLinks->enque("PB-MH-911");

11

SchlangeLinks->enque("PB-MF-777");

12

SchlangeLinks->enque("PB-CL-001");

13

SchlangeRechts->enque("PB-AB-123");

14

SchlangeRechts->enque("PB-CD-456");

15

delete SchlangeLinks;

16

delete SchlangeRechts;

17

18

return 0;

19

}

Name, Vorname:

Matrikelnummer:

b) Vervollständigen Sie die Methode Schlange::enque(string x, int index) der Klasse Schlan- ge, mit der ein Element hinter der angegebenen Indexposition eingereiht wird. Hierbei entspricht die 0-te Indexposition der Position vor dem ersten Schlangenelement. (Mit dem ersten Schlangenelement bezeichnen wir das Element, welches beim Aufruf von head() zurückgegeben wird.) Entsprechend soll bei Index i das neue Element nach der Einfügeoperation das (i + 1)-te Element der Liste sein. Wenn der angegebene Index größer als die Anzahl der Elemente ist, dann soll das Element hinter dem letzten Listenelement angehängt werden. Sie können davon ausgehen, dass der Indexwert nicht-negativ ist. Das folgende Programmfragment behandelt bereits die Fälle, wenn die Schlange leer ist oder das Element an der 0-ten Stelle eingefügt werden soll.

1

void Schlange::enque(string x, int index)

2

{

3

Node *ptr = new Node(x);

4

if (empty()) {

5

last = ptr;

6

first = ptr;

7

return;

8

}

9

if (index == 0) {

10

ptr->next = first;

11

first = ptr;

12

return;

13

}

14

}

Aufgabe 8 – Streams

(10 + 10 = 20 Punkte)

a) Gegeben ist folgendes Programm, welches Daten aus einer Datei einliest und auf der Konsole sowie in einer zweiten Datei ausgibt. Vollziehen Sie den Ablauf des Programms nach und tragen Sie die Ausgaben des Programms in die Tabelle ein: Ausgaben in die Datei ausgabe.txt in die linke Spalte und die Konsolenausgaben in die rechte Spalte; es bleiben Felder leer.

Inhalt der Datei eingabe.txt 0 montag 1 dienstag 3 mittwoch 2 donnerstag 4 freitag

Programm:

1

#include <fstream>

2

#include <iostream>

3

#include <sstream>

4

#include <string>

5

using namespace std;

6

void ausgabe(ostream& out, const string& s){

7

out << s << endl;

8

}

9

int main() {

10

ifstream inFile("eingabe.txt", ios::in);

11

ofstream outFile("ausgabe.txt", ios::out);

12

while (!inFile.eof()) {

13

int i;

14

string s;

15

ostringstream sstr;

16

inFile >> i;

17

inFile >> s;

18

switch (i) {

19

case 0:

20

ausgabe(outFile, s);

21

break;

22

case 1:

23

ausgabe(cout, s);

24

break;

25

case 2:

26

for (int k = s.size()-1; k>=0; --k){

27

sstr << s.at(k);

28

}

29

ausgabe(outFile, sstr.str());

30

break;

31

default:

32

ausgabe(cout, "quatsch");

33

break;

34

}

35

}

36

inFile.close();

37

outFile.close();

38

return 0;

39

}

Name, Vorname:

Matrikelnummer:

ausgabe.txt Konsole
ausgabe.txt
Konsole

Hinweis: Die Tabelle hat mehr Zeilen als benötigt werden.

b) Schreiben Sie ein Programm, welches eine Datei zahlenEingabe.txt zum Lesen öffnet und die enthaltenen Zahlen liest. Alle geraden Zahlen sollen durch Leerzeichen getrennt in eine Datei namens geradeZahlen.txt geschrieben werden. Die ungeraden Zahlen sollen durch Leerzeichen getrennt auf der Konsole ausgegeben werden. Vergessen Sie nicht, die geöffneten Dateien auch wieder zu schließen!

Beispieldaten:

Inhalt der Datei zahlenEingabe.txt: -500 3 34 7 49 120 4 17 Inhalt der Datei geradeZahlen.txt nach Ausführung des Programms: -500 34 120 4 Konsolenausgabe des Programms: 3 7 49 17

1

#include <fstream>

2

#include <iostream>

3

using namespace std;

4

5

int main(){

6

return 0;

7

}

Name, Vorname:

Matrikelnummer:

Diese Seite wurde absichtlich leer gelassen.

Name, Vorname:

Matrikelnummer:

a) Schreiben Sie zwei der möglichen Ausgaben des Programms auf.

Sie zwei der möglichen Ausgaben des Programms auf. b) Beschreiben Sie kurz, warum das Programm

b) Beschreiben Sie kurz, warum das Programm unterschiedliche Ausgaben erzeugen kann.

warum das Programm unterschiedliche Ausgaben erzeugen kann. c) Schreiben Sie eine Ausgabe des Programms auf, die

c) Schreiben Sie eine Ausgabe des Programms auf, die nur möglich ist, falls das Programm ohne den

Mutex in Zeilen 12 und 16 ausgeführt wird.

ohne den Mutex in Zeilen 12 und 16 ausgeführt wird. http://www.hni.uni-paderborn.de/alg/lehre/ 23 / 28

Name, Vorname:

Matrikelnummer:

a) Schreiben Sie eine Funktion void print(Stack &stack), welche die Referenz auf einen Stack als Argument übergeben bekommt und sämtliche Elemente des Stacks von oben (Top-Element) nach unten, durch Leerzeichen getrennt, auf der Konsole ausgibt. Nach Ende des Funktionsaufrufs soll der Stack exakt den gleichen Inhalt haben, wie vor dem Aufruf der Funktion.

Hinweis: Da es sich bei der zu implementierenden Funktion nicht um eine Methode der Klasse handelt können Zugriffe nur über die public-Methoden der Klasse erfolgen. Insbesondere ändern diese Methoden den Stack und es ist daher notwendig die Änderungen zwischenzuspeichern, um am Ende wieder den Ausgangszustand herzustellen.

1

void print(Stack &stack) {

2

return;

3

}

Name, Vorname:

Matrikelnummer:

Zusatzblatt. Wichtig: Falls Sie dieses Blatt zur Lösung einer Aufgabe verwenden, kennzeichnen Sie dieses auch direkt an der Aufgabe und streichen Sie nicht zu bewertende Lösungen!

Zusatzblatt. Wichtig: Falls Sie dieses Blatt zur Lösung einer Aufgabe verwenden, kennzeichnen Sie dieses auch direkt an der Aufgabe und streichen Sie nicht zu bewertende Lösungen!