Übungsaufgaben

Martin Sulzmann

Übersicht

Übungsaufgaben zu folgenden Themen

OO 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";
}

Aufgabe 1

Gegeben folgender Programmtext.

void ex1() {
  Vehicle v;
  Bike b;
  printVehicle(v);
  v = b;
  printVehicle(v);
}

Welche Ausgabe liefert die Ausführung von ex1?

Aufgabe 2

Gegeben folgender Programmtext.

void ex2() {
  Vehicle v;
  Bike b;
  printVehicle2(&v);
  v = b;
  printVehicle2(&v);
}

Welche Ausgabe liefert die Ausführung von ex2?

Aufgabe 3

Gegeben folgender Programmtext.

void ex3() {
  Vehicle v;
  Bike b;
  printVehicle2(&v);
  printVehicle2(&b);
}

Welche Ausgabe liefert die Ausführung von ex3?

Aufgabe 4

Gegeben folgender Programmtext.

void ex4() {
  Vehicle* p;
  Bike b;
  Car c;
  p = &b;
  printVehicle2(p);
  p = &c;
  printVehicle2(p);
}

Welche Ausgabe liefert die Ausführung von ex4?

Aufgabe 5

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.

Speicher + Verwaltung in C++

Aufgabe 1

Gegeben folgender Programmtext.

void ex1() {
  int i;
  int* p = &i;
  int* q = (int*)malloc(sizeof(int));
}

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.

Aufgabe 2

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?

Aufgabe 3

Gegeben folgender Programmtext.

class C {};

void ex3() {
  C q = C();
  C* p = new C();

  delete p;
}

Welche Daten befinden sich auf dem Stack? Welche Daten befinden sich auf dem Heap?

Aufgabe 4

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?

Aufgabe 5

Gegeben folgender Programmtext.

void f(CC &d) { d.print(); }

void ex5() {
  CC c;
  f(c);
  c.print();
}

Welche Ausgabe liefert die Ausführung von ex5?

Aufgabe 6

Gegeben folgender Programmtext.

void h(CC d) { d.print(); }

void ex6() {
  CC c;
  h(c);
  c.print();
}

Was passiert bei der Ausführung von ex6?

Aufgabe 7

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?

Aufgabe 8

Gegeben folgender Programmtext.

void g(CCC &d) {};

void ex8() {
  CCC c;
  g(c);
}

Welche Ausgabe liefert die Ausführung von ex8?

Aufgabe 9

Gegeben folgender Programmtext.

void k(CCC d) {};

void ex9() {
  CCC c;
  k(c);
}

Welche Ausgabe liefert die Ausführung von ex9?

Aufgabe 10

Gegeben folgender Programmtext.

void ex10() {
  CCC p1;
  CCC* p2 = new CCC();
  CCC* p3 = &p1;

  delete p3;
}

Was passiert bei der Ausführung von ex10?

Eine Musterlösung findet sich hier.

Polymorphie in C++

Aufgabe 1

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?

Aufgabe 2

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?

Aufgabe 3

Gegeben folgender Programmtext.

void ex3() {
  CC x = CC();
  g(&x);
}

Welche Ausgabe liefert die Ausführung von ex3?

Aufgabe 4

Gegeben folgender Programmtext.

void ex4() {
  BB x = CC();
  g(&x);
}

Welche Ausgabe liefert die Ausführung von ex4?

Aufgabe 5

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?

Aufgabe 6

Gegeben folgender Programmtext.

void ex6() {
  int i;
  string s;
  m(i,s);
}

Welche Ausgabe liefert die Ausführung von ex6?

Aufgabe 7

Gegeben folgender Programmtext.

void ex7() {
  int i;
  string s;
  m<int,string>(i,s);
}

Welche Ausgabe liefert die Ausführung von ex7?

Eine Musterlösung findet sich hier.

Syntax Darstellung in C++

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; }
};

Aufgabe - Abstrakte Syntax in C++

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++.

 Mult(Mult(One(),Zero()), One())

Gebe die abstrakte Syntax C++ Darstellung folgender arithemtischer Ausdrücke.

  1. “(1 + (0))”

  2. “1 * (0 - 1)”

  3. “1 + 0 - 1”

Ist eine C++ Darstellung für folgenden String möglich?

  1. “1 * - 2 3”

Eine Musterlösung findet sich hier.

Stack-basierte virtuelle Maschinen in C++

Wir betrachten die stack-basierte Virtuelle Maschine (VM) bekannt aus der Vorlesung. Folgende VM Operationen werden betrachtet.

typedef enum {
  MULT,
  MINUS,
  PLUS,
  ONE,
  ZERO
} Code_t;

Notation.

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]

Aufgaben

Zeige die einzelnen Auswertungsschritte an folgenden Beispielen. Verwende dabei obige Notation.

Aufgabe 1

Initial:
  VM Instruktionen = ONE;ONE;ZERO;MINUS;MULT;
  Stack = []

Aufgabe 2

Initial:
  VM Instruktionen = ONE;ONE;MINUS;ZERO;MULT;
  Stack = []

Aufgabe 3

Initial:
  VM Instruktionen = ONE;ZERO;ONE;MULT;PLUS;
  Stack = []

Aufgabe 4

Initial:
  VM Instruktionen = ONE;ZERO;ONE;MULT;ONE;PLUS;MINUS;
  Stack = []

Weitere Aufgaben

Betrachte

Initial:
  VM Instruktionen = ONE;MULT;
  Stack = []

Was passiert bei der Ausführung?

Aufgabe “Validity Check”

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.

Musterlösungen

Lösungen zu obigen Aufgaben finden sich hier.

Am besten verwenden Sie eine Desktop-basierte IDE.

Funktionale Programmierung (FP) in C++

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]);
}

Aufgabe 1

Mit Hilfe obiger Funktionen, implementiere folgende Funktion.

void mapIntSquare(int *p, int len) {
  // Your code
}

Aufgabe 2

Mit Hilfe von map, implementiere folgende Funktion.

void mapIntInc(int *p, int len) {
  // Your code
  // Your code
}

Aufgabe 3

Gegeben folgender Programmcode.

  int x = 1;
  auto f = [x](int y) -> int { return x + y; };
  x = 2;
  cout << f(2);

Welcher Wert wird auf der Konsole ausgegeben?

Aufgabe 4

Gegeben folgender Programmcode.

  int x = 1;
  auto f = [&x](int y) -> int { return x + y; };
  x = 2;
  cout << f(2);

Welcher Wert wird auf der Konsole ausgegeben?

Aufgabe 5

Gegeben folgender Programmcode.

  auto f = [](int y) { return y > 1; };

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?

Aufgabe 6

Gegeben folgender Programmcode.

  auto f = [](int z) -> int { return z + 1; };

Ersetze auto durch den Typen von f.

Aufgabe 7

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.

Aufgabe 8

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.