diff --git a/20200116/aufgabe-1.c b/20200116/aufgabe-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..abbf364a3db17611e41d086591826e98a8a3672b
--- /dev/null
+++ b/20200116/aufgabe-1.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+int fak (int n)
+{
+  if (n <= 0)
+    return 1;
+  else
+    return n * fak (n - 1);
+}
+
+int main (void)
+{
+  for (int n = 0; n <= 5; n++)
+    printf ("%d\n", fak (n));
+  return 0;
+}
diff --git a/20200116/aufgabe-2.c b/20200116/aufgabe-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..d0b065941fbc0082bf867d872527299dca97b98f
--- /dev/null
+++ b/20200116/aufgabe-2.c
@@ -0,0 +1,18 @@
+#include <string.h>
+
+int fun_1 (char *s)
+{
+  int x = 0;
+  for (int i = 0; i < strlen (s); i++)
+    x += s[i];
+  return x;
+}
+
+int fun_2 (char *s)
+{
+  int i = 0, x = 0;
+  int len = strlen (s);
+  while (i < len)
+    x += s[i++];
+  return x;
+}
diff --git a/20200116/aufgabe-3a.c b/20200116/aufgabe-3a.c
new file mode 100644
index 0000000000000000000000000000000000000000..61b6e79400afbb8ac0609eb1b72c04b83a0fce41
--- /dev/null
+++ b/20200116/aufgabe-3a.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/20200116/aufgabe-3b.c b/20200116/aufgabe-3b.c
new file mode 100644
index 0000000000000000000000000000000000000000..2cf3b56f4540f399d3761b0de929d80a1f1de611
--- /dev/null
+++ b/20200116/aufgabe-3b.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/20200116/hp-uebung-20200116.pdf b/20200116/hp-uebung-20200116.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..47a2ed43cd89005d445e36f19ad0cd4c1326696f
Binary files /dev/null and b/20200116/hp-uebung-20200116.pdf differ
diff --git a/20200116/hp-uebung-20200116.tex b/20200116/hp-uebung-20200116.tex
new file mode 100644
index 0000000000000000000000000000000000000000..9cfb7e0754407cd2f362ab8a1b8d4ebf7e5e2a14
--- /dev/null
+++ b/20200116/hp-uebung-20200116.tex
@@ -0,0 +1,297 @@
+% hp-uebung-20200109.pdf - Exercises on Low-Level Programming
+% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020  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: Fakultät, Länge von Strings (Neuauflage), objektorientierte Tier-Datenbank
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+
+\begin{document}
+
+  \thispagestyle{empty}
+
+  \section*{Hardwarenahe Programmierung\\
+            Übungsaufgaben -- 9.\ Januar 2020}
+
+  Diese Übung enthält Punkteangaben wie in einer Klausur.
+  Um zu "`bestehen"', müssen Sie innerhalb von 100 Minuten
+  unter Verwendung ausschließlich zugelassener Hilfsmittel
+  19 Punkte (von insgesamt \totalpoints) erreichen.
+  (Davon entfallen 12 Punkte, entsprechend 30 Minuten,
+  auf die bereits früher gestellte Aufgabe 2, Teilaufgaben (a) bis (e).)
+
+  \exercise{Fakultät}
+
+  Die Fakultät $n!$ einer ganzen Zahl $n \ge 0$ ist definiert als:
+  \begin{eqnarray*}
+    1 & \mbox{für} & n = 0, \\
+    n \cdot (n-1)! & \mbox{für} & n > 0.
+  \end{eqnarray*}
+
+  Mit anderen Worten: $n! = 1\cdot2\cdot3\cdot\dots\cdot n$.
+
+  Die folgende Funktion \lstinline{fak()} berechnet die Fakultät \emph{rekursiv}
+  (Datei: \gitfile{hp}{20200116}{aufgabe-1.c}):
+
+  \begin{lstlisting}
+    int fak (int n)
+    {
+      if (n <= 0)
+        return 1;
+      else
+        return n * fak (n - 1);
+    }
+  \end{lstlisting}
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      Schreiben Sie eine Funktion, die die Fakultät \emph{iterativ} berechnet,\\
+      d.\,h.\ mit Hilfe einer Schleife anstelle von Rekursion.
+      \points{3}
+    \item
+      Wie viele Multiplikationen (Landau-Symbol)
+      erfordern beide Versionen der Fakultätsfunktion\\
+      in Abhängigkeit von \lstinline$n$?
+      Begründen Sie Ihre Antwort.
+      \points{2}
+    \item
+      Wieviel Speicherplatz (Landau-Symbol)
+      erfordern beide Versionen der Fakultätsfunktion\\
+      in Abhängigkeit von \lstinline$n$?
+      Begründen Sie Ihre Antwort.
+      \points{3}
+  \end{enumerate}
+
+  \exercise{Länge von Strings}
+
+  Diese Aufgabe ist eine Neuauflage von Aufgabe 3 der
+  Übung vom 14.\ November 2019,\\
+  ergänzt um die Teilaufgaben (f) und (g).
+
+  \medskip
+
+  Strings werden in der Programmiersprache C durch Zeiger auf \lstinline{char}-Variable realisiert.
+
+  Beispiel: \lstinline{char *hello_world = "Hello, world!\n"}
+
+  Die Systembibliothek stellt eine Funktion \lstinline{strlen()} zur Ermittlung der Länge von Strings\\
+  zur Verfügung (\lstinline{#include <string.h>}).
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      Auf welche Weise ist die Länge eines Strings gekennzeichnet?
+      \points{1}
+    \item
+      Wie lang ist die Beispiel-String-Konstante \lstinline{"Hello, world!\n"},
+      und wieviel Speicherplatz belegt sie?\\
+      \points{2}
+    \item
+      Schreiben Sie eine eigene Funktion \lstinline{int strlen (char *s)},
+      die die Länge eines Strings zurückgibt.\\
+      \points{3}
+  \end{enumerate}
+
+  \goodbreak
+
+  Wir betrachten nun die folgenden Funktionen (Datei: \gitfile{hp}{20200116}{aufgabe-2.c}):
+  \begin{center}
+    \begin{minipage}{8cm}
+      \begin{lstlisting}[gobble=8]
+        int fun_1 (char *s)
+        {
+          int x = 0;
+          for (int i = 0; i < strlen (s); i++)
+            x += s[i];
+          return x;
+        }
+      \end{lstlisting}
+    \end{minipage}%
+    \begin{minipage}{6cm}
+      \vspace*{-1cm}
+      \begin{lstlisting}[gobble=8]
+        int fun_2 (char *s)
+        {
+          int i = 0, x = 0;
+          int len = strlen (s);
+          while (i < len)
+            x += s[i++];
+          return x;
+        }
+      \end{lstlisting}
+      \vspace*{-1cm}
+    \end{minipage}
+  \end{center}
+  \begin{enumerate}[\quad(a)]\setcounter{enumi}{3}
+    \item
+      Was bewirken die beiden Funktionen?
+      \points{2}
+    \item
+      Schreiben Sie eine eigene Funktion,
+      die dieselbe Aufgabe erledigt wie \lstinline{fun_2()},\\
+      nur effizienter.
+      \points{4}
+    \item
+      Von welcher Ordnung (Landau-Symbol) sind die beiden Funktionen
+      hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen im String?
+      Begründen Sie Ihre Antwort.
+      Sie dürfen für \lstinline{strlen()} Ihre eigene Version der Funktion voraussetzen.
+       \points{3}
+    \item
+      Von welcher Ordnung (Landau-Symbol) ist Ihre effizientere Funktion?\\
+      Begründen Sie Ihre Antwort.
+      \points{1}
+  \end{enumerate}
+
+  \exercise{Objektorientierte Tier-Datenbank}
+
+  Das auf der nächsten Seite in Blau dargestellte Programm (Datei: \gitfile{hp}{20200116}{aufgabe-3a.c})\\
+  soll Daten von Tieren verwalten.
+
+  Beim Compilieren erscheinen die folgende Fehlermeldungen:
+  \begin{lstlisting}[style=terminal]
+    $ ¡gcc -std=c99 -Wall -O aufgabe-2a.c -o aufgabe-2a¿
+    aufgabe-2a.c: In function 'main':
+    aufgabe-2a.c:31: error: 'animal' has no member named 'wings'
+    aufgabe-2a.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}{20200116}{aufgabe-3b.c}).
+  Daraufhin gelingt das Compilieren, und die Ausgabe des Programms lautet:
+  \begin{lstlisting}[style=terminal]
+    $ ¡gcc -std=c99 -Wall -O aufgabe-2b.c -o aufgabe-2b¿
+    $ ¡./aufgabe-2b¿
+    A duck has 2 legs.
+    Error in animal: cow
+  \end{lstlisting}
+
+  \begin{itemize}
+    \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}
+%    \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}
+
+  \begin{flushright}
+    \textit{Viel Erfolg!}
+  \end{flushright}
+
+  \makeatletter
+    \immediate\write\@mainaux{\string\gdef\string\totalpoints{\arabic{points}}}
+  \makeatother
+
+\end{document}
diff --git a/20200116/logo-hochschule-bochum-cvh-text-v2.pdf b/20200116/logo-hochschule-bochum-cvh-text-v2.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..3725a72c764b4d9ab200553474e4262161f7a5b5
Binary files /dev/null and b/20200116/logo-hochschule-bochum-cvh-text-v2.pdf differ
diff --git a/20200116/logo-hochschule-bochum.pdf b/20200116/logo-hochschule-bochum.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..8cad73dbb48a2b550bf29355b5a6ec895ce091f8
Binary files /dev/null and b/20200116/logo-hochschule-bochum.pdf differ
diff --git a/20200116/pgscript.sty b/20200116/pgscript.sty
new file mode 120000
index 0000000000000000000000000000000000000000..95c888478c99ea7fda0fd11ccf669ae91be7178b
--- /dev/null
+++ b/20200116/pgscript.sty
@@ -0,0 +1 @@
+../common/pgscript.sty
\ No newline at end of file
diff --git a/README.md b/README.md
index 70d6cf8382aeb1f24296e403a7c95de608856372..8985f87d5730e652b5efa1f7fab977a6847ee7f5 100644
--- a/README.md
+++ b/README.md
@@ -29,6 +29,7 @@ Vortragsfolien und Beispiele:
  * [12.12.2019: make, Byte-Reihenfolge - Endianness](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20191212/hp-20191212.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/master/20191212/)
  * [19.12.2019: Binärdarstellung negativer Zahlen, Speicherausrichtung - Alignment](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20191219/hp-20191219.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/master/20191219/)
  * [02.01.2020: Quantencomputer, Datensicherheit und Datenschutz](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20200102/hp-20200102.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/master/20200102/)
+ * [09.01.2020: Rekursion, Aufwandsabschätzungen, objektorientierte Programmierung](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20200109/hp-20200109.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/master/20200109/)
  * [alle in 1 Datei](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/hp-slides-2019ws.pdf)
 
 Übungsaufgaben:
@@ -45,6 +46,7 @@ Vortragsfolien und Beispiele:
  * [12.12.2019: Kondensator, hüpfender Ball](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20191212/hp-uebung-20191212.pdf)
  * [19.12.2019: Trickprogrammierung, Thermometer-Baustein an I²C-Bus](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20191219/hp-uebung-20191219.pdf)
  * [09.01.2020: Speicherformate von Zahlen, Zeigerarithmetik, Personen-Datenbank](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20200109/hp-uebung-20200109.pdf)
+ * [16.01.2020: Fakultät, Länge von Strings (Neuauflage), objektorientierte Tier-Datenbank](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20200116/hp-uebung-20200116.pdf)
 
 Musterlösungen:
 ---------------
@@ -72,6 +74,7 @@ Praktikumsunterlagen:
  * [Versuch 1, 17. und 31.10.2019: RSA-Verschlüsselung](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20191010/hp-2019ws-p1.pdf)
  * [Versuch 2, 14. und 21.11.2019: Druckknopfampel](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20191107/hp-2019ws-p2.pdf)
  * [Versuch 3, 12. und 19.12.2019: Weltraum-Simulation](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20191212/hp-2019ws-p3.pdf)
+ * [Versuch 4, 16. und 23.1.2020: Objektorientiertes Grafik-Programm](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20200109/hp-2019ws-p4.pdf)
 
 Alte Klausuren:
 ---------------