diff --git a/20231214/dynmem-01.c b/20231214/dynmem-01.c
new file mode 100644
index 0000000000000000000000000000000000000000..0ffe355084006090fc13a895516ab80938df25be
--- /dev/null
+++ b/20231214/dynmem-01.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+char *name[] = { "Anna", "Berthold", "Caesar" };
+
+int main (void)
+{
+  name[3] = "Dieter";
+  for (int i = 0; i < 4; i++)
+    printf ("%s\n", name[i]);
+  return 0;
+}
diff --git a/20231214/dynmem-02.c b/20231214/dynmem-02.c
new file mode 100644
index 0000000000000000000000000000000000000000..d8f71409680d6ecfd8ae175cc44aa2ab3d28fc15
--- /dev/null
+++ b/20231214/dynmem-02.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main (void)
+{
+  char **name = malloc (3 * sizeof (char *));  /* Speicherplatz für 3 Zeiger anfordern */
+  name[0] = "Anna";
+  name[1] = "Berthold";
+  name[2] = "Caesar";
+  name[3] = "Dieter";  /* immer noch unzulässig */
+  for (int i = 0; i < 4; i++)
+    printf ("%s\n", name[i]);
+  free (name);
+  return 0;
+}
diff --git a/20231214/dynmem-03.c b/20231214/dynmem-03.c
new file mode 100644
index 0000000000000000000000000000000000000000..852f915346ea40bf5c22d41304f665136d7900ef
--- /dev/null
+++ b/20231214/dynmem-03.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main (void)
+{
+  char **name = malloc (3 * sizeof (char *));  /* Speicherplatz für 3 Zeiger anfordern */
+  name[0] = "Anna";
+  name[1] = "Berthold";
+  name[2] = "Caesar";
+//  name[3] = "Dieter";  /* immer noch unzulässig */
+  for (int i = 0; i < 3; i++)   /* vorher: 4 (unzulässig) */
+    printf ("%s\n", name[i]);
+  free (name);
+  return 0;
+}
diff --git a/20231214/dynmem-04.c b/20231214/dynmem-04.c
new file mode 100644
index 0000000000000000000000000000000000000000..5b154ef182bed0c1c32c7d454a34a22a94fcb44c
--- /dev/null
+++ b/20231214/dynmem-04.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main (void)
+{
+  char **name = malloc (3 * sizeof (char *));  /* Speicherplatz für 3 Zeiger anfordern */
+  name[0] = "Anna";
+  name[1] = "Berthold";
+  name[2] = "Caesar";
+
+  char **new_name = malloc (4 * sizeof (char *));  /* Speicherplatz für 4 Zeiger anfordern */
+  for (int i = 0; i < 3; i++)
+    new_name[i] = name[i];
+  new_name[3] = "Dieter";
+
+  free (name);  /* altes Array */
+  name = new_name;  /* alter Zeiger zeigt auf neues Array */
+
+  for (int i = 0; i < 4; i++)
+    printf ("%s\n", name[i]);
+  free (name);
+  return 0;
+}
diff --git a/20231214/dynmem-05.c b/20231214/dynmem-05.c
new file mode 100644
index 0000000000000000000000000000000000000000..fc53998df034d3b3c06a87a9372be2daf9c71aae
--- /dev/null
+++ b/20231214/dynmem-05.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main (void)
+{
+  char **name = malloc (3 * sizeof (char *));  /* Speicherplatz für 3 Zeiger anfordern */
+  name[0] = "Anna";
+  name[1] = "Berthold";
+  name[2] = "Caesar";
+
+  char **new_name = malloc (4 * sizeof (char *));  /* Speicherplatz für 4 Zeiger anfordern */
+  for (int i = 0; i < 3; i++)
+    new_name[i] = name[i];
+  new_name[3] = "Dieter";
+
+  free (name);  /* altes Array */
+  name = new_name;  /* alter Zeiger zeigt auf neues Array */
+
+  for (int i = 0; i < 4; i++)
+    printf ("%s\n", name[i]);
+  free (name);
+  free (new_name);  /* zeigt auf denselben Speicherplatz wie name --> Fehler */
+  return 0;
+}
diff --git a/20231214/dynmem-06.c b/20231214/dynmem-06.c
new file mode 100644
index 0000000000000000000000000000000000000000..226f12f62f02dafed072eefe32503188168bb668
--- /dev/null
+++ b/20231214/dynmem-06.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main (void)
+{
+  char **name = malloc (3 * sizeof (char *));  /* Speicherplatz für 3 Zeiger anfordern */
+  name[0] = "Anna";
+  name[1] = "Berthold";
+  name[2] = "Caesar";
+
+  name = realloc (name, 4 * sizeof (char *));  /* Speicherplatz für 4 Zeiger anfordern */
+  name[3] = "Dieter";
+
+  for (int i = 0; i < 4; i++)
+    printf ("%s\n", name[i]);
+  free (name);
+  return 0;
+}
diff --git a/20231214/hello-gtk.png b/20231214/hello-gtk.png
new file mode 120000
index 0000000000000000000000000000000000000000..cca99209d86683a9a3b0f70bbc149780bae10ba6
--- /dev/null
+++ b/20231214/hello-gtk.png
@@ -0,0 +1 @@
+../common/hello-gtk.png
\ No newline at end of file
diff --git a/20231214/hp-20231214.pdf b/20231214/hp-20231214.pdf
index b6d6d49611933ec9543ecdfcadb6cb4c8c625d41..0e8563ddedf2155e90f04d51d81bfaf68cda047e 100644
Binary files a/20231214/hp-20231214.pdf and b/20231214/hp-20231214.pdf differ
diff --git a/20231214/hp-20231214.tex b/20231214/hp-20231214.tex
index ea69ab90e96f387b0cc8f85ba59cd7a037a3cbf0..05a42f277a4dfdab51ba7f2c6572ca9609c6a827 100644
--- a/20231214/hp-20231214.tex
+++ b/20231214/hp-20231214.tex
@@ -65,11 +65,10 @@
         \item[6.0] Dynamische Speicherverwaltung
         \item[6.1] Konzepte und Ziele
         \item[6.2] Beispiel: Zahlen und Buchstaben
-        \color{black}
         \item[6.3] Unions
         \item[6.4] Virtuelle Methoden
-        \vspace*{-\smallskipamount}
-        \item[\dots]
+        \item[6.5] Beispiel: Graphische Benutzeroberfläche (GUI)
+        \item[6.6] Ausblick: C++
       \end{itemize}
     \item[\textbf{7}] \textbf{Datenstrukturen}
   \end{itemize}
@@ -337,8 +336,8 @@
           \put(-2.75,-0.05){\tikz{\draw[thick](0,0.25)--(2.5,-0.05);%
                                   \draw[thick](-0.1,-0.05)--(2.5,0.3);}}
           \put(1.5,-1.1){\begin{rotate}{7}\large\bf\textarrow\
-%                           kommt gleich
-                           nächste Woche
+                           kommt gleich
+%                           nächste Woche
                          \end{rotate}}
         \end{picture}
         Zeiger, die im Objekt gespeichert sind\\
@@ -478,8 +477,6 @@
   
 \end{frame}
 
-\iffalse
-
 \subsection{Unions}
 
 \begin{frame}[fragile]
@@ -830,6 +827,4 @@
   
 \end{frame}
 
-\fi
-
 \end{document}
diff --git a/20231214/objects-01.c b/20231214/objects-01.c
new file mode 100644
index 0000000000000000000000000000000000000000..1a628668fd7b8fb3a0d9886ac14e8e909bc23793
--- /dev/null
+++ b/20231214/objects-01.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+
+typedef struct
+{
+  int type;
+} t_base;
+
+typedef struct
+{
+  int type;
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  char *content;
+} t_string;
+
+int main (void)
+{
+  t_integer i = { 1, 42 };
+  t_string s = { 2, "Hello, world!" };
+
+  t_base *object[] = { &i, &s };
+
+  return 0;
+}
diff --git a/20231214/objects-02.c b/20231214/objects-02.c
new file mode 100644
index 0000000000000000000000000000000000000000..a47cfb4276085399afb86795d04b1f6ae20c95bf
--- /dev/null
+++ b/20231214/objects-02.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+
+typedef struct
+{
+  int type;
+} t_base;
+
+typedef struct
+{
+  int type;
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  char *content;
+} t_string;
+
+int main (void)
+{
+  t_integer i = { 1, 42 };
+  t_string s = { 2, "Hello, world!" };
+
+  t_base *object[] = { (t_base *) &i, (t_base *) &s };
+
+  return 0;
+}
diff --git a/20231214/objects-03.c b/20231214/objects-03.c
new file mode 100644
index 0000000000000000000000000000000000000000..ff9224c0767ccad39f5b1396720ee73b6a0455fb
--- /dev/null
+++ b/20231214/objects-03.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+
+typedef struct
+{
+  int type;
+} t_base;
+
+typedef struct
+{
+  int type;
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  char *content;
+} t_string;
+
+int main (void)
+{
+  t_integer i = { 1, 42 };
+  t_string s = { 2, "Hello, world!" };
+
+  t_base *object[] = { (t_base *) &i, (t_base *) &s };
+
+  for (int i = 0; i < 2; i++)
+    if (object[i]->type == 1)
+      printf ("Integer: %d\n", object[i]->content);
+    else if (object[i]->type == 2)
+      printf ("String: \"%s\"\n", object[i]->content);
+
+  return 0;
+}
diff --git a/20231214/objects-04.c b/20231214/objects-04.c
new file mode 100644
index 0000000000000000000000000000000000000000..ef7bffe80471d4b014258824421dce0557fc41dd
--- /dev/null
+++ b/20231214/objects-04.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+
+typedef struct
+{
+  int type;
+} t_base;
+
+typedef struct
+{
+  int type;
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  char *content;
+} t_string;
+
+int main (void)
+{
+  t_integer i = { 1, 42 };
+  t_string s = { 2, "Hello, world!" };
+
+  t_base *object[] = { (t_base *) &i, (t_base *) &s };
+
+  for (int i = 0; i < 2; i++)
+    if (object[i]->type == 1)
+      printf ("Integer: %d\n", (t_integer *) object[i]->content);
+    else if (object[i]->type == 2)
+      printf ("String: \"%s\"\n", (t_string *) object[i]->content);
+
+  return 0;
+}
diff --git a/20231214/objects-05.c b/20231214/objects-05.c
new file mode 100644
index 0000000000000000000000000000000000000000..820181d87e2a04b81cd2e03aa7980d970cd6c1a6
--- /dev/null
+++ b/20231214/objects-05.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+
+typedef struct
+{
+  int type;
+} t_base;
+
+typedef struct
+{
+  int type;
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  char *content;
+} t_string;
+
+int main (void)
+{
+  t_integer i = { 1, 42 };
+  t_string s = { 2, "Hello, world!" };
+
+  t_base *object[] = { (t_base *) &i, (t_base *) &s };
+
+  for (int i = 0; i < 2; i++)
+    if (object[i]->type == 1)
+      printf ("Integer: %d\n", ((t_integer *) object[i])->content);
+    else if (object[i]->type == 2)
+      printf ("String: \"%s\"\n", ((t_string *) object[i])->content);
+
+  return 0;
+}
diff --git a/20231214/objects-06.c b/20231214/objects-06.c
new file mode 100644
index 0000000000000000000000000000000000000000..86847c9085083e2d5093026619550fb272b5f4ec
--- /dev/null
+++ b/20231214/objects-06.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+typedef struct
+{
+  int type;
+} t_base;
+
+typedef struct
+{
+  int type;
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  char *content;
+} t_string;
+
+void print_object (t_base *this)
+{
+  if (this->type == 1)
+    printf ("Integer: %d\n", ((t_integer *) this)->content);
+  else if (this->type == 2)
+    printf ("String: \"%s\"\n", ((t_string *) this)->content);
+}
+
+int main (void)
+{
+  t_integer i = { 1, 42 };
+  t_string s = { 2, "Hello, world!" };
+
+  t_base *object[] = { (t_base *) &i, (t_base *) &s };
+
+  for (int i = 0; i < 2; i++)
+    print_object (object[i]);
+
+  return 0;
+}
diff --git a/20231214/objects-07.c b/20231214/objects-07.c
new file mode 100644
index 0000000000000000000000000000000000000000..b9b24ad65f650aeda194e4570ae853e1a5ad8f11
--- /dev/null
+++ b/20231214/objects-07.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+
+#define T_BASE    0
+#define T_INTEGER 1
+#define T_STRING  2
+
+typedef struct
+{
+  int type;
+} t_base;
+
+typedef struct
+{
+  int type;
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  char *content;
+} t_string;
+
+void print_object (t_base *this)
+{
+  if (this->type == T_INTEGER)
+    printf ("Integer: %d\n", ((t_integer *) this)->content);
+  else if (this->type == T_STRING)
+    printf ("String: \"%s\"\n", ((t_string *) this)->content);
+}
+
+int main (void)
+{
+  t_integer i = { T_INTEGER, 42 };
+  t_string s = { T_STRING, "Hello, world!" };
+
+  t_base *object[] = { (t_base *) &i, (t_base *) &s, NULL };
+
+  for (int i = 0; object[i]; i++)
+    print_object (object[i]);
+
+  return 0;
+}
diff --git a/20231214/objects-08.c b/20231214/objects-08.c
new file mode 100644
index 0000000000000000000000000000000000000000..0c93e8f6c3c4b5e504c758dfa87b8510e98c0692
--- /dev/null
+++ b/20231214/objects-08.c
@@ -0,0 +1,59 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define T_BASE    0
+#define T_INTEGER 1
+#define T_STRING  2
+
+typedef struct
+{
+  int type;
+} t_base;
+
+typedef struct
+{
+  int type;
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  char *content;
+} t_string;
+
+void print_object (t_base *this)
+{
+  if (this->type == T_INTEGER)
+    printf ("Integer: %d\n", ((t_integer *) this)->content);
+  else if (this->type == T_STRING)
+    printf ("String: \"%s\"\n", ((t_string *) this)->content);
+}
+
+t_integer *new_integer (int i)
+{
+  t_integer *p = malloc (sizeof (t_integer));
+  p->type = T_INTEGER;
+  p->content = i;
+  return p;
+}
+
+t_string *new_string (char *s)
+{
+  t_string *p = malloc (sizeof (t_string));
+  p->type = T_STRING;
+  p->content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_base *object[] = { (t_base *) new_integer (42),
+                       (t_base *) new_string ("Hello, world!"),
+                       NULL };
+
+  for (int i = 0; object[i]; i++)
+    print_object (object[i]);
+
+  return 0;
+}
diff --git a/20231214/objects-09.c b/20231214/objects-09.c
new file mode 100644
index 0000000000000000000000000000000000000000..3355ce354278e9839db0952c6de0d7acca172157
--- /dev/null
+++ b/20231214/objects-09.c
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define T_BASE    0
+#define T_INTEGER 1
+#define T_STRING  2
+
+typedef struct
+{
+  int type;
+} t_base;
+
+typedef struct
+{
+  int type;
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  char *content;
+} t_string;
+
+typedef union
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_object (t_object *this)
+{
+  if (this->base.type == T_INTEGER)
+    printf ("Integer: %d\n", this->integer.content);
+  else if (this->base.type == T_STRING)
+    printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_object *new_integer (int i)
+{
+  t_object *p = malloc (sizeof (t_integer));
+  p->integer.type = T_INTEGER;
+  p->integer.content = i;
+  return p;
+}
+
+t_object *new_string (char *s)
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.type = T_STRING;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    print_object (object[i]);
+
+  for (int i = 0; object[i]; i++)
+    free (object[i]);
+
+  return 0;
+}
diff --git a/20231214/objects-09a.c b/20231214/objects-09a.c
new file mode 100644
index 0000000000000000000000000000000000000000..e98c5bd7f08421834d3322d1d7cdd568707ed4ba
--- /dev/null
+++ b/20231214/objects-09a.c
@@ -0,0 +1,60 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct
+{
+} t_base;
+
+typedef struct
+{
+  int content;
+} t_integer;
+
+typedef struct
+{
+  char *content;
+} t_string;
+
+typedef union
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_object (t_object *this)
+{
+//   if (this->base.type == T_INTEGER)
+//     printf ("Integer: %d\n", this->integer.content);
+//   else if (this->base.type == T_STRING)
+//     printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_object *new_integer (int i)
+{
+  t_object *p = malloc (sizeof (t_integer));
+  p->integer.content = i;
+  return p;
+}
+
+t_object *new_string (char *s)
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    print_object (object[i]);
+
+  for (int i = 0; object[i]; i++)
+    free (object[i]);
+
+  return 0;
+}
diff --git a/20231214/objects-09b.c b/20231214/objects-09b.c
new file mode 100644
index 0000000000000000000000000000000000000000..f1d8678839e5b2fc66bebf77074a1a2195440444
--- /dev/null
+++ b/20231214/objects-09b.c
@@ -0,0 +1,60 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct
+{
+} t_base;
+
+typedef struct
+{
+  int content;
+} t_integer;
+
+typedef struct
+{
+  char *content;
+} t_string;
+
+typedef union
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_object (t_object *this)
+{
+  printf ("Wenn dies eine Integer ist, dann lautet sie: %d.\n", this->integer.content);
+  printf ("Wenn dies ein String ist, ist er %zu Zeichen lang.\n",
+          strlen (this->string.content));
+}
+
+t_object *new_integer (int i)
+{
+  t_object *p = malloc (sizeof (t_integer));
+  p->integer.content = i;
+  return p;
+}
+
+t_object *new_string (char *s)
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    print_object (object[i]);
+
+  for (int i = 0; object[i]; i++)
+    free (object[i]);
+
+  return 0;
+}
diff --git a/20231214/objects-09c.c b/20231214/objects-09c.c
new file mode 100644
index 0000000000000000000000000000000000000000..6eeff4f335112fea7ef6f4d5b8384a8242f4515b
--- /dev/null
+++ b/20231214/objects-09c.c
@@ -0,0 +1,61 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct
+{
+} t_base;
+
+typedef struct
+{
+  int content;
+} t_integer;
+
+typedef struct
+{
+  char *content;
+} t_string;
+
+typedef union
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_object (t_object *this)
+{
+  if (this->integer.content < 1000)  /* Heuristik --> Aua! =8-O */
+    printf ("Integer: %d\n", this->integer.content);
+  else
+    printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_object *new_integer (int i)
+{
+  t_object *p = malloc (sizeof (t_integer));
+  p->integer.content = i;
+  return p;
+}
+
+t_object *new_string (char *s)
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    print_object (object[i]);
+
+  for (int i = 0; object[i]; i++)
+    free (object[i]);
+
+  return 0;
+}
diff --git a/20231214/objects-10.c b/20231214/objects-10.c
new file mode 100644
index 0000000000000000000000000000000000000000..86787f3d0339bda54baefd062392d8792cd4b2be
--- /dev/null
+++ b/20231214/objects-10.c
@@ -0,0 +1,76 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define T_BASE    0
+#define T_INTEGER 1
+#define T_STRING  2
+
+typedef struct
+{
+  int type;
+  void (*print) (t_object *this);
+} t_base;
+
+typedef struct
+{
+  int type;
+  void (*print) (t_object *this);
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  void (*print) (t_object *this);
+  char *content;
+} t_string;
+
+typedef union
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_integer (t_object *this)
+{
+  printf ("Integer: %d\n", this->integer.content);
+}
+
+void print_string (t_object *this)
+{
+  printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_object *new_integer (int i)
+{
+  t_object *p = malloc (sizeof (t_integer));
+  p->integer.type = T_INTEGER;
+  p->integer.print = print_integer;
+  p->integer.content = i;
+  return p;
+}
+
+t_object *new_string (char *s)
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.type = T_STRING;
+  p->string.print = print_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.print (object[i]);
+
+  for (int i = 0; object[i]; i++)
+    free (object[i]);
+
+  return 0;
+}
diff --git a/20231214/objects-11.c b/20231214/objects-11.c
new file mode 100644
index 0000000000000000000000000000000000000000..0a921d8b5c88198cdd07aeb409da6b2a57be33ac
--- /dev/null
+++ b/20231214/objects-11.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define T_BASE    0
+#define T_INTEGER 1
+#define T_STRING  2
+
+union t_object;
+
+typedef struct
+{
+  int type;
+  void (*print) (union t_object *this);
+} t_base;
+
+typedef struct
+{
+  int type;
+  void (*print) (union t_object *this);
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  void (*print) (union t_object *this);
+  char *content;
+} t_string;
+
+typedef union t_object
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_integer (t_object *this)
+{
+  printf ("Integer: %d\n", this->integer.content);
+}
+
+void print_string (t_object *this)
+{
+  printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_object *new_integer (int i)
+{
+  t_object *p = malloc (sizeof (t_integer));
+  p->integer.type = T_INTEGER;
+  p->integer.print = print_integer;
+  p->integer.content = i;
+  return p;
+}
+
+t_object *new_string (char *s)
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.type = T_STRING;
+  p->string.print = print_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.print (object[i]);
+
+  for (int i = 0; object[i]; i++)
+    free (object[i]);
+
+  return 0;
+}
diff --git a/20231214/objects-12.c b/20231214/objects-12.c
new file mode 100644
index 0000000000000000000000000000000000000000..3b0dddd0b7eda19d8b0545906dabd76bc9c8a378
--- /dev/null
+++ b/20231214/objects-12.c
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+union t_object;
+
+typedef struct
+{
+  void (* print) (union t_object *this);
+} t_base;
+
+typedef struct
+{
+  void (* print) (union t_object *this);
+  int content;
+} t_integer;
+
+typedef struct
+{
+  void (* print) (union t_object *this);
+  char *content;
+} t_string;
+
+typedef union t_object
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_integer (t_object *this)
+{
+  printf ("Integer: %d\n", this->integer.content);
+}
+
+void print_string (t_object *this)
+{
+  printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_object *new_integer (int i)
+{
+  t_object *p = malloc (sizeof (t_integer));
+  p->integer.print = print_integer;
+  p->integer.content = i;
+  return p;
+}
+
+t_object *new_string (char *s)
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.print = print_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.print (object[i]);
+
+  for (int i = 0; object[i]; i++)
+    free (object[i]);
+
+  return 0;
+}
diff --git a/20231214/objects-13.c b/20231214/objects-13.c
new file mode 100644
index 0000000000000000000000000000000000000000..81ef279b060e0b6290194fdeda8c3330cb716cdd
--- /dev/null
+++ b/20231214/objects-13.c
@@ -0,0 +1,75 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+union t_object;
+struct t_vmt;
+
+typedef struct
+{
+  struct t_vmt *vmt;
+} t_base;
+
+typedef struct
+{
+  struct t_vmt *vmt;
+  int content;
+} t_integer;
+
+typedef struct
+{
+  struct t_vmt *vmt;
+  char *content;
+} t_string;
+
+typedef union t_object
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+typedef struct t_vmt
+{
+  void (* print) (union t_object *this);
+} t_vmt;
+
+void print_integer (t_object *this)
+{
+  printf ("Integer: %d\n", this->integer.content);
+}
+
+void print_string (t_object *this)
+{
+  printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_vmt vmt_integer = { print_integer };
+t_vmt vmt_string = { print_string };
+
+t_object *new_integer (int i)
+{
+  t_object *p = malloc (sizeof (t_integer));
+  p->integer.vmt = &vmt_integer;
+  p->integer.content = i;
+  return p;
+}
+
+t_object *new_string (char *s)
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->integer.vmt = &vmt_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.vmt->print (object[i]);
+
+  return 0;
+}
diff --git a/20231214/objects-14.cpp b/20231214/objects-14.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..90329346afd7d1cfd1caad1d267781b25300b4ca
--- /dev/null
+++ b/20231214/objects-14.cpp
@@ -0,0 +1,55 @@
+#include <stdio.h>
+
+struct TBase
+{
+  virtual void print () = 0;
+};
+
+struct TInteger: TBase
+{
+  int content;
+  virtual void print ();
+  TInteger (int i);
+};
+
+struct TString: TBase
+{
+  char *content;
+  virtual void print ();
+  TString (char *s);
+};
+
+void TInteger::print ()
+{
+  printf ("Integer: %d\n", content);
+}
+
+void TString::print ()
+{
+  printf ("String: \"%s\"\n", content);
+}
+
+TInteger::TInteger (int i)
+{
+  content = i;
+}
+
+TString::TString (char *s)
+{
+  content = s;
+}
+
+int main (void)
+{
+  TBase *object[] = { new TInteger (42),
+                      new TString ("Hello, world!"),
+                      NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->print ();
+
+  for (int i = 0; object[i]; i++)
+    delete object[i];
+
+  return 0;
+}
diff --git a/20231214/sort-4b.c b/20231214/sort-4b.c
new file mode 100644
index 0000000000000000000000000000000000000000..ca8a01870880c77b13f6744e1ee9a28ae60e957a
--- /dev/null
+++ b/20231214/sort-4b.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+int comparisons = 0;
+
+void display (char **name, int left, int right)
+{
+  printf ("\e[H\e[J");
+  for (int i = 0; name[i]; i++)
+    {
+      printf ("%s", name[i]);
+      if (i == left || i == right)
+        printf (" <--");
+      printf ("\n");
+    }
+  printf ("%d\n", comparisons);
+}
+
+int compare (char **name, int left, int right)
+{
+  int result = strcmp (name[left], name[right]);
+  comparisons++;
+  display (name, left, right);
+  usleep (200000);
+  return result;
+}
+
+int find_first (char **name)
+{
+  int first = 0;
+  for (int i = 1; name[i]; i++)
+    if (compare (name, i, first) < 0)
+      first = i;
+  return first;
+}
+
+void sort (char **name)
+{
+  if (*name)
+    {
+      int first = find_first (name);
+      char *temp = name[0];
+      name[0] = name[first];
+      name[first] = temp;
+      sort (name + 1);
+    }
+}
+
+int main (void)
+{
+  char *name[] = { "Otto", "Lisa", "Anna", "Heinrich", "Siegfried", "Peter",
+                   "Dieter", "Hugo", "Berta", "Maria", "Fritz", "Box", "Hans",
+                   "Thomas", "Ulrich", "Zacharias", NULL };
+  sort (name);
+  display (name, -1, -1);
+  return 0;
+}
diff --git a/20231214/unions-01.c b/20231214/unions-01.c
new file mode 100644
index 0000000000000000000000000000000000000000..87e5325939f6b045d78f92d62eacdbe2045e3190
--- /dev/null
+++ b/20231214/unions-01.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdint.h>
+
+typedef union
+{
+  int8_t i;
+  uint8_t u;
+} num8_t;
+
+int main (void)
+{
+  num8_t n;
+  n.i = -3;
+  printf ("%d\n", n.u);
+  return 0;
+}
diff --git a/20231214/unions-02.c b/20231214/unions-02.c
new file mode 100644
index 0000000000000000000000000000000000000000..be8562a50395e50e007dc1c0b19b98a476935670
--- /dev/null
+++ b/20231214/unions-02.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdint.h>
+
+typedef union
+{
+  char s[8];
+  uint64_t x;
+} num_char_t;
+
+int main (void)
+{
+  num_char_t test = { "Hello!" };
+  printf ("%lx\n", test.x);
+  return 0;
+}
diff --git a/20231214/unions-03.c b/20231214/unions-03.c
new file mode 100644
index 0000000000000000000000000000000000000000..f60307ed622ffb38982089bcb5a1f1db53a89cd0
--- /dev/null
+++ b/20231214/unions-03.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdint.h>
+
+typedef union
+{
+  char s[8];
+  uint64_t x;
+} num_char_t;
+
+int main (void)
+{
+  num_char_t test = { "Hello!" };
+  printf ("%ld\n", test.x);
+  return 0;
+}
diff --git a/20231214/unions-04.c b/20231214/unions-04.c
new file mode 100644
index 0000000000000000000000000000000000000000..1dbbe1fa7854793905f2fca584a48803fc9ef7f5
--- /dev/null
+++ b/20231214/unions-04.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdint.h>
+
+typedef union
+{
+  char s[8];
+  uint64_t x;
+} num_char_t;
+
+int main (void)
+{
+  num_char_t test = { 36762444129608 };
+  printf ("%s\n", test.s);
+  return 0;
+}
diff --git a/20231214/unions-05.c b/20231214/unions-05.c
new file mode 100644
index 0000000000000000000000000000000000000000..c234678992f4500364f2b3c478949c45429905f9
--- /dev/null
+++ b/20231214/unions-05.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdint.h>
+
+typedef union
+{
+  char s[8];
+  uint64_t x;
+} num_char_t;
+
+int main (void)
+{
+  num_char_t test = { x: 36762444129608 };
+  printf ("%s\n", test.s);
+  return 0;
+}