diff --git a/20201126/aufgabe-2-1.c b/20201126/aufgabe-2-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..e56af8cdd1c1abcac992605475472612878b786d
--- /dev/null
+++ b/20201126/aufgabe-2-1.c
@@ -0,0 +1,6 @@
+char *f = "char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";
+
+main ()
+{
+  printf (f, 34, f, 34, 10);
+}
diff --git a/20201126/aufgabe-2-2.c b/20201126/aufgabe-2-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..9d3e005456a7316340a5c5d404e7d6f911487771
--- /dev/null
+++ b/20201126/aufgabe-2-2.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+char *f = "char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";
+
+int main (void)
+{
+  printf (f, 34, f, 34, 10);
+  return 0;
+}
diff --git a/20201203/aufgabe-1.c b/20201203/aufgabe-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..632b4b796ae2f4060878a8870b9e7e55e5f064b9
--- /dev/null
+++ b/20201203/aufgabe-1.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+void f (int *s0, int *s1)
+{
+  while (*s0 >= 0)
+  {
+    int *s = s1;
+    while (*s >= 0)
+      if (*s0 == *s++)
+        printf ("%d ", *s0);
+    s0++;
+  }
+  printf ("\n");
+}
+
+int main (void)
+{
+  int a[] = { 10, 4, 3, 7, 12, 0, 1, -1 };
+  int b[] = { 7, 14, 0, 8, 9, 22, 10, -1 };
+  f (a, b);
+  return 0;
+}
diff --git a/20201203/aufgabe-1c.c b/20201203/aufgabe-1c.c
new file mode 100644
index 0000000000000000000000000000000000000000..9b6e7ab2ecfbddc16121acd229a13745182190c2
--- /dev/null
+++ b/20201203/aufgabe-1c.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+void f (int *s0, int *s1)
+{
+  while (*s0 >= 0)
+  {
+    int *s = s1;
+    while (*s >= 0)
+      if (*s0 == *s++)
+        printf ("%d ", *s0);
+    s0++;
+  }
+  printf ("\n");
+}
+
+int main (void)
+{
+  int a[] = { 10, 4, 3, 7, 12, 0, 1 };
+  int b[] = { 7, 14, 0, 8, 9, 22, 10 };
+  f (a, b);
+  return 0;
+}
diff --git a/20201203/functions-1.c b/20201203/functions-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..306c83a358fa5cae65e0fde2c2a5aecbbdab17a0
--- /dev/null
+++ b/20201203/functions-1.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+void print (x)
+  int x;
+{
+  printf ("%d\n", x);
+}
+
+int main (void)
+{
+  print (42);
+  return 0;
+}
diff --git a/20201203/functions-2.c b/20201203/functions-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..135f7b3dd22e34a71fdfbc9b1f2cb971fda1f2f7
--- /dev/null
+++ b/20201203/functions-2.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+void print (x)
+  int x;
+{
+  printf ("%d\n", x);
+}
+
+int main (void)
+{
+  print ("42");
+  return 0;
+}
diff --git a/20201203/functions-3.c b/20201203/functions-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..0522e8744ee5d3fe18f7acaaa192e2e052fed81b
--- /dev/null
+++ b/20201203/functions-3.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+void print (x)
+  int x;
+{
+  printf ("%d\n", x);
+}
+
+int main (void)
+{
+  print (atoi ("42"));
+  return 0;
+}
diff --git a/20201203/functions-4.c b/20201203/functions-4.c
new file mode 100644
index 0000000000000000000000000000000000000000..af1d7f7407daebed1373459b8e9a2dd0811f49de
--- /dev/null
+++ b/20201203/functions-4.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+void print (int x)
+{
+  printf ("%d\n", x);
+}
+
+int main (void)
+{
+  print ("42");
+  return 0;
+}
diff --git a/20201203/hp-20201203.pdf b/20201203/hp-20201203.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..948e12d4eb4873f183ef5bd3b35bc11874917928
Binary files /dev/null and b/20201203/hp-20201203.pdf differ
diff --git a/20201203/hp-20201203.tex b/20201203/hp-20201203.tex
new file mode 100644
index 0000000000000000000000000000000000000000..a0f77f82e2d55c574407ee2e2364dae9a255e45b
--- /dev/null
+++ b/20201203/hp-20201203.tex
@@ -0,0 +1,1788 @@
+% hp-20201203.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{3.\ 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.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}
+    \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}{10}
+\subsection{Arrays und Strings}
+
+\begin{frame}[fragile]
+  \showsubsection
+
+  Ein Zeiger zeigt auf eine Variable\only<1->{ und deren Nachbarn}.
+
+%  \bigskip
+%  \pause
+%  \pause
+
+  \begin{onlyenv}<1>
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      int main (void)
+      {
+        int prime[5] = { 2, 3, 5, 7, 11 };
+        int *p = prime;
+        for (int i = 0; i < 5; i++)
+          printf ("%d\n", *(p + i));
+        return 0;
+      }
+    \end{lstlisting}
+  \end{onlyenv}
+  \begin{onlyenv}<2>
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      int main (void)
+      {
+        int prime[5] = { 2, 3, 5, 7, 11 };
+        int *p = prime;
+        for (int i = 0; i < 5; i++)
+          printf ("%d\n", p[i]);
+        return 0;
+      }
+    \end{lstlisting}
+  \end{onlyenv}
+  \begin{onlyenv}<3>
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      int main (void)
+      {
+        int prime[5] = { 2, 3, 5, 7, 11 };
+        for (int i = 0; i < 5; i++)
+          printf ("%d\n", prime[i]);
+        return 0;
+      }
+      ¡ ¿
+    \end{lstlisting}
+  \end{onlyenv}
+  \begin{onlyenv}<4>
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      int main (void)
+      {
+        int prime[5] = { 2, 3, 5, 7, 11 };
+        for (int *p = prime;
+             p < prime + 5; p++)
+          printf ("%d\n", *p);
+        return 0;
+      }
+    \end{lstlisting}
+  \end{onlyenv}
+  \begin{onlyenv}<5>
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      int main (void)
+      {
+        int prime[6] = { 2, 3, 5, 7, 11, 0 };
+        for (int *p = prime; *p; p++)
+          printf ("%d\n", *p);
+        return 0;
+      }
+      ¡ ¿
+    \end{lstlisting}
+  \end{onlyenv}
+  \begin{onlyenv}<6->
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      int main (void)
+      {
+        int prime[] = { 2, 3, 5, 7, 11, 0 };
+        for (int *p = prime; *p; p++)
+          printf ("%d\n", *p);
+        return 0;
+      }
+      ¡ ¿
+    \end{lstlisting}
+  \end{onlyenv}
+
+%  \pause
+  \vspace{-3.05cm}\hspace{5.5cm}%
+  \begin{minipage}{6.5cm}
+    \begin{itemize}
+      \item
+        \lstinline{prime} ist \alt<1->{ein Array}{eine Ansammlung} von\\fünf ganzen Zahlen.
+%      \pause
+%      \pause
+      \item
+        \only<1-2>{\begin{picture}(0,0)
+          \color{red}
+          \put(-1.6,0.1){\tikz{\draw[-latex](0.0,0.0)--(-1,0);}}
+        \end{picture}}%
+        \lstinline{prime} ist ein Zeiger auf eine \lstinline{int}.
+%      \pause
+      \item
+        \lstinline{p + i} ist ein Zeiger\\
+        auf den \lstinline{i}-ten Nachbarn von \lstinline{*p}.
+%      \pause
+      \item
+        \lstinline{*(p + i)} ist der \lstinline{i}-te Nachbar von \lstinline{*p}.
+      \pause
+      \item
+        Andere Schreibweise:\\
+        \lstinline{p[i]} statt \lstinline{*(p + i)}
+      \pause
+      \pause
+      \item
+        Zeiger-Arithmetik:\\
+        \lstinline{p++} rückt den Zeiger \lstinline{p}\\
+        um eine \lstinline{int} weiter.
+      \pause
+      \pause
+      \item
+        Array ohne \only<1->{explizite }Längenangabe:\\
+        Compiler zählt selbst
+        \vspace*{-1cm}
+%        \pause
+        \begin{picture}(0,0)
+          \put(-5.2,1.0){\makebox(0,0)[br]{\color{red}\bf\shortstack{Die Länge des Arrays\\ist \emph{nicht\/} veränderlich!}}}
+        \end{picture}
+    \end{itemize}
+  \end{minipage}
+\end{frame}
+
+% \begin{frame}[fragile]
+%   \showsubsection
+% 
+%   \begin{lstlisting}
+%     #include <stdio.h>
+% 
+%     int main (void)
+%     {
+%       char hello_world[] = "Hello, world!\n";
+%       int i = 0;
+%       while (hello_world[i] != 0)
+%         printf ("%d", hello_world[i++]);
+%       return 0;
+%     }
+%   \end{lstlisting}
+% \end{frame}
+
+% \begin{frame}[fragile]
+%   \showsubsection
+% 
+%   \begin{lstlisting}
+%     #include <stdio.h>
+% 
+%     int main (void)
+%     {
+%       char hello_world[] = "Hello, world!\n";
+%       int i = 0;
+%       while (hello_world[i])
+%         printf ("%d", hello_world[i++]);
+%       return 0;
+%     }
+%   \end{lstlisting}
+% \end{frame}
+
+% \begin{frame}[fragile]
+%   \showsubsection
+% 
+%   \begin{lstlisting}
+%     #include <stdio.h>
+% 
+%     int main (void)
+%     {
+%       char hello_world[] = "Hello, world!\n";
+%       char *p = hello_world;
+%       while (*p)
+%         printf ("%c", *p++);
+%       return 0;
+%     }
+%   \end{lstlisting}
+% \end{frame}
+
+\begin{frame}[fragile]
+  \showsubsection
+
+  \begin{onlyenv}<1>
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      int main (void)
+      {
+        char hello[] = "Hello, world!\n";
+        for (char *p = hello; *p; p++)
+          printf ("%d", *p);
+        return 0;
+      }
+    \end{lstlisting}
+  \end{onlyenv}
+  \begin{onlyenv}<2>
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      int main (void)
+      {
+        char hello[] = "Hello, world!\n";
+        for (char *p = hello; *p; p++)
+          printf ("%c", *p);
+        return 0;
+      }
+    \end{lstlisting}
+  \end{onlyenv}
+  \begin{onlyenv}<3>
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      int main (void)
+      {
+        char hello[] = "Hello, world!\n";
+        printf ("%s", hello);
+        return 0;
+      }
+      ¡ ¿
+    \end{lstlisting}
+  \end{onlyenv}
+  \begin{onlyenv}<4>
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      int main (void)
+      {
+        char *hello = "Hello, world!\n";
+        printf ("%s", hello);
+        return 0;
+      }
+      ¡ ¿
+    \end{lstlisting}
+  \end{onlyenv}
+%  \begin{onlyenv}<5>
+%    \begin{lstlisting}[gobble=6]
+%      #include <stdio.h>
+%
+%      int main (void)
+%      {
+%        char *hello = "Hello, world!\n";
+%        while (*hello)
+%          printf ("%c", *hello++);
+%        return 0;
+%      }
+%    \end{lstlisting}
+%  \end{onlyenv}
+
+  \vspace{-2.5cm}\hfill
+  \begin{minipage}{6.8cm}
+    \begin{itemize}
+%      \pause[2]
+      \item
+        Ein \lstinline{char} ist eine kleinere \lstinline{int}.
+%      \pause
+      \item
+        Ein "`String"' in C ist ein Array von \lstinline{char}s\only<1->{,\\
+        also ein Zeiger auf \lstinline{char}s}\only<1->{\\
+        also ein Zeiger auf (kleinere) Integer}.
+%      \pause
+%      \pause
+%      \pause
+      \item
+        Der letzte \lstinline{char} muß 0 sein.\\
+        Er kennzeichnet das Ende des Strings.
+      \pause
+      \item
+        Die Formatspezifikation\\
+        entscheidet über die Ausgabe:\\[\smallskipamount]
+        \begin{tabular}{ll}
+          \lstinline|%d|\hspace*{0.5em}dezimal
+            & \lstinline|%c|\hspace*{0.5em}Zeichen\\
+          \lstinline|%x|\hspace*{0.5em}hexadezimal
+            \pause
+            & \lstinline|%s|\hspace*{0.5em}String
+        \end{tabular}
+        \vspace*{-1cm}
+    \end{itemize}
+  \end{minipage}
+\end{frame}
+
+\addtocounter{subsection}{-1}
+\subsection{Arrays und Strings \protect\color{gray}und Zeichen}
+
+\begin{frame}[fragile]
+  \showsubsection
+
+  \emph{"`Alles ist Zahl."'\/} -- Schule der Pythagoreer, 6.\ Jh.\ v.\,Chr.
+
+  \medskip
+
+  \begin{center}
+    \renewcommand{\arraystretch}{1.5}
+    \begin{tabular}{r}
+      \lstinline|"Hello"|\\
+      \lstinline|'H'|\\
+      \lstinline|'a' + 4|
+    \end{tabular}
+    \renewcommand{\arraystretch}{1.0}
+    \begin{tabular}{c}
+      ist nur eine andere\\
+      Schreibweise für
+    \end{tabular}
+    \renewcommand{\arraystretch}{1.5}
+    \begin{tabular}{l}
+      \lstinline|{ 72, 101, 108, 108, 111, 0 }|\\
+      \lstinline|72|\\
+      \lstinline|'e'|
+    \end{tabular}
+    \renewcommand{\arraystretch}{1.0}
+  \end{center}
+
+  \begin{itemize}
+    \item
+      Welchen Zahlenwert hat \lstinline{'*'} im Zeichensatz (normalerweise: ASCII)?\\
+      Welches Zeichen entspricht dem Zahlenwert \lstinline{71}?
+      \begin{lstlisting}[gobble=8]
+        printf ("%d\n", '*');
+        printf ("%c\n", 71);
+      \end{lstlisting}
+    \medskip
+    \item
+      Ist \lstinline{char ch} ein Großbuchstabe?
+      \begin{lstlisting}[gobble=8]
+        if (ch >= 'A' && ch <= 'Z')
+          ...
+      \end{lstlisting}
+    \smallskip
+    \item
+      Groß- in Kleinbuchstaben umwandeln
+      \begin{lstlisting}[gobble=8]
+        ch += 'a' - 'A';
+      \end{lstlisting}
+  \end{itemize}
+  \vspace*{-1cm}
+\end{frame}
+
+\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}
+
+\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}
+
+\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}
+
+\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}
+
+\setcounter{section}{4}
+\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/20201203/hp-musterloesung-20201203.pdf b/20201203/hp-musterloesung-20201203.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..34f30286f7f0c2c98370411f33447737c8938a63
Binary files /dev/null and b/20201203/hp-musterloesung-20201203.pdf differ
diff --git a/20201203/hp-musterloesung-20201203.tex b/20201203/hp-musterloesung-20201203.tex
new file mode 100644
index 0000000000000000000000000000000000000000..e93adefdc7bdf7eba6d775e7a615d6d924a1bf68
--- /dev/null
+++ b/20201203/hp-musterloesung-20201203.tex
@@ -0,0 +1,212 @@
+% hp-musterloesung-20201203.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: Arrays mit Zahlen, Datum-Bibliothek
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+
+\begin{document}
+
+  \section*{Hardwarenahe Programmierung\\
+            Musterlösung zu den Übungsaufgaben -- 3.\ Dezember 2020}
+
+  \exercise{Arrays mit Zahlen}
+
+  \begin{minipage}[t]{0.4\textwidth}
+    Wir betrachten das folgende Programm\\
+    (Datei: \gitfile{hp}{20201203}{aufgabe-1.c}):
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      void f (int *s0, int *s1)
+      {
+        while (*s0 >= 0)
+        {
+          int *s = s1;
+          while (*s >= 0)
+            if (*s0 == *s++)
+              printf ("%d ", *s0);
+          s0++;
+        }
+        printf ("\n");
+      }
+
+      int main (void)
+      {
+        int a[] = { 10, 4, 3, 7, 12, 0, 1, -1 };
+        int b[] = { 7, 14, 0, 8, 9, 22, 10, -1 };
+        f (a, b);
+        return 0;
+      }
+    \end{lstlisting}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{0.55\textwidth}
+    \vspace*{-\bigskipamount}
+    \begin{enumerate}[\quad(a)]
+      \item
+        Was bewirkt die Funktion \lstinline{f},\\
+        und wie funktioniert sie?
+        \points{4}
+%      \item
+%        Von welcher Ordnung (Landau-Symbol) ist die Funktion?
+%        Begründen Sie Ihre Antwort.
+%
+%        Wir beziehen uns hierbei auf die Anzahl der Vergleiche
+%        in Abhängigkeit von der Länge der Eingabedaten \lstinline{s0} und \lstinline{s1}.
+%        Für die Rechnung dürfen Sie beide Längen mit $n$ gleichsetzen,
+%        obwohl sie normalerweise nicht gleich sind.
+%        \points{2}
+      \item
+        Was passiert, wenn Sie beim Aufruf der Funktion für einen der
+        Parameter den Wert \lstinline{NULL} übergeben?
+        Begründen Sie Ihre Antwort.
+        \points{2}
+      \item
+        Was kann passieren, wenn Sie das Hauptprogramm wie folgt abändern
+        (\gitfile{hp}{20201203}{aufgabe-1c.c})?
+        Begründen Sie Ihre Antwort.
+        \begin{lstlisting}[gobble=8]
+          int main (void)
+          {
+            int a[] = { 10, 4, 3, 7, 12, 0, 1 };
+            int b[] = { 7, 14, 0, 8, 9, 22, 10 };
+            f (a, b);
+            return 0;
+          }
+        \end{lstlisting}
+        \points{2}
+%      \item
+%        Beschreiben Sie -- in Worten und/oder als C-Quelltext --, wie
+%        sich die Funktion \lstinline{f} effizienter gestalten läßt,
+%        wenn man die ihr übergebenen Arrays \lstinline{s0} und
+%        \lstinline{s1} als sortiert voraussetzt.
+%        \points{5}
+%
+%        Hinweis: Wie würden Sie als Mensch die Aufgabe erledigen?
+%      \item
+%        Von welcher
+%        Ordnung (Landau-Symbol) ist Ihre effizientere Version der Funktion und warum?
+%        \points{2}
+    \end{enumerate}
+  \end{minipage}
+
+  \solution
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      \textbf{Was bewirkt die Funktion \lstinline{f}, und wie funktioniert sie?}
+
+      Die Funktion gibt alle Zahlen aus, die sowohl im Array \lstinline{s0}
+      als auch im Array \lstinline{s1} vorkommen (Schnittmenge).
+
+      Dies geschieht, indem der Zeiger \lstinline{s0} das gesamte Array durchläuft
+      (äußere Schleife).
+      Für jedes Element des ersten Arrays durchläuft der Zeiger \lstinline{s}
+      das gesamte zweite Array (innere Schleife).
+      Auf diese Weise wird jedes Element von \lstinline{s0}
+      mit jedem von \lstinline{s1} verglichen und bei Gleichheit ausgegeben.
+
+      Um die Schleifen abbrechen zu können, enthalten beide Arrays
+      als Ende-Markierung eine negative Zahl (\lstinline{-1}).
+
+    \item
+      \textbf{Was passiert, wenn Sie beim Aufruf der Funktion für einen der
+      Parameter den Wert \lstinline{NULL} übergeben?
+      Begründen Sie Ihre Antwort.}
+
+      In dem Moment, wo auf den jeweiligen Parameter-Zeiger zugegriffen wird
+      (\lstinline{while (*s0 >= 0)} für \lstinline{s0} bzw.\
+      \lstinline{int *s = s1; while (*s >= 0)} für \lstinline{s1}),
+      kommt es zu einem Absturz (Speicherzugriffsfehler).
+      Die Dereferenzierung eines Zeigers mit dem Wert \lstinline{NULL}
+      ist nicht zulässig.
+
+    \item
+      \textbf{Was kann passieren, wenn Sie das Hauptprogramm wie folgt abändern
+      (\gitfile{hp}{20201203}{aufgabe-1c.c})?
+      Begründen Sie Ihre Antwort.}
+
+      \begin{minipage}{0.35\textwidth}
+        \begin{lstlisting}[gobble=10]
+          int main (void)
+          {
+            int a[] = { 10, 4, 3, 7, 12, 0, 1 };
+            int b[] = { 7, 14, 0, 8, 9, 22, 10 };
+            f (a, b);
+            return 0;
+          }
+        \end{lstlisting}
+      \end{minipage}\hfill
+      \begin{minipage}{0.575\textwidth}
+        Durch die fehlenden Ende-Markierungen der Arrays
+        laufen die Schleifen immer weiter,
+        bis sie irgendwann zufällig auf Speicherzellen stoßen,
+        die sich als Ende-Markierungen interpretieren lassen (negative Zahlen).
+        Dadurch kann es zu einem Lesezugriff auf Speicher kommen,
+        für den das Programm kein Lesezugriffsrecht hat,
+        also zu einem Absturz (Speicherzugriffsfehler).
+      \end{minipage}
+  \end{enumerate}
+
+  \exercise{Datum-Bibliothek}
+
+  Schreiben Sie eine Bibliothek (= Sammlung von Deklarationen und Funktionen)
+  zur Behandlung von Datumsangaben.
+
+  Diese soll enthalten:
+  \begin{itemize}
+    \item
+      einen \lstinline{struct}-Datentyp \lstinline{date},
+      der eine Datumsangabe speichert,
+    \item
+      eine Funktion \lstinline{void date_print (date *d)}, die ein Datum ausgibt,
+    \item
+      eine Funktion \lstinline{int date_set (date *d, int day, int month, int year)},
+      die ein Datum auf einen gegebenen Tag setzt
+      und zurückgibt, ob es sich um ein gültiges Datum handelt (0 = nein, 1 = ja),
+    \item
+      eine Funktion \lstinline{void date_next (date *d)},
+      die ein Datum auf den nächsten Tag vorrückt.
+  \end{itemize}
+
+  Schreiben Sie auch ein Programm, das die o.\,a.\ Funktionen testet.
+
+  \solution
+
+  Die Datei \gitfile{hp}{20201203}{loesung-2.c}
+  enthält die Bibliothek zusammen mit einem Test-Programm.
+
+  Eine detaillierte Anleitung,
+  wie man auf die Funktion \lstinline{date_next()} kommt,
+  finden Sie im Skript zur Lehrveranstaltung, Datei \gitfile{hp}{script}{hp-2020ws.pdf},
+  ab Seite 29.
+
+  (Die Vorgehensweise,
+  die Bibliothek und das Hauptprogramm in dieselbe Datei zu schreiben,
+  hat den Nachteil,
+  daß man die Bibliothek in jedes weitere Programm, das sie benutzt,
+  kopieren und auch dort aktuell halten muß.
+  Eine sinnvollere Lösung wird demnächst in der Vorlesung vorgestellt werden.)
+
+\end{document}
diff --git a/20201203/hp-uebung-20201203.pdf b/20201203/hp-uebung-20201203.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..77b848f34fa2783531c7149f9dde9261482b78d6
Binary files /dev/null and b/20201203/hp-uebung-20201203.pdf differ
diff --git a/20201203/hp-uebung-20201203.tex b/20201203/hp-uebung-20201203.tex
new file mode 100644
index 0000000000000000000000000000000000000000..dd019955cf7bc0d77c3b0715cb8b24b0bd147e14
--- /dev/null
+++ b/20201203/hp-uebung-20201203.tex
@@ -0,0 +1,152 @@
+% hp-uebung-20201203.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: Arrays mit Zahlen, Datum-Bibliothek
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+
+\thispagestyle{empty}
+
+\begin{document}
+
+  \thispagestyle{empty}
+
+  \section*{Hardwarenahe Programmierung\\
+            Übungsaufgaben -- 3.\ Dezember 2020}
+
+  Diese Übung enthält Punkteangaben wie in einer Klausur.
+  Um zu "`bestehen"', müssen Sie innerhalb von 45 Minuten
+  unter Verwendung ausschließlich zugelassener Hilfsmittel
+  8 Punkte (von insgesamt \totalpoints) erreichen.
+
+  \exercise{Arrays mit Zahlen}
+
+  \begin{minipage}[t]{0.4\textwidth}
+    Wir betrachten das folgende Programm\\
+    (Datei: \gitfile{hp}{20201203}{aufgabe-1.c}):
+    \begin{lstlisting}[gobble=6]
+      #include <stdio.h>
+
+      void f (int *s0, int *s1)
+      {
+        while (*s0 >= 0)
+        {
+          int *s = s1;
+          while (*s >= 0)
+            if (*s0 == *s++)
+              printf ("%d ", *s0);
+          s0++;
+        }
+        printf ("\n");
+      }
+
+      int main (void)
+      {
+        int a[] = { 10, 4, 3, 7, 12, 0, 1, -1 };
+        int b[] = { 7, 14, 0, 8, 9, 22, 10, -1 };
+        f (a, b);
+        return 0;
+      }
+    \end{lstlisting}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{0.55\textwidth}
+    \vspace*{-\bigskipamount}
+    \begin{enumerate}[\quad(a)]
+      \item
+        Was bewirkt die Funktion \lstinline{f},\\
+        und wie funktioniert sie?
+        \points{4}
+%      \item
+%        Von welcher Ordnung (Landau-Symbol) ist die Funktion?
+%        Begründen Sie Ihre Antwort.
+%
+%        Wir beziehen uns hierbei auf die Anzahl der Vergleiche
+%        in Abhängigkeit von der Länge der Eingabedaten \lstinline{s0} und \lstinline{s1}.
+%        Für die Rechnung dürfen Sie beide Längen mit $n$ gleichsetzen,
+%        obwohl sie normalerweise nicht gleich sind.
+%        \points{2}
+      \item
+        Was passiert, wenn Sie beim Aufruf der Funktion für einen der
+        Parameter den Wert \lstinline{NULL} übergeben?
+        Begründen Sie Ihre Antwort.
+        \points{2}
+      \item
+        Was kann passieren, wenn Sie das Hauptprogramm wie folgt abändern
+        (\gitfile{hp}{20201203}{aufgabe-1c.c})?
+        Begründen Sie Ihre Antwort.
+        \begin{lstlisting}[gobble=8]
+          int main (void)
+          {
+            int a[] = { 10, 4, 3, 7, 12, 0, 1 };
+            int b[] = { 7, 14, 0, 8, 9, 22, 10 };
+            f (a, b);
+            return 0;
+          }
+        \end{lstlisting}
+        \points{2}
+%      \item
+%        Beschreiben Sie -- in Worten und/oder als C-Quelltext --, wie
+%        sich die Funktion \lstinline{f} effizienter gestalten läßt,
+%        wenn man die ihr übergebenen Arrays \lstinline{s0} und
+%        \lstinline{s1} als sortiert voraussetzt.
+%        \points{5}
+%
+%        Hinweis: Wie würden Sie als Mensch die Aufgabe erledigen?
+%      \item
+%        Von welcher
+%        Ordnung (Landau-Symbol) ist Ihre effizientere Version der Funktion und warum?
+%        \points{2}
+    \end{enumerate}
+  \end{minipage}
+
+  \exercise{Datum-Bibliothek}
+
+  Schreiben Sie eine Bibliothek (= Sammlung von Deklarationen und Funktionen)
+  zur Behandlung von Datumsangaben.
+
+  Diese soll enthalten:
+  \begin{itemize}
+    \item
+      einen \lstinline{struct}-Datentyp \lstinline{date},
+      der eine Datumsangabe speichert,
+    \item
+      eine Funktion \lstinline{void date_print (date *d)}, die ein Datum ausgibt,
+    \item
+      eine Funktion \lstinline{int date_set (date *d, int day, int month, int year)},
+      die ein Datum auf einen gegebenen Tag setzt
+      und zurückgibt, ob es sich um ein gültiges Datum handelt (0 = nein, 1 = ja),
+    \item
+      eine Funktion \lstinline{void date_next (date *d)},
+      die ein Datum auf den nächsten Tag vorrückt.
+  \end{itemize}
+
+  Schreiben Sie auch ein Programm, das die o.\,a.\ Funktionen testet.
+
+  \points{8}
+
+  \makeatletter
+    \immediate\write\@mainaux{\string\gdef\string\totalpoints{\arabic{points}}}
+  \makeatother
+
+\end{document}
diff --git a/20201203/loesung-2.c b/20201203/loesung-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..151c965980df79b5d0e04188f7bf6ac7a3b836a9
--- /dev/null
+++ b/20201203/loesung-2.c
@@ -0,0 +1,109 @@
+#include <stdio.h>
+
+typedef struct
+{
+  char day, month;
+  int year;
+}
+date;
+
+int is_leap_year (int year)
+{
+  if (year % 4 == 0)
+    if (year % 100 == 0)
+      if (year % 400 == 0)
+        return 1;
+      else
+        return 0;
+    else
+      return 1;
+  else
+    return 0;
+}
+
+int days_in_month (int month, int year)
+{
+  if (month == 2)
+    if (is_leap_year (year))
+      return 29;
+    else
+      return 28;
+  else if (month == 4 || month == 6 || month == 9 || month == 11)
+    return 30;
+  else
+    return 31;
+}
+
+void date_print (date *d)
+{
+  printf ("%02d.%02d.%04d", d->day, d->month, d->year);
+}
+
+int date_set (date *d, char day, char month, int year)
+{
+  d->year = year;
+  if (month > 0 && month <= 12)
+    d->month = month;
+  else
+    return 0;
+  if (day > 0 && day <= days_in_month (month, year))
+    d->day = day;
+  else
+    return 0;
+  return 1;
+}
+
+void date_next (date *d)
+{
+  d->day++;
+  if (d->day > days_in_month (d->month, d->year))
+    {
+      d->month++;
+      d->day = 1;
+      if (d->month > 12)
+        {
+          d->year++;
+          d->month = 1;
+        }
+    }
+}
+
+void check (char day, char month, int year)
+{
+  date d;
+  if (date_set (&d, day, month, year))
+    {
+      date_print (&d);
+      printf (" --> ");
+      date_next (&d);
+      date_print (&d);
+      printf ("\n");
+    }
+  else
+    printf ("%02d.%02d.%04d: invalid date\n", day, month, year);
+}
+
+int main (void)
+{
+  check (6, 11, 2018);
+  check (29, 11, 2018);
+  check (30, 11, 2018);
+  check (31, 11, 2018);
+  check (29, 12, 2018);
+  check (30, 12, 2018);
+  check (31, 12, 2018);
+  check (28, 2, 2016);
+  check (29, 2, 2016);
+  check (30, 2, 2016);
+  check (28, 2, 2015);
+  check (29, 2, 2015);
+  check (30, 2, 2015);
+  check (31, 12, 2008);
+  check (28, 2, 2000);
+  check (29, 2, 2000);
+  check (30, 2, 2000);
+  check (28, 2, 1900);
+  check (29, 2, 1900);
+  check (30, 2, 1900);
+  return 0;
+}
diff --git a/20201203/logo-hochschule-bochum-cvh-text-v2.pdf b/20201203/logo-hochschule-bochum-cvh-text-v2.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..4aa99b8f81061aca6dcaf43eed2d9efef40555f8
--- /dev/null
+++ b/20201203/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/20201203/logo-hochschule-bochum.pdf b/20201203/logo-hochschule-bochum.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1
--- /dev/null
+++ b/20201203/logo-hochschule-bochum.pdf
@@ -0,0 +1 @@
+../common/logo-hochschule-bochum.pdf
\ No newline at end of file
diff --git a/20201203/main-params-1.c b/20201203/main-params-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..e6e64ba029e1042aff60960fc8b7c3d4d5d8e2e2
--- /dev/null
+++ b/20201203/main-params-1.c
@@ -0,0 +1,9 @@
+#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;
+}
diff --git a/20201203/main-params-10.c b/20201203/main-params-10.c
new file mode 100644
index 0000000000000000000000000000000000000000..01909d2df3074e1ba1be80a7bb9a7815fffb6b62
--- /dev/null
+++ b/20201203/main-params-10.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+int main (char **y, int x)
+{
+  printf ("x = %d\n", x);
+  int i = 0;
+  char **s = y;
+  while (*s)
+    printf ("y[%d] = \"%s\"\n", i++, *s++);
+  return 0;
+}
diff --git a/20201203/main-params-2.c b/20201203/main-params-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..242aa8abb5f3af0ea60aeba94edb978388ea4c4d
--- /dev/null
+++ b/20201203/main-params-2.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int main (int argc, char **argv)
+{
+  printf ("argc = %d\n", argc);
+  for (int i = 0; argv[i]; i++)
+    printf ("argv[%d] = \"%s\"\n", i, argv[i]);
+  return 0;
+}
diff --git a/20201203/main-params-3.c b/20201203/main-params-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..78d0e6aebb012d6401a0f44497d66a85be32dc0b
--- /dev/null
+++ b/20201203/main-params-3.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int main (int argc, char **argv)
+{
+  printf ("argc = %d\n", argc);
+  for (char **s argv; *s; s++)
+    printf ("argv[%d] = \"%s\"\n", i, *s);
+  return 0;
+}
diff --git a/20201203/main-params-4.c b/20201203/main-params-4.c
new file mode 100644
index 0000000000000000000000000000000000000000..9b68f005f9eb7b8da9fae0783ae36831051732ad
--- /dev/null
+++ b/20201203/main-params-4.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+int main (int argc, char **argv)
+{
+  printf ("argc = %d\n", argc);
+  int i = 0;
+  for (char **s = argv; *s; s++)
+    printf ("argv[%d] = \"%s\"\n", i, *s);
+  return 0;
+}
diff --git a/20201203/main-params-5.c b/20201203/main-params-5.c
new file mode 100644
index 0000000000000000000000000000000000000000..f2e68bc84bf46b3d62774e6f768e2c8bcab3a01b
--- /dev/null
+++ b/20201203/main-params-5.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+int main (int argc, char **argv)
+{
+  printf ("argc = %d\n", argc);
+  int i = 0;
+  char **s = argv;
+  while (*s)
+    printf ("argv[%d] = \"%s\"\n", i++, *s++);
+  return 0;
+}
diff --git a/20201203/main-params-6.c b/20201203/main-params-6.c
new file mode 100644
index 0000000000000000000000000000000000000000..9555a8f5207b63c81d2a2a212aee3594fb400aab
--- /dev/null
+++ b/20201203/main-params-6.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+int main (int x, char **y)
+{
+  printf ("x = %d\n", x);
+  int i = 0;
+  char **s = y;
+  while (*s)
+    printf ("y[%d] = \"%s\"\n", i++, *s++);
+  return 0;
+}
diff --git a/20201203/main-params-7.c b/20201203/main-params-7.c
new file mode 100644
index 0000000000000000000000000000000000000000..0ab2c3061f17634df91f75d7cbbed80e655e8b99
--- /dev/null
+++ b/20201203/main-params-7.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main (int x)
+{
+  printf ("x = %d\n", x);
+  return 0;
+}
diff --git a/20201203/main-params-8.c b/20201203/main-params-8.c
new file mode 100644
index 0000000000000000000000000000000000000000..b5dd4e21346d723f4a535b88f4c523153b0dd0fa
--- /dev/null
+++ b/20201203/main-params-8.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main (int x, char **y)
+{
+  printf ("x = %d\n", x);
+  return 0;
+}
diff --git a/20201203/main-params-9.c b/20201203/main-params-9.c
new file mode 100644
index 0000000000000000000000000000000000000000..d742f43eb354c75e23ced8d86e5e6a60c6a97d1a
--- /dev/null
+++ b/20201203/main-params-9.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main (int x, char **)
+{
+  printf ("x = %d\n", x);
+  return 0;
+}
diff --git a/20201203/main-params-link b/20201203/main-params-link
new file mode 120000
index 0000000000000000000000000000000000000000..05db77323d41949eaf431b8d4e6adc1920e28a90
--- /dev/null
+++ b/20201203/main-params-link
@@ -0,0 +1 @@
+main-params-1
\ No newline at end of file
diff --git a/20201203/pgscript.sty b/20201203/pgscript.sty
new file mode 120000
index 0000000000000000000000000000000000000000..95c888478c99ea7fda0fd11ccf669ae91be7178b
--- /dev/null
+++ b/20201203/pgscript.sty
@@ -0,0 +1 @@
+../common/pgscript.sty
\ No newline at end of file
diff --git a/20201203/pgslides.sty b/20201203/pgslides.sty
new file mode 120000
index 0000000000000000000000000000000000000000..5be1416f4216f076aa268901f52a15d775e43f64
--- /dev/null
+++ b/20201203/pgslides.sty
@@ -0,0 +1 @@
+../common/pgslides.sty
\ No newline at end of file
diff --git a/20201203/spaces-1.txt b/20201203/spaces-1.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f2d1ba4e270e93cf6765ae84fa9267b2d55c57d1
--- /dev/null
+++ b/20201203/spaces-1.txt
@@ -0,0 +1,18 @@
+cassini/home/peter/bo/2020ws/hp/20201203> ./main-params-6 a b " " c
+x = 5
+y[0] = "./main-params-6"
+y[1] = "a"
+y[2] = "b"
+y[3] = " "
+y[4] = "c"
+cassini/home/peter/bo/2020ws/hp/20201203> ./main-params-6 Dies\ ist ein\ Test
+x = 3
+y[0] = "./main-params-6"
+y[1] = "Dies ist"
+y[2] = "ein Test"
+cassini/home/peter/bo/2020ws/hp/20201203> ./main-params-6 "Dies ist" "ein Test"
+x = 3
+y[0] = "./main-params-6"
+y[1] = "Dies ist"
+y[2] = "ein Test"
+cassini/home/peter/bo/2020ws/hp/20201203>
diff --git a/20201203/strings-1.c b/20201203/strings-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..396e2c16fb8695f38c95b40e947a83975c0ccd84
--- /dev/null
+++ b/20201203/strings-1.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main (void)
+{
+  printf ("Es heißt: \"Hello, world!\"\n");
+  return 0;
+}
diff --git a/20201203/strings-2.c b/20201203/strings-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..5cbeb48d81fc636b126b900209324843c46ae5e9
--- /dev/null
+++ b/20201203/strings-2.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main (void)
+{
+  printf ("Es heißt: %cHello, world!%c\n", 34, 34);
+  return 0;
+}
diff --git a/20201203/strings-3.c b/20201203/strings-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..4d1d3bd31762299b8dbc171abc47535e6fe202bc
--- /dev/null
+++ b/20201203/strings-3.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main (void)
+{
+  printf ("Es heißt: "Hello, world!"\n", 34, 34);
+  return 0;
+}