diff --git a/20201210/aufgabe-2.c b/20201210/aufgabe-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..9ae72941b931c04f3c380cb3bbcd64bec7f08c20
--- /dev/null
+++ b/20201210/aufgabe-2.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <string.h>
+
+void insert_into_string (char src, char *target, int pos)
+{
+  int len = strlen (target);
+  for (int i = pos; i < len; i++)
+    target[i+1] = target[i];
+  target[pos] = src;
+}
+
+int main (void)
+{
+  char test[100] = "Hochshule Bochum";
+  insert_into_string ('c', test, 5);
+  printf ("%s\n", test);
+  return 0;
+}
diff --git a/20201210/aufgabe-3.c b/20201210/aufgabe-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..d0b065941fbc0082bf867d872527299dca97b98f
--- /dev/null
+++ b/20201210/aufgabe-3.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/20201210/hp-20201210.pdf b/20201210/hp-20201210.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..1cdccee96eaf935b0977fe801f9da0bb84478945
Binary files /dev/null and b/20201210/hp-20201210.pdf differ
diff --git a/20201210/hp-20201210.tex b/20201210/hp-20201210.tex
new file mode 100644
index 0000000000000000000000000000000000000000..b5fe31c4d208a477e31a9c509ddc183c5f0eaa42
--- /dev/null
+++ b/20201210/hp-20201210.tex
@@ -0,0 +1,1423 @@
+% hp-20201210.pdf - Lecture Slides on Low-Level Programming
+% Copyright (C) 2012, 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: Parameter des Hauptprogramms, String-Operationen
+
+\documentclass[10pt,t]{beamer}
+
+\usepackage{pgslides}
+\usepackage{pdftricks}
+\usepackage{tikz}
+
+\begin{psinputs}
+  \usepackage[utf8]{inputenc}
+  \usepackage[german]{babel}
+  \usepackage[T1]{fontenc}
+  \usepackage{helvet}
+  \renewcommand*\familydefault{\sfdefault}
+  \usepackage{pstricks,pst-grad}
+\end{psinputs}
+
+\title{Hardwarenahe Programmierung}
+\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski}
+\date{10.\ Dezember 2020}
+
+\begin{document}
+
+\maketitleframe
+
+\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}
+      \begin{itemize}
+        \vspace*{-\smallskipamount}
+        \item[\dots]
+        \item[2.12] Strukturen
+        \item[2.13] Dateien und Fehlerbehandlung
+        \color{medgreen}
+        \item[2.14] Parameter des Hauptprogramms
+        \item[2.15] String-Operationen
+      \end{itemize}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+    \item[\textbf{4}] \textbf{Hardwarenahe Programmierung}
+    \item[\textbf{5}] \textbf{Algorithmen}
+    \vspace*{-\smallskipamount}
+    \item[\textbf{\dots}]
+  \end{itemize}
+
+\end{frame}
+
+\setcounter{section}{1}
+\section{Einführung in C}
+\setcounter{subsection}{12}
+\subsection{Strukturen}
+
+\begin{frame}[fragile]
+  \showsubsection
+
+  \begin{minipage}[b]{6cm}
+    \begin{lstlisting}[gobble=6]
+      ¡#include <stdio.h>
+
+      typedef struct
+      {
+        char day, month;
+        int year;
+      }
+      date;
+
+      int main (void)
+      {
+        date today = { 3, 12, 2020 };
+        printf ("%d.%d.%d\n", today.day, today.month, today.year);
+        return 0;
+      }¿
+    \end{lstlisting}
+  \end{minipage}
+
+\end{frame}
+
+\begin{frame}[fragile]
+  \showsubsection
+
+%  \vspace*{0.9mm}
+  \begin{minipage}[b]{6cm}
+    \begin{lstlisting}[gobble=6]
+      ¡#include <stdio.h>
+
+      typedef struct
+      {
+        char day, month;
+        int year;
+      }
+      date;
+
+      void set_date (date *d)
+      {
+        (*d).day = 3;
+        (*d).month = 12;
+        (*d).year = 2020;
+      }¿
+    \end{lstlisting}
+  \end{minipage}%
+  \begin{minipage}[b]{6cm}
+    \begin{lstlisting}[gobble=6]
+      ¡int main (void)
+      {
+        date today;
+        set_date (&today);
+        printf ("%d.%d.%d\n", today.day,
+                today.month, today.year);
+        return 0;
+      }¿
+    \end{lstlisting}
+  \end{minipage}
+\end{frame}
+
+\begin{frame}[fragile]
+  \showsubsection
+
+%  \vspace*{0.9mm}
+  \begin{minipage}[b]{6cm}
+    \begin{lstlisting}[gobble=6]
+      ¡#include <stdio.h>
+
+      typedef struct
+      {
+        char day, month;
+        int year;
+      }
+      date;
+
+      void set_date (date *d)
+      {
+        d->day = 3;
+        d->month = 12;
+        d->year = 2020;
+      }¿
+    \end{lstlisting}
+  \end{minipage}%
+  \begin{minipage}[b]{6cm}
+    \hspace*{-1cm}%
+    \lstinline{foo->bar}
+    ist Abkürzung für
+    \lstinline{(*foo).bar}
+
+    \bigskip
+
+    \visible<2->{%
+      \hspace*{-1cm}%
+      Eine Funktion, die mit einem \lstinline{struct} arbeitet,\\
+      \hspace*{-1cm}%
+      kann man eine \newterm{Methode\/} des \lstinline{struct} nennen.}
+
+    \bigskip
+    \bigskip
+
+    \begin{lstlisting}[gobble=6]
+      ¡int main (void)
+      {
+        date today;
+        set_date (&today);
+        printf ("%d.%d.%d\n", today.day,
+                today.month, today.year);
+        return 0;
+      }¿
+    \end{lstlisting}
+  \end{minipage}
+
+\end{frame}
+
+\subsection{Dateien und Fehlerbehandlung}
+
+\begin{frame}[fragile]
+  \showsubsection
+  \vspace*{-0.2925cm}
+  \begin{minipage}[t]{6cm}
+    \begin{onlyenv}<1>
+      \begin{lstlisting}[gobble=8]
+        ¡#include <stdio.h>
+
+        int main (void)
+        {
+          FILE *f = fopen ("fhello.txt", "w");
+          fprintf (f, "Hello, world!\n");
+          fclose (f);
+          return 0;
+        }¿
+      \end{lstlisting}
+    \end{onlyenv}
+    \begin{onlyenv}<2>
+      \begin{lstlisting}[gobble=8]
+        ¡#include <stdio.h>
+
+        int main (void)
+        {
+          FILE *f = fopen ("fhello.txt", "w");
+          if (f)
+            {
+              fprintf (f, "Hello, world!\n");
+              fclose (f);
+            }
+          return 0;
+        }¿
+      \end{lstlisting}
+    \end{onlyenv}
+    \begin{onlyenv}<3>
+      \begin{lstlisting}[gobble=8]
+        ¡#include <stdio.h>
+        #include <errno.h>
+
+        int main (void)
+        {
+          FILE *f = fopen ("fhello.txt", "w");
+          if (f)
+            {
+              fprintf (f, "Hello, world!\n");
+              fclose (f);
+            }
+          else
+            fprintf (stderr, "error #%d\n", errno);
+          return 0;
+        }¿
+      \end{lstlisting}
+    \end{onlyenv}
+    \begin{onlyenv}<4>
+      \begin{lstlisting}[gobble=8]
+        ¡#include <stdio.h>
+        #include <errno.h>
+        #include <string.h>
+
+        int main (void)
+        {
+          FILE *f = fopen ("fhello.txt", "w");
+          if (f)
+            {
+              fprintf (f, "Hello, world!\n");
+              fclose (f);
+            }
+          else
+            {
+              char *msg = strerror (errno);
+              fprintf (stderr, "%s\n", msg);
+            }
+          return 0;
+        }¿
+      \end{lstlisting}
+      \vspace*{-1cm}
+    \end{onlyenv}
+    \begin{onlyenv}<5->
+      \begin{lstlisting}[gobble=8]
+        ¡#include <stdio.h>
+        #include <errno.h>
+        #include <er¡ror.h>
+
+        int main (void)
+        {
+          FILE *f = fopen ("fhello.txt", "w");
+          if (!f)
+            error (1, errno, "cannot open file");
+          fprintf (f, "Hello, world!\n");
+          fclose (f);
+          return 0;
+        }
+      \end{lstlisting}
+    \end{onlyenv}
+  \end{minipage}\pause\hspace*{-1.5cm}%
+  \begin{minipage}[t]{8.5cm}
+    \bigskip
+    \only<3->{\bigskip}
+    \begin{itemize}
+      \item
+        Wenn die Datei nicht geöffnet werden kann,\\
+        gibt \lstinline{fopen()} den Wert \lstinline{NULL} zurück.
+        \pause
+        \medskip
+      \item
+        \addtolength{\leftskip}{1cm}
+        Die globale Variable \lstinline{int errno}\\
+        enthält dann die Nummer des Fehlers.\\
+        Benötigt: \lstinline{#include <errno.h>}
+        \pause
+        \medskip
+        \only<5->{\bigskip}
+      \item
+        Die Funktion \lstinline{strerror()} wandelt \lstinline{errno}\\
+        in einen Fehlermeldungstext um.\\
+        Benötigt: \lstinline{#include <string.h>}
+        \pause
+        \medskip
+      \item
+        \addtolength{\leftskip}{-1.5cm}
+        Die Funktion \lstinline{error()} gibt eine Fehlermeldung aus\\
+        und beendet das Programm.\\
+        Benötigt: \lstinline{#include <er¡¿ror.h>}
+        \pause
+        \medskip
+      \item
+        \textbf{Niemals Fehler einfach ignorieren!}
+    \end{itemize}
+    \addtolength{\leftskip}{0.5cm}
+  \end{minipage}
+\end{frame}
+
+\subsection{Parameter des Hauptprogramms}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \begin{lstlisting}
+    #include <stdio.h>
+
+    int main (int argc, char **argv)
+    {
+      printf ("argc = %d\n", argc);
+      for (int i = 0; i < argc; i++)
+        printf ("argv[%d] = \"%s\"\n", i, argv[i]);
+      return 0;
+    }
+  \end{lstlisting}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \begin{lstlisting}
+    #include <stdio.h>
+
+    int main (int argc, char **argv)
+    {
+      printf ("argc = %d\n", argc);
+      for (int i = 0; *argv; i++, argv++)
+        printf ("argv[%d] = \"%s\"\n", i, *argv);
+      return 0;
+    }
+  \end{lstlisting}
+
+\end{frame}
+
+\subsection{String-Operationen}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \vspace*{-0.4cm}
+  \begin{lstlisting}
+    #include <stdio.h>
+    #include <string.h>
+
+    int main (void)
+    {
+      char hello[] = "Hello, world!\n";
+
+      printf ("%s\n", hello);
+      printf ("%zd\n", strlen (hello));
+
+      printf ("%s\n", hello + 7);
+      printf ("%zd\n", strlen (hello + 7));
+
+      hello[5] = 0;
+      printf ("%s\n", hello);
+      printf ("%zd\n", strlen (hello));
+
+      return 0;
+    }
+  \end{lstlisting}
+  \vspace*{-1cm}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \vspace*{-0.4cm}
+  \begin{lstlisting}
+    #include <stdio.h>
+    #include <string.h>
+
+    int main (void)
+    {
+      char *anton = "Anton";
+      char *zacharias = "Zacharias";
+
+      printf ("%d\n", strcmp (anton, zacharias));
+      printf ("%d\n", strcmp (zacharias, anton));
+      printf ("%d\n", strcmp (anton, anton));
+
+      char buffer[100] = "Huber ";
+      strcat (buffer, anton);
+      printf ("%s\n", buffer);
+
+      return 0;
+    }
+  \end{lstlisting}
+  \vspace*{-1cm}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \vspace*{-0.4cm}
+  \begin{lstlisting}
+    #include <stdio.h>
+    #include <string.h>
+
+    int main (void)
+    {
+      char buffer[100] = "";
+      sprintf (buffer, "Die Antwort lautet: %d", 42);
+      printf ("%s\n", buffer);
+
+      char *answer = strstr (buffer, "Antwort");
+      printf ("%s\n", answer);
+      printf ("found at: %zd\n", answer - buffer);
+
+      return 0;
+    }
+  \end{lstlisting}
+  \vspace*{-1cm}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \vspace*{-0.4cm}
+  \begin{lstlisting}
+    #include <stdio.h>
+    #include <string.h>
+
+    int main (void)
+    {
+      char buffer[100] = "";
+      snprintf (buffer, 100, "Die Antwort lautet: %d", 42);
+      printf ("%s\n", buffer);
+
+      char *answer = strstr (buffer, "Antwort");
+      printf ("%s\n", answer);
+      printf ("found at: %zd\n", answer - buffer);
+
+      return 0;
+    }
+  \end{lstlisting}
+
+\end{frame}
+
+\begin{frame}
+
+  \showsection
+
+  Sprachelemente weitgehend komplett
+
+  \bigskip
+  Es fehlen:
+  \begin{itemize}
+    \item
+      Ergänzungen (z.\,B.\ ternärer Operator, \lstinline{union}, \lstinline{unsigned}, \lstinline{volatile})
+    \item
+      Bibliotheksfunktionen (z.\,B.\ \lstinline{malloc()})
+    \arrowitem
+      werden eingeführt, wenn wir sie brauchen
+    \bigskip
+    \item
+      Konzepte (z.\,B.\ rekursive Datenstrukturen, Klassen selbst bauen)
+    \arrowitem
+      werden eingeführt, wenn wir sie brauchen, oder:
+    \arrowitem
+      Literatur\\[\smallskipamount]
+      (z.\,B.\ Wikibooks: C-Programmierung,\\
+      Dokumentation zu Compiler und Bibliotheken)
+    \bigskip
+    \item
+      Praxiserfahrung
+    \arrowitem
+      Übung und Praktikum: nur Einstieg
+    \arrowitem
+      selbständig arbeiten
+  \end{itemize}
+\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}
+      \begin{itemize}
+        \vspace*{-\smallskipamount}
+        \item[\dots]
+        \item[2.12] Strukturen
+        \item[2.13] Dateien und Fehlerbehandlung
+        \color{medgreen}
+        \item[2.14] Parameter des Hauptprogramms
+        \item[2.15] String-Operationen
+      \end{itemize}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+      \begin{itemize}
+        \color{red}
+        \item[3.1] Der Präprozessor
+        \item[3.2] Bibliotheken einbinden
+        \item[3.3] Bibliotheken verwenden
+        \item[3.4] Projekt organisieren: make
+        \vspace*{-\smallskipamount}
+        \item[\dots]
+      \end{itemize}
+    \vspace*{-\smallskipamount}
+    \item[\textbf{4}] \textbf{Algorithmen}
+    \item[\textbf{5}] \textbf{Hardwarenahe Programmierung}
+    \vspace*{-\smallskipamount}
+    \item[\textbf{\dots}]
+  \end{itemize}
+
+\end{frame}
+
+\section{Bibliotheken}
+\subsection{Der Präprozessor}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \lstinline{#include}: %\pause:
+  Text einbinden
+  \begin{itemize}
+%    \pause
+    \item
+      \lstinline{#include <stdio.h>}: Standard-Verzeichnisse -- Standard-Header
+%    \pause
+    \item
+      \lstinline{#include "answer.h"}: auch aktuelles Verzeichnis -- eigene Header
+  \end{itemize}
+
+  \pause
+  \bigskip
+
+  \lstinline{#define VIER 4}: Text ersetzen lassen -- Konstante definieren
+  \begin{itemize}
+    \pause
+    \item
+      Kein Semikolon!
+    \pause
+    \item
+      Berechnungen in Klammern setzen:\\
+      \lstinline{#define VIER (2 + 2)}
+    \pause
+    \item
+      Konvention: Großbuchstaben
+  \end{itemize}
+
+\end{frame}
+
+\subsection{Bibliotheken einbinden}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  Inhalt der Header-Datei: externe Deklarationen
+
+%  \pause
+  \smallskip
+  \lstinline{extern int answer (void);}
+
+%  \pause
+  \smallskip
+  \lstinline{extern int printf (__const char *__restrict __format, ...);}
+
+%  \pause
+  \bigskip
+  Funktion wird "`anderswo"' definiert
+  \begin{itemize}
+%    \pause
+    \item
+      separater C-Quelltext: mit an \lstinline[style=terminal]{gcc} übergeben
+%    \pause
+    \item
+      Zusammenfügen zu ausführbarem Programm durch den \newterm{Linker}
+%    \pause
+    \item
+      vorcompilierte Bibliothek: \lstinline[style=terminal]{-lfoo}\\
+%      \pause
+      = Datei \file{libfoo.a} in Standard-Verzeichnis
+  \end{itemize}
+
+\end{frame}
+
+\subsection{Bibliothek verwenden (Beispiel: GTK+)}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \begin{itemize}
+    \item
+      \lstinline{#include <gtk/gtk.h>}
+    \pause
+    \smallskip
+    \item
+      Mit \lstinline[style=cmd]{pkg-config --cflags --libs} erfährt man,\\
+      welche Optionen und Bibliotheken man an \lstinline[style=cmd]{gcc}
+      übergeben muß\alt<4->{.}{:}
+      \pause
+      \begin{onlyenv}<3>
+        \begin{lstlisting}[style=terminal,gobble=10]
+          $ ¡pkg-config --cflags --libs gtk+-3.0¿
+          -pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-
+          atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1
+          .0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/
+          include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/inc
+          lude/cairo -I/usr/include/pango-1.0 -I/usr/include/harf
+          buzz -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I
+          /usr/include/cairo -I/usr/include/pixman-1 -I/usr/inclu
+          de/freetype2 -I/usr/include/libpng16 -I/usr/include/gdk
+          -pixbuf-2.0 -I/usr/include/libpng16 -I/usr/include/glib
+          -2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lgtk
+          -3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcai
+          ro-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject
+          -2.0 -lglib-2.0
+        \end{lstlisting}
+        \vspace*{-3cm}
+      \end{onlyenv}
+    \pause
+    \arrowitem
+      Compiler-Aufruf:
+      \begin{onlyenv}<4>
+        \begin{lstlisting}[style=terminal,gobble=10]
+          $ ¡gcc -Wall -O hello-gtk.c -pthread -I/usr/include/gtk-
+          3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-sp
+          i-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-g
+          nu/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/inclu
+          de/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pa
+          ngo-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.
+          0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/in
+          clude/pixman-1 -I/usr/include/freetype2 -I/usr/include/
+          libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/l
+          ibpng16 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux
+          -gnu/glib-2.0/include -lgtk-3 -lgdk-3 -lpangocairo-1.0
+          -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pix
+          buf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0-o hello-gtk¿
+        \end{lstlisting}
+        \vspace*{-2cm}
+      \end{onlyenv}
+      \begin{onlyenv}<5->
+        \begin{lstlisting}[style=terminal,gobble=10]
+          $ ¡gcc -Wall -O hello-gtk.c $(pkg-config --cflags --libs)
+                 -o hello-gtk¿
+        \end{lstlisting}
+      \end{onlyenv}
+      \begin{onlyenv}<5>
+        \begin{picture}(0,0)(0.3,0.3)
+          \color{red}
+          \put(6.6,-0.6){\makebox(0,0)[bl]{\tikz{\draw[-latex](0,0)--(3,1.5);}}}
+          \put(6.3,-0.7){\makebox(0,0)[t]{\shortstack{\strut Optionen:\\
+                           \strut u.\,a.\ viele Include-Verzeichnisse:\\
+                           \lstinline[style=cmd]{-I/usr/include/gtk-3.0}}}}
+          \put(10.0,-2.1){\makebox(0,0)[bl]{\tikz{\draw[-latex](0,0)--(1.5,3);}}}
+          \put(10.3,-2.2){\makebox(0,0)[t]{\shortstack{\strut Bibliotheken:\\
+                            \strut u.\,a.\ \lstinline[style=cmd]{-lgtk-3 -lcairo}}}}
+        \end{picture}
+      \end{onlyenv}
+    \pause
+    \pause
+    \item
+      Auf manchen Plattformen kommt es auf die Reihenfolge an:
+      \begin{lstlisting}[style=terminal,gobble=8]
+        $ ¡gcc -Wall -O $(pkg-config --cflags) \
+               hello-gtk.c $(pkg-config --libs) \
+               -o hello-gtk¿
+      \end{lstlisting}
+      (Backslash = "`Es geht in der nächsten Zeile weiter."')
+  \end{itemize}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  Selbst geschriebene Funktion übergeben: \newterm{Callback}
+
+  \bigskip
+
+  \begin{lstlisting}[xleftmargin=1em]
+    gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+    {
+      /* Zeichenbefehle */
+      ...
+
+      return FALSE;
+    }
+  
+    ...
+
+    g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+  \end{lstlisting}
+
+  \medskip
+
+  \begin{itemize}
+    \arrowitem 
+      GTK+ ruft immer dann, wenn es etwas zu zeichnen gibt,\\
+      die Funktion \lstinline{draw} auf.
+  \end{itemize}
+
+  \pause
+  \begin{picture}(0,0)(-0.07,0.2)
+    \color{red}
+    \put(5.3,4.8){\makebox(0,0)[bl]{\tikz{\draw[-latex](0,0)--(1.90,1.15);}}}
+    \put(5.0,4.7){\makebox(0,0)[t]{\shortstack{\strut repräsentiert den\\
+                    \strut Bildschirm, auf den\\
+                    \strut gezeichnet werden soll}}}
+    \pause
+    \put(9.7,5.1){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-0.2,0.85);}}}
+    \put(9.7,5.0){\makebox(0,0)[t]{\shortstack{\strut optionale Zusatzinformationen\\
+                    \strut für draw(), typischerweise\\
+                    \strut ein Zeiger auf ein struct}}}
+    \put(10.0,3.5){\makebox(0,0)[tl]{\tikz{\draw[-latex](0,0)--(0.6,-1.25);}}}
+  \end{picture}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  Selbst geschriebene Funktion übergeben: \newterm{Callback}
+
+  \bigskip
+
+  \begin{lstlisting}[xleftmargin=1em]
+    gboolean timer (GtkWidget *widget)
+    {
+      /* Rechenbefehle */
+      ...
+
+      gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+      g_timeout_add (50, (GSourceFunc) timer, widget);
+      return FALSE;
+    }
+  
+    ...
+
+    g_timeout_add (50, (GSourceFunc) timer, drawing_area);
+  \end{lstlisting}
+
+  \medskip
+
+  \begin{itemize}
+    \arrowitem 
+      GTK+ ruft nach 50 Millisekunden
+      die Funktion \lstinline{timer} auf.
+  \end{itemize}
+
+  \pause
+  \begin{picture}(0,0)(-0.07,0.2)
+    \color{red}
+    \put(9.7,6.7){\makebox(0,0)[t]{\shortstack{\strut Dieser Bereich soll\\
+                    \strut neu gezeichnet werden.}}}
+    \put(9.7,5.7){\makebox(0,0)[tr]{\tikz{\draw[-latex](0,0)--(-0.6,-0.8);}}}
+    \pause
+    \put(4.3,3.2){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-0.7,0.6);}}}
+    \put(4.3,3.1){\makebox(0,0)[t]{\shortstack{\strut In weiteren 50 Millisekunden soll\\
+                    \strut die Funktion erneut aufgerufen werden.}}}
+    \pause
+    \put(9.3,2.9){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-3.3,0.9);}}}
+    \put(9.8,2.8){\makebox(0,0)[t]{\shortstack{\strut Explizite Typumwandlung\\
+                    \strut eines Zeigers (später)}}}
+  \end{picture}
+
+\end{frame}
+
+\section{Algorithmen}
+\subsection{Differentialgleichungen}
+
+%\begin{frame}[fragile]
+%
+%  \showsection
+%  \showsubsection
+%
+%  \textbf{Beispiel 1: Gleichmäßig beschleunigte Bewegung}
+%
+%  \begin{center}
+%    \includegraphics[width=\textwidth,trim={0cm 7cm 0cm 0cm},clip]{../20181112/photo-20181112-173737.jpg}
+%  \end{center}
+%
+%\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \textbf{Beispiel 1: Gleichmäßig beschleunigte Bewegung}
+
+  \strut\hfill
+  \begin{minipage}{2.5cm}
+    \vspace*{0.6cm}
+    \begin{align*}
+      x'(t) &= v_x(t) \\[0.65cm]
+      y'(t) &= v_y(t) \\[0.75cm]
+      v_x'(t) &= 0 \\[0.65cm]
+      v_y'(t) &= -g
+    \end{align*}
+    \vspace*{0.0cm}
+  \end{minipage}%
+  \only<1>{\hspace*{9.49cm}}\strut
+  \only<2->{\hfill$\Rightarrow$\hfill}%
+  \begin{onlyenv}<2-8>
+    \begin{minipage}{8.3cm}
+      \begin{align*}
+        x(t) &= \int v_x(t)\,dt
+          \visible<4->{= \int v_{0x}\,dt}
+          \visible<5->{= x_0 + v_{0x}\cdot t}\\[\medskipamount]
+        y(t) &= \int v_y(t)\,dt
+          \visible<7->{= \int v_{0y} - g\cdot t\,dt}
+          \visible<8->{= y_0 + v_{0y}\cdot t
+                         - {\textstyle\frac12}gt^2}\\[\bigskipamount]
+        v_x(t) &= \int 0\,dt
+          \visible<3->{= v_{0x}} \\[\medskipamount]
+        v_y(t) &= \int -g\,dt
+          \visible<6->{= v_{0y} - g\cdot t}
+      \end{align*}
+    \end{minipage}%
+  \end{onlyenv}%
+  \begin{onlyenv}<9->
+    \begin{minipage}{3.5cm}
+      \vspace*{0.5cm}
+      \begin{lstlisting}[gobble=8,xleftmargin=0.5em]
+        ¡x += vx * dt;¿
+      \end{lstlisting}
+      \vspace{0.75cm}
+      \begin{lstlisting}[gobble=8,xleftmargin=0.5em]
+        ¡y += vy * dt;¿
+      \end{lstlisting}
+      \vspace{0.90cm}
+      \begin{lstlisting}[gobble=8,xleftmargin=0.5em]
+        ¡vx += 0 * dt;¿
+      \end{lstlisting}
+      \vspace{0.75cm}
+      \begin{lstlisting}[gobble=8,xleftmargin=0.5em]
+        ¡vy += -g * dt;¿
+      \end{lstlisting}
+    \end{minipage}%
+    \begin{minipage}{5.13cm}
+      Siehe: \file{gtk-13.c}
+    \end{minipage}
+  \end{onlyenv}%
+  \hfill\strut
+
+\end{frame}
+
+\begin{frame}[fragile]
+  \showsection
+  \showsubsection
+
+  \textbf{Beispiel 1: Gleichmäßig beschleunigte Bewegung}
+
+  \medskip
+
+  \textbf{Beispiel 2: Mathematisches Pendel}
+
+  \vspace*{-2\bigskipamount}
+
+  \begin{picture}(0,0)
+    \put(8,-6.5){\includegraphics{pendulum.pdf}}
+  \end{picture}
+
+  \begin{eqnarray*}
+    \varphi'(t) &=& \omega(t) \\[\smallskipamount]
+    \omega'(t) &=& -\frac{g}{l}\cdot\sin\varphi(t)\hspace*{7.1cm}
+  \end{eqnarray*}
+  \vspace*{-1.5\medskipamount}
+  \begin{itemize}
+    \item
+      Von Hand (analytisch):\\
+      Lösung raten (Ansatz), Parameter berechnen
+    \item
+      Mit Computer (numerisch):\\
+      Eulersches Polygonzugverfahren
+  \end{itemize}
+  \smallskip
+  \begin{lstlisting}[gobble=0]
+    phi += dt * omega;
+    omega += - dt * g / l * sin (phi);
+  \end{lstlisting}
+
+  \pause
+  \bigskip
+
+  \textbf{Beispiel 3: Weltraum-Simulation}
+
+  Praktikumsaufgabe
+  \vspace*{-1cm}
+
+\end{frame}
+
+\setcounter{section}{2}
+\section{Bibliotheken}
+\setcounter{subsection}{3}
+\subsection{Projekt organisieren: make}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+  \begin{itemize}
+    \item
+      \only<4->{explizite und implizite} Regeln
+      \begin{onlyenv}<2>
+        \smallskip
+        \begin{lstlisting}[language=make,gobble=10]
+          philosophy: philosophy.o answer.o
+                  gcc philosophy.o answer.o -o philosophy
+
+          answer.o: answer.c answer.h
+                  gcc -Wall -O answer.c -c
+
+          philosophy.o: philosophy.c answer.h
+                  gcc -Wall -O philosophy.c -c
+        \end{lstlisting}
+      \end{onlyenv}
+      \begin{onlyenv}<4>
+        \smallskip
+        \begin{lstlisting}[language=make,gobble=10]
+          TARGET = philosophy
+          OBJECTS = philosophy.o answer.o
+          HEADERS = answer.h
+          CFLAGS = -Wall -O
+
+          $(TARGET): $(OBJECTS)
+                  gcc $(OBJECTS) -o $(TARGET)
+
+          %.o: %.c $(HEADERS)
+                  gcc $(CFLAGS) $< -c
+
+          clean:
+                  rm -f $(OBJECTS) $(TARGET)
+        \end{lstlisting}
+      \end{onlyenv}
+    \item
+      Makros
+      \begin{onlyenv}<3>
+        \smallskip
+        \begin{lstlisting}[language=make,gobble=10]
+          TARGET = philosophy
+          OBJECTS = philosophy.o answer.o
+          HEADERS = answer.h
+          CFLAGS = -Wall -O
+
+          $(TARGET): $(OBJECTS)
+                  gcc $(OBJECTS) -o $(TARGET)
+
+          answer.o: answer.c $(HEADERS)
+                  gcc $(CFLAGS) answer.c -c
+
+          philosophy.o: philosophy.c $(HEADERS)
+                  gcc $(CFLAGS) philosophy.c -c
+
+          clean:
+                  rm -f $(OBJECTS) $(TARGET)
+        \end{lstlisting}
+        \vspace*{-1cm}
+      \end{onlyenv}
+    \begin{onlyenv}<5->
+      \smallskip
+      \arrowitem
+        3 Sprachen: C, Präprozessor, make
+    \end{onlyenv}
+  \end{itemize}
+
+\end{frame}
+
+\iffalse
+
+\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.git}}}
+    \item[\textbf{2}] \textbf{Einführung in C}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+      \begin{itemize}
+        \color{medgreen}
+        \item[3.1] Der Präprozessor
+        \item[3.2] Bibliotheken einbinden
+        \item[3.3] Bibliotheken verwenden
+        \color{red}
+        \item[3.4] Projekt organisieren: make
+      \end{itemize}
+    \item[\textbf{4}] \textbf{Hardwarenahe Programmierung}
+      \begin{itemize}
+        \color{red}
+        \item[4.1] Bit-Operationen
+        \item[4.2] I/O-Ports
+        \item[4.3] Interrupts
+        \vspace*{-0.1cm}
+        \item[\dots]
+      \end{itemize}
+    \item[\textbf{5}] \textbf{Algorithmen}
+      \begin{itemize}
+        \color{medgreen}
+        \item[5.1] Differentialgleichungen
+        \color{black}
+        \vspace*{-0.1cm}
+        \item[\dots]
+      \end{itemize}
+    \item[\textbf{\dots}]
+%    \item[\textbf{4}] \textbf{Hardwarenahe Programmierung}
+%    \item[\textbf{5}] \textbf{Algorithmen}
+%    \item[\textbf{6}] \textbf{Ergänzungen und Ausblicke}
+  \end{itemize}
+  \vspace*{-1cm}
+
+\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}
+      \begin{itemize}
+        \vspace*{-\smallskipamount}
+        \item[\dots]
+        \item[2.10] Zeiger
+        \color{medgreen}
+        \item[2.11] Arrays und Strings
+        \item[2.12] Strukturen
+        \item[2.13] Dateien und Fehlerbehandlung
+        \color{red}
+        \item[2.14] Parameter des Hauptprogramms
+        \item[2.15] String-Operationen
+      \end{itemize}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+%      \begin{itemize}
+%        \color{red}
+%        \item[3.1] Der Präprozessor
+%        \item[3.2] Bibliotheken einbinden
+%        \item[3.3] Bibliotheken verwenden
+%        \vspace*{-\smallskipamount}
+%        \item[\dots]
+%%        \item[3.4] Projekt organisieren: make
+%      \end{itemize}
+%    \vspace*{-\smallskipamount}
+    \item[\textbf{4}] \textbf{Hardwarenahe Programmierung}
+      \begin{itemize}
+        \color{red}
+        \item[4.1] Bit-Operationen
+        \item[4.2] I/O-Ports
+        \color{black}
+        \item[4.3] Interrupts
+        \vspace*{-0.1cm}
+        \item[\dots]
+      \end{itemize}
+    \item[\textbf{5}] \textbf{Algorithmen}
+    \item[\textbf{\dots}]
+  \end{itemize}
+
+\end{frame}
+
+\setcounter{section}{3}
+\section{Hardwarenahe Programmierung}
+\subsection{Bit-Operationen}
+\subsubsection{Zahlensysteme}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \vspace*{-\smallskipamount}
+  \showsubsection
+  \vspace*{-\medskipamount}
+  \showsubsubsection
+
+  \begin{tabular}{rlrl}
+    Basis & Name & Beispiel & Anwendung \\[\smallskipamount]
+      2 & Binärsystem & 1\,0000\,0011 & Bit-Operationen \\
+      8 & Oktalsystem & \lstinline,0403, & Dateizugriffsrechte (Unix) \\
+     10 & Dezimalsystem & \lstinline,259, & Alltag \\
+     16 & Hexadezimalsystem & \lstinline,0x103, & Bit-Operationen \\
+    256 & (keiner gebräuchlich) & 0.0.1.3 & IP-Adressen (IPv4)
+  \end{tabular}
+
+  \bigskip
+
+  \begin{itemize}
+    \item
+      Computer rechnen im Binärsystem.
+    \item
+      Für viele Anwendungen (z.\,B.\ I/O-Ports, Grafik, \dots) ist es notwendig,\\
+      Bits in Zahlen einzeln ansprechen zu können.
+  \end{itemize}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsubsection
+
+  \begin{tabular}{rlrlrc}
+    \qquad 000 & \bf 0 \hspace*{1.5cm} & 0000 & \bf 0 & \quad 1000 & \bf 8\\
+           001 & \bf 1                 & 0001 & \bf 1 &       1001 & \bf 9\\
+           010 & \bf 2                 & 0010 & \bf 2 &       1010 & \bf A\\
+           011 & \bf 3                 & 0011 & \bf 3 &       1011 & \bf B\\[\smallskipamount]
+           100 & \bf 4                 & 0100 & \bf 4 &       1100 & \bf C\\
+           101 & \bf 5                 & 0101 & \bf 5 &       1101 & \bf D\\
+           110 & \bf 6                 & 0110 & \bf 6 &       1110 & \bf E\\
+           111 & \bf 7                 & 0111 & \bf 7 &       1111 & \bf F\\
+  \end{tabular}
+
+  \medskip
+
+  \begin{itemize}
+    \item
+      Oktal- und Hexadezimalzahlen lassen sich ziffernweise\\
+      in Binär-Zahlen umrechnen.
+    \item
+      Hexadezimalzahlen sind eine Kurzschreibweise für Binärzahlen,\\
+      gruppiert zu jeweils 4 Bits.
+    \item
+      Oktalzahlen sind eine Kurzschreibweise für Binärzahlen,\\
+      gruppiert zu jeweils 3 Bits.
+    \item
+      Trotz Taschenrechner u.\,ä.\ lohnt es sich,\\
+      die o.\,a.\ Umrechnungstabelle \textbf{auswendig} zu kennen.
+  \end{itemize}
+
+\end{frame}
+
+\subsubsection{Bit-Operationen in C}
+
+\begin{frame}[fragile]
+
+  \showsubsubsection
+
+  \begin{tabular}{lll}
+    C-Operator     & Verknüpfung              & Anwendung                \\[\smallskipamount]
+    \lstinline,&,  & Und                      & Bits gezielt löschen     \\
+    \lstinline,|,  & Oder                     & Bits gezielt setzen      \\
+    \lstinline,^,  & Exklusiv-Oder            & Bits gezielt invertieren \\
+    \lstinline,~,  & Nicht                    & Alle Bits invertieren    \\[\smallskipamount]
+    \lstinline,<<, & Verschiebung nach links  & Maske generieren         \\
+    \lstinline,>>, & Verschiebung nach rechts & Bits isolieren
+  \end{tabular}
+
+  \bigskip
+
+  Numerierung der Bits: von rechts ab 0
+
+  \medskip
+
+  \begin{tabular}{ll}
+    Bit Nr.\ 3 auf 1 setzen: &
+    \lstinline,a |= 1 << 3;, \\
+    Bit Nr.\ 4 auf 0 setzen: &
+    \lstinline,a &= ~(1 << 4);, \\
+    Bit Nr.\ 0 invertieren: &
+    \lstinline,a ^= 1 << 0;,
+  \end{tabular}
+
+  \smallskip
+
+  ~~Abfrage, ob Bit Nr.\ 1 gesetzt ist:\quad
+  \lstinline{if (a & (1 << 1))}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsubsection
+
+  C-Datentypen für Bit-Operationen:
+  \smallskip\par
+  \lstinline{#include <stdint.h>}
+  \medskip\par
+  \begin{tabular}{lllll}
+                    & 8 Bit & 16 Bit & 32 Bit & 64 Bit \\
+    mit Vorzeichen  & \lstinline,int8_t,
+                    & \lstinline,int16_t,
+                    & \lstinline,int32_t,
+                    & \lstinline,int64_t, \\
+    ohne Vorzeichen & \lstinline,uint8_t,
+                    & \lstinline,uint16_t,
+                    & \lstinline,uint32_t,
+                    & \lstinline,uint64_t,
+  \end{tabular}
+
+  \bigskip
+  \bigskip
+
+  Ausgabe:
+  \smallskip\par
+  \begin{lstlisting}
+    #include <stdio.h>
+    #include <stdint.h>
+    #include <inttypes.h>
+    ...
+    uint64_t x = 42;
+    printf ("Die Antwort lautet: %" PRIu64 "\n", x);
+  \end{lstlisting}
+
+  \bigskip
+
+  Aufgabe: Schreiben Sie C-Funktionen, die ein "`Array von Bits"' realisieren, z.\,B.
+
+  \smallskip
+
+  \begin{tabular}[t]{ll}
+    \lstinline|void set_bit (int i);|   & Bei Index $i$ auf 1 setzen \\
+    \lstinline|void clear_bit (int i);| & Bei Index $i$ auf 0 setzen \\
+    \lstinline|int get_bit (int i);|    & Bei Index $i$ lesen
+  \end{tabular}
+
+  \medskip
+
+  Hinweise:
+  \begin{itemize}
+    \item
+      Die Größe des Bit-"`Arrays"' (z.\,B.\ 1000) dürfen Sie als \emph{vorher bekannt\/} voraussetzen.
+    \item
+      Sie benötigen ein Array, z.\,B.\ von \lstinline|char|- oder \lstinline|int|-Variablen.
+    \item
+      Sie benötigen eine Division (\lstinline|/|) sowie den Divisionsrest (Modulo: \lstinline|%|).
+  \end{itemize}
+
+\end{frame}
+
+\subsection{I/O-Ports}
+
+\begin{frame}[fragile]
+
+%  \showsection
+  \showsubsection
+  \vspace*{-1.5\medskipamount}
+  {\large\textbf{\color{structure}4.3\quad Interrupts}}
+
+  \bigskip
+
+  Kommunikation mit externen Geräten
+
+  \bigskip
+
+  \begin{center}
+    \includegraphics{io-ports-and-interrupts.pdf}
+  \end{center}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  In Output-Port schreiben = Aktoren ansteuern
+
+  Beispiel: LED
+
+  \medskip
+
+  \begin{lstlisting}
+    #include <avr/io.h>
+    ...
+    DDRC = 0x70;
+    PORTC = 0x40;
+  \end{lstlisting}
+  \begin{picture}(0,0)
+    \put(3,0.67){\begin{minipage}{3cm}
+                \color{red}%
+                binär: 0111\,0000\\
+                binär: 0100\,0000
+              \end{minipage}}
+    \put(10,0.67){\makebox(0,0)[r]{\color{red}Herstellerspezifisch!}}
+  \end{picture}
+
+  \bigskip
+
+  \lstinline{DDR} = Data Direction Register\\
+  Bit = 1 für Output-Port\\
+  Bit = 0 für Input-Port
+
+  \bigskip
+
+  \emph{Details: siehe Datenblatt und Schaltplan}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  Aus Input-Port lesen = Sensoren abfragen
+
+  Beispiel: Taster
+
+  \medskip
+
+  \begin{lstlisting}
+    #include <avr/io.h>
+    ...
+    DDRC = 0xfd;
+    while ((PINC & 0x02) == 0)
+      ; /* just wait */
+  \end{lstlisting}
+  \begin{picture}(0,0)(-1.5,-0.42)
+    \put(3,0.67){\begin{minipage}{3cm}
+                \color{red}%
+                binär: 1111\,1101\\
+                binär: 0000\,0010
+              \end{minipage}}
+    \put(10,0.67){\makebox(0,0)[r]{\color{red}Herstellerspezifisch!}}
+  \end{picture}
+
+  \bigskip
+
+  \lstinline{DDR} = Data Direction Register\\
+  Bit = 1 für Output-Port\\
+  Bit = 0 für Input-Port
+
+  \bigskip
+
+  \emph{Details: siehe Datenblatt und Schaltplan}
+  
+  \bigskip
+
+  Praktikumsaufgabe: Druckknopfampel
+
+\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}
+      \begin{itemize}
+        \vspace*{-\smallskipamount}
+        \item[\dots]
+        \item[2.10] Zeiger
+        \item[2.11] Arrays und Strings
+        \item[2.12] Strukturen
+        \item[2.13] Dateien und Fehlerbehandlung
+        \color{medgreen}
+        \item[2.14] Parameter des Hauptprogramms
+        \item[2.15] String-Operationen
+      \end{itemize}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+%      \begin{itemize}
+%        \color{red}
+%        \item[3.1] Der Präprozessor
+%        \item[3.2] Bibliotheken einbinden
+%        \item[3.3] Bibliotheken verwenden
+%        \vspace*{-\smallskipamount}
+%        \item[\dots]
+%%        \item[3.4] Projekt organisieren: make
+%      \end{itemize}
+%    \vspace*{-\smallskipamount}
+    \item[\textbf{4}] \textbf{Hardwarenahe Programmierung}
+      \begin{itemize}
+        \color{medgreen}
+        \item[4.1] Bit-Operationen
+        \item[4.2] I/O-Ports
+        \color{red}
+        \item[4.3] Interrupts
+        \vspace*{-0.1cm}
+        \item[\dots]
+      \end{itemize}
+    \item[\textbf{5}] \textbf{Algorithmen}
+    \item[\textbf{\dots}]
+  \end{itemize}
+
+\end{frame}
+
+\fi
+
+\end{document}
diff --git a/20201210/hp-musterloesung-20201210.pdf b/20201210/hp-musterloesung-20201210.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..9b53df19a21b11266eb047f91894b433218ce66f
Binary files /dev/null and b/20201210/hp-musterloesung-20201210.pdf differ
diff --git a/20201210/hp-musterloesung-20201210.tex b/20201210/hp-musterloesung-20201210.tex
new file mode 100644
index 0000000000000000000000000000000000000000..3b948f5f6cd46a811057e18e21f3bd1a1742dadb
--- /dev/null
+++ b/20201210/hp-musterloesung-20201210.tex
@@ -0,0 +1,458 @@
+% hp-musterloesung-20201114.pdf - Solutions to the 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: Ausgabe von Hexadezimalzahlen, Einfügen in Strings, Länge von Strings
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+
+\begin{document}
+
+  \section*{Hardwarenahe Programmierung\\
+            Musterlösung zu den Übungsaufgaben -- 10.\ Dezember 2020}
+
+  \exercise{Ausgabe von Hexadezimalzahlen}
+
+  Schreiben Sie eine Funktion \lstinline{void print_hex (uint32_t x)},
+  die eine gegebene vorzeichenlose 32-Bit-Ganzzahl \lstinline{x}
+  als Hexadezimalzahl ausgibt.
+  (Der Datentyp \lstinline{uint32_t} ist mit \lstinline{#include <stdint.h>} verfügbar.)
+
+  Verwenden Sie dafür \emph{nicht\/} \lstinline{printf()} mit
+  der Formatspezifikation \lstinline{%x} als fertige Lösung,
+  sondern programmieren Sie die nötige Ausgabe selbst.
+  (Für Tests ist \lstinline{%x} hingegen erlaubt und sicherlich nützlich.)
+
+  Die Verwendung von \lstinline{printf()}
+  mit anderen Formatspezifikationen wie z.\,B.\ \lstinline{%d}
+  oder \lstinline{%c} oder \lstinline{%s} ist hingegen zulässig.
+
+  \points{8}
+
+  (Hinweis für die Klausur: Abgabe auf Datenträger ist erlaubt und erwünscht,
+  aber nicht zwingend.)
+
+  \solution
+
+  Um die Ziffern von \lstinline{x} zur Basis 16 zu isolieren,
+  berechnen wir \lstinline{x % 16} (modulo 16 = Rest bei Division durch 16)
+  und dividieren anschließend \lstinline{x} durch 16,
+  solange bis \lstinline{x} den Wert 0 erreicht.
+
+  Wenn wir die auf diese Weise ermittelten Ziffern direkt ausgeben,
+  sind sie \emph{Little-Endian}, erscheinen also in umgekehrter Reihenfolge.
+  Die Datei \gitfile{hp}{20201210}{loesung-1-1.c} setzt diesen Zwischenschritt um.
+
+  Die Ausgabe der Ziffern erfolgt in \gitfile{hp}{20201210}{loesung-1-1.c}
+  über \lstinline{printf ("%d")}
+  für die Ziffern 0 bis 9. Für die darüberliegenden Ziffern
+  wird der Buchstabe \lstinline{a} um die Ziffer abzüglich 10 inkrementiert
+  und der erhaltene Wert mit \lstinline{printf ("%c")} als Zeichen ausgegeben.
+
+  Um die umgekehrte Reihenfolge zu beheben,
+  speichern wir die Ziffern von \lstinline{x}
+  in einem Array \lstinline{digits[]} zwischen
+  und geben sie anschließend in einer zweiten Schleife
+  in umgekehrter Reihenfolge aus (siehe \gitfile{hp}{20201210}{loesung-1-2.c}).
+  Da wir wissen, daß \lstinline{x} eine 32-Bit-Zahl ist
+  und daher höchstens 8 Hexadezimalziffern haben kann,
+  ist 8 eine sinnvolle Länge für das Ziffern-Array \lstinline{digits[8]}.
+
+  Nun sind die Ziffern in der richtigen Reihenfolge,
+  aber wir erhalten zusätzlich zu den eigentlichen Ziffern führende Nullen.
+  Da in der Aufgabenstellung nicht von führenden Nullen die Rede war,
+  sind diese nicht verboten; \gitfile{hp}{20201210}{loesung-1-2.c} ist daher
+  eine richtige Lösung der Aufgabe.
+
+  \breath
+
+  Wenn wir die führenden Nullen vermeiden wollen,
+  können wir die \lstinline{for}-Schleifen durch \lstinline{while}-Schleifen ersetzen.
+  Die erste Schleife zählt hoch, solange \lstinline{x} ungleich 0 ist;
+  die zweite zählt von dem erreichten Wert aus wieder herunter
+  -- siehe \gitfile{hp}{20201210}{loesung-1-3.c}.
+  Da wir wissen, daß die Zahl \lstinline{x} höchstens 32 Bit,
+  also höchstens 8 Hexadezimalziffern hat,
+  wissen wir, daß \lstinline{i} höchstens den Wert 8 erreichen kann,
+  das Array also nicht überlaufen wird.
+
+  Man beachte, daß der Array-Index nach der ersten Schleife "`um einen zu hoch"' ist.
+  In der zweiten Schleife muß daher \emph{zuerst\/} der Index dekrementiert werden.
+  Erst danach darf ein Zugriff auf \lstinline{digit[i]} erfolgen.
+
+  \breath
+
+  Alternativ können wir auch mitschreiben,
+  ob bereits eine Ziffer ungleich Null ausgegeben wurde,
+  und andernfalls die Ausgabe von Null-Ziffern unterdrücken
+  -- siehe \gitfile{hp}{20201210}{loesung-1-4.c}.
+
+  \breath
+
+  Weitere Möglichkeiten ergeben sich, wenn man bedenkt,
+  daß eine Hexadezimalziffer genau einer Gruppe von vier Binärziffern entspricht.
+  Eine Bitverschiebung um 4 nach rechts
+  ist daher dasselbe wie eine Division durch 16,
+  und eine Und-Verknüpfung mit 15$_{10}$ = f$_{16}$ = 1111$_2$
+  ist dasselbe wie die Operation Modulo 16.
+  Die Datei \gitfile{hp}{20201210}{loesung-1-5.c} ist eine in dieser Weise abgewandelte Variante
+  von \gitfile{hp}{20201210}{loesung-1-3.c}.
+
+  Mit dieser Methode kann man nicht nur auf die jeweils unterste Ziffer,
+  sondern auf alle Ziffern direkt zugreifen.
+  Damit ist kein Array als zusätzlicher Speicher mehr nötig.
+  Die Datei \gitfile{hp}{20201210}{loesung-1-6.c} setzt dies auf einfache Weise um.
+  Sie gibt wieder führende Nullen mit aus,
+  ist aber trotzdem eine weitere richtige Lösung der Aufgabe.
+
+  Die führenden Nullen ließen sich auf die gleiche Weise vermeiden
+  wie in \gitfile{hp}{20201210}{loesung-1-4.c}.
+
+  Die Bitverschiebungsmethode hat den Vorteil,
+  daß kein zusätzliches Array benötigt wird.
+  Auch wird die als Parameter übergebene Zahl \lstinline{x} nicht verändert,
+  was bei größeren Zahlen, die über Zeiger übergeben werden, von Vorteil sein kann.
+  Demgegenüber steht der Nachteil,
+  daß diese Methode nur für eine ganze Anzahl von Bits funktioniert,
+  also für Basen, die Zweierpotenzen sind (z.\,B.\ 2, 8, 16, 256).
+  Für alle anderen Basen (z.\,B.\ 10) eignet sich nur die Methode
+  mit Division und Modulo-Operation.
+
+  \exercise{Einfügen in Strings}
+
+  Wir betrachten das folgende Programm (\gitfile{hp}{20201210}{aufgabe-2.c}):
+%  \begin{lstlisting}[style=numbered]
+  \begin{lstlisting}
+    #include <stdio.h>
+    #include <string.h>
+
+    void insert_into_string (char src, char *target, int pos)
+    {
+      int len = strlen (target);
+      for (int i = pos; i < len; i++)
+        target[i+1] = target[i];
+      target[pos] = src;
+    }
+
+    int main (void)
+    {
+      char test[100] = "Hochshule Bochum";
+      insert_into_string ('c', test, 5);
+      printf ("%s\n", test);
+      return 0;
+    }
+  \end{lstlisting}
+  Die Ausgabe des Programms lautet:
+  \lstinline[style=terminal]{Hochschhhhhhhhhhh}
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      Erklären Sie, wie die Ausgabe zustandekommt.
+      \points{3}
+%      \workspace{12}
+    \item
+      Schreiben Sie die Funktion \lstinline|insert_into_string()| so um,
+      daß sie den Buchstaben \lstinline{src} an der Stelle \lstinline{pos}
+      in den String \lstinline{target} einfügt.\par
+      Die Ausgabe des Programms müßte dann
+      \lstinline[style=terminal]{Hochschule Bochum} lauten.
+      \points{2}
+%      \workspace{13}
+    \item
+      Was kann passieren, wenn Sie die Zeile
+      \lstinline{char test[100] = "Hochshule Bochum";}\\
+      durch
+      \lstinline{char test[] = "Hochshule Bochum";} ersetzen?
+      Begründen Sie Ihre Antwort.
+      \points{2}
+%      \workspace{10}
+    \item
+      Was kann passieren, wenn Sie die Zeile
+      \lstinline{char test[100] = "Hochshule Bochum";}\\
+      durch
+      \lstinline{char *test = "Hochshule Bochum";} ersetzen?
+      Begründen Sie Ihre Antwort.
+      \points{2}
+%      \workspace{10}
+%    \item
+%      Schreiben Sie eine Funktion
+%      \lstinline{void insert_into_string_sorted (char src, char *target)},
+%      die voraussetzt, daß der String \lstinline{target} alphabetisch sortiert ist
+%      und den Buchstaben \lstinline{src} an der alphabetisch richtigen Stelle
+%      einfügt. Diese Funktion darf die bereits vorhandene Funktion
+%      \lstinline|insert_into_string()| aufrufen.\\
+%      \points{4}\par
+%      Zum Testen eignen sich die folgenden Zeilen im Hauptprogramm:
+%      \begin{lstlisting}[gobble=8]
+%        char test[100] = "";
+%        insert_into_string_sorted ('c', test);
+%        insert_into_string_sorted ('a', test);
+%        insert_into_string_sorted ('d', test);
+%        insert_into_string_sorted ('b', test);
+%      \end{lstlisting}
+%      Danach sollte \lstinline{test[]} die Zeichenfolge \lstinline{"abcd"} enthalten.
+%      \workspace{14}
+%    \item
+%      Wie schnell (Landau-Symbol in Abhängigkeit von der Länge $n$ des Strings)
+%      arbeitet Ihre Funktion
+%      \lstinline{void insert_into_string_sorted (char src, char *target)}
+%      und warum?
+%      \points{1}
+%      \workspace{10}
+%    \item
+%      Beschreiben Sie -- in Worten oder als C-Quelltext --, wie man die Funktion\\
+%      \lstinline{void insert_into_string_sorted (char src, char *target)}
+%      so gestalten kann,\\
+%      daß sie in $\mathcal{O}(\log n)$ arbeitet.
+%      \points{3}
+%      \workspace{35}
+  \end{enumerate}
+
+  \solution
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      \textbf{Erklären Sie, wie die Ausgabe zustandekommt.}
+
+      In der Schleife wird \emph{zuerst\/} der nächste Buchstabe \lstinline{target[i + 1]}
+      gleich dem aktuellen gesetzt
+      und \emph{danach\/} der Zähler \lstinline{i} erhöht.
+      Dadurch wird im nächsten Schleifendurchlauf der bereits verschobene Buchstabe
+      noch weiter geschoben und letztlich alle Buchstaben in \lstinline{target[]}
+      durch den an der Stelle \lstinline{pos} ersetzt.
+
+    \item
+      \textbf{Schreiben Sie die Funktion \lstinline|insert_into_string()| so um,
+      daß sie den Buchstben \lstinline{src} an der Stelle \lstinline{pos}
+      in den String \lstinline{target} einfügt.}\par
+      \textbf{Die Ausgabe des Programms müßte dann
+      \lstinline[style=terminal]{Hochschule Bochum} lauten.}
+
+      Um im String "`Platz zu schaffen"', muß man von hinten beginnen,
+      also die Schleife umdrehen\\
+      (siehe: \gitfile{hp}{20201210}{loesung-2.c}):
+      \begin{lstlisting}{gobble=8}
+        for (int i = len; i >= pos; i--)
+          target[i + 1] = target[i];
+      \end{lstlisting}
+
+    \item
+      \textbf{Was kann passieren, wenn Sie die Zeile
+      \lstinline{char test[100] = "Hochshule Bochum";}\\
+      durch
+      \lstinline{char test[] = "Hochshule Bochum";}
+      ersetzen und warum?}
+
+      Die Schreibweise \lstinline{test[]} bedeutet,
+      daß der Compiler selbst zählt, wieviel Speicherplatz der String benötigt,
+      un dann genau die richtige Menge Speicher reserviert
+      (anstatt, wie wir es manuell getan haben, pauschal Platz für 100 Zeichen).
+
+      Wenn wir nun in den String ein zusätzliches Zeichen einfügen,
+      ist dafür kein Speicherplatz reserviert worden,
+      und wir \textbf{überschreiben} dann Speicher, an dem sich andere Variable befinden,
+      was zu einem \textbf{Absturz} führen kann.
+
+      Da wir hier nur ein einziges Zeichen schreiben,
+      wird dieser Fehler nicht sofort auffallen.
+      Dies ist schlimmer, als wenn das Programm direkt beim ersten Test abstürzt,
+      denn dadurch entsteht bei uns der Eindruck, es sei in Ordnung.
+      Wenn danach der Fehler in einer Produktivumgebung auftritt,
+      kann dadurch Schaden entstehen -- je nach Einsatzgebiet der Software
+      u.\,U.\ erheblicher Vermögens-, Sach- und/oder Personenschaden
+      (z.\,B.\ Absturz eines Raumflugkörpers).
+
+    \item
+      \textbf{Was kann passieren, wenn Sie 
+      \lstinline{char test[100] = "Hochshule Bochum";}\\
+      durch
+      \lstinline{char *test = "Hochshule Bochum";}
+      ersetzen und warum?}
+
+      In diesem Fall wird der Speicher für den eigentlichen String
+      in einem unbenannten, \textbf{nicht schreibbaren} Teil des Speichers reserviert.
+      Unser Versuch, dorthin ein zusätzliches Zeichen zu schreiben,
+      fürt dann normalerweise zu einem \textbf{Absturz}.
+
+      In manchen Systemen (Betriebssystem, Compiler, \dots)
+      ist der Speicherbereich tatsächlich sehr wohl schreibbar.
+      In diesem Fall tritt der Absturz nicht immer und nicht immer sofort auf --
+      genau wie in Aufgabenteil (c).
+     
+  \end{enumerate}
+
+  \exercise{Länge von Strings}
+
+  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{itemize}
+    \item[(a)]
+      Auf welche Weise ist die Länge eines Strings gekennzeichnet?
+      \points{1}
+    \item[(b)]
+      Wie lang ist die Beispiel-String-Konstante \lstinline{"Hello, world!\n"},
+      und wieviel Speicherplatz belegt sie?\\
+      \points{2}
+    \item[(c)]
+      Schreiben Sie eine eigene Funktion \lstinline{int strlen (char *s)},
+      die die Länge eines Strings zurückgibt.\\
+      \points{3}
+  \end{itemize}
+
+  Wir betrachten nun die folgenden Funktionen (Datei: \gitfile{hp}{20201210}{aufgabe-3.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{itemize}
+    \item[(d)]
+      Was bewirken die beiden Funktionen?
+      \points{2}
+    \item[(e)]
+%      Von welcher Ordnung (Landau-Symbol) sind die beiden Funktionen
+%      hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen im String -- und warum?
+%      Sie dürfen für \lstinline{strlen()} Ihre eigene Version der Funktion voraussetzen.
+%       \points 3
+%    \item[(f)]
+      Schreiben Sie eine eigene Funktion,
+      die dieselbe Aufgabe erledigt wie \lstinline{fun_2()},\\
+      nur effizienter.
+      \points{4}
+  \end{itemize}
+
+  \solution
+
+  \begin{itemize}
+    \item[(a)]
+      \textbf{Auf welche Weise ist die Länge eines Strings gekennzeichnet?}
+
+      Ein String ist ein Array von \lstinline{char}s.
+      Nach den eigentlichen Zeichen des Strings enthält das Array
+      \textbf{ein Null-Symbol} (Zeichen mit Zahlenwert 0,
+      nicht zu verwechseln mit der Ziffer \lstinline{'0'}) als Ende-Markierung.
+      Die Länge eines Strings ist die Anzahl der Zeichen
+      \emph{vor\/} diesem Symbol.
+
+    \item[(b)]
+      {\bf Wie lang ist die Beispiel-String-Konstante \lstinline{"Hello, world!\n"},
+      und wieviel Speicherplatz belegt sie?}
+
+      Sie ist 14 Zeichen lang (\lstinline{'\n'} ist nur 1 Zeichen;
+      das Null-Symbol, das das Ende markiert, zählt hier nicht mit)
+      und belegt Speicherplatz für 15 Zeichen
+      (15 Bytes -- einschließlich Null-Symbol / Ende-Markierung).
+
+    \item[(c)]
+      \textbf{Schreiben Sie eine eigene Funktion \lstinline{int strlen (char *s)},
+      die die Länge eines Strings zurückgibt.}
+
+      Siehe die Dateien \gitfile{hp}{20201210}{loesung-3c-1.c} (mit Array-Index)
+      und \gitfile{hp}{20201210}{loesung-3c-2.c} (mit Zeiger-Arithmetik).
+      Beide Lösungen sind korrekt und arbeiten gleich schnell.
+
+      Die Warnung \lstinline[style=terminal]{conflicting types for built-in function "strlen"}
+      kann normalerweise ignoriert werden;
+      auf manchen Systemen (z.\,B.\ MinGW) hat jedoch die eingebaute Funktion \lstinline{strlen()}
+      beim Linken Vorrang vor der selbstgeschriebenen,
+      so daß die selbstgeschriebene Funktion nie aufgerufen wird.
+      In solchen Fällen ist es zulässig, die selbstgeschriebene Funktion
+      anders zu nennen (z.\,B.\ \lstinline{my_strlen()}).
+
+    \item[(d)]
+      \textbf{Was bewirken die beiden Funktionen?}
+
+      Beide addieren die Zahlenwerte der im String enthaltenen Zeichen
+      und geben die Summe als Funktionsergebnis zurück.
+
+      Im Falle des Test-Strings \lstinline{"Hello, world!\n"}
+      lautet der Rückgabewert 1171 (siehe \gitfile{hp}{20201210}{loesung-3d-1.c} und \gitfile{hp}{20201210}{loesung-3d-2.c}).
+
+    \item[(e)]
+%      \textbf{Von welcher Ordnung (Landau-Symbol) sind die beiden Funktionen
+%      hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen im String -- und warum?
+%      Sie dürfen für \lstinline{strlen()} Ihre eigene Version der Funktion voraussetzen.}
+%
+%      Vorüberlegung: \lstinline{strlen()} greift in einer Schleife
+%      auf alle Zeichen des Strings der Länge $n$ zu,
+%      hat also $\mathcal{O}(n)$.
+%
+%      \lstinline{fun_1()} ruft in jedem Schleifendurchlauf
+%      (zum Prüfen der \lstinline{while}-Bedingung) einmal \lstinline{strlen()} auf
+%      und greift anschließend auf ein Zeichen des Strings zu,
+%      hat also $\mathcal{O}\bigl(n\cdot(n+1)\bigr) = \mathcal{O}(n^2)$.
+%
+%      \lstinline{fun_2()} ruft einmalig \lstinline{strlen()} auf
+%      und greift anschließend in einer Schleife auf alle Zeichen des Strings zu,
+%      hat also $\mathcal{O}(n+n) = \mathcal{O}(n)$.
+%
+%    \item[(f)]
+      \textbf{Schreiben Sie eine eigene Funktion,
+      die dieselbe Aufgabe erledigt wie \lstinline{fun_2()},
+      nur effizienter.}
+
+      Die Funktion wird effizienter,
+      wenn man auf den Aufruf von \lstinline{strlen()} verzichtet
+      und stattdessen die Ende-Prüfung in derselben Schleife vornimmt,
+      in der man auch die Zahlenwerte der Zeichen des Strings aufsummiert.
+
+      Die Funktion \lstinline{fun_3()} in der Datei \gitfile{hp}{20201210}{loesung-3e-1.c}
+      realisiert dies mit einem Array-Index,
+      Die Funktion \lstinline{fun_4()} in der Datei \gitfile{hp}{20201210}{loesung-3e-2.c}
+      mit Zeiger-Arithmetik.
+      Beide Lösungen sind korrekt und arbeiten gleich schnell.
+
+%      \textbf{Bemerkung:} Die effizientere Version der Funktion
+%      arbeitet doppelt so schnell wie die ursprüngliche,
+%      hat aber ebenfalls die Ordnung $\mathcal{O}(n)$.
+
+  \end{itemize}
+
+\end{document}
diff --git a/20201210/hp-uebung-20201210.pdf b/20201210/hp-uebung-20201210.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..0c97d9d304f3890dc9016e9f17898a5492a5da00
Binary files /dev/null and b/20201210/hp-uebung-20201210.pdf differ
diff --git a/20201210/hp-uebung-20201210.tex b/20201210/hp-uebung-20201210.tex
new file mode 100644
index 0000000000000000000000000000000000000000..fed8650425ab484ed374fdd943766230b2c6e761
--- /dev/null
+++ b/20201210/hp-uebung-20201210.tex
@@ -0,0 +1,227 @@
+% hp-uebung-20201210.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: Ausgabe von Hexadezimalzahlen, Einfügen in Strings, Länge von Strings
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+
+\begin{document}
+
+  \section*{Hardwarenahe Programmierung\\
+            Übungsaufgaben -- 10.\ Dezember 2020}
+
+  Diese Übung enthält Punkteangaben wie in einer Klausur.
+  Um zu "`bestehen"', müssen Sie innerhalb von 80 Minuten
+  unter Verwendung ausschließlich zugelassener Hilfsmittel
+  14 Punkte (von insgesamt \totalpoints) erreichen.
+
+  \exercise{Ausgabe von Hexadezimalzahlen}
+
+  Schreiben Sie eine Funktion \lstinline{void print_hex (uint32_t x)},
+  die eine gegebene vorzeichenlose 32-Bit-Ganzzahl \lstinline{x}
+  als Hexadezimalzahl ausgibt.
+  (Der Datentyp \lstinline{uint32_t} ist mit \lstinline{#include <stdint.h>} verfügbar.)
+
+  Verwenden Sie dafür \emph{nicht\/} \lstinline{printf()} mit
+  der Formatspezifikation \lstinline{%x} als fertige Lösung,
+  sondern programmieren Sie die nötige Ausgabe selbst.
+  (Für Tests ist \lstinline{%x} hingegen erlaubt und sicherlich nützlich.)
+
+  Die Verwendung von \lstinline{printf()}
+  mit anderen Formatspezifikationen wie z.\,B.\ \lstinline{%d}
+  oder \lstinline{%c} oder \lstinline{%s} ist hingegen zulässig.
+
+  \points{8}
+
+  (Hinweis für die Klausur: Abgabe auf Datenträger ist erlaubt und erwünscht,
+  aber nicht zwingend.)
+
+  \exercise{Einfügen in Strings}
+
+  Wir betrachten das folgende Programm (\gitfile{hp}{20201210}{aufgabe-2.c}):
+%  \begin{lstlisting}[style=numbered]
+  \begin{lstlisting}
+    #include <stdio.h>
+    #include <string.h>
+
+    void insert_into_string (char src, char *target, int pos)
+    {
+      int len = strlen (target);
+      for (int i = pos; i < len; i++)
+        target[i+1] = target[i];
+      target[pos] = src;
+    }
+
+    int main (void)
+    {
+      char test[100] = "Hochshule Bochum";
+      insert_into_string ('c', test, 5);
+      printf ("%s\n", test);
+      return 0;
+    }
+  \end{lstlisting}
+  Die Ausgabe des Programms lautet:
+  \lstinline[style=terminal]{Hochschhhhhhhhhhh}
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      Erklären Sie, wie die Ausgabe zustandekommt.
+      \points{3}
+%      \workspace{12}
+    \item
+      Schreiben Sie die Funktion \lstinline|insert_into_string()| so um,
+      daß sie den Buchstaben \lstinline{src} an der Stelle \lstinline{pos}
+      in den String \lstinline{target} einfügt.\par
+      Die Ausgabe des Programms müßte dann
+      \lstinline[style=terminal]{Hochschule Bochum} lauten.
+      \points{2}
+%      \workspace{13}
+    \item
+      Was kann passieren, wenn Sie die Zeile
+      \lstinline{char test[100] = "Hochshule Bochum";}\\
+      durch
+      \lstinline{char test[] = "Hochshule Bochum";} ersetzen?
+      Begründen Sie Ihre Antwort.
+      \points{2}
+%      \workspace{10}
+    \item
+      Was kann passieren, wenn Sie die Zeile
+      \lstinline{char test[100] = "Hochshule Bochum";}\\
+      durch
+      \lstinline{char *test = "Hochshule Bochum";} ersetzen?
+      Begründen Sie Ihre Antwort.
+      \points{2}
+%      \workspace{10}
+%    \item
+%      Schreiben Sie eine Funktion
+%      \lstinline{void insert_into_string_sorted (char src, char *target)},
+%      die voraussetzt, daß der String \lstinline{target} alphabetisch sortiert ist
+%      und den Buchstaben \lstinline{src} an der alphabetisch richtigen Stelle
+%      einfügt. Diese Funktion darf die bereits vorhandene Funktion
+%      \lstinline|insert_into_string()| aufrufen.\\
+%      \points{4}\par
+%      Zum Testen eignen sich die folgenden Zeilen im Hauptprogramm:
+%      \begin{lstlisting}[gobble=8]
+%        char test[100] = "";
+%        insert_into_string_sorted ('c', test);
+%        insert_into_string_sorted ('a', test);
+%        insert_into_string_sorted ('d', test);
+%        insert_into_string_sorted ('b', test);
+%      \end{lstlisting}
+%      Danach sollte \lstinline{test[]} die Zeichenfolge \lstinline{"abcd"} enthalten.
+%      \workspace{14}
+%    \item
+%      Wie schnell (Landau-Symbol in Abhängigkeit von der Länge $n$ des Strings)
+%      arbeitet Ihre Funktion
+%      \lstinline{void insert_into_string_sorted (char src, char *target)}
+%      und warum?
+%      \points{1}
+%      \workspace{10}
+%    \item
+%      Beschreiben Sie -- in Worten oder als C-Quelltext --, wie man die Funktion\\
+%      \lstinline{void insert_into_string_sorted (char src, char *target)}
+%      so gestalten kann,\\
+%      daß sie in $\mathcal{O}(\log n)$ arbeitet.
+%      \points{3}
+%      \workspace{35}
+  \end{enumerate}
+
+  \exercise{Länge von Strings}
+
+  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{itemize}
+    \item[(a)]
+      Auf welche Weise ist die Länge eines Strings gekennzeichnet?
+      \points{1}
+    \item[(b)]
+      Wie lang ist die Beispiel-String-Konstante \lstinline{"Hello, world!\n"},
+      und wieviel Speicherplatz belegt sie?\\
+      \points{2}
+    \item[(c)]
+      Schreiben Sie eine eigene Funktion \lstinline{int strlen (char *s)},
+      die die Länge eines Strings zurückgibt.\\
+      \points{3}
+  \end{itemize}
+
+  Wir betrachten nun die folgenden Funktionen (Datei: \gitfile{hp}{20201210}{aufgabe-3.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{itemize}
+    \item[(d)]
+      Was bewirken die beiden Funktionen?
+      \points{2}
+    \item[(e)]
+%      Von welcher Ordnung (Landau-Symbol) sind die beiden Funktionen
+%      hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen im String -- und warum?
+%      Sie dürfen für \lstinline{strlen()} Ihre eigene Version der Funktion voraussetzen.
+%       \points 3
+%    \item[(f)]
+      Schreiben Sie eine eigene Funktion,
+      die dieselbe Aufgabe erledigt wie \lstinline{fun_2()},\\
+      nur effizienter.
+      \points{4}
+  \end{itemize}
+
+  \bigskip
+
+  \begin{flushright}
+    \textit{Viel Erfolg!}
+  \end{flushright}
+
+  \makeatletter
+    \immediate\write\@mainaux{\string\gdef\string\totalpoints{\arabic{points}}}
+  \makeatother
+
+\end{document}
diff --git a/20201210/loesung-1-1.c b/20201210/loesung-1-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..98b2f03f19d21aa2a794fef1f3f98feff95f5142
--- /dev/null
+++ b/20201210/loesung-1-1.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <stdint.h>
+
+void print_hex (uint32_t x)
+{
+  while (x)
+    {
+      int digit = x % 16;
+      if (digit < 10)
+        printf ("%d", digit);
+      else
+        printf ("%c", 'a' + digit - 10);
+      x /= 16;
+    }
+}
+
+int main (void)
+{
+  print_hex (0xcafe42);
+  printf ("\n");
+  return 0;
+}
diff --git a/20201210/loesung-1-2.c b/20201210/loesung-1-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..35aa3b3aea6fc8faaa55c7d5382f0a8de9282aee
--- /dev/null
+++ b/20201210/loesung-1-2.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <stdint.h>
+
+void print_hex (uint32_t x)
+{
+  char digit[8];
+  for (int i = 0; i < 8; i++)
+    {
+      digit[i] = x % 16;
+      x /= 16;
+    }
+  for (int i = 7; i >= 0; i--)
+    {
+      if (digit[i] < 10)
+        printf ("%d", digit[i]);
+      else
+        printf ("%c", 'a' + digit[i] - 10);
+    }
+}
+
+int main (void)
+{
+  print_hex (0xcafe42);
+  printf ("\n");
+  return 0;
+}
diff --git a/20201210/loesung-1-3.c b/20201210/loesung-1-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..2462f2b537896722d8d1774a5d47f374ee5ef7fa
--- /dev/null
+++ b/20201210/loesung-1-3.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <stdint.h>
+
+void print_hex (uint32_t x)
+{
+  char digit[8];
+  int i = 0;
+  while (x)
+    {
+      digit[i] = x % 16;
+      x /= 16;
+      i++;
+    }
+  while (i > 0)
+    {
+      i--;
+      if (digit[i] < 10)
+        printf ("%d", digit[i]);
+      else
+        printf ("%c", 'a' + digit[i] - 10);
+    }
+}
+
+int main (void)
+{
+  print_hex (0xcafe42);
+  printf ("\n");
+  return 0;
+}
diff --git a/20201210/loesung-1-4.c b/20201210/loesung-1-4.c
new file mode 100644
index 0000000000000000000000000000000000000000..5083dcb865c86beafd43ce3e8837510b13cbe850
--- /dev/null
+++ b/20201210/loesung-1-4.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <stdint.h>
+
+void print_hex (uint32_t x)
+{
+  char digit[8];
+  for (int i = 0; i < 8; i++)
+    {
+      digit[i] = x % 16;
+      x /= 16;
+    }
+  int printing = 0;
+  for (int i = 7; i >= 0; i--)
+    {
+      if (printing || digit[i] != 0)
+        {
+          printing = 1;
+          if (digit[i] < 10)
+            printf ("%d", digit[i]);
+          else
+            printf ("%c", 'a' + digit[i] - 10);
+        }
+    }
+}
+
+int main (void)
+{
+  print_hex (0xcafe42);
+  printf ("\n");
+  return 0;
+}
diff --git a/20201210/loesung-1-5.c b/20201210/loesung-1-5.c
new file mode 100644
index 0000000000000000000000000000000000000000..e3446edb4a40348ac14da420f344c208f8916f7e
--- /dev/null
+++ b/20201210/loesung-1-5.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <stdint.h>
+
+void print_hex (uint32_t x)
+{
+  char digit[8];
+  int i = 0;
+  while (x)
+    {
+      digit[i] = x & 0x0000000f;
+      x >>= 4;
+      i++;
+    }
+  while (i > 0)
+    {
+      i--;
+      if (digit[i] < 10)
+        printf ("%d", digit[i]);
+      else
+        printf ("%c", 'a' + digit[i] - 10);
+    }
+}
+
+int main (void)
+{
+  print_hex (0xcafe42);
+  printf ("\n");
+  return 0;
+}
diff --git a/20201210/loesung-1-6.c b/20201210/loesung-1-6.c
new file mode 100644
index 0000000000000000000000000000000000000000..7b8e8e1a9d7285b8a1e02ff1a91310f1dc02ed5b
--- /dev/null
+++ b/20201210/loesung-1-6.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <stdint.h>
+
+void print_hex (uint32_t x)
+{
+  int i = 32;
+  while (i > 0)
+    {
+      i -= 4;
+      int digit = (x >> i) & 0x0000000f;
+      if (digit < 10)
+        printf ("%d", digit);
+      else
+        printf ("%c", 'a' + digit - 10);
+    }
+}
+
+int main (void)
+{
+  print_hex (0xcafe42);
+  printf ("\n");
+  return 0;
+}
diff --git a/20201210/loesung-2.c b/20201210/loesung-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..85abfcf3e1e4bacf454acd10f6832b757a64ac35
--- /dev/null
+++ b/20201210/loesung-2.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <string.h>
+
+void insert_into_string (char src, char *target, int pos)
+{
+  int len = strlen (target);
+  for (int i = len; i >= pos; i--)
+    target[i + 1] = target[i];
+  target[pos] = src;
+}
+
+int main (void)
+{
+  char test[100] = "Hochshule Bochum";
+  insert_into_string ('c', test, 5);
+  printf ("%s\n", test);
+  return 0;
+}
diff --git a/20201210/loesung-3c-1.c b/20201210/loesung-3c-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..69ddd0e4e749f6ca31bfa3d4f929c333648ef6ea
--- /dev/null
+++ b/20201210/loesung-3c-1.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int strlen (char *s)
+{
+  int l = 0;
+  while (s[l])
+    l++;
+  return l;
+}
+
+int main (void)
+{
+  printf ("%d\n", strlen ("Hello, world!\n"));
+  return 0;
+}
diff --git a/20201210/loesung-3c-2.c b/20201210/loesung-3c-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..e783c474e485e80d08a6e86f8ae6e179f5a294f4
--- /dev/null
+++ b/20201210/loesung-3c-2.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int strlen (char *s)
+{
+  char *s0 = s;
+  while (*s)
+    s++;
+  return s - s0;
+}
+
+int main (void)
+{
+  printf ("%d\n", strlen ("Hello, world!\n"));
+  return 0;
+}
diff --git a/20201210/loesung-3d-1.c b/20201210/loesung-3d-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..57521382c21fb743c6f5f5c65320bc4ac9360b1a
--- /dev/null
+++ b/20201210/loesung-3d-1.c
@@ -0,0 +1,34 @@
+
+#include <stdio.h>
+
+int strlen (char *s)
+{
+  int l = 0;
+  while (s[l])
+    l++;
+  return l;
+}
+
+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;
+}
+
+int main (void)
+{
+  printf ("%d\n", fun_1 ("Hello, world!\n"));
+  printf ("%d\n", fun_2 ("Hello, world!\n"));
+  return 0;
+}
diff --git a/20201210/loesung-3d-2.c b/20201210/loesung-3d-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..5f3f0961129aa16fc9c4510ae21bb77b69913b12
--- /dev/null
+++ b/20201210/loesung-3d-2.c
@@ -0,0 +1,34 @@
+
+#include <stdio.h>
+
+int strlen (char *s)
+{
+  char *s0 = s;
+  while (*s)
+    s++;
+  return s - s0;
+}
+
+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;
+}
+
+int main (void)
+{
+  printf ("%d\n", fun_1 ("Hello, world!\n"));
+  printf ("%d\n", fun_2 ("Hello, world!\n"));
+  return 0;
+}
diff --git a/20201210/loesung-3e-1.c b/20201210/loesung-3e-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..74f5add0c5f62cccb8f817d40f860893f496db11
--- /dev/null
+++ b/20201210/loesung-3e-1.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int fun_3 (char *s)
+{
+  int i = 0, x = 0;
+  while (s[i])
+    x += s[i++];
+  return x;
+}
+
+int main (void)
+{
+  printf ("%d\n", fun_3 ("Hello, world!\n"));
+  return 0;
+}
diff --git a/20201210/loesung-3e-2.c b/20201210/loesung-3e-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..b223d2d17c261d7cf1373a8379def8911a45ccb7
--- /dev/null
+++ b/20201210/loesung-3e-2.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int fun_4 (char *s)
+{
+  int x = 0;
+  while (*s)
+    x += *s++;
+  return x;
+}
+
+int main (void)
+{
+  printf ("%d\n", fun_4 ("Hello, world!\n"));
+  return 0;
+}
diff --git a/20201210/logo-hochschule-bochum-cvh-text-v2.pdf b/20201210/logo-hochschule-bochum-cvh-text-v2.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..4aa99b8f81061aca6dcaf43eed2d9efef40555f8
--- /dev/null
+++ b/20201210/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/20201210/logo-hochschule-bochum.pdf b/20201210/logo-hochschule-bochum.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1
--- /dev/null
+++ b/20201210/logo-hochschule-bochum.pdf
@@ -0,0 +1 @@
+../common/logo-hochschule-bochum.pdf
\ No newline at end of file
diff --git a/20201210/pendulum.pdf b/20201210/pendulum.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..7d1d87305cdb8840a248ff2207538d758464f452
--- /dev/null
+++ b/20201210/pendulum.pdf
@@ -0,0 +1 @@
+../common/pendulum.pdf
\ No newline at end of file
diff --git a/20201210/pgscript.sty b/20201210/pgscript.sty
new file mode 120000
index 0000000000000000000000000000000000000000..95c888478c99ea7fda0fd11ccf669ae91be7178b
--- /dev/null
+++ b/20201210/pgscript.sty
@@ -0,0 +1 @@
+../common/pgscript.sty
\ No newline at end of file
diff --git a/20201210/pgslides.sty b/20201210/pgslides.sty
new file mode 120000
index 0000000000000000000000000000000000000000..5be1416f4216f076aa268901f52a15d775e43f64
--- /dev/null
+++ b/20201210/pgslides.sty
@@ -0,0 +1 @@
+../common/pgslides.sty
\ No newline at end of file