diff --git a/20231214/hp-20231214.tex b/20231214/hp-20231214.tex
index 05a42f277a4dfdab51ba7f2c6572ca9609c6a827..6595d3fb0a8415c70bd58547a8824e921eb3c759 100644
--- a/20231214/hp-20231214.tex
+++ b/20231214/hp-20231214.tex
@@ -20,7 +20,7 @@
 % Attribution-ShareAlike 3.0 Unported License along with this
 % document.  If not, see <http://creativecommons.org/licenses/>.
 
-% README: Objektorientierte Programmierung: Einführung
+% README: Objektorientierte Programmierung
 
 \documentclass[10pt,t]{beamer}
 
diff --git a/20240104/hp-20240104.pdf b/20240104/hp-20240104.pdf
index 338dafd6c8e542e2a79a76f66c28b3a18e73b307..28bb8e063958ac5153f9b45b601fbff617bf12f5 100644
Binary files a/20240104/hp-20240104.pdf and b/20240104/hp-20240104.pdf differ
diff --git a/20240104/hp-20240104.tex b/20240104/hp-20240104.tex
index cf6d9ee6e567042ec5841019f51f1afb7cb5b439..7efd6def0713089d3252b3707e2667abb9fadfe8 100644
--- a/20240104/hp-20240104.tex
+++ b/20240104/hp-20240104.tex
@@ -556,7 +556,7 @@
   - 7R_{\mu\nu\rho\sigma}R^{\mu\nu\rho\sigma})$
   \vspace{-\medskipamount}
   \begin{displaymath}
-    \Rightarrow V_{\text{CC}}(r) \approx -\frac{c^2\beta}{r} + \fr12 c^2 \gamma\,r
+    \Rightarrow V(r) \approx -\frac{c^2\beta}{r} + \fr12 c^2 \gamma\,r
     \qquad
     \text{(Newton + \only<2->{winzige }konstante Kraft)}
   \end{displaymath}
@@ -728,7 +728,7 @@
   \vspace{-\smallskipamount}
   \begin{itemize}
     \item
-      \file{adl2xsm.c}\\
+      \file{adl2xym.c}\\
       astronomische in kartesische Koordinaten\\
       und Leuchtkraft in Masse umrechnen
     \item
diff --git a/20240111/aufgabe-1a.c b/20240111/aufgabe-1a.c
new file mode 100644
index 0000000000000000000000000000000000000000..61b6e79400afbb8ac0609eb1b72c04b83a0fce41
--- /dev/null
+++ b/20240111/aufgabe-1a.c
@@ -0,0 +1,50 @@
+#include <stdio.h>
+
+#define ANIMAL     0
+#define WITH_WINGS 1
+#define WITH_LEGS  2
+
+typedef struct animal
+{
+  int type;
+  char *name;
+} animal;
+
+typedef struct with_wings
+{
+  int wings;
+} with_wings;
+
+typedef struct with_legs
+{
+  int legs;
+} with_legs;
+
+int main (void)
+{
+  animal *a[2];
+
+  animal duck;
+  a[0] = &duck;
+  a[0]->type = WITH_WINGS;
+  a[0]->name = "duck";
+  a[0]->wings = 2;
+
+  animal cow;
+  a[1] = &cow;
+  a[1]->type = WITH_LEGS;
+  a[1]->name = "cow";
+  a[1]->legs = 4;
+
+  for (int i = 0; i < 2; i++)
+    if (a[i]->type == WITH_LEGS)
+      printf ("A %s has %d legs.\n", a[i]->name,
+              ((with_legs *) a[i])-> legs);
+    else if (a[i]->type == WITH_WINGS)
+      printf ("A %s has %d wings.\n", a[i]->name,
+              ((with_wings *) a[i])-> wings);
+    else
+      printf ("Error in animal: %s\n", a[i]->name);
+
+  return 0;
+}
diff --git a/20240111/aufgabe-1b.c b/20240111/aufgabe-1b.c
new file mode 100644
index 0000000000000000000000000000000000000000..2cf3b56f4540f399d3761b0de929d80a1f1de611
--- /dev/null
+++ b/20240111/aufgabe-1b.c
@@ -0,0 +1,50 @@
+#include <stdio.h>
+
+#define ANIMAL     0
+#define WITH_WINGS 1
+#define WITH_LEGS  2
+
+typedef struct animal
+{
+  int type;
+  char *name;
+} animal;
+
+typedef struct with_wings
+{
+  int wings;
+} with_wings;
+
+typedef struct with_legs
+{
+  int legs;
+} with_legs;
+
+int main (void)
+{
+  animal *a[2];
+
+  animal duck;
+  a[0] = &duck;
+  a[0]->type = WITH_WINGS;
+  a[0]->name = "duck";
+  ((with_wings *) a[0])->wings = 2;
+
+  animal cow;
+  a[1] = &cow;
+  a[1]->type = WITH_LEGS;
+  a[1]->name = "cow";
+  ((with_legs *) a[1])->legs = 4;
+
+  for (int i = 0; i < 2; i++)
+    if (a[i]->type == WITH_LEGS)
+      printf ("A %s has %d legs.\n", a[i]->name,
+              ((with_legs *) a[i])-> legs);
+    else if (a[i]->type == WITH_WINGS)
+      printf ("A %s has %d wings.\n", a[i]->name,
+              ((with_wings *) a[i])-> wings);
+    else
+      printf ("Error in animal: %s\n", a[i]->name);
+
+  return 0;
+}
diff --git a/20240111/aufgabe-2.c b/20240111/aufgabe-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..a1054f2b601850a402dccb6f4878437d1bb6909c
--- /dev/null
+++ b/20240111/aufgabe-2.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+void foreach (int *a, void (*fun) (int x))
+{
+  for (int *p = a; *p >= 0; p++)
+    fun (*p);
+}
+
+void even_or_odd (int x)
+{
+  if (x % 2)
+    printf ("%d ist ungerade.\n", x);
+  else
+    printf ("%d ist gerade.\n", x);
+}
+
+int main (void)
+{
+  int numbers[] = { 12, 17, 32, 1, 3, 16, 19, 18, -1 };
+  foreach (numbers, even_or_odd);
+  return 0;
+}
diff --git a/20240111/aufgabe-3.c b/20240111/aufgabe-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..82e5b1ca9e2f896bcbec98bc5c34cdf15d086e26
--- /dev/null
+++ b/20240111/aufgabe-3.c
@@ -0,0 +1,53 @@
+#include <stdio.h>
+
+#define STACK_SIZE 10
+
+int stack[STACK_SIZE];
+int stack_pointer = 0;
+
+void push (int x)
+{
+  stack[stack_pointer++] = x;
+}
+
+void show (void)
+{
+  printf ("stack content:");
+  for (int i = 0; i < stack_pointer; i++)
+    printf (" %d", stack[i]);
+  if (stack_pointer)
+    printf ("\n");
+  else
+    printf (" (empty)\n");
+}
+
+void insert (int x, int pos)
+{
+  for (int i = pos; i < stack_pointer; i++)
+    stack[i + 1] = stack[i];
+  stack[pos] = x;
+  stack_pointer++;
+}
+
+void insert_sorted (int x)
+{
+  int i = 0;
+  while (i < stack_pointer && x < stack[i])
+    i++;
+  insert (x, i);
+}
+
+int main (void)
+{
+  push (3);
+  push (7);
+  push (137);
+  show ();
+  insert (5, 1);
+  show ();
+  insert_sorted (42);
+  show ();
+  insert_sorted (2);
+  show ();
+  return 0;
+}
diff --git a/20240111/hello-gtk.png b/20240111/hello-gtk.png
new file mode 120000
index 0000000000000000000000000000000000000000..cca99209d86683a9a3b0f70bbc149780bae10ba6
--- /dev/null
+++ b/20240111/hello-gtk.png
@@ -0,0 +1 @@
+../common/hello-gtk.png
\ No newline at end of file
diff --git a/20240111/hp-20240111.pdf b/20240111/hp-20240111.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..d0fe82a6dfacae31d92e6e94ffc75cb272446cdc
Binary files /dev/null and b/20240111/hp-20240111.pdf differ
diff --git a/20240111/hp-20240111.tex b/20240111/hp-20240111.tex
new file mode 100644
index 0000000000000000000000000000000000000000..e367d2765f8939fe4e68d9e138d49d106ce73769
--- /dev/null
+++ b/20240111/hp-20240111.tex
@@ -0,0 +1,1137 @@
+% hp-20240111.pdf - Lecture Slides on Low-Level Programming
+% Copyright (C) 2012, 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024  Peter Gerwinski
+%
+% This document is free software: you can redistribute it and/or
+% modify it either under the terms of the Creative Commons
+% Attribution-ShareAlike 3.0 License, or under the terms of the
+% GNU General Public License as published by the Free Software
+% Foundation, either version 3 of the License, or (at your option)
+% any later version.
+%
+% This document is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this document.  If not, see <http://www.gnu.org/licenses/>.
+%
+% You should have received a copy of the Creative Commons
+% Attribution-ShareAlike 3.0 Unported License along with this
+% document.  If not, see <http://creativecommons.org/licenses/>.
+
+% README: Datenstrukturen
+
+\documentclass[10pt,t]{beamer}
+
+\usepackage{pgslides}
+\usepackage{tikz}
+\usepackage{rotating}
+
+\newcommand{\redurl}[1]{\href{#1}{\color{red}\nolinkurl{#1}}}
+
+\title{Hardwarenahe Programmierung}
+\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski}
+\date{11.\ Januar 2024}
+
+\begin{document}
+
+\maketitleframe
+
+\title{Hardwarenahe Programmierung}
+
+\nosectionnonumber{\inserttitle}
+
+\begin{frame}
+
+  \shownosectionnonumber
+
+  \begin{itemize}
+    \item[\textbf{1}] \textbf{Einführung}
+      \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp}}}
+    \item[\textbf{2}] \textbf{Einführung in C}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+    \item[\textbf{4}] \textbf{Hardwarenahe Programmierung}
+    \item[\textbf{5}] \textbf{Algorithmen}
+    \item[\textbf{6}] \textbf{Objektorientierte Programmierung}
+      \begin{itemize}
+        \color{medgreen}
+        \item[6.0] Dynamische Speicherverwaltung
+        \item[6.1] Konzepte und Ziele
+        \item[6.2] Beispiel: Zahlen und Buchstaben
+        \item[6.3] Unions
+        \item[6.4] Virtuelle Methoden
+        \item[6.5] Beispiel: Graphische Benutzeroberfläche (GUI)
+        \item[6.6] Ausblick: C++
+      \end{itemize}
+    \item[\textbf{7}] \textbf{Datenstrukturen}
+  \end{itemize}
+
+\end{frame}
+
+\setcounter{section}{5}
+\section{Objektorientierte Programmierung}
+
+\addtocounter{subsection}{-1}
+\subsection{Dynamische Speicherverwaltung}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \begin{itemize}
+    \item
+      Array: feste Anzahl von Elementen desselben Typs (z.\,B.\ 3 ganze Zahlen)
+    \item
+      Dynamisches Array: variable Anzahl von Elementen desselben Typs
+  \end{itemize}
+
+  \bigskip
+
+  \begin{lstlisting}
+    char *name[] = { "Anna", "Berthold", "Caesar" };
+
+    ...
+
+     name[3] = "Dieter";
+  \end{lstlisting}
+
+  \begin{picture}(0,0)
+    \color{red}
+    \put(0,0){\line(3,1){3.5}}
+    \put(0,1){\line(3,-1){3.5}}
+  \end{picture}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \bigskip
+
+  \begin{lstlisting}
+    #include <stdlib.h>
+
+    ...
+
+      char **name = malloc (3 * sizeof (char *));
+        /* Speicherplatz für 3 Zeiger anfordern */
+
+    ...
+
+      free (name);
+        /* Speicherplatz freigeben */
+
+  \end{lstlisting}
+
+\end{frame}
+
+\subsection{Konzepte und Ziele}
+
+\begin{frame}
+
+  \showsection
+  \showsubsection
+
+  \begin{itemize}
+    \item
+%      Array: feste Anzahl von Elementen desselben Typs (z.\,B.\ 3 ganze Zahlen)
+      Array: Elemente desselben Typs (z.\,B.\ 3 ganze Zahlen)
+%    \item
+%      Dynamisches Array: variable Anzahl von Elementen desselben Typs
+    \item
+      Problem: Elemente unterschiedlichen Typs
+    \item
+      Lösung: den Typ des Elements zusätzlich speichern \textarrow\ \newterm{Objekt}
+    \item
+      Problem: Die Elemente sind unterschiedlich groß (Speicherplatz).
+    \item
+      Lösung: Im Array nicht die Objekte selbst speichern, sondern Zeiger darauf.
+  \end{itemize}
+  \begin{itemize}
+    \item
+      Funktionen, die mit dem Objekt arbeiten: \newterm{Methoden}
+    \begin{onlyenv}<1>
+      \item
+        Was die Funktion bewirkt,\\
+        hängt vom Typ des Objekts ab
+      \item
+        Realisierung über endlose \lstinline{if}-Ketten
+    \end{onlyenv}
+    \begin{onlyenv}<2>
+      \item
+        Was die Funktion bewirkt
+        \begin{picture}(0,0)
+          \color{red}
+          \put(-4.00,-0.05){\tikz{\draw[thick](0,0.25)--(3.75,-0.05);%
+                                  \draw[thick](-0.1,-0.05)--(3.75,0.3);}}
+        \end{picture}%
+        Welche Funktion aufgerufen wird,\\
+        hängt vom Typ des Objekts ab: \newterm{virtuelle Methode}
+      \item
+        Realisierung über endlose \lstinline{if}-Ketten%
+        \begin{picture}(0,0)
+          \color{red}
+          \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
+                         \end{rotate}}
+        \end{picture}
+        Zeiger, die im Objekt gespeichert sind\\
+        (Genaugenommen: Tabelle von Zeigern)
+    \end{onlyenv}
+  \end{itemize}
+
+\end{frame}
+
+\begin{frame}
+
+  \showsection
+  \showsubsection
+
+  \begin{itemize}
+    \item
+      Problem: Elemente unterschiedlichen Typs
+    \item
+      Lösung: den Typ des Elements zusätzlich speichern \textarrow\ \newterm{Objekt}
+    \item
+      \newterm{Methoden\/} und \newterm{virtuelle Methoden}
+  \end{itemize}
+
+  \begin{itemize}
+    \item
+      Zeiger auf verschiedene Strukturen\\
+      mit einem gemeinsamen Anteil von Datenfeldern\\
+      \textarrow\ "`verwandte"' \newterm{Objekte}, \newterm{Klassenhierarchie} von Objekten
+    \item
+      Struktur, die \emph{nur\/} den gemeinsamen Anteil enthält\\
+      \textarrow\ "`Vorfahr"', \newterm{Basisklasse}, \newterm{Vererbung}
+    \item
+%      Explizite Typumwandlung eines Zeigers auf die Basisklasse\\
+%      in einen Zeiger auf die \newterm{abgeleitete Klasse}\\
+%      \textarrow\ Man kann ein Array unterschiedlicher Objekte\\
+%      \strut\phantom{\textarrow} in einer Schleife abarbeiten.\\
+      Zeiger auf die Basisklasse dürfen auf Objekte\\
+      der \newterm{abgeleiteten Klasse} zeigen\\
+      \textarrow\ \newterm{Polymorphie}
+  \end{itemize}
+
+\end{frame}
+
+\subsection{Beispiel: Zahlen und Buchstaben}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \begin{center}
+    \begin{minipage}{5cm}
+      \begin{lstlisting}[gobble=8]
+        ¡typedef struct
+        {
+          int type;
+        } t_base;¿
+      \end{lstlisting}
+    \end{minipage}\\[0.5cm]
+    \begin{minipage}{5cm}
+      \begin{lstlisting}[gobble=8]
+        ¡typedef struct
+        {
+          int type;
+          int content;
+        } t_integer;¿
+      \end{lstlisting}
+    \end{minipage}
+    \begin{minipage}{5cm}
+      \begin{lstlisting}[gobble=8]
+        ¡typedef struct
+        {
+          int type;
+          char *content;
+        } t_string;¿
+      \end{lstlisting}
+    \end{minipage}
+  \end{center}
+  
+\end{frame}
+
+\begin{frame}[fragile]
+  \begin{center}
+    \begin{minipage}{5cm}
+      \begin{lstlisting}[gobble=8]
+        ¡typedef struct
+        {
+          int type;
+        } t_base;¿
+      \end{lstlisting}
+    \end{minipage}\\[0.5cm]
+    \begin{minipage}{5cm}
+      \begin{lstlisting}[gobble=8]
+        ¡typedef struct
+        {
+          int type;
+          int content;
+        } t_integer;¿
+      \end{lstlisting}
+    \end{minipage}
+    \begin{minipage}{5cm}
+      \begin{lstlisting}[gobble=8]
+        ¡typedef struct
+        {
+          int type;
+          char *content;
+        } t_string;¿
+      \end{lstlisting}
+    \end{minipage}\\[0.7cm]
+    \begin{onlyenv}<1>
+      \begin{minipage}{8cm}
+        \begin{lstlisting}[gobble=10]
+          ¡t_integer i = { 1, 42 };
+          t_string s = { 2, "Hello, world!" };
+
+          t_base *object[] = { (t_base *) &i, (t_base *) &s };¿
+        \end{lstlisting}
+      \end{minipage}%
+      \begin{picture}(0,0)
+        \color{red}
+        \put(-5.4,-0.8){\mbox{$\underbrace{\rule{1.45cm}{0pt}}_{\shortstack{\strut explizite\\Typumwandlung}}$}}
+      \end{picture}
+    \end{onlyenv}
+%    \begin{onlyenv}<2>
+%      \begin{minipage}{5cm}
+%        \begin{lstlisting}[gobble=10]
+%          ¡typedef union
+%          {
+%            t_base base;
+%            t_integer integer;
+%            t_string string;
+%          } t_object;¿
+%        \end{lstlisting}
+%      \end{minipage}
+%    \end{onlyenv}
+  \end{center}
+  
+\end{frame}
+
+\subsection{Unions}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  Variable teilen sich denselben Speicherplatz.
+
+  \medskip
+
+  \begin{minipage}[t]{3.7cm}
+    \begin{lstlisting}[gobble=6]
+      ¡typedef union
+      {
+        int8_t i;
+        uint8_t u;
+      } num8_t;¿
+    \end{lstlisting}
+  \end{minipage}%
+  \begin{minipage}[t]{4.5cm}
+    \begin{lstlisting}[gobble=6]
+      ¡int main (void)
+      {
+        num8_t test;
+        test.i = -1;
+        printf ("%d\n", test.u);
+        return 0;
+      }¿
+    \end{lstlisting}
+  \end{minipage}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  Variable teilen sich denselben Speicherplatz.
+
+  \medskip
+
+  \begin{minipage}[t]{3.7cm}
+    \begin{lstlisting}[gobble=6]
+      ¡typedef union
+      {
+        char s[8];
+        uint64_t x;
+      } num_char_t;¿
+    \end{lstlisting}
+  \end{minipage}%
+  \begin{minipage}[t]{4.5cm}
+    \begin{lstlisting}[gobble=6]
+      ¡int main (void)
+      {
+        num_char_t test = { "Hello!" };
+        printf ("%lx\n", test.x);
+        return 0;
+      }¿
+    \end{lstlisting}
+  \end{minipage}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  Variable teilen sich denselben Speicherplatz.
+
+  \medskip
+
+  \begin{minipage}[t]{3.7cm}
+    \begin{lstlisting}[gobble=6]
+      ¡typedef union
+      {
+        t_base base;
+        t_integer integer;
+        t_string string;
+      } t_object;¿
+    \end{lstlisting}
+  \end{minipage}%
+  \begin{minipage}[t]{3.0cm}
+    \begin{lstlisting}[gobble=6]
+
+      ¡typedef struct
+      {
+        int type;
+      } t_base;¿
+    \end{lstlisting}
+  \end{minipage}%
+  \begin{minipage}[t]{3.0cm}
+    \begin{lstlisting}[gobble=6]
+
+      ¡typedef struct
+      {
+        int type;
+        int content;
+      } t_integer;¿
+    \end{lstlisting}
+  \end{minipage}%
+  \begin{minipage}[t]{3.0cm}
+    \begin{lstlisting}[gobble=6]
+
+      ¡typedef struct
+      {
+        int type;
+        char *content;
+      } t_string;¿
+    \end{lstlisting}
+  \end{minipage}
+
+  \bigskip
+
+  \begin{center}
+    \begin{minipage}{8.5cm}
+      \begin{lstlisting}[gobble=8]
+        ¡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);¿
+      \end{lstlisting}
+    \end{minipage}
+  \end{center}
+
+\end{frame}
+
+\subsection{Virtuelle Methoden}
+
+\begin{frame}[fragile]
+  \showsubsection
+
+  \begin{lstlisting}
+    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);
+    }
+  \end{lstlisting}
+
+  \begin{picture}(0,0)
+    \color{red}
+    \put(9,1.7){\shortstack[l]{if-Kette:\\\strut wird unübersichtlich}}
+    \put(1,-2){\mbox{\textarrow}}
+    \put(0,-3){\mbox{Zeiger auf Funktionen}}
+  \end{picture}
+
+  \begin{lstlisting}[xleftmargin=4cm]
+    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);
+    }
+  \end{lstlisting}
+
+\end{frame}
+
+\begin{frame}[fragile]
+  \showsubsection
+
+  Zeiger auf Funktionen
+
+  \medskip
+
+  \begin{lstlisting}
+    void (* print) (t_object *this);
+  \end{lstlisting}
+  \begin{picture}(0,1.2)(0,-0.9)
+    \color{red}
+    \put(0.95,0.3){\mbox{$\underbrace{\rule{1cm}{0pt}}$}}
+    \put(0.2,-0.7){\shortstack{das, worauf print zeigt,\\ist eine Funktion}}
+  \end{picture}
+
+  \begin{itemize}
+    \item
+      Objekt enthält Zeiger auf Funktion
+      \begin{onlyenv}<1>
+        \medskip
+        \begin{lstlisting}[gobble=10]
+          typedef struct
+          {
+            void (* print) (union t_object *this);
+            int content;
+          } t_integer;
+        \end{lstlisting}
+      \end{onlyenv}
+      \begin{onlyenv}<2->
+        \vspace*{-3.5cm}  % Why doesn't a picture environment work here??? :-(
+        \begin{lstlisting}[gobble=10,xleftmargin=5.5cm]
+          typedef struct
+          {
+            void (* print) (union t_object *this);
+            int content;
+          } t_integer;
+        \end{lstlisting}
+        \vspace*{0.85cm}
+        \bigskip
+        \smallskip
+      \end{onlyenv}
+    \pause
+    \item
+      Konstruktor initialisiert diesen Zeiger
+      \begin{onlyenv}<2>
+        \medskip
+        \begin{lstlisting}[gobble=10]
+          t_object *new_integer (int i)
+          {
+            t_object *p = malloc (sizeof (t_integer));
+            p->integer.print = print_integer;
+            p->integer.content = i;
+            return p;
+          }
+        \end{lstlisting}
+        \vspace*{-2cm}
+      \end{onlyenv}
+    \pause
+    \item
+      Aufruf: "`automatisch"' die richtige Funktion
+      \begin{onlyenv}<3>
+        \medskip
+        \begin{lstlisting}[gobble=10]
+          for (int i = 0; object[i]; i++)
+            object[i]->base.print (object[i]);
+        \end{lstlisting}
+      \end{onlyenv}
+    \pause
+    \medskip
+    \item
+      in größeren Projekten:\\
+      Objekt enthält Zeiger auf Tabelle von Funktionen
+  \end{itemize}
+\end{frame}
+
+\subsection{Beispiel: Graphische Benutzeroberfläche (GUI)}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \scriptsize
+  \begin{lstlisting}
+    #include <gtk/gtk.h>
+
+    int main (int argc, char **argv)
+    {
+      gtk_init (&argc, &argv);
+      GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+      gtk_window_set_title (GTK_WINDOW (window), "Hello");
+      g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+      GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
+      gtk_container_add (GTK_CONTAINER (window), vbox);
+      gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
+      GtkWidget *label = gtk_label_new ("Hello, world!");
+      gtk_container_add (GTK_CONTAINER (vbox), label);
+      GtkWidget *button = gtk_button_new_with_label ("Quit");
+      g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
+      gtk_container_add (GTK_CONTAINER (vbox), button);
+      gtk_widget_show (button);
+      gtk_widget_show (label);
+      gtk_widget_show (vbox);
+      gtk_widget_show (window);
+      gtk_main ();
+      return 0;
+    }
+  \end{lstlisting}
+
+  \vspace*{-6cm}\strut\hfill
+  \includegraphics[scale=0.85]{hello-gtk.png}\\[2cm]
+  \begin{flushright}
+    \normalsize\bf Praktikumsversuch:\\
+    Objektorientiertes Zeichenprogramm
+  \end{flushright}
+  
+\end{frame}
+
+\subsection{Ausblick: C++}
+
+\begin{frame}[fragile]
+  \showsubsection
+
+  \begin{center}
+    \begin{minipage}{5cm}
+      \begin{lstlisting}[gobble=8]
+        ¡typedef struct
+        {
+          void (* print) (union t_object *this);
+        } t_base;¿
+      \end{lstlisting}
+    \end{minipage}\\[0.5cm]
+    \begin{minipage}{5.5cm}
+      \begin{lstlisting}[gobble=8]
+        ¡typedef struct
+        {
+          void (* print) (...);
+          int content;
+        } t_integer;¿
+      \end{lstlisting}
+    \end{minipage}
+    \begin{minipage}{5cm}
+      \begin{lstlisting}[gobble=8]
+        ¡typedef struct
+        {
+          void (* print) (union t_object *this);
+          char *content;
+        } t_string;¿
+      \end{lstlisting}
+    \end{minipage}
+  \end{center}
+  
+\end{frame}
+
+\begin{frame}[fragile]
+  \showsubsection
+
+  \begin{center}
+    \begin{minipage}{5cm}
+      \begin{lstlisting}[gobble=8]
+        ¡struct TBase
+        {
+          virtual void print (void);
+        };¿
+      \end{lstlisting}
+    \end{minipage}\\[0.5cm]
+    \begin{minipage}{5.5cm}
+      \begin{lstlisting}[gobble=8]
+        ¡struct TInteger: public TBase
+        {
+          virtual void print (void);
+          int content;
+        };¿
+      \end{lstlisting}
+    \end{minipage}
+    \begin{minipage}{5cm}
+      \begin{lstlisting}[gobble=8]
+        ¡struct TString: public TBase
+        {
+          virtual void print (void);
+          char *content;
+        };¿
+      \end{lstlisting}
+    \end{minipage}
+  \end{center}
+  
+\end{frame}
+
+\section{Datenstrukturen}
+\subsection{Stack und FIFO}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \begin{minipage}{0.48\textwidth}
+    Im letzten Praktikumsversuch:
+    \begin{itemize}
+      \item
+        Array nur zum Teil benutzt
+      \item
+        Variable speichert genutzte Länge
+      \item
+        Elemente hinten anfügen\\
+        oder entfernen
+      \arrowitem
+        Stack\\
+        \strut
+    \end{itemize}
+    \bigskip
+    \begin{itemize}
+      \item
+        hinten anfügen/entfernen: $\mathcal{O}(1)$\hspace*{-1cm}
+      \item
+        vorne oder in der Mitte einfügen/entfernen: $\mathcal{O}(n)$
+    \end{itemize}
+  \end{minipage}\hfill
+  \begin{minipage}{0.52\textwidth}
+    Auch möglich:
+    \begin{itemize}
+      \item
+        Array nur zum Teil benutzt
+      \item
+        2 Variable speichern\\genutzte Länge (ringförmig)
+      \item
+        Elemente hinten anfügen\\
+        oder vorne entfernen
+      \arrowitem
+        FIFO
+    \end{itemize}
+    \bigskip
+    \begin{itemize}
+      \item
+        vorne oder hinten\\
+        anfügen oder entfernen: $\mathcal{O}(1)$
+      \item
+        in der Mitte einfügen/entfernen: $\mathcal{O}(n)$
+    \end{itemize}
+  \end{minipage}\hspace*{-1.5mm}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \bigskip
+
+  \begin{minipage}[b]{6cm}
+    \begin{center}
+      "`First In -- First Out"'
+
+      \bigskip
+
+      \begin{picture}(6,4)
+        \thicklines
+        \color{structure}
+        \put(0.5,0){\line(1,0){5}}
+
+        \put(3.5,0){\only<1-5>{\line(0,1){1}}}
+        \put(4.5,0){\only<1-4>{\line(0,1){1}}}
+        \put(3.5,1){\only<1-4>{\line(1,0){1}}}
+        \put(4.0,0.5){\only<1-4>{\makebox(0,0){\lstinline{3}}}}
+        \put(3.0,1.5){\only<1>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}}
+        \put(3.0,1.5){\only<1>{\makebox(0,0)[b]{\lstinline{push (3)}}}}
+
+        \put(2.5,0){\only<2-6>{\line(0,1){1}}}
+        \put(2.5,1){\only<2-5>{\line(1,0){1}}}
+        \put(3.0,0.5){\only<2-5>{\makebox(0,0){\lstinline{7}}}}
+        \put(2.0,1.5){\only<2>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}}
+        \put(2.0,1.5){\only<2>{\makebox(0,0)[b]{\lstinline{push (7)}}}}
+
+        \put(1.5,0){\only<3-6>{\line(0,1){1}}}
+        \put(1.5,1){\only<3-6>{\line(1,0){1}}}
+        \put(2.0,0.5){\only<3-6>{\makebox(0,0){\lstinline{137}}}}
+        \put(1.0,1.5){\only<3>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}}
+        \put(1.0,1.5){\only<3>{\makebox(0,0)[b]{\lstinline{push (137)}}}}
+
+        \put(4.55,1.05){\only<4>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}}
+        \put(5.00,1.60){\only<4>{\makebox(0,0)[b]{\lstinline{pop ()}: 3}}}
+
+        \put(3.55,1.05){\only<5>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}}
+        \put(4.00,1.60){\only<5>{\makebox(0,0)[b]{\lstinline{pop ()}: 7}}}
+
+        \put(2.55,1.05){\only<6>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}}
+        \put(3.00,1.60){\only<6>{\makebox(0,0)[b]{\lstinline{pop ()}: 137}}}
+      \end{picture}
+
+      \bigskip
+
+      FIFO = Queue = Reihe
+    \end{center}
+  \end{minipage}\hfill
+  \begin{minipage}[b]{6cm}
+    \begin{center}
+      "`Last In -- First Out"'
+
+      \bigskip
+
+      \begin{picture}(6,4)
+        \thicklines
+        \color{structure}
+        \put(1.5,0){\line(1,0){3}}
+
+        \put(2.5,0){\line(0,1){1}}
+        \put(3.5,0){\line(0,1){1}}
+        \put(2.5,1){\line(1,0){1}}
+        \put(3.0,0.5){\makebox(0,0){\lstinline{3}}}
+        \put(2.0,1.5){\only<1>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}}
+        \put(2.0,1.5){\only<1>{\makebox(0,0)[b]{\lstinline{push (3)}}}}
+
+        \put(2.5,1){\only<2-5>{\line(0,1){1}}}
+        \put(3.5,1){\only<2-5>{\line(0,1){1}}}
+        \put(2.5,2){\only<2-5>{\line(1,0){1}}}
+        \put(3.0,1.5){\only<2-5>{\makebox(0,0){\lstinline{7}}}}
+        \put(2.0,2.5){\only<2>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}}
+        \put(2.0,2.5){\only<2>{\makebox(0,0)[b]{\lstinline{push (7)}}}}
+
+        \put(2.5,2){\only<3-4>{\line(0,1){1}}}
+        \put(3.5,2){\only<3-4>{\line(0,1){1}}}
+        \put(2.5,3){\only<3-4>{\line(1,0){1}}}
+        \put(3.0,2.5){\only<3-4>{\makebox(0,0){\lstinline{137}}}}
+        \put(2.0,3.5){\only<3>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}}
+        \put(2.0,3.5){\only<3>{\makebox(0,0)[b]{\lstinline{push (137)}}}}
+
+        \put(3.55,3.05){\only<4>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}}
+        \put(4.00,3.60){\only<4>{\makebox(0,0)[b]{\lstinline{pop ()}: 137}}}
+
+        \put(3.55,2.05){\only<5>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}}
+        \put(4.00,2.60){\only<5>{\makebox(0,0)[b]{\lstinline{pop ()}: 7}}}
+
+        \put(3.55,1.05){\only<6>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}}
+        \put(4.00,1.60){\only<6>{\makebox(0,0)[b]{\lstinline{pop ()}: 3}}}
+      \end{picture}
+
+      \bigskip
+
+      LIFO = Stack = Stapel
+    \end{center}
+  \end{minipage}
+
+%
+%  \dots
+
+\end{frame}
+
+\begin{frame}
+
+  \showsection
+  \showsubsection
+
+  \bigskip
+
+  \begin{minipage}[t]{6cm}
+    Array (Stack, FIFO):\\
+    in der Mitte einfügen
+    \begin{center}
+      \begin{picture}(6,3.8)
+        \thicklines
+        \color{structure}
+        \put(1.5,0){\line(1,0){3}}
+
+        \put(2.5,0){\line(0,1){3}}
+        \put(3.5,0){\line(0,1){3}}
+        \put(2.5,1){\line(1,0){1}}
+        \put(3.0,0.5){\makebox(0,0){\lstinline{3}}}
+        \put(2.5,1){\line(1,0){1}}
+        \put(3.0,1.5){\makebox(0,0){\lstinline{7}}}
+        \put(2.5,2){\line(1,0){1}}
+        \put(3.0,2.5){\makebox(0,0){\lstinline{137}}}
+        \put(2.5,3){\line(1,0){1}}
+
+        \put(1.5,1.5){\makebox(0,0)[b]{\lstinline{push (5)}}}
+        \put(1.5,1.45){\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.95,-0.45);}}}
+
+        \put(3.55,2.5){\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)..controls(0.5,0.45)..(0,0.9);}}}
+        \put(3.55,1.5){\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)..controls(0.5,0.45)..(0,0.9);}}}
+
+        \pause
+        \color{red}
+        \put(4.1,3.0){\makebox(0,0)[l]{\textbf{1.}}}
+        \put(4.1,2.0){\makebox(0,0)[l]{\textbf{2.}}}
+        \put(1.5,1.9){\makebox(0,0)[b]{\textbf{3.}}}
+
+        \pause
+        \put(6.0,1.5){\makebox(0,0)[tl]{$\mathcal{O}(n)$}}
+        \put(5.95,1.45){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-1.3,0.4);}}}
+        \put(5.95,1.49){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-1.3,1.1);}}}
+      \end{picture}
+    \end{center}
+  \end{minipage}\pause\hfill
+  \begin{minipage}[t]{5cm}
+    In Array (Stack, FIFO) \dots
+    \begin{itemize}
+      \item
+        einfügen: $\mathcal{O}(n)$
+      \item
+        suchen: $\mathcal{O}(n)$
+      \item
+        geschickt suchen: $\mathcal{O}(\log n)$
+      \item
+        beim Einfügen sortieren:\\
+        $\mathcal{O}(n \log n)$ \hspace*{-1.8cm}\tikz{\draw[red](-1.8,0)--(0,0.2);\draw[red](-1.8,0.2)--(0,0);}
+        $\mathcal{O}(n^2)$
+    \end{itemize}
+  \end{minipage}
+
+\end{frame}
+
+\subsection{Verkettete Listen}
+
+\begin{frame}
+
+  \showsection
+  \showsubsection
+
+  \begin{tikzpicture}
+    \color{structure}
+    \node(first) at (0,0.5) {first};
+    \node[shape=rectangle,draw,line width=1pt](3) at (1,2) {3};
+    \node[shape=rectangle,draw,line width=1pt](5) at (2,1) {5};
+    \node[shape=rectangle,draw,line width=1pt](7) at (3,2) {7};
+    \node[shape=rectangle,draw,line width=1pt](137) at (5,2) {137};
+    \node(NULL) at (7,2) {NULL};
+    \draw[-latex](first)--(3);
+    \only<1>{\draw[-latex](3)--(7);}
+    \only<2>{\draw[-latex](3) to[out=0] (5);}
+    \only<2>{\draw[-latex](5) to[in=180] (7);}
+    \draw[-latex](7)--(137);
+    \draw[-latex](137)--(NULL);
+  \end{tikzpicture}
+  \begin{itemize}
+    \item
+      Jeder Datensatz enthält einen Zeiger auf das nächste Element.
+    \item
+      Beim letzten Element zeigt der Zeiger auf \lstinline{NULL}.
+    \item
+      Eine Variable zeigt auf das erste Element.
+    \item
+      Wenn die Liste leer ist, zeigt die Variable auf \lstinline{NULL}.
+    \arrowitem
+      (einfach) \textbf{verkettete Liste}
+  \end{itemize}
+
+\end{frame}
+
+\begin{frame}
+
+  \showsection
+  \showsubsection
+
+  \begin{minipage}[t]{5cm}
+    In Array (Stack, FIFO) \dots
+    \begin{itemize}
+      \item
+        in der Mitte einfügen: $\mathcal{O}(n)$
+      \item
+        wahlfreier Zugriff: $\mathcal{O}(1)$
+      \item
+        suchen: $\mathcal{O}(n)$
+      \item
+        geschickt suchen: $\mathcal{O}(\log n)$
+      \item
+        beim Einfügen sortieren:\\
+        $\mathcal{O}(n \log n)$ \hspace*{-1.8cm}\tikz{\draw[red](-1.8,0)--(0,0.2);\draw[red](-1.8,0.2)--(0,0);}
+        $\mathcal{O}(n^2)$
+    \end{itemize}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{6cm}
+    In (einfach) verkettete/r Liste \dots
+    \begin{itemize}
+      \item
+        in der Mitte einfügen: $\mathcal{O}(1)$
+      \item
+        wahlfreier Zugriff: $\mathcal{O}(n)$
+      \item
+        suchen: $\mathcal{O}(n)$
+      \item
+        geschickt \hspace*{-1.7cm}\tikz{\draw[red](-1.7,0)--(0,0.2);\draw[red](-1.7,0.2)--(0,0);}
+        suchen: {\color{red}$\mathcal{O}(n)$}
+      \item
+        beim Einfügen sortieren:
+        $\mathcal{O}(n \log n)$ \hspace*{-1.8cm}\tikz{\draw[red](-1.8,0)--(0,0.2);\draw[red](-1.8,0.2)--(0,0);}
+        $\mathcal{O}(n^2)$
+    \end{itemize}
+  \end{minipage}
+  \pause
+  \medskip
+  \begin{center}
+    \begin{minipage}[t]{6cm}
+      In (ausbalancierten) Bäumen \dots
+      \begin{itemize}
+        \item
+          in der Mitte einfügen: $\mathcal{O}(\log n)$
+        \item
+          wahlfreier Zugriff: $\mathcal{O}(\log n)$
+        \item
+          suchen: $\mathcal{O}(\log n)$
+        \item
+          beim Einfügen sortieren:
+          $\mathcal{O}(n \log n)$
+      \end{itemize}
+    \end{minipage}
+  \end{center}
+  \vspace*{-1cm}
+
+\end{frame}
+
+\subsection{Bäume}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \begin{minipage}[t]{5cm}
+    \vspace*{-6cm}
+    \begin{lstlisting}[gobble=6]
+      ¡typedef struct node
+      {
+        int content;
+        struct node *left, *right;
+      } node;¿
+    \end{lstlisting}
+%    \bigskip
+    \bigskip
+    \begin{onlyenv}<6->
+      \begin{itemize}
+        \item
+          Einfügen: rekursiv, $\mathcal{O}(\log n)$
+        \item
+          Suchen: rekursiv, $\mathcal{O}(\log n)$
+        \item
+          beim Einfügen sortieren:\\
+          rekursiv, $\mathcal{O}(n\log n)$
+        \begin{onlyenv}<7->
+          \smallskip
+          \item
+            {\color{red}
+            \emph{Worst Case\/}: $\mathcal{O}(n^2)$\\
+            vorher bereits sortiert}\\
+            \textarrow\ balancierte Bäume\\
+            \hspace*{2.15em}Anwendung: Datenbanken\hspace*{-2cm}
+        \end{onlyenv}
+      \end{itemize}
+      \vspace*{-1cm}
+    \end{onlyenv}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{7cm}
+    \begin{center}
+      \begin{tikzpicture}
+        \color{structure}
+        \node(root) at (0,0) {\lstinline{node *root;}};
+        \begin{onlyenv}<2>
+          \node(3) at (-2,-3) {\lstinline{NULL}};
+          \node(137) at (2,-3) {\lstinline{NULL}};
+        \end{onlyenv}
+        \begin{onlyenv}<2->
+          \node[shape=rectangle,draw,line width=1pt](7) at (0,-1.5) {7};
+          \draw[-latex](root)--(7);
+          \draw[-latex](7)--(3);
+          \draw[-latex](7)--(137);
+        \end{onlyenv}
+        \begin{onlyenv}<3>
+          \node(3) at (-2,-3) {\lstinline{NULL}};
+        \end{onlyenv}
+        \begin{onlyenv}<3->
+          \node[shape=rectangle,draw,line width=1pt](137) at (2,-3) {137};
+          \node(137_left) at (1,-4.5) {\lstinline{NULL}};
+          \node(137_right) at (3,-4.5) {\lstinline{NULL}};
+          \draw[-latex](137)--(137_left);
+          \draw[-latex](137)--(137_right);
+        \end{onlyenv}
+        \begin{onlyenv}<4>
+          \node(5) at (-1,-4.5) {\lstinline{NULL}};
+        \end{onlyenv}
+        \begin{onlyenv}<4->
+          \node[shape=rectangle,draw,line width=1pt](3) at (-2,-3) {3};
+          \node(3_left) at (-3,-4.5) {\lstinline{NULL}};
+          \draw[-latex](3)--(3_left);
+          \draw[-latex](3)--(5);
+        \end{onlyenv}
+        \begin{onlyenv}<5->
+          \node[shape=rectangle,draw,line width=1pt](5) at (-1,-4.5) {5};
+          \node(5_left) at (-2,-6) {\lstinline{NULL}};
+          \node(5_right) at (0,-6) {\lstinline{NULL}};
+          \draw[-latex](5)--(5_left);
+          \draw[-latex](5)--(5_right);
+        \end{onlyenv}
+      \end{tikzpicture}
+    \end{center}
+  \end{minipage}
+
+\end{frame}
+
+\nosectionnonumber{\inserttitle}
+
+\begin{frame}
+
+  \shownosectionnonumber
+
+  \begin{itemize}
+    \item[\textbf{1}] \textbf{Einführung}
+      \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp}}}
+    \item[\textbf{2}] \textbf{Einführung in C}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+    \item[\textbf{4}] \textbf{Hardwarenahe Programmierung}
+    \item[\textbf{5}] \textbf{Algorithmen}
+    \item[\textbf{6}] \textbf{Objektorientierte Programmierung}
+    \item[\textbf{7}] \textbf{Datenstrukturen}
+      \begin{itemize}
+        \color{medgreen}
+        \item[7.1] Stack und FIFO
+        \item[7.2] Verkettete Listen
+        \item[7.3] Bäume
+      \end{itemize}
+  \end{itemize}
+
+\end{frame}
+
+\iffalse
+
+\begin{frame}
+
+  \shownosectionnonumber
+
+  \begin{itemize}
+    \item[\textbf{1}] \textbf{Einführung}
+      \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp}}}
+    \item[\textbf{2}] \textbf{Einführung in C}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+    \item[\textbf{4}] \textbf{Hardwarenahe Programmierung}
+    \item[\textbf{5}] \textbf{Algorithmen}
+    \item[\textbf{6}] \textbf{Objektorientierte Programmierung}
+    \item[\textbf{7}] \textbf{Datenstrukturen}
+      \begin{itemize}
+        \item[7.1] Stack und FIFO
+        \item[7.2] Verkettete Listen
+        \item[7.3] Bäume
+      \end{itemize}
+  \end{itemize}
+
+  \begin{flushright}
+    \large\bf\em\color{medgreen}Vielen Dank für Ihre Aufmerksamkeit\\
+      und viel Erfolg bei den Prüfungen!
+  \end{flushright}
+
+\end{frame}
+
+\fi
+
+\end{document}
diff --git a/20240111/hp-musterloesung-20240111.pdf b/20240111/hp-musterloesung-20240111.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..28f62bbf57a6d54b18a2ee00ad289381400eacce
Binary files /dev/null and b/20240111/hp-musterloesung-20240111.pdf differ
diff --git a/20240111/hp-musterloesung-20240111.tex b/20240111/hp-musterloesung-20240111.tex
new file mode 100644
index 0000000000000000000000000000000000000000..1fd559e49b91aaff1cdddedd40e0431f46247021
--- /dev/null
+++ b/20240111/hp-musterloesung-20240111.tex
@@ -0,0 +1,500 @@
+% hp-musterloesung-20240111.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences
+% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024  Peter Gerwinski
+%
+% This document is free software: you can redistribute it and/or
+% modify it either under the terms of the Creative Commons
+% Attribution-ShareAlike 3.0 License, or under the terms of the
+% GNU General Public License as published by the Free Software
+% Foundation, either version 3 of the License, or (at your option)
+% any later version.
+%
+% This document is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this document.  If not, see <http://www.gnu.org/licenses/>.
+%
+% You should have received a copy of the Creative Commons
+% Attribution-ShareAlike 3.0 Unported License along with this
+% document.  If not, see <http://creativecommons.org/licenses/>.
+
+% README: Objektorientierte Tier-Datenbank (Ergänzung), Iterationsfunktionen, Stack-Operationen
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+\usepackage{gnuplot-lua-tikz}
+
+\begin{document}
+
+  \section*{Hardwarenahe Programmierung\\
+            Musterlösung zu den Übungsaufgaben -- 11.\ Januar 2024}
+
+  \exercise{Objektorientierte Tier-Datenbank (Ergänzung)}
+
+  Diese Aufgabe ist eine Neuauflage
+  der Übungsaufgabe 3 vom 14.\ Dezember 2023,
+  ergänzt um die Teilaufgaben (e) bis (g).
+
+  \medskip
+
+  Das auf der nächsten Seite dargestellte Programm
+  (Datei: \gitfile{hp}{2023ws/20240111}{aufgabe-1a.c})
+  soll Daten von Tieren verwalten.
+
+  Beim Compilieren erscheinen die folgende Fehlermeldungen:
+  \begin{lstlisting}[style=terminal]
+    $ ¡gcc -std=c99 -Wall -O aufgabe-1a.c -o aufgabe-1a¿
+    aufgabe-1a.c: In function 'main':
+    aufgabe-1a.c:31: error: 'animal' has no member named 'wings'
+    aufgabe-1a.c:37: error: 'animal' has no member named 'legs'
+  \end{lstlisting}
+
+  Der Programmierer nimmt die auf der nächsten Seite in Rot dargestellten Ersetzungen vor\\
+  (Datei: \gitfile{hp}{2023ws/20240111}{aufgabe-1b.c}).
+  Daraufhin gelingt das Compilieren, und die Ausgabe des Programms lautet:
+  \begin{lstlisting}[style=terminal]
+    $ ¡gcc -std=c99 -Wall -O aufgabe-1b.c -o aufgabe-1b¿
+    $ ¡./aufgabe-1b¿
+    A duck has 2 legs.
+    Error in animal: cow
+  \end{lstlisting}
+
+  \begin{itemize}
+    \color{gray}
+    \item[(a)]
+      Erklären Sie die o.\,a.\ Compiler-Fehlermeldungen.
+  %    \points{2}
+    \item[(b)]
+      Wieso verschwinden die Fehlermeldungen nach den o.\,a.\ Ersetzungen?
+  %    \points{3}
+    \item[(c)]
+      Erklären Sie die Ausgabe des Programms.
+  %    \points{5}
+    \item[(d)]
+      Beschreiben Sie -- in Worten und/oder als C-Quelltext -- einen Weg,
+      das Programm so zu berichtigen, daß es die Eingabedaten
+      (``A duck has 2 wings. A cow has 4 legs.'') korrekt speichert und ausgibt. %\\
+  %    \points{4}
+    \color{black}
+    \item[(e)]
+      Schreiben Sie das Programm so um,
+      daß es keine expliziten Typumwandlungen mehr benötigt.\par
+      Hinweis: Verwenden Sie \lstinline{union}.
+      \points{4}
+    \item[(f)]
+      Schreiben Sie das Programm weiter um,
+      so daß es die Objektinstanzen \lstinline{duck} und \lstinline{cow}
+      dynamisch erzeugt.\par
+      Hinweis: Verwenden Sie \lstinline{malloc()} und schreiben Sie Konstruktoren.
+      \points{4}
+    \item[(g)]
+      Schreiben Sie das Programm weiter um,
+      so daß die Ausgabe nicht mehr direkt im Hauptprogramm erfolgt,
+      sondern stattdessen eine virtuelle Methode \lstinline{print()}
+      aufgerufen wird.\par
+      Hinweis: Verwenden Sie in den Objekten Zeiger auf Funktionen,
+      und initialisieren Sie diese in den Konstruktoren.
+      \points{4}
+  \end{itemize}
+
+  \begin{minipage}[t]{0.34\textwidth}
+    \begin{lstlisting}[gobble=6,xleftmargin=0pt]
+      #include <stdio.h>
+
+      #define ANIMAL     0
+      #define WITH_WINGS 1
+      #define WITH_LEGS  2
+
+      typedef struct animal
+      {
+        int type;
+        char *name;
+      } animal;
+
+      typedef struct with_wings
+      {
+        int wings;
+      } with_wings;
+
+      typedef struct with_legs
+      {
+        int legs;
+      } with_legs;
+    \end{lstlisting}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{0.65\textwidth}
+    \begin{lstlisting}[gobble=6,xleftmargin=0pt]
+      int main (void)
+      {
+        animal *a[2];
+
+        animal duck;
+        a[0] = &duck;
+        a[0]->type = WITH_WINGS;
+        a[0]->name = "duck";
+        a[0]->wings = 2;
+
+        animal cow;
+        a[1] = &cow;
+        a[1]->type = WITH_LEGS;
+        a[1]->name = "cow";
+        a[1]->legs = 4;
+
+        for (int i = 0; i < 2; i++)
+          if (a[i]->type == WITH_LEGS)
+            printf ("A %s has %d legs.\n", a[i]->name,
+                    ((with_legs *) a[i])-> legs);
+          else if (a[i]->type == WITH_WINGS)
+            printf ("A %s has %d wings.\n", a[i]->name,
+                    ((with_wings *) a[i])-> wings);
+          else
+            printf ("Error in animal: %s\n", a[i]->name);
+
+        return 0;
+      }
+    \end{lstlisting}
+    \begin{picture}(0,0)
+      \color{red}
+      \put(3.7,6.207){\vector(-1,0){0.7}}
+      \put(3.8,6.207){\makebox(0,0)[l]{\lstinline[basicstyle=\color{red}]{((with_legs *) a[1])->legs = 4;}}}
+      \put(4.0,8.735){\vector(-1,0){0.7}}
+      \put(4.1,8.735){\makebox(0,0)[l]{\lstinline[basicstyle=\color{red}]{((with_wings *) a[0])->wings = 2;}}}
+    \end{picture}
+  \end{minipage}
+
+  \solution
+
+  \begin{itemize}
+    \item[(e)]
+      \textbf{Schreiben Sie das Programm so um,
+      daß es keine expliziten Typumwandlungen mehr benötigt.}\par
+      \textbf{Hinweis: Verwenden Sie \lstinline{union}.}
+
+      Siehe \gitfile{hp}{2023ws/20240111}{loesung-1e.c}.
+      
+      Diese Lösung basiert auf \gitfile{hp}{2023ws/20240111}{loesung-3d-2.c},
+      da diese bereits weniger explizite Typumwandlungen enthält
+      als \gitfile{hp}{2023ws/20240111}{loesung-3d-1.c}.
+
+      Arbeitsschritte:
+      \begin{itemize}
+        \item
+          Umbenennen des Basistyps \lstinline{animal} in \lstinline{base},
+          damit wir den Bezeichner \lstinline{animal}
+          für die \lstinline{union} verwenden können
+        \item
+          Schreiben einer \lstinline{union animal},
+          die die drei Klassen \lstinline{base},
+          \lstinline{with_wings} und \lstinline{with_legs}
+          als Datenfelder enthält
+        \item
+          Umschreiben der Initialisierungen:
+          Zugriff auf Datenfelder erfolgt nun durch
+          z.\,B.\ \lstinline{a[0]->b.name}.
+          Hierbei ist \lstinline{b} der Name des \lstinline{base}-Datenfelds
+          innerhalb der \lstinline{union animal}.
+        \item
+          Auf gleiche Weise schreiben wir die \lstinline{if}-Bedingungen
+          innerhalb der \lstinline{for}-Schleife
+          sowie die Parameter der \lstinline{printf()}-Aufrufe um.
+      \end{itemize}
+      Explizite Typumwandlungen sind nun nicht mehr nötig.
+
+      Nachteil dieser Lösung:
+      Jede Objekt-Variable belegt nun Speicherplatz
+      für die gesamte \lstinline{union animal},
+      anstatt nur für die benötigte Variable vom Typ
+      \lstinline{with_wings} oder \lstinline{with_legs}.
+      Dies kann zu einer Verschwendung von Speicherplatz führen,
+      auch wenn dies in diesem Beispielprogramm tatsächlich nicht der Fall ist.
+
+    \item[(f)]
+      \textbf{Schreiben Sie das Programm weiter um,
+      so daß es die Objektinstanzen \lstinline{duck} und \lstinline{cow}
+      dynamisch erzeugt.}\par
+      \textbf{Hinweis: Verwenden Sie \lstinline{malloc()} und schreiben Sie Konstruktoren.}
+
+      Siehe \gitfile{hp}{2023ws/20240111}{loesung-1f.c}.
+
+    \item[(g)]
+      \textbf{Schreiben Sie das Programm weiter um,
+      so daß die Ausgabe nicht mehr direkt im Hauptprogramm erfolgt,
+      sondern stattdessen eine virtuelle Methode \lstinline{print()}
+      aufgerufen wird.}\par
+      \textbf{Hinweis: Verwenden Sie in den Objekten Zeiger auf Funktionen,
+      und initialisieren Sie diese in den Konstruktoren.}
+
+      Siehe \gitfile{hp}{2023ws/20240111}{loesung-1g.c}.
+
+  \end{itemize}
+
+  \exercise{Iterationsfunktionen}
+
+  Wir betrachten das folgende Programm (\gitfile{hp}{2023ws/20240111}{aufgabe-2.c}):
+
+  \begin{minipage}[t]{0.4\textwidth}
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      void foreach (int *a, void (*fun) (int x))
+      {
+        for (int *p = a; *p >= 0; p++)
+          fun (*p);
+      }
+
+      void even_or_odd (int x)
+      {
+        if (x % 2)
+          printf ("%d ist ungerade.\n", x);
+        else
+          printf ("%d ist gerade.\n", x);
+      }
+    \end{lstlisting}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{0.52\textwidth}
+    \begin{lstlisting}[gobble=6]
+      int main (void)
+      {
+        int numbers[] = { 12, 17, 32, 1, 3, 16, 19, 18, -1 };
+        foreach (numbers, even_or_odd);
+        return 0;
+      }
+    \end{lstlisting}
+    \begin{enumerate}[\quad(a)]
+      \item
+        Was bedeutet \lstinline{void (*fun) (int x)},
+        und welchen Sinn hat seine Verwendung in der Funktion \lstinline{foreach()}?
+        \points{2}
+      \item
+        Schreiben Sie das Hauptprogramm \lstinline{main()} so um,
+        daß es unter Verwendung der Funktion \lstinline{foreach()}
+        die Summe aller positiven Zahlen in dem Array berechnet.
+        Sie dürfen dabei weitere Funktionen sowie globale Variable einführen.
+        \points{4}
+    \end{enumerate}
+  \end{minipage}
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      \textbf{Was bedeutet \lstinline{void (*fun) (int x)},
+      und welchen Sinn hat seine Verwendung in der Funktion \lstinline{foreach()}?}
+
+      \lstinline{void (*fun) (int x)} deklariert einen Zeiger \lstinline{fun},
+      der auf Funktionen zeigen kann, die einen Parameter \lstinline{x}
+      vom Typ \lstinline{int} erwarten und keinen Wert zurückgeben (\lstinline{void}).
+
+      Durch die Übergabe eines derartigen Parameters an die Funktion \lstinline{foreach()}
+      lassen wir dem Aufrufer die Wahl,
+      welche Aktion für alle Elemente des Arrays aufgerufen werden soll.
+
+    \item
+      \textbf{Schreiben Sie das Hauptprogramm \lstinline{main()} so um,
+      daß es unter Verwendung der Funktion \lstinline{foreach()}
+      die Summe aller positiven Zahlen in dem Array berechnet.
+      Sie dürfen dabei weitere Funktionen sowie globale Variable einführen.}
+
+      Siehe: \gitfile{hp}{2023ws/20240111}{loesung-2.c}
+
+      Damit die Funktion \lstinline{add_up()} Zugriff auf die Variable \lstinline{sum} hat,
+      muß diese global sein
+      und vor der Funktion \lstinline{add_up()} deklariert werden.
+
+      Die Bedingung, daß nur positive Zahlen summiert werden sollen,
+      ist durch die Arbeitsweise der Funktion \lstinline{foreach()}
+      bereits gewährleistet, da negative Zahlen als Ende-Markierungen dienen.
+
+      Wichtig ist, daß die Variable \lstinline{sum}
+      vor dem Aufruf der Funktion \lstinline{foreach()}
+      auf den Wert \lstinline{0} gesetzt wird.
+      In \gitfile{hp}{2023ws/20240111}{loesung-2.c} geschieht dies
+      durch die Initialisierung von \lstinline{sum}.
+      Wenn mehrere Summen berechnet werden sollen,
+      muß dies durch explizite Zuweisungen \lstinline{sum = 0}
+      vor den Aufrufen von \lstinline{foreach()} erfolgen.
+  \end{enumerate}
+
+  \exercise{Stack-Operationen}
+
+  Das folgende Programm (\gitfile{hp}{2023ws/20240111}{aufgabe-3.c})
+  implementiert einen Stapelspeicher (Stack).
+  Dies ist ein Array, das nur bis zu einer variablen Obergrenze (Stack-Pointer)
+  tatsächlich genutzt wird.
+  An dieser Obergrenze kann man Elemente hinzufügen (push).
+  
+  In dieser Aufgabe sollen zusätzlich Elemente
+  in der Mitte eingefügt werden (insert).
+  Die dafür bereits existierenden Funktionen \lstinline{insert()}
+  und \lstinline{insert_sorted()} sind jedoch fehlerhaft.
+
+  \begin{minipage}[t]{0.5\textwidth}
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      #define STACK_SIZE 10
+
+      int stack[STACK_SIZE];
+      int stack_pointer = 0;
+
+      void push (int x)
+      {
+        stack[stack_pointer++] = x;
+      }
+
+      void show (void)
+      {
+        printf ("stack content:");
+        for (int i = 0; i < stack_pointer; i++)
+          printf (" %d", stack[i]);
+        if (stack_pointer)
+          printf ("\n");
+        else
+          printf (" (empty)\n");
+      }
+    \end{lstlisting}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{0.5\textwidth}
+    \begin{lstlisting}[gobble=6]
+      void insert (int x, int pos)
+      {
+        for (int i = pos; i < stack_pointer; i++)
+          stack[i + 1] = stack[i];
+        stack[pos] = x;
+        stack_pointer++;
+      }
+
+      void insert_sorted (int x)
+      {
+        int i = 0;
+        while (i < stack_pointer && x < stack[i])
+          i++;
+        insert (x, i);
+      }
+
+      int main (void)
+      {
+        push (3);
+        push (7);
+        push (137);
+        show ();
+        insert (5, 1);
+        show ();
+        insert_sorted (42);
+        show ();
+        insert_sorted (2);
+        show ();
+        return 0;
+      }
+    \end{lstlisting}
+  \end{minipage}
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      Korrigieren Sie das Programm so,
+      daß die Funktion \lstinline{insert()} ihren Parameter \lstinline{x}
+      an der Stelle \lstinline{pos} in den Stack einfügt
+      und den sonstigen Inhalt des Stacks verschiebt, aber nicht zerstört.
+      \points{3}
+    \item
+      Korrigieren Sie das Programm so,
+      daß die Funktion \lstinline{insert_sorted()} ihren Parameter \lstinline{x}
+      an derjenigen Stelle einfügt, an die er von der Sortierung her gehört.
+      (Der Stack wird hierbei vor dem Funktionsaufruf als sortiert vorausgesetzt.)
+      \points{2}
+    \item
+      Schreiben Sie eine zusätzliche Funktion \lstinline{int search (int x)},
+      die die Position (Index) des Elements \lstinline{x}
+      innerhalb des Stack zurückgibt -- oder die Zahl
+      \lstinline{-1}, wenn \lstinline{x} nicht im Stack enthalten ist.
+      Der Rechenaufwand darf höchstens $\mathcal{O}(n)$ betragen.
+      \points{3}
+    \item
+      Wie (c), aber der Rechenaufwand darf höchstens $\mathcal{O}(\log n)$ betragen.
+      \points{4}
+  \end{enumerate}
+
+  \solution
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      \textbf{Korrigieren Sie das Programm so,
+      daß die Funktion \lstinline{insert()} ihren Parameter \lstinline{x}
+      an der Stelle \lstinline{pos} in den Stack einfügt,
+      und den sonstigen Inhalt des Stacks verschiebt, aber nicht zerstört.}
+
+      Die \lstinline{for}-Schleife in der  Funktion \lstinline{insert()}
+      durchläuft das Array von unten nach oben.
+      Um den Inhalt des Arrays von unten nach oben zu verschieben,
+      muß man die Schleife jedoch von oben nach unten durchlaufen.
+
+      \goodbreak
+      Um die Funktion zu reparieren, ersetze man also
+      \begin{lstlisting}[gobble=8]
+        for (int i = pos; i < stack_pointer; i++)
+      \end{lstlisting}
+      durch:
+      \begin{lstlisting}[gobble=8]
+        for (int i = stack_pointer - 1; i >= pos; i--)
+      \end{lstlisting}
+      (Siehe auch: \gitfile{hp}{2023ws/20240111}{loesung-3.c})
+
+    \item
+      \textbf{Korrigieren Sie das Programm so,
+      daß die Funktion \lstinline{insert_sorted()} ihren Parameter \lstinline{x}
+      an derjenigen Stelle einfügt, an die er von der Sortierung her gehört.
+      (Der Stack wird hierbei vor dem Funktionsaufruf als sortiert vorausgesetzt.)}
+
+      Der Vergleich \lstinline{x < stack[i]}
+      als Bestandteil der \lstinline{while}-Bedingung
+      paßt nicht zur Durchlaufrichtung der Schleife (von unten nach oben).
+
+      Um die Funktion zu reparieren, kann man daher entweder
+      das Kleinerzeichen durch ein Größerzeichen ersetzen
+      (\lstinline{x > stack[i]} -- siehe \gitfile{hp}{2023ws/20240111}{loesung-3b-1.c})
+      oder die Schleife von oben nach unten durchlaufen
+      (siehe \gitfile{hp}{2023ws/20240111}{loesung-3b-2.c}).
+
+      Eine weitere Möglichkeit besteht darin,
+      das Suchen nach der Einfügeposition
+      mit dem Verschieben des Arrays zu kombinieren
+      (siehe \gitfile{hp}{2023ws/20240111}{loesung-3.c}).
+      Hierdurch spart man sich eine Schleife; das Programm wird schneller.
+      (Es bleibt allerdings bei $\mathcal{O}(n)$.)
+
+    \item
+      \textbf{Schreiben Sie eine zusätzliche Funktion \lstinline{int search (int x)},
+      die die Position (Index) des Elements \lstinline{x}
+      innerhalb des Stack zurückgibt
+      -- oder \lstinline{-1}, wenn \lstinline{x} nicht im Stack enthalten ist.
+      Der Rechenaufwand darf höchstens $\mathcal{O}(n)$ betragen.}
+
+      Man geht in einer Schleife den Stack (= den genutzten Teil des Arrays) durch.
+      Bei Gleichheit gibt man direkt mit \lstinline{return} den Index zurück.
+      Nach dem Schleifendurchlauf steht fest,
+      daß \lstinline{x} nicht im Stack vorhanden ist;
+      man kann dann direkt \lstinline{-1} zurückgeben
+      (siehe \gitfile{hp}{2023ws/20240111}{loesung-3c.c}).
+
+      Da es sich um eine einzelne Schleife handelt,
+      ist die Ordnung $\mathcal{O}(n)$.
+
+    \item
+      \textbf{Wie (c), aber der Rechenaufwand darf höchstens $\mathcal{O}(\log n)$ betragen.}
+
+      Um $\mathcal{O}(\log n)$ zu erreichen,
+      halbiert man fortwährend das Intervall von (einschließlich) \lstinline{0}
+      bis (ausschließlich) \lstinline{stack_pointer}
+      (siehe \gitfile{hp}{2023ws/20240111}{loesung-3d.c}). % --
+%      wie in der Funktion \lstinline{push_sorted()}
+%      im Beispiel-Programm \gitfile{hp}{2023ws/20240111}{stack-11.c}.
+
+%      Ein wichtiger Unterschied besteht darin,
+      Wichtig ist,
+      daß man nach dem Durchlauf der Schleife noch auf die Gleichheit
+      \lstinline{x == stack[left]} (insbesondere nicht: \lstinline{stack[right]})
+      prüfen und ggf.\ \lstinline{left} bzw.\ \lstinline{-1} zurückgeben muß.
+  \end{enumerate}
+
+\end{document}
diff --git a/20240111/hp-uebung-20240111.pdf b/20240111/hp-uebung-20240111.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..0353e44f437ec93059f5fac44b2cd38e8cb82cdc
Binary files /dev/null and b/20240111/hp-uebung-20240111.pdf differ
diff --git a/20240111/hp-uebung-20240111.tex b/20240111/hp-uebung-20240111.tex
new file mode 100644
index 0000000000000000000000000000000000000000..ea0e843d3dd45a2e8bfd1e15ba2df3e436546e1f
--- /dev/null
+++ b/20240111/hp-uebung-20240111.tex
@@ -0,0 +1,331 @@
+% hp-uebung-20240111.pdf - Exercises on Low-Level Programming / Applied Computer Sciences
+% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024  Peter Gerwinski
+%
+% This document is free software: you can redistribute it and/or
+% modify it either under the terms of the Creative Commons
+% Attribution-ShareAlike 3.0 License, or under the terms of the
+% GNU General Public License as published by the Free Software
+% Foundation, either version 3 of the License, or (at your option)
+% any later version.
+%
+% This document is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this document.  If not, see <http://www.gnu.org/licenses/>.
+%
+% You should have received a copy of the Creative Commons
+% Attribution-ShareAlike 3.0 Unported License along with this
+% document.  If not, see <http://creativecommons.org/licenses/>.
+
+% README: Objektorientierte Tier-Datenbank (Ergänzung), Iterationsfunktionen, Stack-Operationen
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+
+\begin{document}
+
+  \thispagestyle{empty}
+
+  \section*{Hardwarenahe Programmierung\\
+            Übungsaufgaben -- 11.\ Januar 2024}
+
+  Diese Übung enthält Punkteangaben wie in einer Klausur.
+  Um zu "`bestehen"', müssen Sie innerhalb von 85 Minuten
+  unter Verwendung ausschließlich zugelassener Hilfsmittel
+  15 Punkte (von insgesamt \totalpoints) erreichen.
+
+  \exercise{Objektorientierte Tier-Datenbank (Ergänzung)}
+
+  Diese Aufgabe ist eine Neuauflage
+  der Übungsaufgabe 3 vom 14.\ Dezember 2023,
+  ergänzt um die Teilaufgaben (e) bis (g).
+
+  \medskip
+
+  Das auf der nächsten Seite dargestellte Programm
+  (Datei: \gitfile{hp}{2023ws/20240111}{aufgabe-1a.c})
+  soll Daten von Tieren verwalten.
+
+  Beim Compilieren erscheinen die folgende Fehlermeldungen:
+  \begin{lstlisting}[style=terminal]
+    $ ¡gcc -std=c99 -Wall -O aufgabe-1a.c -o aufgabe-1a¿
+    aufgabe-1a.c: In function 'main':
+    aufgabe-1a.c:31: error: 'animal' has no member named 'wings'
+    aufgabe-1a.c:37: error: 'animal' has no member named 'legs'
+  \end{lstlisting}
+
+  Der Programmierer nimmt die auf der nächsten Seite in Rot dargestellten Ersetzungen vor\\
+  (Datei: \gitfile{hp}{2023ws/20240111}{aufgabe-1b.c}).
+  Daraufhin gelingt das Compilieren, und die Ausgabe des Programms lautet:
+  \begin{lstlisting}[style=terminal]
+    $ ¡gcc -std=c99 -Wall -O aufgabe-1b.c -o aufgabe-1b¿
+    $ ¡./aufgabe-1b¿
+    A duck has 2 legs.
+    Error in animal: cow
+  \end{lstlisting}
+
+  \begin{itemize}
+    \color{gray}
+    \item[(a)]
+      Erklären Sie die o.\,a.\ Compiler-Fehlermeldungen.
+  %    \points{2}
+    \item[(b)]
+      Wieso verschwinden die Fehlermeldungen nach den o.\,a.\ Ersetzungen?
+  %    \points{3}
+    \item[(c)]
+      Erklären Sie die Ausgabe des Programms.
+  %    \points{5}
+    \item[(d)]
+      Beschreiben Sie -- in Worten und/oder als C-Quelltext -- einen Weg,
+      das Programm so zu berichtigen, daß es die Eingabedaten
+      (``A duck has 2 wings. A cow has 4 legs.'') korrekt speichert und ausgibt. %\\
+  %    \points{4}
+    \color{black}
+    \item[(e)]
+      Schreiben Sie das Programm so um,
+      daß es keine expliziten Typumwandlungen mehr benötigt.\par
+      Hinweis: Verwenden Sie \lstinline{union}.
+      \points{4}
+    \item[(f)]
+      Schreiben Sie das Programm weiter um,
+      so daß es die Objektinstanzen \lstinline{duck} und \lstinline{cow}
+      dynamisch erzeugt.\par
+      Hinweis: Verwenden Sie \lstinline{malloc()} und schreiben Sie Konstruktoren.
+      \points{4}
+    \item[(g)]
+      Schreiben Sie das Programm weiter um,
+      so daß die Ausgabe nicht mehr direkt im Hauptprogramm erfolgt,
+      sondern stattdessen eine virtuelle Methode \lstinline{print()}
+      aufgerufen wird.\par
+      Hinweis: Verwenden Sie in den Objekten Zeiger auf Funktionen,
+      und initialisieren Sie diese in den Konstruktoren.
+      \points{4}
+  \end{itemize}
+
+  \begin{minipage}[t]{0.34\textwidth}
+    \begin{lstlisting}[gobble=6,xleftmargin=0pt]
+      #include <stdio.h>
+
+      #define ANIMAL     0
+      #define WITH_WINGS 1
+      #define WITH_LEGS  2
+
+      typedef struct animal
+      {
+        int type;
+        char *name;
+      } animal;
+
+      typedef struct with_wings
+      {
+        int wings;
+      } with_wings;
+
+      typedef struct with_legs
+      {
+        int legs;
+      } with_legs;
+    \end{lstlisting}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{0.65\textwidth}
+    \begin{lstlisting}[gobble=6,xleftmargin=0pt]
+      int main (void)
+      {
+        animal *a[2];
+
+        animal duck;
+        a[0] = &duck;
+        a[0]->type = WITH_WINGS;
+        a[0]->name = "duck";
+        a[0]->wings = 2;
+
+        animal cow;
+        a[1] = &cow;
+        a[1]->type = WITH_LEGS;
+        a[1]->name = "cow";
+        a[1]->legs = 4;
+
+        for (int i = 0; i < 2; i++)
+          if (a[i]->type == WITH_LEGS)
+            printf ("A %s has %d legs.\n", a[i]->name,
+                    ((with_legs *) a[i])-> legs);
+          else if (a[i]->type == WITH_WINGS)
+            printf ("A %s has %d wings.\n", a[i]->name,
+                    ((with_wings *) a[i])-> wings);
+          else
+            printf ("Error in animal: %s\n", a[i]->name);
+
+        return 0;
+      }
+    \end{lstlisting}
+    \begin{picture}(0,0)
+      \color{red}
+      \put(3.7,6.207){\vector(-1,0){0.7}}
+      \put(3.8,6.207){\makebox(0,0)[l]{\lstinline[basicstyle=\color{red}]{((with_legs *) a[1])->legs = 4;}}}
+      \put(4.0,8.735){\vector(-1,0){0.7}}
+      \put(4.1,8.735){\makebox(0,0)[l]{\lstinline[basicstyle=\color{red}]{((with_wings *) a[0])->wings = 2;}}}
+    \end{picture}
+  \end{minipage}
+
+  \vfil
+
+  \exercise{Iterationsfunktionen}
+
+  Wir betrachten das folgende Programm (\gitfile{hp}{2023ws/20240111}{aufgabe-2.c}):
+
+  \begin{minipage}[t]{0.4\textwidth}
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      void foreach (int *a, void (*fun) (int x))
+      {
+        for (int *p = a; *p >= 0; p++)
+          fun (*p);
+      }
+
+      void even_or_odd (int x)
+      {
+        if (x % 2)
+          printf ("%d ist ungerade.\n", x);
+        else
+          printf ("%d ist gerade.\n", x);
+      }
+    \end{lstlisting}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{0.52\textwidth}
+    \begin{lstlisting}[gobble=6]
+      int main (void)
+      {
+        int numbers[] = { 12, 17, 32, 1, 3, 16, 19, 18, -1 };
+        foreach (numbers, even_or_odd);
+        return 0;
+      }
+    \end{lstlisting}
+    \begin{enumerate}[\quad(a)]
+      \item
+        Was bedeutet \lstinline{void (*fun) (int x)},
+        und welchen Sinn hat seine Verwendung in der Funktion \lstinline{foreach()}?
+        \points{2}
+      \item
+        Schreiben Sie das Hauptprogramm \lstinline{main()} so um,
+        daß es unter Verwendung der Funktion \lstinline{foreach()}
+        die Summe aller positiven Zahlen in dem Array berechnet.
+        Sie dürfen dabei weitere Funktionen sowie globale Variable einführen.
+        \points{4}
+    \end{enumerate}
+  \end{minipage}
+
+  \clearpage
+
+  \exercise{Stack-Operationen}
+
+  Das folgende Programm (\gitfile{hp}{2023ws/20240111}{aufgabe-3.c})
+  implementiert einen Stapelspeicher (Stack).
+  Dies ist ein Array, das nur bis zu einer variablen Obergrenze (Stack-Pointer)
+  tatsächlich genutzt wird.
+  An dieser Obergrenze kann man Elemente hinzufügen (push).
+  
+  In dieser Aufgabe sollen zusätzlich Elemente
+  in der Mitte eingefügt werden (insert).
+  Die dafür bereits existierenden Funktionen \lstinline{insert()}
+  und \lstinline{insert_sorted()} sind jedoch fehlerhaft.
+
+  \begin{minipage}[t]{0.5\textwidth}
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      #define STACK_SIZE 10
+
+      int stack[STACK_SIZE];
+      int stack_pointer = 0;
+
+      void push (int x)
+      {
+        stack[stack_pointer++] = x;
+      }
+
+      void show (void)
+      {
+        printf ("stack content:");
+        for (int i = 0; i < stack_pointer; i++)
+          printf (" %d", stack[i]);
+        if (stack_pointer)
+          printf ("\n");
+        else
+          printf (" (empty)\n");
+      }
+    \end{lstlisting}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{0.5\textwidth}
+    \begin{lstlisting}[gobble=6]
+      void insert (int x, int pos)
+      {
+        for (int i = pos; i < stack_pointer; i++)
+          stack[i + 1] = stack[i];
+        stack[pos] = x;
+        stack_pointer++;
+      }
+
+      void insert_sorted (int x)
+      {
+        int i = 0;
+        while (i < stack_pointer && x < stack[i])
+          i++;
+        insert (x, i);
+      }
+
+      int main (void)
+      {
+        push (3);
+        push (7);
+        push (137);
+        show ();
+        insert (5, 1);
+        show ();
+        insert_sorted (42);
+        show ();
+        insert_sorted (2);
+        show ();
+        return 0;
+      }
+    \end{lstlisting}
+  \end{minipage}
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      Korrigieren Sie das Programm so,
+      daß die Funktion \lstinline{insert()} ihren Parameter \lstinline{x}
+      an der Stelle \lstinline{pos} in den Stack einfügt
+      und den sonstigen Inhalt des Stacks verschiebt, aber nicht zerstört.
+      \points{3}
+    \item
+      Korrigieren Sie das Programm so,
+      daß die Funktion \lstinline{insert_sorted()} ihren Parameter \lstinline{x}
+      an derjenigen Stelle einfügt, an die er von der Sortierung her gehört.
+      (Der Stack wird hierbei vor dem Funktionsaufruf als sortiert vorausgesetzt.)
+      \points{2}
+    \item
+      Schreiben Sie eine zusätzliche Funktion \lstinline{int search (int x)},
+      die die Position (Index) des Elements \lstinline{x}
+      innerhalb des Stack zurückgibt -- oder die Zahl
+      \lstinline{-1}, wenn \lstinline{x} nicht im Stack enthalten ist.
+      Der Rechenaufwand darf höchstens $\mathcal{O}(n)$ betragen.
+      \points{3}
+    \item
+      Wie (c), aber der Rechenaufwand darf höchstens $\mathcal{O}(\log n)$ betragen.
+      \points{4}
+  \end{enumerate}
+
+  \begin{flushright}
+    \textit{Viel Erfolg!}
+  \end{flushright}
+
+  \makeatletter
+    \immediate\write\@mainaux{\string\gdef\string\totalpoints{\arabic{points}}}
+  \makeatother
+
+\end{document}
diff --git a/20240111/loesung-1e.c b/20240111/loesung-1e.c
new file mode 100644
index 0000000000000000000000000000000000000000..b984d9253b9c379a88f0fc0ca130c88c3103f8f3
--- /dev/null
+++ b/20240111/loesung-1e.c
@@ -0,0 +1,61 @@
+#include <stdio.h>
+
+#define ANIMAL     0
+#define WITH_WINGS 1
+#define WITH_LEGS  2
+
+typedef struct
+{
+  int type;
+  char *name;
+} base;
+
+typedef struct
+{
+  int type;
+  char *name;
+  int wings;
+} with_wings;
+
+typedef struct
+{
+  int type;
+  char *name;
+  int legs;
+} with_legs;
+
+typedef union
+{
+  base b;
+  with_wings w;
+  with_legs l;
+} animal;
+
+int main (void)
+{
+  animal *a[2];
+
+  animal duck;
+  a[0] = &duck;
+  duck.b.type = WITH_WINGS;
+  duck.b.name = "duck";
+  duck.w.wings = 2;
+
+  animal cow;
+  a[1] = &cow;
+  cow.b.type = WITH_LEGS;
+  cow.b.name = "cow";
+  cow.l.legs = 4;
+
+  for (int i = 0; i < 2; i++)
+    if (a[i]->b.type == WITH_LEGS)
+      printf ("A %s has %d legs.\n", a[i]->b.name,
+              a[i]->l.legs);
+    else if (a[i]->b.type == WITH_WINGS)
+      printf ("A %s has %d wings.\n", a[i]->b.name,
+              a[i]->w.wings);
+    else
+      printf ("Error in animal: %s\n", a[i]->b.name);
+
+  return 0;
+}
diff --git a/20240111/loesung-1f.c b/20240111/loesung-1f.c
new file mode 100644
index 0000000000000000000000000000000000000000..7b949e6365fc3839e6adc7661e0f8b4dd0c059df
--- /dev/null
+++ b/20240111/loesung-1f.c
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define ANIMAL     0
+#define WITH_WINGS 1
+#define WITH_LEGS  2
+
+typedef struct
+{
+  int type;
+  char *name;
+} base;
+
+typedef struct
+{
+  int type;
+  char *name;
+  int wings;
+} with_wings;
+
+typedef struct
+{
+  int type;
+  char *name;
+  int legs;
+} with_legs;
+
+typedef union
+{
+  base b;
+  with_wings w;
+  with_legs l;
+} animal;
+
+animal *new_with_wings (char *name, int wings)
+{
+  animal *a = malloc (sizeof (with_wings));
+  a->b.type = WITH_WINGS;
+  a->b.name = name;
+  a->w.wings = wings;
+  return a;
+}
+
+animal *new_with_legs (char *name, int legs)
+{
+  animal *a = malloc (sizeof (with_legs));
+  a->b.type = WITH_LEGS;
+  a->b.name = name;
+  a->l.legs = legs;
+  return a;
+}
+
+int main (void)
+{
+  animal *a[2] = { new_with_wings ("duck", 2),
+                   new_with_legs ("cow", 4) };
+
+  for (int i = 0; i < 2; i++)
+    if (a[i]->b.type == WITH_LEGS)
+      printf ("A %s has %d legs.\n", a[i]->b.name,
+              a[i]->l.legs);
+    else if (a[i]->b.type == WITH_WINGS)
+      printf ("A %s has %d wings.\n", a[i]->b.name,
+              a[i]->w.wings);
+    else
+      printf ("Error in animal: %s\n", a[i]->b.name);
+
+  return 0;
+}
diff --git a/20240111/loesung-1g.c b/20240111/loesung-1g.c
new file mode 100644
index 0000000000000000000000000000000000000000..b453a52dbe0ef27399255819808b3f6e562ba3ef
--- /dev/null
+++ b/20240111/loesung-1g.c
@@ -0,0 +1,77 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define ANIMAL     0
+#define WITH_WINGS 1
+#define WITH_LEGS  2
+
+union animal;
+
+typedef struct
+{
+  int type;
+  char *name;
+  void (*print) (union animal *this);
+} base;
+
+typedef struct
+{
+  int type;
+  char *name;
+  void (*print) (union animal *this);
+  int wings;
+} with_wings;
+
+typedef struct
+{
+  int type;
+  char *name;
+  void (*print) (union animal *this);
+  int legs;
+} with_legs;
+
+typedef union animal
+{
+  base b;
+  with_wings w;
+  with_legs l;
+} animal;
+
+void print_with_wings (animal *this)
+{
+  printf ("A %s has %d wings.\n", this->b.name, this->w.wings);
+}
+
+void print_with_legs (animal *this)
+{
+  printf ("A %s has %d legs.\n", this->b.name, this->l.legs);
+}
+
+animal *new_with_wings (char *name, int wings)
+{
+  animal *a = malloc (sizeof (with_wings));
+  a->b.type = WITH_WINGS;
+  a->b.name = name;
+  a->b.print = print_with_wings;
+  a->w.wings = wings;
+  return a;
+}
+
+animal *new_with_legs (char *name, int legs)
+{
+  animal *a = malloc (sizeof (with_legs));
+  a->b.type = WITH_LEGS;
+  a->b.name = name;
+  a->b.print = print_with_legs;
+  a->l.legs = legs;
+  return a;
+}
+
+int main (void)
+{
+  animal *a[2] = { new_with_wings ("duck", 2),
+                   new_with_legs ("cow", 4) };
+  for (int i = 0; i < 2; i++)
+    a[i]->b.print (a[i]);
+  return 0;
+}
diff --git a/20240111/loesung-3.c b/20240111/loesung-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..9b87d6c2f977af2843bcc2b75896fb5f00d8fc35
--- /dev/null
+++ b/20240111/loesung-3.c
@@ -0,0 +1,62 @@
+#include <stdio.h>
+
+#define STACK_SIZE 10
+
+int stack[STACK_SIZE];
+int stack_pointer = 0;
+
+void push (int x)
+{
+  stack[stack_pointer++] = x;
+}
+
+int pop (void)
+{
+  return stack[--stack_pointer];
+}
+
+void show (void)
+{
+  printf ("stack content:");
+  for (int i = 0; i < stack_pointer; i++)
+    printf (" %d", stack[i]);
+  if (stack_pointer)
+    printf ("\n");
+  else
+    printf (" (empty)\n");
+}
+
+void insert (int x, int pos)
+{
+  for (int i = stack_pointer - 1; i >= pos; i--)
+    stack[i + 1] = stack[i];
+  stack[pos] = x;
+  stack_pointer++;
+}
+
+void insert_sorted (int x)
+{
+  int i = stack_pointer - 1;
+  while (i >= 0 && x < stack[i])
+    {
+      stack[i + 1] = stack[i];
+      i--;
+    }
+  stack[i + 1] = x;
+  stack_pointer++;
+}
+
+int main (void)
+{
+  push (3);
+  push (7);
+  push (137);
+  show ();
+  insert (5, 1);
+  show ();
+  insert_sorted (42);
+  show ();
+  insert_sorted (2);
+  show ();
+  return 0;
+}
diff --git a/20240111/loesung-3b-1.c b/20240111/loesung-3b-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..cbbe37055109d203105a7ad4acb63d5bef61f4c0
--- /dev/null
+++ b/20240111/loesung-3b-1.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+
+#define STACK_SIZE 10
+
+int stack[STACK_SIZE];
+int stack_pointer = 0;
+
+void push (int x)
+{
+  stack[stack_pointer++] = x;
+}
+
+int pop (void)
+{
+  return stack[--stack_pointer];
+}
+
+void show (void)
+{
+  printf ("stack content:");
+  for (int i = 0; i < stack_pointer; i++)
+    printf (" %d", stack[i]);
+  if (stack_pointer)
+    printf ("\n");
+  else
+    printf (" (empty)\n");
+}
+
+void insert (int x, int pos)
+{
+  for (int i = stack_pointer - 1; i >= pos; i--)
+    stack[i + 1] = stack[i];
+  stack[pos] = x;
+  stack_pointer++;
+}
+
+void insert_sorted (int x)
+{
+  int i = 0;
+  while (i < stack_pointer && x > stack[i])
+    i++;
+  insert (x, i);
+}
+
+int main (void)
+{
+  push (3);
+  push (7);
+  push (137);
+  show ();
+  insert (5, 1);
+  show ();
+  insert_sorted (42);
+  show ();
+  insert_sorted (2);
+  show ();
+  return 0;
+}
diff --git a/20240111/loesung-3b-2.c b/20240111/loesung-3b-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..b1e1ae846f15a29e9cd53a8d1d689e3ccbefacce
--- /dev/null
+++ b/20240111/loesung-3b-2.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+
+#define STACK_SIZE 10
+
+int stack[STACK_SIZE];
+int stack_pointer = 0;
+
+void push (int x)
+{
+  stack[stack_pointer++] = x;
+}
+
+int pop (void)
+{
+  return stack[--stack_pointer];
+}
+
+void show (void)
+{
+  printf ("stack content:");
+  for (int i = 0; i < stack_pointer; i++)
+    printf (" %d", stack[i]);
+  if (stack_pointer)
+    printf ("\n");
+  else
+    printf (" (empty)\n");
+}
+
+void insert (int x, int pos)
+{
+  for (int i = stack_pointer - 1; i >= pos; i--)
+    stack[i + 1] = stack[i];
+  stack[pos] = x;
+  stack_pointer++;
+}
+
+void insert_sorted (int x)
+{
+  int i = stack_pointer - 1;
+  while (i >= 0 && x < stack[i])
+    i--;
+  insert (x, i + 1);
+}
+
+int main (void)
+{
+  push (3);
+  push (7);
+  push (137);
+  show ();
+  insert (5, 1);
+  show ();
+  insert_sorted (42);
+  show ();
+  insert_sorted (2);
+  show ();
+  return 0;
+}
diff --git a/20240111/loesung-3c.c b/20240111/loesung-3c.c
new file mode 100644
index 0000000000000000000000000000000000000000..79d061e3d7b78a2bec05b632e74b083a16d5a326
--- /dev/null
+++ b/20240111/loesung-3c.c
@@ -0,0 +1,72 @@
+#include <stdio.h>
+
+#define STACK_SIZE 10
+
+int stack[STACK_SIZE];
+int stack_pointer = 0;
+
+void push (int x)
+{
+  stack[stack_pointer++] = x;
+}
+
+int pop (void)
+{
+  return stack[--stack_pointer];
+}
+
+void show (void)
+{
+  printf ("stack content:");
+  for (int i = 0; i < stack_pointer; i++)
+    printf (" %d", stack[i]);
+  if (stack_pointer)
+    printf ("\n");
+  else
+    printf (" (empty)\n");
+}
+
+void insert (int x, int pos)
+{
+  for (int i = stack_pointer - 1; i >= pos; i--)
+    stack[i + 1] = stack[i];
+  stack[pos] = x;
+  stack_pointer++;
+}
+
+void insert_sorted (int x)
+{
+  int i = stack_pointer - 1;
+  while (i >= 0 && x < stack[i])
+    {
+      stack[i + 1] = stack[i];
+      i--;
+    }
+  stack[i + 1] = x;
+  stack_pointer++;
+}
+
+int search (int x)
+{
+  for (int i = 0; i < stack_pointer; i++)
+    if (stack[i] == x)
+      return i;
+  return -1;
+}
+
+int main (void)
+{
+  push (3);
+  push (7);
+  push (137);
+  show ();
+  insert (5, 1);
+  show ();
+  insert_sorted (42);
+  show ();
+  insert_sorted (2);
+  show ();
+  printf ("%d\n", search (42));
+  printf ("%d\n", search (1117));
+  return 0;
+}
diff --git a/20240111/loesung-3d.c b/20240111/loesung-3d.c
new file mode 100644
index 0000000000000000000000000000000000000000..9079d8d3be7a500498aede2cf8e89a7d7db48a35
--- /dev/null
+++ b/20240111/loesung-3d.c
@@ -0,0 +1,86 @@
+#include <stdio.h>
+
+#define STACK_SIZE 10
+
+int stack[STACK_SIZE];
+int stack_pointer = 0;
+
+void push (int x)
+{
+  stack[stack_pointer++] = x;
+}
+
+int pop (void)
+{
+  return stack[--stack_pointer];
+}
+
+void show (void)
+{
+  printf ("stack content:");
+  for (int i = 0; i < stack_pointer; i++)
+    printf (" %d", stack[i]);
+  if (stack_pointer)
+    printf ("\n");
+  else
+    printf (" (empty)\n");
+}
+
+void insert (int x, int pos)
+{
+  for (int i = stack_pointer - 1; i >= pos; i--)
+    stack[i + 1] = stack[i];
+  stack[pos] = x;
+  stack_pointer++;
+}
+
+void insert_sorted (int x)
+{
+  int i = stack_pointer - 1;
+  while (i >= 0 && x < stack[i])
+    {
+      stack[i + 1] = stack[i];
+      i--;
+    }
+  stack[i + 1] = x;
+  stack_pointer++;
+}
+
+int search (int x)
+{
+  int left = 0;
+  int right = stack_pointer;
+  while (left < right - 1)
+    {
+      int middle = (left + right) / 2;
+      if (x < stack[middle])
+        right = middle;
+      else
+        left = middle;
+    }
+  if (x == stack[left])
+    return left;
+  else
+   return -1;
+}
+
+int main (void)
+{
+  push (3);
+  push (7);
+  push (137);
+  show ();
+  insert (5, 1);
+  show ();
+  insert_sorted (42);
+  show ();
+  insert_sorted (2);
+  show ();
+  printf ("%d\n", search (2));
+  printf ("%d\n", search (4));
+  printf ("%d\n", search (42));
+  printf ("%d\n", search (67));
+  printf ("%d\n", search (137));
+  printf ("%d\n", search (1117));
+  return 0;
+}
diff --git a/20240111/logo-hochschule-bochum-cvh-text-v2.pdf b/20240111/logo-hochschule-bochum-cvh-text-v2.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..4aa99b8f81061aca6dcaf43eed2d9efef40555f8
--- /dev/null
+++ b/20240111/logo-hochschule-bochum-cvh-text-v2.pdf
@@ -0,0 +1 @@
+../common/logo-hochschule-bochum-cvh-text-v2.pdf
\ No newline at end of file
diff --git a/20240111/logo-hochschule-bochum.pdf b/20240111/logo-hochschule-bochum.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1
--- /dev/null
+++ b/20240111/logo-hochschule-bochum.pdf
@@ -0,0 +1 @@
+../common/logo-hochschule-bochum.pdf
\ No newline at end of file
diff --git a/20240111/pgscript.sty b/20240111/pgscript.sty
new file mode 120000
index 0000000000000000000000000000000000000000..95c888478c99ea7fda0fd11ccf669ae91be7178b
--- /dev/null
+++ b/20240111/pgscript.sty
@@ -0,0 +1 @@
+../common/pgscript.sty
\ No newline at end of file
diff --git a/20240111/pgslides.sty b/20240111/pgslides.sty
new file mode 120000
index 0000000000000000000000000000000000000000..5be1416f4216f076aa268901f52a15d775e43f64
--- /dev/null
+++ b/20240111/pgslides.sty
@@ -0,0 +1 @@
+../common/pgslides.sty
\ No newline at end of file
diff --git a/README.md b/README.md
index 5adfc390f64dbb59c0f5c2cfaff4bd1fa65630fb..ade2427c9bbe4f047607b5c4126a727be646429f 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,9 @@ Vortragsfolien und Beispiele:
  * [23.11.2023: Speicherausrichtung, Algorithmen: Differentialgleichungen](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231123/hp-20231123.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/2023ws/20231123/)
  * [30.11.2023: Algorithmen: Rekursion](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231130/hp-20231130.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/2023ws/20231130/)
  * [07.12.2023: Algorithmen: Aufwandsabschätzungen](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231207/hp-20231207.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/2023ws/20231207/)
- * [14.12.2023: Objektorientierte Programmierung: Einführung](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231214/hp-20231214.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/2023ws/20231214/)
+ * [14.12.2023: Objektorientierte Programmierung](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231214/hp-20231214.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/2023ws/20231214/)
+ * [04.01.2024: Dunkle Materie und angewandte hardwarenahe Programmierung](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20240104/hp-20240104.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/2023ws/20240104/)
+ * [11.01.2024: Datenstrukturen](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20240111/hp-20240111.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/2023ws/20240111/)
  * [alle in 1 Datei](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/hp-slides-2023ws.pdf)
 
 Übungsaufgaben:
@@ -43,6 +45,7 @@ Vortragsfolien und Beispiele:
  * [30.11.2023: PBM-Grafik, Fakultät](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231130/hp-uebung-20231130.pdf)
  * [07.12.2023: Länge von Strings, Einfügen in Strings (Ergänzung)](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231207/hp-uebung-20231207.pdf)
  * [14.12.2023: dynamisches Bit-Array, objektorientierte Tier-Datenbank](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231214/hp-uebung-20231214.pdf)
+ * [11.01.2024: Objektorientierte Tier-Datenbank (Ergänzung), Iterationsfunktionen, Stack-Operationen](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20240111/hp-uebung-20240111.pdf)
 
 Musterlösungen:
 ---------------
@@ -56,6 +59,7 @@ Musterlösungen:
  * [30.11.2023: PBM-Grafik, Fakultät](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231130/hp-musterloesung-20231130.pdf)
  * [07.12.2023: Länge von Strings, Einfügen in Strings (Ergänzung)](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231207/hp-musterloesung-20231207.pdf)
  * [14.12.2023: dynamisches Bit-Array, objektorientierte Tier-Datenbank](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231214/hp-musterloesung-20231214.pdf)
+ * [11.01.2024: Objektorientierte Tier-Datenbank (Ergänzung), Iterationsfunktionen, Stack-Operationen](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20240111/hp-musterloesung-20240111.pdf)
 
 Praktikumsunterlagen:
 ---------------------
diff --git a/hp-slides-2023ws.pdf b/hp-slides-2023ws.pdf
index 32caad54ae92a1e5bdf9b9186463eea6a6e83b88..afca7691e231f4ad3011c55fda89c0fc650751ca 100644
Binary files a/hp-slides-2023ws.pdf and b/hp-slides-2023ws.pdf differ
diff --git a/hp-slides-2023ws.tex b/hp-slides-2023ws.tex
index 26466349727172a8629fe6e1296e96d96edc0bdb..cb0aaeabe00dbdecb32c3c18ffa1f872cf1440a1 100644
--- a/hp-slides-2023ws.tex
+++ b/hp-slides-2023ws.tex
@@ -31,6 +31,10 @@
   \includepdf[pages=-]{20231130/hp-20231130.pdf}
   \pdfbookmark[1]{07.12.2023: Algorithmen: Aufwandsabschätzungen}{20231207}
   \includepdf[pages=-]{20231207/hp-20231207.pdf}
-  \pdfbookmark[1]{14.12.2023: Objektorientierte Programmierung: Einführung}{20231214}
+  \pdfbookmark[1]{14.12.2023: Objektorientierte Programmierung}{20231214}
   \includepdf[pages=-]{20231214/hp-20231214.pdf}
+  \pdfbookmark[1]{04.01.2024: Dunkle Materie und angewandte hardwarenahe Programmierung}{20240104}
+  \includepdf[pages=-]{20240104/hp-20240104.pdf}
+  \pdfbookmark[1]{11.01.2024: Datenstrukturen}{20240111}
+  \includepdf[pages=-]{20240111/hp-20240111.pdf}
 \end{document}