diff --git a/20231012/hp-20231012.pdf b/20231012/hp-20231012.pdf
index 93c71c869abba34501199b479e959a4dc9e50d04..3768ad212987328dc63a94ef85608178b7c23e60 100644
Binary files a/20231012/hp-20231012.pdf and b/20231012/hp-20231012.pdf differ
diff --git a/20231012/hp-20231012.tex b/20231012/hp-20231012.tex
index ed26b56d5b6efb14dc4617d4f6ade27732c3e318..7d9bb7f5f71a523b30999fb68fde94866550291a 100644
--- a/20231012/hp-20231012.tex
+++ b/20231012/hp-20231012.tex
@@ -1340,6 +1340,8 @@
   \end{minipage}
 \end{frame}
 
+\iffalse
+
 % \begin{frame}[fragile]
 %   \showsubsection
 % 
@@ -1559,6 +1561,8 @@
   \end{itemize}
 \end{frame}
 
+\fi
+
 \nosectionnonumber{\inserttitle}
 
 \begin{frame}
@@ -1581,6 +1585,7 @@
         \item[2.8] Seiteneffekte
         \item[2.9] Funktionen
         \item[2.10] Zeiger
+        \color{orange}
         \item[2.11] Arrays und Strings
         \color{red}
         \item[2.12] Strukturen
diff --git a/20231019/aufgabe-3.c b/20231019/aufgabe-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..ad9d80416bad5c7c0edf9c9d4f175146c92a2755
--- /dev/null
+++ b/20231019/aufgabe-3.c
@@ -0,0 +1,8 @@
+int fun_1 (char *s1, char *s2)
+{
+  int result = 1;
+  for (int i = 0; s1[i] && s2[i]; i++)
+    if (s1[i] != s2[i])
+      result = 0;
+  return result;
+}
diff --git a/20231019/aufgabe-4.c b/20231019/aufgabe-4.c
new file mode 100644
index 0000000000000000000000000000000000000000..dc58b6e8ee4a7a023654aa0eb3a9715a5b9f75cf
--- /dev/null
+++ b/20231019/aufgabe-4.c
@@ -0,0 +1 @@
+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/20231019/gitlab.png b/20231019/gitlab.png
new file mode 100644
index 0000000000000000000000000000000000000000..5724da8b8338534857e5e845f1f1a9b67f0fab1a
Binary files /dev/null and b/20231019/gitlab.png differ
diff --git a/20231019/hp-20231019.pdf b/20231019/hp-20231019.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..37ccf57ed6f0d63235ac4d4beae3a835c71f7993
Binary files /dev/null and b/20231019/hp-20231019.pdf differ
diff --git a/20231019/hp-20231019.tex b/20231019/hp-20231019.tex
new file mode 100644
index 0000000000000000000000000000000000000000..266ebe9007677bb157c8f0dda3141dc016b42725
--- /dev/null
+++ b/20231019/hp-20231019.tex
@@ -0,0 +1,1307 @@
+% hp-20231019.pdf - Lecture Slides on Low-Level Programming
+% Copyright (C) 2012, 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023  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: Einführung in C (ab 2.11: Arrays und Strings)
+
+\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}
+
+\newcommand{\redurl}[1]{\href{#1}{\color{red}\nolinkurl{#1}}}
+
+\title{Hardwarenahe Programmierung}
+\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski}
+\date{19.\ Oktober 2023}
+
+\begin{document}
+
+\maketitleframe
+
+%\date{\begin{picture}(0,0)
+%        \color{red}
+%        \put(0.65,1.05){\makebox(0,0)[t]{$\underbrace{\rule{1.45cm}{0pt}}_{%
+%          \mbox{\emph{rerum naturalium\/} = der natürlichen Dinge (lat.)}}$}}
+%        \put(1.65,-3){\makebox(0,0)[bl]{\redurl{https://www.peter.gerwinski.de/physik/}}}
+%      \end{picture}%
+%      12.\ Oktober 2023}
+%
+%\maketitleframe
+
+\title{Hardwarenahe Programmierung}
+
+\nosectionnonumber{\inserttitle}
+
+\begin{frame}
+
+  \shownosectionnonumber
+
+  \begin{itemize}
+    \item[\textbf{1}] \textbf{Einführung}
+      \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp}}}
+    \item[\textbf{2}] \textbf{Einführung in C}
+      \begin{itemize}
+        \item[2.1] Hello, world!
+        \item[2.2] Programme compilieren und ausführen
+        \item[2.3] Elementare Aus- und Eingabe
+        \item[2.4] Elementares Rechnen
+        \item[2.5] Verzweigungen
+        \item[2.6] Schleifen
+        \color{medgreen}
+        \item[2.7] Strukturierte Programmierung
+        \item[2.8] Seiteneffekte
+        \item[2.9] Funktionen
+        \item[2.10] Zeiger
+        \color{orange}
+        \item[2.11] Arrays und Strings
+        \color{red}
+        \item[2.12] Strukturen
+        \item[\dots]
+      \end{itemize}
+    \color{gray}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+    \vspace*{-\smallskipamount}
+    \item[\textbf{\dots}]
+%    \item[\textbf{4}] \textbf{Hardwarenahe Programmierung}
+%    \item[\textbf{5}] \textbf{Algorithmen}
+%    \item[\textbf{6}] \textbf{Ergänzungen und Ausblicke}
+  \end{itemize}
+
+\end{frame}
+
+\section{Einführung}
+\section{Einführung in C}
+\setcounter{subsection}{7}
+\subsection{Seiteneffekte}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \begin{lstlisting}
+    #include <stdio.h>
+
+    int main (void)
+    {
+      printf ("Hello, world!\n");
+      "Hello, world!\n";
+      return 0;
+    }
+  \end{lstlisting}
+  \pause
+  \begin{picture}(0,0)
+    \color{red}
+    \put(3.1,1.35){\tikz{\draw[-latex](0.0,0.0)--(-0.8,0);}}
+    \put(4.0,1.35){\makebox(0,0)[l]{Ausdruck als Anweisung: Wert wird ignoriert}}
+    \pause
+    \put(3.55,1.40){\tikz{\draw[-latex](0.0,0.0)--(-0.4,0.2);}}
+  \end{picture}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \begin{lstlisting}
+    #include <stdio.h>
+
+    int main (void)
+    {
+      int a = printf ("Hello, world!\n");
+      printf ("%d\n", a);
+      return 0;
+    }
+  \end{lstlisting}
+%  \pause
+  \bigskip
+  \begin{lstlisting}[style=terminal]
+    $ ¡gcc -Wall -O side-effects-1.c -o side-effects-1¿
+    $ ¡./side-effects-1¿
+    Hello, world!
+    14
+    $
+  \end{lstlisting}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \begin{lstlisting}
+    #include <stdio.h>
+
+    int main (void)
+    {
+      int a = printf ("Hello, world!\n");
+      printf ("%d\n", a);
+      return 0;
+    }
+  \end{lstlisting}
+  \begin{itemize}
+    \item
+      \lstinline{printf()} ist eine Funktion.
+%    \pause
+    \item
+      "`Haupteffekt"': Wert zurückliefern\\
+      (hier: Anzahl der ausgegebenen Zeichen)
+%    \pause
+    \item
+      \newterm{Seiteneffekt\/}: Ausgabe
+  \end{itemize}
+
+\end{frame}
+
+\addtocounter{subsection}{-1}
+\subsection{Seiteneffekte \protect\color{gray}bei Operatoren}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \begin{minipage}[t]{6cm}
+    Unäre Operatoren:
+    \begin{itemize}
+      \item
+        Negation: \lstinline{-foo}
+      \item
+        {\only<2->{\color{red}}Funktionsaufruf}: \lstinline{foo ()}
+      \item
+        {\only<2->{\color{red}}Post-Inkrement}: \lstinline{foo++}
+      \item
+        {\only<2->{\color{red}}Post-Dekrement}: \lstinline{foo--}
+      \item
+        {\only<2->{\color{red}}Prä-Inkrement}: \lstinline{++foo}
+      \item
+        {\only<2->{\color{red}}Prä-Dekrement}: \lstinline{--foo}
+    \end{itemize}
+    \medskip
+    Binäre Operatoren:
+    \begin{itemize}
+      \item
+        Rechnen: \lstinline{+ - * / %}
+      \item
+        Vergleich: \lstinline{== != < > <= >=}
+      \item
+        {\only<2->{\color{red}}Zuweisung}: \lstinline{= += -= *= /= %=}
+      \item
+        Ignorieren: \lstinline{,}\quad \lstinline{a, b}: berechne \lstinline{a}, ignoriere es, nimm stattdessen \lstinline{b}
+    \end{itemize}
+    \pause
+    \medskip
+    {\color{red}rot = mit Seiteneffekt}
+  \end{minipage}
+  \pause
+  \begin{minipage}[t]{6cm}
+    \vspace{-\bigskipamount}
+    \begin{lstlisting}
+      ¡int i;¿
+    \end{lstlisting}
+    \bigskip
+    \begin{lstlisting}
+      ¡i = 0;
+      while (i < 10)
+        {
+          printf ("%d\n", i);
+          i++;
+        }¿
+    \end{lstlisting}
+    \bigskip
+%    \pause
+    \begin{lstlisting}
+      ¡for (i = 0; i < 10; i++)
+        printf ("%d\n", i);¿
+    \end{lstlisting}
+    \bigskip
+%    \pause
+    \begin{lstlisting}
+      ¡i = 0;
+      while (i < 10)
+        printf ("%d\n", i++);¿
+    \end{lstlisting}
+    \bigskip
+%    \pause
+    \begin{lstlisting}
+      ¡for (i = 0; i < 10; printf ("%d\n", i++));¿
+    \end{lstlisting}
+  \end{minipage}
+  \vspace*{-1cm}
+
+\end{frame}
+
+\subsection{Funktionen}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \begin{minipage}[t]{6.5cm}
+    \vspace{-\medskipamount}
+    \begin{lstlisting}[gobble=6]
+      ¡#include <stdio.h>
+
+      int answer (void)
+      {
+        return 42;
+      }
+
+      void foo (void)
+      {
+        printf ("%d\n", answer ());
+      }
+
+      int main (void)
+      {
+        foo ();
+        return 0;
+      }¿
+    \end{lstlisting}
+    \vspace*{-1cm}
+  \end{minipage}%
+  \begin{minipage}[t]{6cm}
+    \begin{itemize}
+%      \pause
+      \item
+        Funktionsdeklaration:\\[\smallskipamount]
+        Typ Name ( Parameterliste )\\
+        \{\\
+        \quad Anweisungen\\
+        \}
+    \end{itemize}
+  \end{minipage}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \begin{minipage}[t]{6.5cm}
+    \vspace{-\medskipamount}
+    \begin{lstlisting}[gobble=6]
+      ¡#include <stdio.h>
+
+      void add_verbose (int a, int b)
+      {
+        printf ("%d + %d = %d\n", a, b, a + b);
+      }
+
+      int main (void)
+      {
+        add_verbose (3, 7);
+        return 0;
+      }¿
+    \end{lstlisting}
+  \end{minipage}%
+  \begin{minipage}[t]{6cm}
+    \begin{itemize}
+      \item
+        Funktionsdeklaration:\\[\smallskipamount]
+        Typ Name ( Parameterliste )\\
+        \{\\
+        \quad Anweisungen\\
+        \}
+%      \pause
+      \bigskip
+      \item
+        Der Datentyp \lstinline{void}\\
+        steht für "`nichts"'\\
+        und \alt<2->{muß}{kann} ignoriert werden.
+    \end{itemize}
+  \end{minipage}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \begin{minipage}{6cm}
+    \begin{lstlisting}[gobble=6]
+      ¡#include <stdio.h>
+
+      int a, b = 3;
+
+      void foo (void)
+      {
+        b++;
+        static int a = 5;
+        int b = 7;
+        printf ("foo(): "
+               "a = %d, b = %d\n",
+               a, b);
+        a++;
+      }¿
+    \end{lstlisting}
+  \end{minipage}%
+  \begin{minipage}{6cm}
+    \vspace{-0.4cm}
+    \begin{lstlisting}[gobble=6]
+      ¡int main (void)
+      {
+        printf ("main(): "
+               "a = %d, b = %d\n",
+               a, b);
+        foo ();
+        printf ("main(): "
+               "a = %d, b = %d\n",
+               a, b);
+        a = b = 12;
+        printf ("main(): "
+               "a = %d, b = %d\n",
+               a, b);
+        foo ();
+        printf ("main(): "
+               "a = %d, b = %d\n",
+               a, b);
+        return 0;
+      }¿
+    \end{lstlisting}
+  \end{minipage}
+
+\end{frame}
+
+\subsection{Zeiger}
+
+\begin{frame}[fragile]
+  \showsubsection
+
+  \begin{lstlisting}
+    #include <stdio.h>
+
+    void calc_answer (int *a)
+    {
+      *a = 42;
+    }
+
+    int main (void)
+    {
+      int answer;
+      calc_answer (&answer);
+      printf ("The answer is %d.\n", answer);
+      return 0;
+    }
+  \end{lstlisting}
+
+%  \pause
+  \vspace{-5cm}\hspace{5cm}%
+  \begin{minipage}{7cm}
+    \begin{itemize}
+      \item
+        \lstinline{*a} ist eine \lstinline{int}.
+%      \pause
+      \item
+        unärer Operator \lstinline{*}:\\
+        Pointer-Dererefenzierung
+%      \pause
+      \arrowitem
+        \lstinline{a} ist ein Zeiger (Pointer) auf eine \lstinline{int}.
+%      \pause
+      \bigskip
+      \item
+        unärer Operator \lstinline{&}: Adresse
+    \end{itemize}
+  \end{minipage}
+\end{frame}
+
+\subsection{Arrays und Strings}
+
+\begin{frame}[fragile]
+  \showsubsection
+
+  Ein Zeiger zeigt auf eine Variable\only<2->{ und deren Nachbarn}.
+
+  \bigskip
+  \pause
+  \pause
+
+  \begin{onlyenv}<1-8>
+    \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}<9>
+    \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}<10>
+    \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}<11>
+    \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}<12>
+    \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}<13->
+    \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<5->{ein Array}{eine Ansammlung} von\\fünf ganzen Zahlen.
+      \pause
+      \pause
+      \item
+        \only<6-9>{\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<14->{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}
+
+\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{-1.5\smallskipamount}
+        \item[\dots]
+        \item[2.5] Verzweigungen
+        \item[2.6] Schleifen
+        \color{medgreen}
+        \item[2.7] Strukturierte Programmierung
+        \item[2.8] Seiteneffekte
+        \item[2.9] Funktionen
+        \item[2.10] Zeiger
+        \color{orange}
+        \item[2.11] Arrays und Strings
+        \color{red}
+        \item[2.12] Strukturen
+        \item[2.13] Dateien und Fehlerbehandlung
+        \item[2.14] Parameter des Hauptprogramms
+        \item[2.15] String-Operationen
+      \end{itemize}
+    \color{gray}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+    \vspace*{-\smallskipamount}
+    \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}
+
+% \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-6>
+    \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}<7>
+    \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}<8>
+%    \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}<9>
+%    \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}<10>
+%    \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{-1.7cm}\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<4->{,\\
+        also ein Zeiger auf \lstinline{char}s}\only<5->{\\
+        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?
+
+      \smallskip
+
+      \begin{lstlisting}[gobble=8]
+        printf ("%d\n", '*');
+      \end{lstlisting}
+
+      \smallskip
+
+      (normalerweise: ASCII)
+    \medskip
+    \item
+      Ist \lstinline{char ch} ein Großbuchstabe?
+
+      \smallskip
+
+      \begin{lstlisting}[gobble=8]
+        if (ch >= 'A' && ch <= 'Z')
+          ...
+      \end{lstlisting}
+    \medskip
+    \item
+      Groß- in Kleinbuchstaben umwandeln
+
+      \smallskip
+
+      \begin{lstlisting}[gobble=8]
+        ch += 'a' - 'A';
+      \end{lstlisting}
+  \end{itemize}
+\end{frame}
+
+\subsection{Strukturen}
+
+\begin{frame}[fragile]
+  \showsubsection
+
+  \begin{lstlisting}
+    #include <stdio.h>
+
+    typedef struct
+    {
+      char day, month;
+      int year;
+    }
+    date;
+
+    int main (void)
+    {
+      date today = { 17, 10, 2022 };
+      printf ("%d.%d.%d\n", today.day, today.month, today.year);
+      return 0;
+    }
+  \end{lstlisting}
+\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 = 17;
+        (*d).month = 10;
+        (*d).year = 2022;
+      }¿
+    \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 = 17;
+        d->month = 10;
+        d->year = 2022;
+      }¿
+    \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 (errno, 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{-1.5\smallskipamount}
+        \item[\dots]
+        \item[2.5] Verzweigungen
+        \item[2.6] Schleifen
+        \item[2.7] Strukturierte Programmierung
+        \item[2.8] Seiteneffekte
+        \item[2.9] Funktionen
+        \item[2.10] Zeiger
+        \color{medgreen}
+        \item[2.11] Arrays und Strings
+        \item[2.12] Strukturen
+        \item[2.13] Dateien und Fehlerbehandlung
+        \item[2.14] Parameter des Hauptprogramms
+        \item[2.15] String-Operationen
+      \end{itemize}
+    \color{gray}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+    \vspace*{-\smallskipamount}
+    \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}
+
+\end{document}
diff --git a/20231019/hp-musterloesung-20231019.pdf b/20231019/hp-musterloesung-20231019.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..e3e0e8179ec50b8ced0869b592c12228860be510
Binary files /dev/null and b/20231019/hp-musterloesung-20231019.pdf differ
diff --git a/20231019/hp-musterloesung-20231019.tex b/20231019/hp-musterloesung-20231019.tex
new file mode 100644
index 0000000000000000000000000000000000000000..b46ec8ed68215842807fe4e52b4ca8f6747b363d
--- /dev/null
+++ b/20231019/hp-musterloesung-20231019.tex
@@ -0,0 +1,523 @@
+% hp-musterloesung-20231019.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences
+% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023  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: Seltsame Programme, Kalender-Berechnung, Strings, Programm analysieren
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+\renewcommand{\breath}{\bigskip}
+
+\begin{document}
+
+  \section*{Hardwarenahe Programmierung\\
+            Musterlösung zu den Übungsaufgaben -- 19.\ Oktober 2023}
+
+  \exercise{Seltsame Programme}
+
+  Unter \url{https://gitlab.cvh-server.de/pgerwinski/hp/tree/2022ws/20221017}
+  finden Sie (unter anderem)\\
+  die Programme \gitfile{hp}{2023ws/20231019}{test-1.c},
+  \gitfile{hp}{2023ws/20231019}{test-2.c} und \gitfile{hp}{2023ws/20231019}{test-3.c}.
+
+  Was bewirken diese Programme, und warum verhalten sie sich so?
+
+  \solution
+
+  \begin{itemize}
+    \item
+      \gitfile{hp}{2023ws/20231019}{test-1.c}
+
+      Hinter \lstinline{return} steht ein Ausdruck mit dem
+      Komma-Operator. Dieser bewirkt, daß der Wert vor dem Komma
+      berechnet und ignoriert und danach der Wert nach dem Komma
+      zurückgegeben wird.
+
+      In diesem Fall wird vor dem Komma der Wert des
+      \lstinline{printf()}-Aufrufs berechnet und ignoriert.
+      Als Seiteneffekt gibt das Programm die Zeile
+      \lstinline[style=terminal]{Hello, world!} aus.
+      Anschließend wird der Wert \lstinline{0} an \lstinline{return}
+      übergeben und daher \lstinline{return 0} ausgeführt.
+
+    \item
+      \gitfile{hp}{2023ws/20231019}{test-2.c}
+
+      Das Programm gibt die Zeile
+      \lstinline[style=terminal]{Die Antwort lautet: 42} aus.
+
+      Die \lstinline{if}-Bedingung ist eine Zuweisung \lstinline{b = 42},
+      die den zugewiesenen Wert \lstinline{42} zurückgibt.
+      Weil dieser Wert ungleich Null ist, interpretiert
+      \lstinline{if} ihn als Wahrheitswert "`wahr"', führt also den
+      \lstinline{if}-Zweig aus und überspringt den
+      \lstinline{else}-Zweig.
+
+    \item
+      \gitfile{hp}{2023ws/20231019}{test-3.c}
+
+      Das Programm stürzt mit einer Fehlermeldung
+      "`Speicherzugriffsfehler"' oder "`Schutzverletzung"' ab.
+
+      Der Funktionsaufruf \lstinline{printf (42)} übergibt den
+      Zahlenwert \lstinline{42} als String, also als einen Zeiger
+      auf \lstinline{char}-Variable, an die Funktion
+      \lstinline{printf()}. Diese versucht, auf den Speicher ab
+      Adresse 42 zuzugreifen, wofür aber das Programm keine
+      Zugriffsrechte hat. Das Betriebssystem beendet daraufhin das
+      Programm mit der o.\,a.\ Fehlermeldung.
+
+      Der String \lstinline{"Die Antwort lautet: "} wird nicht
+      ausgegeben, weil Schreiboperationen aus Effizienzgründen
+      erst nach einer abgeschlossenen Zeile (\lstinline{"\n"})
+      durchgeführt werden.
+  \end{itemize}
+
+  \clearpage
+
+  \exercise{Kalender-Berechnung}
+
+  Am 3.\,1.\,2009 meldete \emph{heise online\/}:
+  \begin{quote}
+    Kunden des ersten mobilen Media-Players von Microsoft
+    erlebten zum Jahresende eine böse Überraschung:
+    Am 31.\ Dezember 2008 fielen weltweit alle Zune-Geräte der ersten Generation aus.
+    Ursache war ein interner Fehler bei der Handhabung von Schaltjahren.
+
+    \strut\hfill\url{http://heise.de/-193332}, 
+  \end{quote}
+  Der Artikel verweist auf ein Quelltextfragment (Datei: \gitfile{hp}{2023ws/20231019}{aufgabe-2.c}),
+  das für einen gegebenen Wert \lstinline{days}
+  das Jahr und den Tag innerhalb des Jahres
+  für den \lstinline{days}-ten Tag nach dem 1.\,1.\,1980 berechnen soll:
+  \begin{lstlisting}
+     year = ORIGINYEAR;  /* = 1980 */
+
+     while (days > 365)
+       {
+         if (IsLeapYear (year))
+           {
+             if (days > 366)
+               {
+                 days -= 366;
+                 year += 1;
+               }
+           }
+         else
+           {
+             days -= 365;
+             year += 1;
+           }
+       }
+  \end{lstlisting}
+  Dieses Quelltextfragment enthält schlechten Programmierstil,
+  nämlich mehrere Code-Verdopplungen:
+  \begin{itemize}
+    \item
+      Die Anweisung \lstinline{year += 1} taucht an zwei Stellen auf.
+    \item
+      Es gibt zwei unabhängige Abfragen \lstinline{days > 365} und \lstinline{days > 366}:\\
+      eine in einer \lstinline{while}- und die andere in einer \lstinline{if}-Bedingung.
+    \item
+      Die Länge eines Jahres wird nicht durch eine Funktion berechnet oder in einer Variablen gespeichert;
+      stattdessen werden an mehreren Stellen die expliziten numerischen Konstanten 365 und 366 verwendet.
+  \end{itemize}
+  Diese Probleme führten am 31.\ Dezember 2008 zu einer Endlosschleife.
+
+  Gut hingegen ist die Verwendung einer Konstanten \lstinline{ORIGINYEAR}
+  anstelle der Zahl 1980
+  sowie die Kapselung der Berechnung der Schaltjahr-Bedingung
+  in einer Funktion \lstinline{IsLeapYear()}.
+
+  \begin{itemize}
+    \item[(a)]
+      Erklären Sie das Zustandekommen der Endlosschleife.
+    \item[(b)]
+      Schreiben Sie das Quelltextfragment so um, daß es die beschriebenen Probleme
+      nicht mehr enthält.
+  \end{itemize}
+
+  \textbf{Hinweis 1:} Verwenden Sie Ihre eigene Funktion \lstinline{IsLeapYear()}.
+
+  \textbf{Hinweis 2}: Schreiben Sie zusätzlich eine Funktion \lstinline{DaysInYear()}.
+
+  \clearpage
+
+  \solution
+
+  \begin{itemize}
+    \item[(a)]
+      \textbf{Erklären Sie das Zustandekommen der Endlosschleife.}
+
+      Das Programm startet mit demjenigen Wert für \lstinline{days},
+      der der Anzahl der Tage vom 1.\,1.\,1980 bis zum
+      31.\,12.\,2008 entspricht. Die \lstinline{while}-Schleife
+      läuft zunächst solange korrekt durch, bis \lstinline{year} den
+      Wert \lstinline{2008} und \lstinline{days} den Wert
+      \lstinline{366} hat. (Der 31.\,12.\ des Schaltjahres 2008 ist
+      der 366.\ Tag seines Jahres.)
+
+      Die Bedingung der \lstinline{while}-Schleife ist damit
+      weiterhin erfüllt; das Programm läuft weiter.
+
+      Da 2008 ein Schaltjahr ist, ist auch die Bedingung der äußeren
+      \lstinline{if}-Anweisung erfüllt.
+
+      Da \lstinline{days} den Wert 366 hat und dieser nicht größer
+      als 366 ist, ist die innere \lstinline{if}-Bedingung nicht
+      erfüllt. Somit wird innerhalb der \lstinline{while}-Schleife
+      kein weiterer Code ausgeführt, die \lstinline{while}-Bedingung
+      bleibt erfüllt, und das Programm führt eine Endlosschleife
+      aus.
+
+    \item[(b)]
+      \textbf{Schreiben Sie das Quelltextfragment so um, daß es die beschriebenen Probleme
+      nicht mehr enthält.}
+
+      Um das Programm zu testen, genügt es, das Datum auf den
+      31.\,12.\,1980 zu stellen, also \lstinline{days} auf den Wert
+      366 zu setzen. Darüberhinaus muß man die Funktion
+      \lstinline{IsLeapYear()} bereitstellen (vgl.\ Aufgabe 1 vom 11.\,10.\,2021).
+
+      Der Quelltext \gitfile{hp}{2023ws/20231019}{loesung-2-f1.c} ist eine lauffähige
+      Version des Programms, die den Fehler (Endlosschleife)
+      reproduziert.
+
+      \breath
+
+      Es liegt nahe, den Fehler in der \lstinline{while}-Bedingung
+      zu korrigieren, so daß diese Schaltjahre berücksichtigt. Der
+      Quelltext \gitfile{hp}{2023ws/20231019}{loesung-2-f2.c} behebt den Fehler auf diese
+      Weise mit Hilfe von Und- (\lstinline{&&}) und
+      Oder-Verknüpfungen (\lstinline{||}) in der
+      \lstinline{while}-Bedingung.
+
+      Der Quelltext \gitfile{hp}{2023ws/20231019}{loesung-2-f3.c} vermeidet die umständliche
+      Formulierung mit \lstinline{&&} und \lstinline{||} durch
+      Verwendung des ternären Operators \lstinline{?:}. Dieser
+      stellt eine "`\lstinline{if}-Anweisung für Ausdrücke"' bereit.
+      In diesem Fall liefert er für die rechte Seite des Vergleichs
+      \lstinline{days >} den Wert 366 im Falle eines Schaltjahrs
+      bzw.\ ansonsten den Wert 365.
+
+      Beide Lösungen \gitfile{hp}{2023ws/20231019}{loesung-2-f2.c} und \gitfile{hp}{2023ws/20231019}{loesung-2-f3.c}
+      sind jedoch im Sinne der Aufgabenstellung \textbf{falsch}.
+      Diese lautet: "`Schreiben Sie das Quelltextfragment so um,
+      daß es die beschriebenen Probleme nicht mehr enthält."'
+      Mit den beschriebenen Problemen sind die genannten drei
+      Code-Verdopplungen gemeint, und diese befinden sich weiterhin
+      im Quelltext. Damit ist der Fehler zwar "`korrigiert"', aber
+      das Programm ist eher noch unübersichtlicher geworden, so daß
+      nicht klar ist, ob es nicht noch weitere Fehler enthält.
+
+      \breath
+
+      Eine richtige Lösung liefert \gitfile{hp}{2023ws/20231019}{loesung-2-4.c}. Dieses
+      Programm speichert den Wert der Tage im Jahr in einer
+      Variablen \lstinline{DaysInYear}. Damit erübrigen sich die
+      \lstinline{if}-Anweisungen innerhalb der
+      \lstinline{while}-Schleife, und die damit verbundenen
+      Code-Verdopplungen verschwinden.
+
+      Etwas unschön ist hierbei die neu hinzugekommene
+      Code-Verdopplung bei der Berechnung von \lstinline{DaysInYear}.
+      Diese ist allerdings weniger kritisch als die vorherigen, da
+      sie nur einmal innerhalb der \lstinline{while}-Schleife
+      vorkommt und das andere Mal außerhalb derselben.
+
+      Um diese Code-Verdopplung loszuwerden, kann man das
+      \lstinline{if} durch den \lstinline{?:}-Operator ersetzen und
+      die Zuweisung innerhalb der \lstinline{while}-Bedingung
+      vornehmen -- siehe \gitfile{hp}{2023ws/20231019}{loesung-2-5.c}. Dies ist einer der
+      seltenen Fälle, in denen ein Programm \emph{übersichtlicher\/}
+      wird, wenn eine Zuweisung innerhalb einer Bedingung
+      stattfindet.
+
+      Alternativ kann \lstinline{DaysInYear()} auch eine Funktion
+      sein -- siehe \gitfile{hp}{2023ws/20231019}{loesung-2-6.c}. Diese Version ist
+      wahrscheinlich die übersichtlichste, hat jedoch den Nachteil,
+      daß die Berechnung von \lstinline{DaysInYear()} zweimal statt
+      nur einmal pro Schleifendurchlauf erfolgt, wodurch Rechenzeit
+      verschwendet wird.
+
+      \gitfile{hp}{2023ws/20231019}{loesung-2-7.c} und \gitfile{hp}{2023ws/20231019}{loesung-2-8.c} beseitigen
+      dieses Problem durch eine Zuweisung des Funktionsergebnisses
+      an eine Variable -- einmal innerhalb der
+      \lstinline{while}-Bedingung und einmal außerhalb.
+      Der zweimalige Aufruf der Funktion \lstinline{DaysInYear()} in
+      \gitfile{hp}{2023ws/20231019}{loesung-2-8.c} zählt nicht als Code-Verdopplung, denn
+      der Code ist ja in einer Funktion gekapselt. (Genau dazu sind
+      Funktionen ja da: daß man sie mehrfach aufrufen kann.)
+
+      \breath
+
+      Fazit: Wenn Sie sich beim Programmieren bei
+      Cut-And-Paste-Aktionen erwischen, sollten Sie die Struktur
+      Ihres Programms noch einmal überdenken.
+
+      Wahrscheinlich gibt es dann eine elegantere Lösung, deren
+      Korrektheit man auf den ersten Blick sieht.
+
+  \end{itemize}
+
+  \exercise{Strings}
+
+  Strings werden in der Programmiersprache C
+  durch Zeiger auf \lstinline{char}-Variable realisiert.
+
+  Wir betrachten die folgende Funktion (Datei: \gitfile{hp}{2023ws/20231019}{aufgabe-3.c}):
+  \begin{center}
+    \begin{minipage}{8cm}
+      \begin{lstlisting}[gobble=8]
+        int fun_1 (char *s1, char *s2)
+        {
+          int result = 1;
+          for (int i = 0; s1[i] && s2[i]; i++)
+            if (s1[i] != s2[i])
+              result = 0;
+          return result;
+        }
+      \end{lstlisting}
+    \end{minipage}%
+  \end{center}
+  \begin{itemize}
+    \item[(a)]
+      Was bewirkt die Funktion? % \points{3}
+    \item[(b)]
+      Welchen Sinn hat die Bedingung "`\lstinline{s1[i] && s2[i]}"'
+      in der \lstinline{for}-Schleife? % \points{2}
+    \item[(c)]
+      Was würde sich ändern, wenn die Bedingung "`\lstinline{s1[i] && s2[i]}"'
+      in der \lstinline{for}-Schleife\\
+      zu "`\lstinline{s1[i]}"' verkürzt würde? % \points{3}
+%    \item[(d)]
+%      Von welcher Ordnung (Landau-Symbol) ist die Funktion \lstinline{fun_1()}
+%      hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen in den Strings
+%      -- und warum? % \points{2}
+    \item[(d)]
+      Schreiben Sie eine eigene Funktion,
+      die dieselbe Aufgabe erledigt wie \lstinline{fun_1()}, nur effizienter.
+%      und geben Sie die Ordnung (Landau-Symbol) der von Ihnen geschriebenen Funktion an. % \points{5}
+  \end{itemize}
+
+  \solution
+
+  \begin{itemize}
+    \item[(a)]
+      \textbf{Was bewirkt die Funktion?}
+
+      Sie vergleicht zwei Strings miteinander bis zur Länge des kürzeren Strings
+      und gibt bei Gleichheit 1 zurück, ansonsten 0.
+
+      Alternative Formulierung:
+      Die Funktion prüft, ob zwei Strings bis zur Länge des kürzeren übereinstimmen,
+      und gibt bei Gleichheit 1 zurück, ansonsten 0.
+
+      Die Funktion prüft insbesondere \textbf{nicht} zwei Strings auf Gleichheit,
+      und sie ist \textbf{nicht} funktionsgleich zur
+      Standard-Bibliotheksfunktion \lstinline{strcmp()}.
+
+    \item[(b)]
+      \textbf{Welchen Sinn hat die Bedingung "`\lstinline{s1[i] && s2[i]}"'
+      in der \lstinline{for}-Schleife?}
+
+      Die Bedingung prüft, ob \emph{bei einem der beiden Strings\/}
+      die Ende-Markierung (Null-Symbol) erreicht ist.
+      Falls ja, wird die Schleife beendet.
+
+    \item[(c)]
+      \textbf{Was würde sich ändern, wenn die Bedingung "`\lstinline{s1[i] && s2[i]}"'
+      in der \lstinline{for}-Schleife\\
+      zu "`\lstinline{s1[i]}"' verkürzt würde?}
+
+      In diesem Fall würde nur für \lstinline{s1} geprüft,
+      ob das Ende erreicht ist.
+      Wenn \lstinline{s1} länger ist als \lstinline{s2},
+      würde \lstinline{s2} über sein Ende hinaus ausgelesen.
+      Dies kann zu Lesezugriffen auf Speicher außerhalb des Programms
+      und damit zu einem Absturz führen
+      ("`Speicherzugriffsfehler"', "`Schutzverletzung"').
+
+    \item[(d)]
+      \textbf{Schreiben Sie eine eigene Funktion,
+      die dieselbe Aufgabe erledigt wie \lstinline{fun_1()}, nur effizienter.}
+
+      Die Effizienz läßt sich steigern, indem man die Schleife abbricht,
+      sobald das Ergebnis feststeht.
+      Es folgen drei Möglichkeiten, dies zu realisieren.
+  \end{itemize}
+
+  \begin{center}
+    \begin{minipage}[t]{8cm}
+      Erweiterung der Schleifenbedingung:
+
+      \begin{lstlisting}[gobble=8]
+        int fun_2 (char *s1, char *s2)
+        {
+          int result = 1;
+          for (int i = 0; s1[i] && s2[i] && result; i++)
+            if (s1[i] != s2[i])
+              result = 0;
+          return result;
+        }
+      \end{lstlisting}
+    \end{minipage}%
+    \begin{minipage}[t]{6cm}
+      Verwendung von \lstinline{return}:
+
+      \begin{lstlisting}[gobble=8]
+        int fun_3 (char *s1, char *s2)
+        {
+          for (int i = 0; s1[i] && s2[i]; i++)
+            if (s1[i] != s2[i])
+              return 0;
+          return 1;
+        }
+      \end{lstlisting}
+    \end{minipage}
+  \end{center}
+  \vspace*{-1cm}\goodbreak
+
+  \begin{center}
+    \begin{minipage}{9cm}
+      Die nebenstehende Lösung unter Verwendung von \lstinline{break}
+      ist zwar ebenfalls richtig, aber länger und weniger übersichtlich
+      als die beiden anderen Lösungen.
+
+      \smallskip
+
+      Die Datei \gitfile{hp}{2023ws/20231019}{loesung-3.c} enthält ein Testprogramm
+      für alle o.\,a.\ Lösungen.
+      Das Programm testet nur die offensichtlichsten Fälle;
+      für den Einsatz der Funktionen in einer Produktivumgebung
+      wären weitaus umfassendere Tests erforderlich.
+
+      \smallskip
+
+      Das Testprogramm enthält String-Zuweisungen wie z.\,B.\
+      \lstinline{s2 = "Apfel"}.
+      Dies funktioniert, weil wir damit einen Zeiger (\lstinline{char *s2})
+      auf einen neuen Speicherbereich (\lstinline{"Apfel"}) zeigen lassen.
+      Eine entsprechende Zuweisung zwischen Arrays
+      (\lstinline{char s3[] = "Birne"; s3 = "Pfirsich";)}
+      funktioniert \emph{nicht}.
+      
+    \end{minipage}\hspace*{1cm}%
+    \begin{minipage}{6cm}
+      \begin{lstlisting}[gobble=8]
+        int fun_4 (char *s1, char *s2)
+        {
+          int result = 1;
+          for (int i = 0; s1[i] && s2[i]; i++)
+            if (s1[i] != s2[i])
+              {
+                result = 0;
+                break;
+              }
+          return result;
+        }
+      \end{lstlisting}
+    \end{minipage}
+  \end{center}
+
+  \exercise{Programm analysieren}
+
+  Wir betrachten das folgende C-Programm (Datei: \gitfile{hp}{2023ws/20231019}{aufgabe-4.c}):
+  \begin{lstlisting}
+    char*f="char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";main(){printf(f,34,f,34,10);}
+  \end{lstlisting}
+  \vspace{-\medskipamount}
+  \begin{itemize}
+    \item[(a)]
+      Was bewirkt dieses Programm?
+    \item[(b)]
+      Wofür stehen die Zahlen?
+    \item[(c)]
+      Ergänzen Sie das Programm derart, daß seine \lstinline{main()}-Funktion
+      \lstinline{int main (void)} lautet und eine \lstinline{return}-Anweisung hat,
+      wobei die in Aufgabenteil (a) festgestellte Eigenschaft erhalten bleiben soll.
+  \end{itemize}
+
+  \solution
+
+  \begin{itemize}
+    \item[(a)]
+      \textbf{Was bewirkt dieses Programm?}
+
+      Es gibt \emph{seinen eigenen Quelltext\/} aus.
+
+      (Wichtig ist die Bezugnahme auf den eigenen Quelltext.
+      Die Angabe\\
+      "`Es gibt
+      \lstinline|char*f="char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";main(){printf(f,34,f,34,10);}|
+      aus"'\\
+      genügt insbesondere nicht.)
+
+    \item[(b)]
+      \textbf{Wofür stehen die Zahlen?}
+
+      Die 34 steht für ein Anführungszeichen und die 10 für ein
+      Zeilenendezeichen (\lstinline{\n}).
+
+      Hintergrund: Um den eigenen Quelltext ausgeben zu können, muß
+      das Programm auch Anführungszeichen und Zeilenendezeichen
+      ausgeben. Dies geschieht normalerweise mit vorangestelltem
+      Backslash: \lstinline{\"} bzw.\ \lstinline{\n}. Um dann aber
+      den Backslash ausgeben zu können, müßte man diesem ebenfalls
+      einen Backslash voranstellen: \lstinline{\\}. Damit dies nicht
+      zu einer Endlosschleife wird, verwendet der Programmierer
+      dieses Programms den Trick mit den Zahlen, die durch
+      \lstinline{%c} als Zeichen ausgegeben werden.
+
+    \item[(c)]
+      \textbf{Ergänzen Sie das Programm derart, daß seine \lstinline{main()}-Funktion
+      \lstinline{int main (void)} lautet und eine \lstinline{return}-Anweisung hat,
+      wobei die in Aufgabenteil (a) festgestellte Eigenschaft erhalten bleiben soll.}
+
+      Datei: \gitfile{hp}{2023ws/20231019}{loesung-4.c}
+      \begin{lstlisting}[gobble=8]
+        char*f="char*f=%c%s%c;int main(void){printf(f,34,f,34,10);return 0;}%c";
+        int main(void){printf(f,34,f,34,10);return 0;}
+      \end{lstlisting}
+      Das Programm ist eine einzige, lange Zeile, die hier nur aus
+      Platzgründen als zwei Zeilen abgedruckt wird. Auf das
+      Semikolon am Ende der "`ersten Zeile"' folgt unmittelbar -- ohne Leerzeichen --
+      das Schlüsselwort \lstinline{int} am Anfang der "`zweiten Zeile"'.
+
+      Mit "`die in Aufgabenteil (a) festgestellte Eigenschaft"' ist
+      gemeint, daß das Programm weiterhin seinen eigenen Quelltext
+      ausgeben soll. Die Herausforderung dieser Aufgabe besteht
+      darin, das Programm zu modifizieren, ohne diese Eigenschaft zu
+      verlieren.
+
+      Zusatzaufgabe für Interessierte: Ergänzen Sie das Programm so,
+      daß es auch mit \lstinline[style=cmd]{-Wall} ohne Warnungen
+      compiliert werden kann.
+      
+      Hinweis dazu: \lstinline{#include<stdio.h>}
+      (ohne Leerzeichen, um Platz zu sparen)
+      
+      Lösung der Zusatzaufgabe: \gitfile{hp}{2023ws/20231019}{loesung-4x.c}
+
+  \end{itemize}
+
+\end{document}
diff --git a/20231019/hp-uebung-20231019.pdf b/20231019/hp-uebung-20231019.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..802b54adb373a925f25e6e745496f663bd4e2269
Binary files /dev/null and b/20231019/hp-uebung-20231019.pdf differ
diff --git a/20231019/hp-uebung-20231019.tex b/20231019/hp-uebung-20231019.tex
new file mode 100644
index 0000000000000000000000000000000000000000..7ca234faa1788a56f217f6ea231f1928b47a6686
--- /dev/null
+++ b/20231019/hp-uebung-20231019.tex
@@ -0,0 +1,319 @@
+% hp-uebung-20231019.pdf - Exercises on Low-Level Programming / Applied Computer Sciences
+% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023  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: Seltsame Programme, Kalender-Berechnung, Strings, Programm analysieren
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+
+\begin{document}
+
+  \thispagestyle{empty}
+
+  \section*{Hardwarenahe Programmierung\\
+            Übungsaufgaben -- 19.\ Oktober 2023}
+
+  \exercise{Seltsame Programme}
+
+  Unter \url{https://gitlab.cvh-server.de/pgerwinski/hp/tree/2022ws/20211017}
+  finden Sie (unter anderem)\\
+  die Programme \gitfile{hp}{2023ws/20231019}{test-1.c},
+  \gitfile{hp}{2023ws/20231019}{test-2.c} und \gitfile{hp}{2023ws/20231019}{test-3.c}.
+
+  Was bewirken diese Programme, und warum verhalten sie sich so?
+
+  \exercise{Kalender-Berechnung}
+
+  Am 3.\,1.\,2009 meldete \emph{heise online\/}:
+  \begin{quote}
+    Kunden des ersten mobilen Media-Players von Microsoft
+    erlebten zum Jahresende eine böse Überraschung:
+    Am 31.\ Dezember 2008 fielen weltweit alle Zune-Geräte der ersten Generation aus.
+    Ursache war ein interner Fehler bei der Handhabung von Schaltjahren.
+
+    \strut\hfill\url{http://heise.de/-193332}, 
+  \end{quote}
+  Der Artikel verweist auf ein Quelltextfragment (Datei: \gitfile{hp}{2023ws/20231019}{aufgabe-2.c}),
+  das für einen gegebenen Wert \lstinline{days}
+  das Jahr und den Tag innerhalb des Jahres
+  für den \lstinline{days}-ten Tag nach dem 1.\,1.\,1980 berechnen soll:
+  \begin{lstlisting}
+     year = ORIGINYEAR;  /* = 1980 */
+
+     while (days > 365)
+       {
+         if (IsLeapYear (year))
+           {
+             if (days > 366)
+               {
+                 days -= 366;
+                 year += 1;
+               }
+           }
+         else
+           {
+             days -= 365;
+             year += 1;
+           }
+       }
+  \end{lstlisting}
+  Dieses Quelltextfragment enthält schlechten Programmierstil,
+  nämlich mehrere Code-Verdopplungen:
+  \begin{itemize}
+    \item
+      Die Anweisung \lstinline{year += 1} taucht an zwei Stellen auf.
+    \item
+      Es gibt zwei unabhängige Abfragen \lstinline{days > 365} und \lstinline{days > 366}:\\
+      eine in einer \lstinline{while}- und die andere in einer \lstinline{if}-Bedingung.
+    \item
+      Die Länge eines Jahres wird nicht durch eine Funktion berechnet oder in einer Variablen gespeichert;
+      stattdessen werden an mehreren Stellen die expliziten numerischen Konstanten 365 und 366 verwendet.
+  \end{itemize}
+  Diese Probleme führten am 31.\ Dezember 2008 zu einer Endlosschleife.
+
+  Gut hingegen ist die Verwendung einer Konstanten \lstinline{ORIGINYEAR}
+  anstelle der Zahl 1980
+  sowie die Kapselung der Berechnung der Schaltjahr-Bedingung
+  in einer Funktion \lstinline{IsLeapYear()}.
+
+  \begin{itemize}
+    \item[(a)]
+      Erklären Sie das Zustandekommen der Endlosschleife.
+    \item[(b)]
+      Schreiben Sie das Quelltextfragment so um, daß es die beschriebenen Probleme
+      nicht mehr enthält.
+  \end{itemize}
+
+  \textbf{Hinweis 1:} Verwenden Sie für \lstinline{IsLeapYear()}
+  Ihre eigene Funktion aus Aufgabe 1 der letzten Übung.
+
+  \textbf{Hinweis 2}: Schreiben Sie zusätzlich eine Funktion \lstinline{DaysInYear()}.
+
+  \exercise{Strings}
+
+  Strings werden in der Programmiersprache C
+  durch Zeiger auf \lstinline{char}-Variable realisiert.
+
+  Wir betrachten die folgende Funktion (Datei: \gitfile{hp}{2023ws/20231019}{aufgabe-3.c}):
+  \begin{center}
+    \begin{minipage}{8cm}
+      \begin{lstlisting}[gobble=8]
+        int fun_1 (char *s1, char *s2)
+        {
+          int result = 1;
+          for (int i = 0; s1[i] && s2[i]; i++)
+            if (s1[i] != s2[i])
+              result = 0;
+          return result;
+        }
+      \end{lstlisting}
+    \end{minipage}%
+  \end{center}
+  \begin{itemize}
+    \item[(a)]
+      Was bewirkt die Funktion? % \points{3}
+    \item[(b)]
+      Welchen Sinn hat die Bedingung "`\lstinline{s1[i] && s2[i]}"'
+      in der \lstinline{for}-Schleife? % \points{2}
+    \item[(c)]
+      Was würde sich ändern, wenn die Bedingung "`\lstinline{s1[i] && s2[i]}"'
+      in der \lstinline{for}-Schleife\\
+      zu "`\lstinline{s1[i]}"' verkürzt würde? % \points{3}
+%    \item[(d)]
+%      Von welcher Ordnung (Landau-Symbol) ist die Funktion \lstinline{fun_1()}
+%      hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen in den Strings
+%      -- und warum? % \points{2}
+    \item[(d)]
+      Schreiben Sie eine eigene Funktion,
+      die dieselbe Aufgabe erledigt wie \lstinline{fun_1()}, nur effizienter.
+%      und geben Sie die Ordnung (Landau-Symbol) der von Ihnen geschriebenen Funktion an. % \points{5}
+  \end{itemize}
+
+  \exercise{Programm analysieren}
+
+  Wir betrachten das folgende C-Programm (Datei: \gitfile{hp}{2023ws/20231019}{aufgabe-4.c}):
+  \begin{lstlisting}
+    char*f="char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";main(){printf(f,34,f,34,10);}
+  \end{lstlisting}
+  \vspace{-\medskipamount}
+  \begin{itemize}
+    \item[(a)]
+      Was bewirkt dieses Programm?
+    \item[(b)]
+      Wofür stehen die Zahlen?
+    \item[(c)]
+      Ergänzen Sie das Programm derart, daß seine \lstinline{main()}-Funktion
+      \lstinline{int main (void)} lautet und eine \lstinline{return}-Anweisung hat,
+      wobei die in Aufgabenteil (a) festgestellte Eigenschaft erhalten bleiben soll.
+  \end{itemize}
+
+\end{document}
+
+% README: Seltsame Programme, Kalender-Berechnung, Strings, Programm analysieren
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+
+\begin{document}
+
+  \thispagestyle{empty}
+
+  \section*{Hardwarenahe Programmierung\\
+            Übungsaufgaben -- 17.\ Oktober 2022}
+
+  \exercise{Seltsame Programme}
+
+  Unter \url{https://gitlab.cvh-server.de/pgerwinski/hp/tree/2022ws/20211017}
+  finden Sie (unter anderem)\\
+  die Programme \gitfile{hp}{2023ws/20231019}{test-1.c},
+  \gitfile{hp}{2023ws/20231019}{test-2.c} und \gitfile{hp}{2023ws/20231019}{test-3.c}.
+
+  Was bewirken diese Programme, und warum verhalten sie sich so?
+
+  \exercise{Kalender-Berechnung}
+
+  Am 3.\,1.\,2009 meldete \emph{heise online\/}:
+  \begin{quote}
+    Kunden des ersten mobilen Media-Players von Microsoft
+    erlebten zum Jahresende eine böse Überraschung:
+    Am 31.\ Dezember 2008 fielen weltweit alle Zune-Geräte der ersten Generation aus.
+    Ursache war ein interner Fehler bei der Handhabung von Schaltjahren.
+
+    \strut\hfill\url{http://heise.de/-193332}, 
+  \end{quote}
+  Der Artikel verweist auf ein Quelltextfragment (Datei: \gitfile{hp}{2023ws/20231019}{aufgabe-2.c}),
+  das für einen gegebenen Wert \lstinline{days}
+  das Jahr und den Tag innerhalb des Jahres
+  für den \lstinline{days}-ten Tag nach dem 1.\,1.\,1980 berechnen soll:
+  \begin{lstlisting}
+     year = ORIGINYEAR;  /* = 1980 */
+
+     while (days > 365)
+       {
+         if (IsLeapYear (year))
+           {
+             if (days > 366)
+               {
+                 days -= 366;
+                 year += 1;
+               }
+           }
+         else
+           {
+             days -= 365;
+             year += 1;
+           }
+       }
+  \end{lstlisting}
+  Dieses Quelltextfragment enthält schlechten Programmierstil,
+  nämlich mehrere Code-Verdopplungen:
+  \begin{itemize}
+    \item
+      Die Anweisung \lstinline{year += 1} taucht an zwei Stellen auf.
+    \item
+      Es gibt zwei unabhängige Abfragen \lstinline{days > 365} und \lstinline{days > 366}:\\
+      eine in einer \lstinline{while}- und die andere in einer \lstinline{if}-Bedingung.
+    \item
+      Die Länge eines Jahres wird nicht durch eine Funktion berechnet oder in einer Variablen gespeichert;
+      stattdessen werden an mehreren Stellen die expliziten numerischen Konstanten 365 und 366 verwendet.
+  \end{itemize}
+  Diese Probleme führten am 31.\ Dezember 2008 zu einer Endlosschleife.
+
+  Gut hingegen ist die Verwendung einer Konstanten \lstinline{ORIGINYEAR}
+  anstelle der Zahl 1980
+  sowie die Kapselung der Berechnung der Schaltjahr-Bedingung
+  in einer Funktion \lstinline{IsLeapYear()}.
+
+  \begin{itemize}
+    \item[(a)]
+      Erklären Sie das Zustandekommen der Endlosschleife.
+    \item[(b)]
+      Schreiben Sie das Quelltextfragment so um, daß es die beschriebenen Probleme
+      nicht mehr enthält.
+  \end{itemize}
+
+  \textbf{Hinweis 1:} Verwenden Sie für \lstinline{IsLeapYear()}
+  Ihre eigene Funktion aus Aufgabe 1 der letzten Übung.
+
+  \textbf{Hinweis 2}: Schreiben Sie zusätzlich eine Funktion \lstinline{DaysInYear()}.
+
+  \exercise{Strings}
+
+  Strings werden in der Programmiersprache C
+  durch Zeiger auf \lstinline{char}-Variable realisiert.
+
+  Wir betrachten die folgende Funktion (Datei: \gitfile{hp}{2023ws/20231019}{aufgabe-3.c}):
+  \begin{center}
+    \begin{minipage}{8cm}
+      \begin{lstlisting}[gobble=8]
+        int fun_1 (char *s1, char *s2)
+        {
+          int result = 1;
+          for (int i = 0; s1[i] && s2[i]; i++)
+            if (s1[i] != s2[i])
+              result = 0;
+          return result;
+        }
+      \end{lstlisting}
+    \end{minipage}%
+  \end{center}
+  \begin{itemize}
+    \item[(a)]
+      Was bewirkt die Funktion? % \points{3}
+    \item[(b)]
+      Welchen Sinn hat die Bedingung "`\lstinline{s1[i] && s2[i]}"'
+      in der \lstinline{for}-Schleife? % \points{2}
+    \item[(c)]
+      Was würde sich ändern, wenn die Bedingung "`\lstinline{s1[i] && s2[i]}"'
+      in der \lstinline{for}-Schleife\\
+      zu "`\lstinline{s1[i]}"' verkürzt würde? % \points{3}
+%    \item[(d)]
+%      Von welcher Ordnung (Landau-Symbol) ist die Funktion \lstinline{fun_1()}
+%      hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen in den Strings
+%      -- und warum? % \points{2}
+    \item[(d)]
+      Schreiben Sie eine eigene Funktion,
+      die dieselbe Aufgabe erledigt wie \lstinline{fun_1()}, nur effizienter.
+%      und geben Sie die Ordnung (Landau-Symbol) der von Ihnen geschriebenen Funktion an. % \points{5}
+  \end{itemize}
+
+  \exercise{Programm analysieren}
+
+  Wir betrachten das folgende C-Programm (Datei: \gitfile{hp}{2023ws/20231019}{aufgabe-4.c}):
+  \begin{lstlisting}
+    char*f="char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";main(){printf(f,34,f,34,10);}
+  \end{lstlisting}
+  \vspace{-\medskipamount}
+  \begin{itemize}
+    \item[(a)]
+      Was bewirkt dieses Programm?
+    \item[(b)]
+      Wofür stehen die Zahlen?
+    \item[(c)]
+      Ergänzen Sie das Programm derart, daß seine \lstinline{main()}-Funktion
+      \lstinline{int main (void)} lautet und eine \lstinline{return}-Anweisung hat,
+      wobei die in Aufgabenteil (a) festgestellte Eigenschaft erhalten bleiben soll.
+  \end{itemize}
+
+\end{document}
diff --git a/20231019/loesung-2-4.c b/20231019/loesung-2-4.c
new file mode 100644
index 0000000000000000000000000000000000000000..d141e32582374a3b3e6955f5634191d15edb3709
--- /dev/null
+++ b/20231019/loesung-2-4.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+
+int IsLeapYear (int year)
+{
+  if (year % 4)
+    return 0;
+  else if (year % 100)
+    return 1;
+  else if (year % 400)
+    return 0;
+  else
+    return 1;
+}
+
+int main (void)
+{
+  int ORIGINYEAR = 1980;
+  int days = 366;
+  int year;
+
+  year = ORIGINYEAR;  /* = 1980 */
+
+  int DaysInYear;
+  if (IsLeapYear (year))
+    DaysInYear = 366;
+  else
+    DaysInYear = 365;
+
+  while (days > DaysInYear)
+    {
+      days -= DaysInYear;
+      year += 1;
+      if (IsLeapYear (year))
+        DaysInYear = 366;
+      else
+        DaysInYear = 365;
+    }
+
+  printf ("year = %d\ndays = %d\n", year, days);
+  return 0;
+}
diff --git a/20231019/loesung-2-5.c b/20231019/loesung-2-5.c
new file mode 100644
index 0000000000000000000000000000000000000000..8a71934b7df24a28d11a6696e212aaccc430277f
--- /dev/null
+++ b/20231019/loesung-2-5.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+int IsLeapYear (int year)
+{
+  if (year % 4)
+    return 0;
+  else if (year % 100)
+    return 1;
+  else if (year % 400)
+    return 0;
+  else
+    return 1;
+}
+
+int main (void)
+{
+  int ORIGINYEAR = 1980;
+  int days = 366;
+  int year;
+
+  year = ORIGINYEAR;  /* = 1980 */
+
+  int DaysInYear;
+
+  while (days > (DaysInYear = IsLeapYear (year) ? 366 : 365))
+    {
+      days -= DaysInYear;
+      year += 1;
+    }
+
+  printf ("year = %d\ndays = %d\n", year, days);
+  return 0;
+}
diff --git a/20231019/loesung-2-6.c b/20231019/loesung-2-6.c
new file mode 100644
index 0000000000000000000000000000000000000000..0605571480991d1ec73a8cec50395ddf68ae3135
--- /dev/null
+++ b/20231019/loesung-2-6.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+int IsLeapYear (int year)
+{
+  if (year % 4)
+    return 0;
+  else if (year % 100)
+    return 1;
+  else if (year % 400)
+    return 0;
+  else
+    return 1;
+}
+
+int DaysInYear (int year)
+{
+  if (IsLeapYear (year))
+    return 366;
+  else
+    return 365;
+}
+
+int main (void)
+{
+  int ORIGINYEAR = 1980;
+  int days = 366;
+  int year;
+
+  year = ORIGINYEAR;  /* = 1980 */
+
+  while (days > DaysInYear (year))
+    {
+      days -= DaysInYear (year);
+      year += 1;
+    }
+
+  printf ("year = %d\ndays = %d\n", year, days);
+  return 0;
+}
diff --git a/20231019/loesung-2-7.c b/20231019/loesung-2-7.c
new file mode 100644
index 0000000000000000000000000000000000000000..5c98286730aae146cf587b5f3401eb6eadd17aa7
--- /dev/null
+++ b/20231019/loesung-2-7.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+
+int IsLeapYear (int year)
+{
+  if (year % 4)
+    return 0;
+  else if (year % 100)
+    return 1;
+  else if (year % 400)
+    return 0;
+  else
+    return 1;
+}
+
+int DaysInYear (int year)
+{
+  if (IsLeapYear (year))
+    return 366;
+  else
+    return 365;
+}
+
+int main (void)
+{
+  int ORIGINYEAR = 1980;
+  int days = 366;
+  int year;
+
+  year = ORIGINYEAR;  /* = 1980 */
+
+  int d;
+
+  while (days > (d = DaysInYear (year)))
+    {
+      days -= d;
+      year += 1;
+    }
+
+  printf ("year = %d\ndays = %d\n", year, days);
+  return 0;
+}
diff --git a/20231019/loesung-2-8.c b/20231019/loesung-2-8.c
new file mode 100644
index 0000000000000000000000000000000000000000..e94dc80375b88fd5ff3245e8a99f76a5955b6bb8
--- /dev/null
+++ b/20231019/loesung-2-8.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+
+int IsLeapYear (int year)
+{
+  if (year % 4)
+    return 0;
+  else if (year % 100)
+    return 1;
+  else if (year % 400)
+    return 0;
+  else
+    return 1;
+}
+
+int DaysInYear (int year)
+{
+  if (IsLeapYear (year))
+    return 366;
+  else
+    return 365;
+}
+
+int main (void)
+{
+  int ORIGINYEAR = 1980;
+  int days = 366;
+  int year;
+
+  year = ORIGINYEAR;  /* = 1980 */
+
+  int d = DaysInYear (year);
+
+  while (days > d)
+    {
+      days -= d;
+      year += 1;
+      d = DaysInYear (year);
+    }
+
+  printf ("year = %d\ndays = %d\n", year, days);
+  return 0;
+}
diff --git a/20231019/loesung-2-f1.c b/20231019/loesung-2-f1.c
new file mode 100644
index 0000000000000000000000000000000000000000..4d511c4fa7ee6a9dfb0bc2f69412eeb48745af56
--- /dev/null
+++ b/20231019/loesung-2-f1.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+
+int IsLeapYear (int year)
+{
+  if (year % 4)
+    return 0;
+  else if (year % 100)
+    return 1;
+  else if (year % 400)
+    return 0;
+  else
+    return 1;
+}
+
+int main (void)
+{
+  int ORIGINYEAR = 1980;
+  int days = 366;
+  int year;
+
+  year = ORIGINYEAR;  /* = 1980 */
+
+  while (days > 365)
+    {
+      if (IsLeapYear (year))
+        {
+          if (days > 366)
+            {
+              days -= 366;
+              year += 1;
+            }
+        }
+      else
+        {
+          days -= 365;
+          year += 1;
+        }
+    }
+
+  printf ("year = %d\ndays = %d\n", year, days);
+  return 0;
+}
diff --git a/20231019/loesung-2-f2.c b/20231019/loesung-2-f2.c
new file mode 100644
index 0000000000000000000000000000000000000000..a44edb09ffde3d3c77cfe673da862260368c33e3
--- /dev/null
+++ b/20231019/loesung-2-f2.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+
+int IsLeapYear (int year)
+{
+  if (year % 4)
+    return 0;
+  else if (year % 100)
+    return 1;
+  else if (year % 400)
+    return 0;
+  else
+    return 1;
+}
+
+int main (void)
+{
+  int ORIGINYEAR = 1980;
+  int days = 366;
+  int year;
+
+  year = ORIGINYEAR;  /* = 1980 */
+
+  while ((IsLeapYear (year) && days > 366)
+         || (!IsLeapYear (year) && days > 365))
+    {
+      if (IsLeapYear (year))
+        {
+          if (days > 366)
+            {
+              days -= 366;
+              year += 1;
+            }
+        }
+      else
+        {
+          days -= 365;
+          year += 1;
+        }
+    }
+
+  printf ("year = %d\ndays = %d\n", year, days);
+  return 0;
+}
diff --git a/20231019/loesung-2-f3.c b/20231019/loesung-2-f3.c
new file mode 100644
index 0000000000000000000000000000000000000000..dbfe5040274953c3b90d6b2da194c0c8ae64f04f
--- /dev/null
+++ b/20231019/loesung-2-f3.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+
+int IsLeapYear (int year)
+{
+  if (year % 4)
+    return 0;
+  else if (year % 100)
+    return 1;
+  else if (year % 400)
+    return 0;
+  else
+    return 1;
+}
+
+int main (void)
+{
+  int ORIGINYEAR = 1980;
+  int days = 366;
+  int year;
+
+  year = ORIGINYEAR;  /* = 1980 */
+
+  while (days > (IsLeapYear (year) ? 366 : 365))
+    {
+      if (IsLeapYear (year))
+        {
+          if (days > 366)
+            {
+              days -= 366;
+              year += 1;
+            }
+        }
+      else
+        {
+          days -= 365;
+          year += 1;
+        }
+    }
+
+  printf ("year = %d\ndays = %d\n", year, days);
+  return 0;
+}
diff --git a/20231019/loesung-3.c b/20231019/loesung-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..29a2b7f234ea5c31b06780e9dd461dff95dd33a3
--- /dev/null
+++ b/20231019/loesung-3.c
@@ -0,0 +1,67 @@
+#include <stdio.h>
+
+int fun_1 (char *s1, char *s2)
+{
+  int result = 1;
+  for (int i = 0; s1[i] && s2[i]; i++)
+    if (s1[i] != s2[i])
+      result = 0;
+  return result;
+}
+
+int fun_2 (char *s1, char *s2)
+{
+  int result = 1;
+  for (int i = 0; s1[i] && s2[i] && result; i++)
+    if (s1[i] != s2[i])
+      result = 0;
+  return result;
+}
+
+int fun_3 (char *s1, char *s2)
+{
+  for (int i = 0; s1[i] && s2[i]; i++)
+    if (s1[i] != s2[i])
+      return 0;
+  return 1;
+}
+
+int fun_4 (char *s1, char *s2)
+{
+  int result = 1;
+  for (int i = 0; s1[i] && s2[i]; i++)
+    if (s1[i] != s2[i])
+      {
+        result = 0;
+        break;
+      }
+  return result;
+}
+
+int main (void)
+{
+  char *s1 = "Apfel";
+  char *s2 = "Apfelkuchen";
+  if (fun_1 (s1, s2) && fun_2 (s1, s2) && fun_3 (s1, s2) && fun_4 (s1, s2))
+    printf ("OK\n");
+  else
+    printf ("failed\n");
+  s1 = "Apfelkuchen";
+  s2 = "Apfel";
+  if (fun_1 (s1, s2) && fun_2 (s1, s2) && fun_3 (s1, s2) && fun_4 (s1, s2))
+    printf ("OK\n");
+  else
+    printf ("failed\n");
+  s2 = "Birnenmarmelade";
+  if (fun_1 (s1, s2) || fun_2 (s1, s2) || fun_3 (s1, s2) || fun_4 (s1, s2))
+    printf ("failed\n");
+  else
+    printf ("OK\n");
+  s1 = s2;
+  s2 = "Apfelkuchen";
+  if (fun_1 (s1, s2) || fun_2 (s1, s2) || fun_3 (s1, s2) || fun_4 (s1, s2))
+    printf ("failed\n");
+  else
+    printf ("OK\n");
+  return 0;
+}
diff --git a/20231019/loesung-4.c b/20231019/loesung-4.c
new file mode 100644
index 0000000000000000000000000000000000000000..6346384a81d62e7e687f4db99be3ba8fe4020744
--- /dev/null
+++ b/20231019/loesung-4.c
@@ -0,0 +1 @@
+char*f="char*f=%c%s%c;int main(void){printf(f,34,f,34,10);return 0;}%c";int main(void){printf(f,34,f,34,10);return 0;}
diff --git a/20231019/loesung-4x.c b/20231019/loesung-4x.c
new file mode 100644
index 0000000000000000000000000000000000000000..fcc65e153ddf009f55af118278774cd202f7c316
--- /dev/null
+++ b/20231019/loesung-4x.c
@@ -0,0 +1,2 @@
+#include<stdio.h>
+char*f="#include<stdio.h>%cchar*f=%c%s%c;int main(void){printf(f,10,34,f,34,10);return 0;}%c";int main(void){printf(f,10,34,f,34,10);return 0;}
diff --git a/20231019/logo-hochschule-bochum-cvh-text-v2.pdf b/20231019/logo-hochschule-bochum-cvh-text-v2.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..4aa99b8f81061aca6dcaf43eed2d9efef40555f8
--- /dev/null
+++ b/20231019/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/20231019/logo-hochschule-bochum.pdf b/20231019/logo-hochschule-bochum.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1
--- /dev/null
+++ b/20231019/logo-hochschule-bochum.pdf
@@ -0,0 +1 @@
+../common/logo-hochschule-bochum.pdf
\ No newline at end of file
diff --git a/20231019/pgscript.sty b/20231019/pgscript.sty
new file mode 120000
index 0000000000000000000000000000000000000000..95c888478c99ea7fda0fd11ccf669ae91be7178b
--- /dev/null
+++ b/20231019/pgscript.sty
@@ -0,0 +1 @@
+../common/pgscript.sty
\ No newline at end of file
diff --git a/20231019/pgslides.sty b/20231019/pgslides.sty
new file mode 120000
index 0000000000000000000000000000000000000000..5be1416f4216f076aa268901f52a15d775e43f64
--- /dev/null
+++ b/20231019/pgslides.sty
@@ -0,0 +1 @@
+../common/pgslides.sty
\ No newline at end of file
diff --git a/20231019/test-1.c b/20231019/test-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..9dcb8ff47664fe804b3c9973166afe0d28b53ade
--- /dev/null
+++ b/20231019/test-1.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int main (void)
+{
+  return
+  printf ("Hello, world!\n"),
+  0;
+}
diff --git a/20231019/test-2.c b/20231019/test-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..216c924cde653228187b133b1a899765eb865584
--- /dev/null
+++ b/20231019/test-2.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+int main (void)
+{
+  int a = 137;
+  int b = 13 * a;
+  if (b = 42)
+    printf ("Die Antwort lautet: %d\n", b);
+  else
+    printf ("Die Antwort lautet: keine Ahnung\n");
+  return 0;
+}
diff --git a/20231019/test-3.c b/20231019/test-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..b8964c8308aec57ed4de30acae8c3e3d31b9fa38
--- /dev/null
+++ b/20231019/test-3.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int main (void)
+{
+  int a = 42;
+  printf ("Die Antwort lautet: ");
+  printf (a);
+  return 0;
+}
diff --git a/README.md b/README.md
index 2ace90665843143326fe32d0d9e0df95a38a549a..4033d36906f26587022f0fa14b9623efdfd40d1f 100644
--- a/README.md
+++ b/README.md
@@ -19,16 +19,19 @@ Vortragsfolien und Beispiele:
 -----------------------------
  * [05.10.2023: Einführung, Einführung in C (bis 2.7: Strukturierte Programmierung)](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231005/hp-20231005.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/2023ws/20231005/)
  * [12.10.2023: Einführung in C (ab 2.8: Seiteneffekte)](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231012/hp-20231012.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/2023ws/20231012/)
+ * [19.10.2023: Einführung in C (ab 2.11: Arrays und Strings)](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231019/hp-20231019.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/2023ws/20231019/)
  * [alle in 1 Datei](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/hp-slides-2023ws.pdf)
 
 Übungsaufgaben:
 ---------------
  * [05.10.2023: Hello-World-Programme, Schaltjahr ermitteln, Maximum berechnen](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231005/hp-uebung-20231005.pdf)
  * [12.10.2023: Schaltjahr ermitteln, Multiplikationstabelle, Fibonacci-Zahlen, fehlerhaftes Programm](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231012/hp-uebung-20231012.pdf)
+ * [19.10.2023: Seltsame Programme, Kalender-Berechnung, Strings, Programm analysieren](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231019/hp-uebung-20231019.pdf)
 
 Musterlösungen:
 ---------------
  * [12.10.2023: Schaltjahr ermitteln, Multiplikationstabelle, Fibonacci-Zahlen, fehlerhaftes Programm](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231012/hp-musterloesung-20231012.pdf)
+ * [19.10.2023: Seltsame Programme, Kalender-Berechnung, Strings, Programm analysieren](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2023ws/20231019/hp-musterloesung-20231019.pdf)
 
 Praktikumsunterlagen:
 ---------------------
diff --git a/hp-slides-2023ws.pdf b/hp-slides-2023ws.pdf
index 4d5db7364d2cc82f44196bd6b647a252f14b182c..b1442153c8d1d391ed95209a412afd12f4768fd1 100644
Binary files a/hp-slides-2023ws.pdf and b/hp-slides-2023ws.pdf differ
diff --git a/hp-slides-2023ws.tex b/hp-slides-2023ws.tex
index 884af13404add23b3074b799135a477c7e4c6317..585323fb35ae2742d5b8fecd872cbfcb278e1c84 100644
--- a/hp-slides-2023ws.tex
+++ b/hp-slides-2023ws.tex
@@ -15,4 +15,6 @@
   \includepdf[pages=-]{20231005/hp-20231005.pdf}
   \pdfbookmark[1]{12.10.2023: Einführung in C (ab 2.8: Seiteneffekte)}{20231012}
   \includepdf[pages=-]{20231012/hp-20231012.pdf}
+  \pdfbookmark[1]{19.10.2023: Einführung in C (ab 2.11: Arrays und Strings)}{20231019}
+  \includepdf[pages=-]{20231019/hp-20231019.pdf}
 \end{document}