IPK WiederholungsTutorium

Ablauf des TUtoriums heute

  1. Besprchung der Probeklausur
  2. Eure Fragen zur Wiederholung
  3. Abschließende Worte
  4. Möglichkeit für Fragen im Einzelgespräch

Allgemeine Tipps zur KLausur

  • Verschafft euch zu Beginn der Klausur einen Überblick
    (z.B. nach Beantwortung des Wissensteils)
  • Lasst euch nicht von schweren/schwer aussehenden Aufgaben durcheinander bringen
  • Lest die Aufgabenstellungen genau (Beachte: Operatoren),
    • schreibt nicht mehr als nötig
    • gebt uns Gründe euch Punkte zu geben
  • Übt vor der Klausur nicht nur das Wissen, sondern auch die Beantwortung der Aufgaben auf Papier
  • Lernt zeitnah und schlaft dann vor der Klausur genug!
  • Beachtet die Hinweise auf der Klausur!

Allgemeine Tipps: Operatoren

  • nennen: zielgerichtet Informationen knapp zusammentragen, ohne diese
    zu kommentieren
  • beschreiben/erläutern: spezifische  Sachverhalte in eigenen Worten strukturiert und fachsprachlich unter Zuhilfenahme eigenen Vorwissens darstellen
  • begründen: einen Sachverhalt bzw. eine Aussage durch nachvollzieh-
    bare Argumente stützen
  • Beispiel: kurzes Beispiel geben, das die Thematik aus der Frage/Aufgabe erkennbar verdeutlicht, nicht verkünsteln

Aufgabe 1: Wissensfragen

Geben Sie kurze Antworten auf die folgenden Fragen:

// Deklaration
class A;

// Defintion
class A{};

// Unterschied:
//  Deklaration: Informiert über die Existenz einer Klasse/Funktion, 
//               kann beliebig of in verschiedenen TUs existieren
//    Definition: Implementiert eine Klasse/Funktion,
//               kann laut ODR nur einmal existieren

1) Kann ein C++-Programm aus mehreren Dateien bestehen? Ja

Kann es aus mehreren .cc-Dateien bestehen? Ja

2) Geben Sie ein Beispiel für eine Deklaration und für eine Definition an.

Was ist der Unterschied?

Aufgabe 1: Wissensfragen

3) Nennen Sie drei C++-Container der STL.

std::vector, std::array, std::list, std::deque, std::stack, std::map

4) Sie haben eine Klasse "Krokodil" geschrieben ohne einen Konstruktor zu schreiben. Hat diese Klasse einen Konstruktor? Falls ja, wie nennt man ihn?

Ja, "Krokodil" hat einen Konstruktor! Default-Constructor

5) Wie definiert man Namespaces und wofür sind sie gut?

Über das "namespace" Keyword und geschweifte Klammern

Mit Namespaces kann man K/T/F mit einem Präfix versehen und sie so trennen um naming conflicts zu verhindern

5) Nennen Sie drei C++-Anweisungen mit denen Sie den Kontrollfluss beeinflussen können.
if, for, switch, while, goto

Aufgabe 1: Wissensfragen

6) Wie können Templates dafür sorgen unnötige Wiederholungen im Code zu vermeiden?
Man kann mit Templates generischen Code, also für mehrere Typen schreiben, s.d. insgesamt weniger Code notwendig ist.

7) Nennen Sie zwei Vorteile, die die Verwendung eines Buildsystems bietet.

  • Vereinfachung/Dokumentation (es ist klar, wie man das Projekt baut)
  • Portability: Gleiches Skript zum Entwickeln wie in der CI/CD Pipeline

8) Sie implementieren ein großes C++-Projekt und teilen Ihren Code in mehrere Header auf. Wie können Sie es vermeiden den Inhalt eines Headers mehrfach in Ihr Programm einzubinden (was zu Kompilierfehlern führen würde)?

Über die Verwendung von Headerguards, s.d. der Präprozessor den Code nur einmal inkludiert.

Aufgabe 1: Wissensfragen

9) Was sind Referenzen, und wofür nutzt man sie (Anwendungsbeispiel)?

Referenzen in C++ sind Aliases (alternative Namen) für bestehende Objekte.
Ein Anwendungsfall für Referenzen ist call-by-reference (outputparameter in Funktionen)

void swap(int& i, int& j)
{
  int tmp = i;
  i = j;
  j = tmp;
}
int main()
{
  int x, y;
  // ...
  swap(x,y);
  // ...
}

Aufgabe 2: Fragen zu Codebeispielen

a)

  • Die Funktion "main" mit Rückgabetyp "int" und Parametern vom Typ "int" und "char**" wird definiert.
  • Ja könnte man.
  • In Zeile 3 wird der Wert "1" zurückgegeben, da wir uns in der Main-Funktion befinden, setzt dies für das Betriebssystem den Exitcode "1"

b)

  • Die b-te Potenz von a
  • Rekursive funktion

c)

  • Zeile 1: Vektor aus doubles von der Standardbibliothek default-konstruiert
  • Zeile 2: Klasse Vektor mit Template-arg "double" wird default-konstruiert
  • Der operator<< mit den richtigen Argumenten/Rückgabewert muss für mpvi::vector<double> definiert und sichtbar sein!

Aufgabe 2: Fragen zu Codebeispielen

d)

  • x_1: std::map<std::string, int>
  • x_2: const std::pair<std::string, int>
  • x_3: std::string

e)

  • Greife auf den Typendefinition "value_type" des (aufgelösten) Templates T zu und setze ihn hier als Rückgabetyp der Funktion "maximum"

Aufgabe 3: Fehlersuche

a)

  1. Zeile 4: Zuweisung statt equality-check, Laufzeitfehler

b)

  • Zeile 5: Potentieller Informationsverlust bei Umwandlung von size_t zu int, Laufzeit
  • Zeile 4: unsigned interger underflow, programm terminiert nicht, Laufzeit

c)

  • Zeile 3: Vektor wird nicht returned und ist keine Referenz, Laufzeit
  • Zeile 4: Werte werden nicht in den Vektor übertragen, da keine Referenz, Laufzeit

d)

  • Zeile 11: "max" im Lambda nicht sichtbar, da keine Captures, Compile-Error

Aufgabe 3: Fehlersuche

e)

  1. Zeile 1: dangling reference auf "result", Laufzeitfehler

Aufgabe 4: Programmieren

Recap der Aufgabe:

  • Klasse "Triangle" schreiben
  • Const-Correctness einhalten
  • Header auch inkludieren
  • "Sinnvoll" Designen (lol)
  • Erst alles Lesen, dann anfangen
#include <array>

class Triangle{
public:
    using value_type = double;
    using point = std::array<value_type, 2>;
    Triangle(const std::array<point, 3>& values) : _corners{values} {};
    Triangle() : _corners{} {};
    // precond: i in (0,1,2)
    const point& getCorner(int i) const {
        return _corners[i];
    }
    // precond: i in (0,1,2)
    point& getCorner(int i) {
        return _corners[i];
    }

    point& setCorner(int i, const point& other) {
        return _corners[i] = other;
    }
private:
    std::array<point, 3> _corners;
};

Triangle operator+(const Triangle& a, const Triangle& b) {
    auto result = Triangle{};
    for(int i = 0; i < 3; i++){
        const auto& a_i = a.getCorner(i);
        const auto& b_i = b.getCorner(i);
        result.setCorner(i, Triangle::point{(a_i[0] + b_i[0]) / 2,
                                            (a_i[1] + b_i[1]) / 2});
    }
    return result;
}
#include <iostream>
#include <string>

// Is apparently already given
class Image {};

class PencilBase {
public:
  virtual Image return_icon() const;
  virtual void change_color(std::string color);
  virtual void print_color() const;
};
class Pencil : public PencilBase {
  std::string _color;
  Image _image;

public:
  Image return_icon() const override {
    return _image; //
  };
  void change_color(std::string color) override {
    _color = color; //
  };
  void print_color() const override {
    std::cout << "Color: " << _color << "\n";
  };
};

// Aufgabenstellung: Das soll funktionieren
void check_pencil(PencilBase &pencil) {
  Image image = pencil.return_icon();
  pencil.change_color("blue");
  pencil.print_color();
}

Abschließende Worte

Viel Erfolg in der Klausur!

Wiederholungstutorium

By Christian Heusel

Wiederholungstutorium

  • 74