Martin Sulzmann
Übungsaufgaben zu folgenden Themen
OO in C++
Speicher + Verwaltung in C++
Polymorphie in C++
Syntax Darstellung in C++
Stack-basierte virtuelle Maschinen in C++
Funktionale Programmierung (FP) in C++
Wir betrachten virtuelle und nicht-virtuelle Methoden in C++.
Gegeben folgender Programmtext.
class Vehicle {
public:
string info() { return "Vehicle"; }
virtual int maxSpeed() { return 0; }
};
class Bike : public Vehicle {
public:
string info() { return "Bike"; }
virtual int maxSpeed() { return 30; }
};
class Car : public Vehicle {
public:
string info() { return "Car"; }
virtual int maxSpeed() { return 110; }
};
void printVehicle(Vehicle v) {
cout << v.info() << " " << v.maxSpeed() << "\n";
}
Gegeben folgender Programmtext.
Welche Ausgabe liefert die Ausführung von ex1
?
Gegeben folgender Programmtext.
Welche Ausgabe liefert die Ausführung von ex2
?
Gegeben folgender Programmtext.
Welche Ausgabe liefert die Ausführung von ex3
?
Gegeben folgender Programmtext.
Welche Ausgabe liefert die Ausführung von ex4
?
Gegeben folgender Programmtext.
void ex5() {
Bike b;
Car c;
cout << c.info() << " " << c.maxSpeed() << "\n";
cout << b.info() << " " << b.maxSpeed() << "\n";
}
Welche Ausgabe liefert die Ausführung von ex5
?
Eine Musterlösung findet sich hier.
Gegeben folgender Programmtext.
Wahr oder falsch? Variablen i
und p
befinden sich auf dem Stack.
Wahr oder falsch? Variable q
befindet sich auf dem
Heap.
Wahr oder falsch? Zeiger p
verweist auf eine
Heap-allokierte Speicherstelle.
Gegeben folgender Programmtext.
void ex2() {
int i;
int* q = (int*)malloc(sizeof(int));
free(q);
scanf("%d",&i);
if(i==0) {
free(q);
}
}
Was kann alles bei der Ausführung von ex2
passieren?
Gegeben folgender Programmtext.
Welche Daten befinden sich auf dem Stack? Welche Daten befinden sich auf dem Heap?
Gegeben folgender Programmtext.
class CC {
int* p;
public:
CC() { p = new int(0); };
~CC() { delete p; }
void print() {
cout << *p;
}
};
void ex4() {
CC c;
}
Was passiert bei der Ausführung von ex4
?
Gegeben folgender Programmtext.
Welche Ausgabe liefert die Ausführung von ex5
?
Gegeben folgender Programmtext.
Was passiert bei der Ausführung von ex6
?
Gegeben folgender Programmtext.
class CCC {
public:
CCC() { cout << "Hi!"; }
~CCC() { cout << "Bye!"; }
};
void ex7() {
CCC p1;
CCC* p2 = new CCC();
CCC* p3 = new CCC();
delete p2;
}
Welche Ausgabe liefert die Ausführung von ex7
?
Gegeben folgender Programmtext.
Welche Ausgabe liefert die Ausführung von ex8
?
Gegeben folgender Programmtext.
Welche Ausgabe liefert die Ausführung von ex9
?
Gegeben folgender Programmtext.
Was passiert bei der Ausführung von ex10
?
Eine Musterlösung findet sich hier.
Gegeben folgender Programmtext.
class A {};
class B : public A {};
class C : public B {};
void f(A a) {}
void h(B b) {}
void ex1() {
A a;
B b;
C c;
a = c; // P1
b = c; // P2
c = a; // P3
f(c); // P4
h(c); // P5
h(a); // P6
};
Welcher der Programmstellen P1-6 liefert eine Fehlermeldung? Wieso?
Gegeben folgender Programmtext.
class AA {
public:
string virtual show()=0;
};
class BB : public AA {
public:
string virtual show() { return "b"; }
};
class CC : public BB {
public:
string virtual show() { return "c"; }
};
void g(AA* x) {
cout << x->show();
}
void k(BB x) {
cout << x.show();
}
void ex2() {
BB* x = new BB();
g(x);
}
Welche Ausgabe liefert die Ausführung von ex2
?
Gegeben folgender Programmtext.
Welche Ausgabe liefert die Ausführung von ex3
?
Gegeben folgender Programmtext.
Welche Ausgabe liefert die Ausführung von ex4
?
Gegeben folgender Programmtext.
void m(int x, char c) {
cout << "m1";
}
void m(int x, string c) {
cout << "m2";
}
template<typename S, typename T>
void m(S x, T c) {
cout << "m3";
}
void ex5() {
m(1, 'a');
}
Welche Ausgabe liefert die Ausführung von ex5
?
Gegeben folgender Programmtext.
Welche Ausgabe liefert die Ausführung von ex6
?
Gegeben folgender Programmtext.
Welche Ausgabe liefert die Ausführung von ex7
?
Eine Musterlösung findet sich hier.
Betrachte folgende C++ Darstellung von arithmetischen Ausdrücken.
class Exp {};
class Zero : public Exp {
};
class One : public Exp {
};
class Plus : public Exp {
Exp l, r;
public:
Plus(Exp x, Exp y) { l = x; r = y; }
};
class Minus : public Exp {
Exp l, r;
public:
Minus(Exp x, Exp y) { l = x; r = y; }
};
class Mult : public Exp {
Exp l, r;
public:
Mult(Exp x, Exp y) { l = x; r = y; }
};
Betrachten folgenden String.
(1 * 0) * 1
Obige konkrete Syntax Darstellung verwendet Leerzeichen und Klammern.
In der abstrakten Syntax Dartelleung werden in der Regel Leerzeichen und Klammern ignoriert.
Hier ist die abstrakte Syntax Darstellung von “(1 * 0) * 1” in C++.
Gebe die abstrakte Syntax C++ Darstellung folgender arithemtischer Ausdrücke.
“(1 + (0))”
“1 * (0 - 1)”
“1 + 0 - 1”
Ist eine C++ Darstellung für folgenden String möglich?
Eine Musterlösung findet sich hier.
Wir betrachten die stack-basierte Virtuelle Maschine (VM) bekannt aus der Vorlesung. Folgende VM Operationen werden betrachtet.
Notation.
Wir schreiben [x1,...,xn]
um einen Stack mit
Elementen x1
,…,xn
darzustellen. Element
x1
ist das oberste (“top”) Element auf dem Stack.
Wir schreiben c1;...;cn
um einen Sequenz mit VM
Operationen c1
,…,cn
darzustellen. Element
c1
ist die erste VM Operation.
Hier ist die Auswertung von VM Operationen an einem Beispiel.
Initial:
VM Instruktionen = ONE;ZERO;ONE;MINUS;MULT;
Stack = []
1. Durchlauf
VM Instruktion = ONE
Stack = [1]
2. Durchlauf
VM Instruktion = ZERO
Stack = [0,1]
3. Durchlauf
VM Instruktion = ONE
Stack = [1,0,1]
4. Durchlauf
VM Instruktion = MINUS
Stack = [-1,1]
5. Durchlauf
VM Instruktion = MULT
Stack = [-1]
Zeige die einzelnen Auswertungsschritte an folgenden Beispielen. Verwende dabei obige Notation.
Initial:
VM Instruktionen = ONE;ONE;ZERO;MINUS;MULT;
Stack = []
Initial:
VM Instruktionen = ONE;ONE;MINUS;ZERO;MULT;
Stack = []
Initial:
VM Instruktionen = ONE;ZERO;ONE;MULT;PLUS;
Stack = []
Initial:
VM Instruktionen = ONE;ZERO;ONE;MULT;ONE;PLUS;MINUS;
Stack = []
Betrachte
Initial:
VM Instruktionen = ONE;MULT;
Stack = []
Was passiert bei der Ausführung?
Nicht jede Sequenz von VM Code Operationen kann erfolgreich ausgeführt werden.
Formuliere eine (einfache) notwendige Bedingung, welche garantiert, dass die VM Code Ausführung erfolgreich ist.
Lösungen zu obigen Aufgaben finden sich hier.
Am besten verwenden Sie eine Desktop-basierte IDE.
Gegeben ist folgender Programmtext.
int square(int x) { return x*x; }
template<typename T>
void map(T* p, int len, T f(T)) {
for(int i=0; i<len; i++)
p[i] = f(p[i]);
}
Mit Hilfe obiger Funktionen, implementiere folgende Funktion.
square
FunktionMit Hilfe von map
, implementiere folgende Funktion.
Definiere zuerst eine lokale (anonyme) Funktion welche Dezeminalzahlen inkrementiert
Verwende diese Funktion als “mapper”
Gegeben folgender Programmcode.
Welcher Wert wird auf der Konsole ausgegeben?
Gegeben folgender Programmcode.
Welcher Wert wird auf der Konsole ausgegeben?
Gegeben folgender Programmcode.
Der Rückgabetyp der lokalen (anonymen) Funktion ist nicht explizit spezifiert. Was ist ein möglicher Rückgabetyp? Gibt es mehrere mögliche Rückgabetypen?
Gegeben folgender Programmcode.
Ersetze auto
durch den Typen von f
.
Gegeben folgender Programmcode.
auto add = [](int x, int y) { return x+y; };
auto plus = [](int x) { return [x](int y) { return x+y; }; };
Liefere explizite Typannotation für obigen Programmtext. Ersetze
auto
durch entsprechende Typen und liefere explizite
Rückgabetypen.
Gegeben folgender Programmcode.
auto add = [](int x, int y) { return x+y; };
auto plus = [](int x) { return [x](int y) { return x+y; }; };
plus(2,3); // A
plus(add(1,3))(2); // B
add(1)(4); // C
add((plus(1))(3),4); // D
plus(4); // E
Welche der Funktionsaufrufe A-E werden vom Kompiler nicht akzeptiert?
Eine Musterlösung findet sich hier.