diff --git a/lec-cpp-advanced-mem.html b/lec-cpp-advanced-mem.html
new file mode 100644
index 0000000..fdd7589
--- /dev/null
+++ b/lec-cpp-advanced-mem.html
@@ -0,0 +1,653 @@
+
+
+
+
+
+
+
+
+ Die Programmiersprache C++ - Speicherverwaltung
+
+
+
+
+
+
+
Die Programmiersprache C++ - Speicherverwaltung
+
+Martin Sulzmann
+
+
+
+
Übersicht
+
Manuelle Speicherverwaltung in C++ ist trickreich
+
+
Abhilfen
+
+Resource Acquisition Is Initialization (RAII)
+
+Copy/Move Semantik (von Hand selbstgebasteltet)
+“smart pointers” (clevere Bibliothek welche die Copy/Move
+Semantik umsetzt)
+
+
Wir verwenden ab jetzt C++11
+
+
+
Beispiel (Speicherleck)
+
+Umdrehen (“reverse”) eines Strings in C
+Anlegen von Speicher via “malloc”
+Fehlende Speicherfreigabe (“free”)
+
+
Zu jedem “malloc” Bedarfs es eines “free” zur richtigen Zeit!
+
#include <stdlib.h>
+#include <iostream>
+#include <string>
+using namespace std;
+
+
+int length( char * s) {
+ int n = 0 ;
+ while (* s != ' \0 ' ) {
+ n++;
+ s++;
+ }
+
+ return n;
+}
+
+char * reverse( char * s) {
+ const int n = length( s);
+ char * t = ( char *) malloc( n + 1 );
+ int i;
+
+ for ( i = 0 ; i < n; i++) {
+ t[ i] = s[ n- 1 - i];
+ }
+ t[ n] = ' \0 ' ;
+
+ return t;
+}
+
+void testReverse() {
+ char s[] = "Hallo" ;
+
+ cout << " \n " << s;
+
+ cout << " \n " << reverse( s);
+
+ cout << " \n " << reverse( reverse( s));
+
+}
+
+
+void testReverse2() {
+ char s[] = "Hallo" ;
+
+ cout << " \n " << s;
+
+ char * s1 = reverse( s);
+ cout << " \n " << s1;
+ free( s1);
+
+
+ char * s2 = reverse( s);
+ char * s3 = reverse( s2);
+ cout << " \n " << s3;
+ free( s2);
+ free( s3);
+
+}
+
+int main() {
+
+ testReverse();
+
+ testReverse2();
+
+
+ return 0 ;
+}
+
+
+
Resource Acquisition Is Initialization (RAII)
+
+
Konstruktor legt Objekt an auf dem “Stack”.
+
Destruktor wird aufgerufen sobald das Objekt freigegeben wird.
+Annahme ist, dass das Objekt auf dem “Stack” liegt.
+
Dadurch wird garantiert, dass es zu jedem “new” ein passendes
+“delete” gibt.
+
In C++, wird “malloc” ersetzt durch “new” und “free” wird ersetzt
+durch “delete”.
+
#include <stdlib.h>
+#include <iostream>
+#include <string>
+using namespace std;
+
+// Resource Acquisition Is Initialization (RAII)
+
+class String {
+public :
+ String() {
+ s = new char [ 1 ]; // (char*)malloc(1);
+ s[ 0 ] = ' \0 ' ;
+ }
+
+ String( char * t) {
+ int n = length_ ( t);
+ s = new char [ n+ 1 ];
+
+ for ( int i= 0 ; i< n; i++) {
+ s[ i] = t[ i];
+ }
+ s[ n] = ' \0 ' ;
+ }
+
+
+ ~ String() {
+ delete ( s); // free(s);
+ }
+
+ int length() {
+ return ( length_ ( this -> s));
+ }
+
+ void reverse() {
+ int n = this -> length();
+ char * t = new char [ n+ 1 ];
+
+ for ( int i = 0 ; i < n; i++) {
+ t[ i] = s[ n- 1 - i];
+ }
+ t[ n] = ' \0 ' ;
+
+ delete ( s);
+ s = t;
+ }
+
+
+
+private :
+ char * s;
+
+ int length_ ( char * s) {
+ int n = 0 ;
+ while (* s != ' \0 ' ) {
+ n++;
+ s++;
+ }
+
+ return n;
+ }
+
+ // Friends can access private attributes.
+ friend ostream& operator << ( ostream & out, String & s);
+
+};
+
+
+ ostream& operator << ( ostream & out, String & str) {
+ for ( int i= 0 ; i< str. length(); i++) {
+ out << str. s[ i];
+ }
+ return out;
+}
+
+void testReverse() {
+ char s[] = "Hallo" ;
+
+ String str( s);
+
+ cout << " \n " << str;
+
+ str. reverse();
+ cout << " \n " << str;;
+
+
+}
+
+int main() {
+
+ testReverse();
+
+ return 0 ;
+}
+
+
+
Problem - Kopieren mit Zeigern
+
+Objekte werden Elementweise kopiert
+In unserem Beispiel verweisen daher zwei verschiedene String
+Objekte auf den gleichen Speicher
+Der Destruktor wird für jedes Objekt aufgefufen
+Zweifacher Aufruf von “delete” auf der gleiche
+Speicheradresse
+Führt zum Programmabsturz
+
+
#include <stdlib.h>
+#include <iostream>
+#include <string>
+using namespace std;
+
+// Kopieren mit Zeiger
+// Zwei-faches delete!
+
+class String {
+public :
+ String() {
+ s = new char [ 1 ];
+ s[ 0 ] = ' \0 ' ;
+ }
+
+ String( char * t) {
+ int n = length_ ( t);
+ s = new char [ n+ 1 ];
+
+ for ( int i= 0 ; i< n; i++) {
+ s[ i] = t[ i];
+ }
+ s[ n] = ' \0 ' ;
+ }
+
+
+ ~ String() {
+ delete ( s);
+ }
+
+private :
+ char * s;
+
+ int length_ ( char * s) {
+ int n = 0 ;
+ while (* s != ' \0 ' ) {
+ n++;
+ s++;
+ }
+
+ return n;
+ }
+
+};
+
+
+void f( String str2) {
+
+}
+// Destruktoraufruf fuer str2
+// => delete str2.s
+
+int main() {
+ char s[] = "Hallo" ;
+
+ String str( s);
+
+ f( str); // str2.s = str.s
+
+ return 0 ;
+}
+// Destruktoraufruf fuer str2
+// => delete str.s
+// Zweifaches delete!
+
+
+
Copy Semantik
+
Jedesmal wenn ein Objekt (mit einem Zeiger) kopiert wird
+
+kopiere nicht den Zeiger, sondern lege eine neue (deep)copy
+an
+
+
Wie und wann werden Objekte kopiert?
+
+Via Kopierkonstruktur
+Via Zuweisungsoperator
+
+
Beides kann überladen werden.
+
#include <stdlib.h>
+#include <iostream>
+#include <string>
+using namespace std;
+
+// Copy Semantik
+
+class String {
+public :
+ String() {
+ s = new char [ 1 ];
+ s[ 0 ] = ' \0 ' ;
+ }
+
+ String( char * t) {
+ int n = length_ ( t);
+ s = new char [ n+ 1 ];
+
+ copy_ ( t, n, s);
+ s[ n] = ' \0 ' ;
+ }
+
+ // Copy Konstruktor
+ // Standard Definition ist: this->s = src.s
+ // Gilt auch fuer Zuweisung.
+ String( const String& src) {
+
+ int n = length_ ( src. s);
+ this -> s = new char [ n+ 1 ];
+ copy_ ( src. s, n, this -> s);
+ this -> s[ n] = ' \0 ' ;
+
+ }
+
+ // Copy Zuweisung
+ String& operator =( const String& src) {
+
+ if ( this != & src) {
+
+ delete this -> s;
+ int n = length_ ( src. s);
+ this -> s = new char [ n+ 1 ];
+ copy_ ( src. s, n, this -> s);
+ this -> s[ n] = ' \0 ' ;
+
+ }
+
+ return * this ;
+ }
+
+ ~ String() {
+ delete ( s);
+ }
+
+private :
+ char * s;
+
+ int length_ ( char * s) {
+ int n = 0 ;
+ while (* s != ' \0 ' ) {
+ n++;
+ s++;
+ }
+
+ return n;
+ }
+
+ void copy_ ( char * s, int n, char * t) {
+ int i = 0 ;
+ while ( i < n) {
+ t[ i] = s[ i];
+ i++;
+ }
+}
+
+};
+
+
+void f( String str2) {
+
+}
+
+int main() {
+ char s[] = "Hallo" ;
+
+ String str( s);
+
+ f( str); // Copy str
+
+ String str2 = str; // Copy str
+
+ f( str2);
+
+ return 0 ;
+}
+
+
+
Copy + Move Semantik
+
Jedes mal eine (deep)copy durchzuführen ist nicht sehr effizient.
+
Man betrachte
+
+
In solchen Fällen führen einen “move” durch
+
#include <stdlib.h>
+#include <iostream>
+#include <string>
+using namespace std;
+
+// Copy/Move Semantik
+
+class String {
+public :
+ String() {
+ s = new char [ 1 ];
+ s[ 0 ] = ' \0 ' ;
+ }
+
+ String( char * t) {
+ int n = length_ ( t);
+ s = new char [ n+ 1 ];
+
+ copy_ ( t, n, s);
+ s[ n] = ' \0 ' ;
+ }
+
+ // Copy Konstruktor
+ // Standard Definition ist: this->s = src.s
+ // Gilt auch fuer Move und Zuweisung.
+ String( const String& src) {
+
+ int n = length_ ( src. s);
+ this -> s = new char [ n+ 1 ];
+ copy_ ( src. s, n, this -> s);
+ this -> s[ n] = ' \0 ' ;
+
+ }
+
+ // Copy Zuweisung
+ String& operator =( const String& src) {
+
+ if ( this != & src) {
+
+ delete this -> s;
+ int n = length_ ( src. s);
+ this -> s = new char [ n+ 1 ];
+ copy_ ( src. s, n, this -> s);
+ this -> s[ n] = ' \0 ' ;
+
+ }
+
+ return * this ;
+ }
+
+
+ // Move Konstruktor
+ String( String&& src) {
+ this -> s = src. s;
+ src. s = nullptr ;
+ }
+
+ // Move Zuweisung
+ String& operator =( String&& src) {
+
+ if ( this != & src) {
+
+ delete this -> s;
+ this -> s = src. s;
+ src. s = nullptr ;
+
+ }
+
+ return * this ;
+ }
+
+ ~ String() {
+ delete ( s);
+ }
+
+ void print() {
+ cout << this -> s;
+ }
+
+private :
+ char * s;
+
+ int length_ ( char * s) {
+ int n = 0 ;
+ while (* s != ' \0 ' ) {
+ n++;
+ s++;
+ }
+
+ return n;
+ }
+
+ void copy_ ( char * s, int n, char * t) {
+ int i = 0 ;
+ while ( i < n) {
+ t[ i] = s[ i];
+ i++;
+ }
+}
+
+};
+
+
+void f( String str2) {
+
+}
+
+int main() {
+ char s[] = "Hallo" ;
+
+ String str( s);
+
+ f( str); // Copy str
+
+ String str3 = str; // Copy str
+
+ f( str3);
+
+ f( String()); // Move eines temporaeren String Objekts
+
+ String str4 = move( str);
+
+ f( str4);
+
+ // str.print();
+ // Liefert segmentation fault
+ // wegen "move"
+
+ return 0 ;
+}
+
+
+
Zusammenfassung
+
+
+Destruktor
+“copy” Konstruktor (für lvalue refs)
+“copy” Zuweisung (für lvalue refs)
+
+
+
Definiere (geeignet)
+
+Destruktor
+“copy” Konstruktor (für lvalue refs)
+“copy” Zuweisung (für lvalue refs)
+“move” Konstruktor (für rvalue refs)
+“move” Zuweisung (für rvalue refs)
+
+
+
+
+
diff --git a/lec-cpp-advanced-poly.html b/lec-cpp-advanced-poly.html
new file mode 100644
index 0000000..4378250
--- /dev/null
+++ b/lec-cpp-advanced-poly.html
@@ -0,0 +1,624 @@
+
+
+
+
+
+
+
+
+ Polymorphie in C++
+
+
+
+
+
+
+
Polymorphie in C++
+
+Martin Sulzmann
+
+
+
+
Polymorphie
+
Polymorphie (griechisch Vielgestaltigkeit) ist ein
+Programmierkonzept. Zweck: Einheitliche Schnittstelle welche auf
+verschiedene Typen anwendbar ist. Es gibt verschiedene Formen von
+Polymorhpie, z.B.
+
+
+
+
Coercive Subtyping
+
Allgemeines Subtyping Prinzip:
+
+Typ
+t t
+ist ein Subtyp von
+s s
+geschrieben
+t ≤ s t \leq s
+In jedem Kontext in welchem ein Wert vom Typ
+s s
+erwartet wird, kann auch ein Wert vom Type
+t t
+verwendet werden
+
+
Hier Coercive Subtyping: char
+≤ \leq
+int
+≤ \leq
+float
+≤ \leq
+double
+
Beispiel
+
int func( float x) {
+ if ( x < 1.0 ) return 1 ;
+ return 0 ;
+}
+
+void testCoerce() {
+ int arg = 1 ;
+ float res;
+
+ // Typkorrekt weil int <= float,
+ // d.h. jeder Wert vom Typ int kann auch an der
+ // Programmstelle verwendet werden, an welcher float erwartet wird.
+ res = func( arg);
+}
+
+
+// Compiler fuegt explizite Coercions ein!
+// Hier wird das ganze simuliert durch die Funktion coerce.
+
+
+float coerce( int x) {
+ return ( float ) x;
+}
+
+void testCoerceTranslated() {
+ int arg = 1 ;
+ float res;
+
+ res = coerce( func( coerce( arg)));
+}
+
+
+int main() {
+ testCoerce();
+
+ testCoerceTranslated();
+
+ return 1 ;
+}
+
+
+
Nominales Subtyping
+
+
Beispiel
+
// B <= A
+// abgeleitet aus Klassendeklaration, in der Literatur als "nominal subtyping" bekannt.
+class A {};
+class B : public A {};
+
+
+void h( A x) {}
+
+void g( B x) {}
+
+void testAB() {
+ A a;
+ B b;
+
+ h( a); // OK
+ h( b); // OK, weil B <= A
+ // g(a); // NICHT OK
+ g( b); // OK
+
+}
+
+int main() {
+
+ testAB();
+
+ return 1 ;
+}
+
+
+
Subtyping und Varianz
+
Betrachte Typkonstruktoren, z.B. Pointer Typen.
+
Welche Beziehung gilt zwischen int*
und
+float*
?
+
Was ist mit B*
und A*
?
+
Pointer Subtyping is kovariant!
+
Falls
+t ≤ s t \leq s
+dann
+t * ≤ s * t* \leq s* .
+
Wieso kovariant? Damit man “generischen” Code schreiben kann, siehe
+Generische Datentypen und Funktionen
+in C
+
Beispiel
+
// B <= A
+// abgeleitet aus Klassendeklaration, in der Literatur als "nominal subtyping" bekannt.
+class A {};
+class B : public A {};
+
+
+void h( A x) {}
+
+void g( B x) {}
+
+void testAB() {
+ A a;
+ B b;
+
+ h( a); // OK
+ h( b); // OK, weil B <= A
+ // g(a); // NICHT OK
+ g( b); // OK
+
+}
+
+// Abgeleitete Subtypbeziehung:
+// B <= A impliziert B* <= A*
+void h2( A* x) {}
+
+void g2( B* x) {}
+
+void testAB_2() {
+ A* a = new A();
+ B* b = new B();
+
+ h2( a); // OK
+ h2( b); // OK, weil B <= A und daher auch B* <= A*
+ // g2(a); // NICHT OK
+ g2( b); // OK
+
+ delete a;
+ delete b;
+}
+
+// Das gleiche gilt auch fuer Arrays.
+void h3( A x[]) {}
+
+void g3( B y[]) {}
+
+void testAB_3() {
+ A a[] = { A(), A(), B() }; // B <= A
+
+ B b[] = { B() };
+
+ h3( b); // OK, weil aus B <= A folgt B[] <= A[]
+
+ g3( b);
+ // g3(a); // Nicht OK
+}
+
+
+int main() {
+
+ testAB();
+ testAB_2();
+ testAB_3();
+
+ return 1 ;
+}
+
Vergleich zu Java
+
Array Subtyping in Java ist auch kovariant.
+
Das folgende Programm “crashes”.
+
void main () {
+String [] s;
+ s = new String [ 10 ];
+test ( s);
+}
+
+void test ( Object [] a) {
+ a[ 1 ] = new Point ( 10 , 20 ); // Crash!
+}
+
+
+
Overloading
+
Gleicher Funktions-/Operator-Name aber verschiedene Verwendung
+(Anzahl Argumente und deren Typen).
+
C++ Regel: Instanz muss eindeutig bestimmbar sein via
+Argumenttypen.
+
Beispiel
+
#include <iostream>
+#include <string>
+using namespace std;
+
+int funny( int x, int y) {
+ return x;
+}
+
+char funny( char x, char y) {
+ return y;
+}
+
+void testFunny() {
+
+ cout << funny( 1 , 2 );
+ cout << funny( 'a' , 'b' );
+
+ // cout << funny(1, 'a'); // Ambiguous, nicht klar welche Instanz wir wollen
+
+}
+
+/*
+
+// Folgendes ist nicht erlaubt, weil
+// "functions that differ only in their return type cannot be overloaded"
+
+int funny2() {
+ return 1;
+}
+
+bool funny2() {
+ return true;
+}
+
+void testFunny2() {
+
+ bool x = funny2();
+
+ int y = funny2();
+
+}
+
+
+*/
+
+
+int main() {
+ testFunny();
+}
+
+
+
C++ Templates und Vergleich zu Java generics
+
C++ verwendet “Monomorphisation”: Für jede Instanz dupliziere den
+Programmcode.
+
+Vorteil. Effizient, da keine Typecasts notwendig sind.
+Typ-spezifischen Optimierungen etc.
+Nachteil. Codeduplikation
+
+
Java verwendet ein “generisches” Übersetzungsscheme: Ersetze jeden
+Typparameter durch Object.
+
+
Beispiel
+
// requires C++11
+
+#include <iostream>
+#include <string>
+using namespace std;
+
+
+
+// C++ Templates und Vergleich zu Java generics
+/////////////////////////////////////////////////
+
+
+/////////////////////////////
+// Templates
+
+template < typename T>
+void mySwap( T& x, T& y) {
+ T tmp;
+
+ tmp = x; x = y; y = tmp;
+}
+
+void testTmp() {
+ int x = 1 ;
+ int y = 2 ;
+
+ mySwap< int >( x, y); // Instanzierung
+
+
+ float u = 1.0 ;
+ float v = 2.0 ;
+
+ mySwap( u, v); // Instanz <float> kann inferriert werden mit Hilfe der Argumente.
+
+}
+
+/*
+
+C++ verwendet "Monomorphisation".
+
+ - Für jede Instanz dupliziere den Programmcode
+
+ - Vorteil. Effizient, da keine Typecasts
+ notwendig sind. Typ-spezifischen Optimierungen etc.
+
+ - Nachteil. Codeduplikation
+
+Hier am Beispiel von oben.
+*/
+
+void mySwap_int( int & x, int & y) {
+ int tmp;
+
+ tmp = x; x = y; y = tmp;
+}
+
+void testTmp_mono() {
+ int x = 1 ;
+ int y = 2 ;
+
+ mySwap_int( x, y);
+
+}
+
+
+
+// Weiteres Template Beispiel.
+
+template < typename T>
+class Elem {
+ T val;
+public :
+ Elem( T init) {
+ val = init;
+ }
+ void print() {
+ cout << " \n " << val;
+ }
+ void replace( T x) {
+ val = x;
+ }
+};
+
+void testElem() {
+ Elem< int > e( 1 );
+ Elem< string> s( "Hello" );
+
+ e. print();
+ e. replace( 2 );
+ e. print();
+ s. print();
+ s. replace( "Hallo" );
+ s. print();
+
+}
+
+// Beachte.
+// Kein Typchecking von templates!
+// Nur Typchecking von Code erhalten
+// durch Monomorphisierung.
+
+struct Point {
+ int x;
+ int y;
+};
+
+
+void testElem2() {
+ Elem< struct Point> p({ 1 , 2 }); // (P)
+
+ // Kein Typfehler.
+ // Erst durch Hinzunahme folgender Codezeile.
+
+ // p.print();
+
+}
+
+
+
+// Beachte:
+// Templates sind verschieden von "generics" in Java.
+// In C++
+// - Monomorpization
+// In Java
+// - Generische Uebersetzung
+
+// Java's generisches Uebersetzungs Schema am Beispiel.
+
+// 1. Ersetze alle Typparameter durch void*.
+// (In Java wird Object verwendet).
+
+class Elem_G {
+ void * val;
+public :
+ Elem_G( void * init) {
+ val = init;
+ }
+ void print() {
+ cout << " \n " << val;
+ }
+ void replace( void * x) {
+ val = x;
+ }
+};
+
+// Passt alles?
+
+void testElem_G() {
+ int i = 1 ;
+ Elem_G e(& i);
+ // int* <= void*
+
+ e. print();
+ int j = 2 ;
+ e. replace(& j);
+ e. print();
+}
+
+
+// Beachte.
+// Keine korrekte Behandlung von print.
+// Benoetigen "run-time type info"
+// im Falle von "<<"
+
+
+
+enum TYPE {
+ INT,
+ BOOL,
+ // and so on
+};
+
+class Elem_GG {
+ void * val;
+ enum TYPE t;
+public :
+ Elem_GG( void * init, enum TYPE ty) {
+ val = init;
+ t = ty;
+ }
+ void print() {
+ // Entspricht "instanceof" in Java.
+ switch ( t) {
+ case INT: {
+ int * p = ( int *)( val);
+ cout << " \n " << * p;
+ break ;
+ }
+ case BOOL: {
+ bool * p = ( bool *)( val);
+ cout << " \n " << * p;
+ break ;
+ }
+ }
+ }
+ void replace( void * x) {
+ val = x;
+ }
+};
+
+
+void testElem_GG() {
+ int i = 1 ;
+ Elem_GG e(& i, INT);
+ // int* <= void*
+
+ e. print();
+ int j = 2 ;
+ e. replace(& j);
+ e. print();
+
+ bool b = true ;
+ Elem_GG f(& b, BOOL);
+ f. print();
+}
+
+/*
+
+Zusammengefasst.
+
+Monomorphization in C++
+ + Effizient
+ - Code Duplikation
+
+Generische Uebersetzung in Java
+ + Generischer Code
+ +- Typchecks zur Laufzeit sind notwendig
+
+ */
+
+
+
+int main() {
+ // testAdd();
+ testElem();
+ testElem_G();
+ testElem_GG();
+}
+
+
+
diff --git a/semWi23-24.html b/semWi23-24.html
new file mode 100644
index 0000000..63e26d3
--- /dev/null
+++ b/semWi23-24.html
@@ -0,0 +1,302 @@
+
+
+
+
+
+
+
+ Softwareprojekt - Winter Semester 23/24
+
+
+
+
+
+Beachte
+ Online test im ilias System sind verfügbar
+Evaluation
+1.Schriftliche Klausur, ohne Hilfsmittel, 90min
+
+Übungsschein bei erfolgreicher Abgabe aller Übungen und Teilnahme
+mit Ergebnis “Bestanden” der relevanten Online Tests. Details siehe hier
+10% Bonuspunkte sind maximal erreichbar durch Teilnahme an Online
+Tests C++ Teil 1-5.
+
+Beachte:
+
+Abgabetermine für Scheinaufgaben (siehe Übungsleiter)
+Durchführungstermine für Online Tests (siehe Ordner Online
+Tests)
+Online Tests (falls durchgeführt) sind einsehbar bis zur
+Klausur.
+2 Versuche pro Online Tests jeweils 90min maximal Zeit.
+
+Inhalt
+
+Einführung in C und C++(11,…) und C-artige Programmiersprachen (Go,
+Rust, …)
+
+Wichtigsten Sprachmerkmale kennen lernen.
+
+Programmieren lernen
+
+Problem verstehen und lösen.
+Kodierung der Lösung in C/C++.
+Verifikation und Validation
+
+Programmiersprachen Merkmale
+
+Vorlesungsunterlagen
+Siehe hier
+Semesterablauf
+
+Vorlesung
+
+INFB + MINB
+Dienstags 14:00-17:10
+E201 und auf zoom
+
+Tutorium
+
+Mittwoch 14:00-17:10
+E301
+
+Übungen
+
+Montag 9:50-11:20 und Mittwoch 14:00-17:10
+E203
+
+
+Ablauf siehe unten.
+
+W1, 25.09-01.10
+
+Intro
+Programmiersprache C
+
+W2, 02.10-08.10 (03.10 public holiday)
+
+W3, 09.10-15.10
+
+Programmiersprache C
+Grundlagen
+Zeigerarithmetik
+
+W4, 16.10-22.10
+
+Programmiersprache C
+Speicherverwaltung
+Fortgeschrittene Themen
+
+W5, 23.10-29.10
+
+Programmiersprache C++ (basics)
+
+W6, 30.10-05.11 (01.11 public holiday)
+
+Übung am Montag
+Keine Vorlesung am Dienstag
+Keine Übung und Tutorium am Mittwoch
+
+W7, 06.11-12.11
+
+Programmiersprache C++ (Klassen, virtuelle und nicht-virtuelle
+Methoden, Templates)
+Programmiersprache C++ (Speicherwaltung)
+
+W8, 13.11-19.11
+
+Programmiersprache C++ (Speicherverwaltung)
+Polymorphie
+
+W9, 20.11-26.11
+
+Polymorphie (kurze Wiederholung)
+Syntax Analyse
+
+W10, 27.11-03.12
+
+W11, 04.12-10.12
+
+Funktionale Programmierung
+
+W12, 11.12-17.12
+
+W13, 18.12-24.12
+
+Winter break
+W14, 08.01-14.01
+
+W15, 15.01-21.01
+
+
+
+