diff --git a/20231123/hp-20231123.pdf b/20231123/hp-20231123.pdf index 44bf8dfc4de090990e3d4061099d2bb3a366ec7f..a9875318c61eedb0a03d50cbe6ec40a21a25e20a 100644 Binary files a/20231123/hp-20231123.pdf and b/20231123/hp-20231123.pdf differ diff --git a/20231123/hp-20231123.tex b/20231123/hp-20231123.tex index eda7fca5dcfed48f0854d68b34d6d1fd01c45ed8..abcaac6d80172739a5cba19e311644614a829824 100644 --- a/20231123/hp-20231123.tex +++ b/20231123/hp-20231123.tex @@ -551,6 +551,7 @@ \begin{picture}(0,0) \put(8,-6.5){\includegraphics{pendulum.pdf}} + \put(5,-1.5){\rotatebox{10}{\color{red}\bf\textarrow\ nächste Woche}} \end{picture} \begin{eqnarray*} diff --git a/20231123/hp-musterloesung-20231123.pdf b/20231123/hp-musterloesung-20231123.pdf index 1782abc389d59c3de4999c95356c99baf45cd738..5a40d75a038f32e91e57df6c59f75740d7562454 100644 Binary files a/20231123/hp-musterloesung-20231123.pdf and b/20231123/hp-musterloesung-20231123.pdf differ diff --git a/20231123/hp-musterloesung-20231123.tex b/20231123/hp-musterloesung-20231123.tex index 810480f0f431e547c1f4cc9f472b1337f2598e0b..08bc1dbcf1f13936a99768deae1f2bec54828b66 100644 --- a/20231123/hp-musterloesung-20231123.tex +++ b/20231123/hp-musterloesung-20231123.tex @@ -1,4 +1,4 @@ -% hp-musterloesung-20231116.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences +% hp-musterloesung-20231123.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 @@ -30,7 +30,7 @@ \begin{document} \section*{Hardwarenahe Programmierung\\ - Musterlösung zu den Übungsaufgaben -- 16.\ November 2023} + Musterlösung zu den Übungsaufgaben -- 23.\ November 2023} \exercise{Kondensator} diff --git a/20231130/Tower_of_Hanoi.jpeg b/20231130/Tower_of_Hanoi.jpeg new file mode 120000 index 0000000000000000000000000000000000000000..a1a794afda08596ffa2f46f278db53455de25b6c --- /dev/null +++ b/20231130/Tower_of_Hanoi.jpeg @@ -0,0 +1 @@ +../common/Tower_of_Hanoi.jpeg \ No newline at end of file diff --git a/20231130/aufgabe-1.c b/20231130/aufgabe-1.c new file mode 100644 index 0000000000000000000000000000000000000000..ac63ca250c79fd76c26f4045ece703407024a4ce --- /dev/null +++ b/20231130/aufgabe-1.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +/* ... */ + +int main (void) +{ + pbm_open (14, 14, "test.pbm"); + pbm_line (" "); + pbm_line (" XXXXXX "); + pbm_line (" X X "); + pbm_line (" X X "); + pbm_line (" X X "); + pbm_line (" X XX XX X "); + pbm_line (" X X X X "); + pbm_line (" X X "); + pbm_line (" X X X X "); + pbm_line (" X X X X "); + pbm_line (" X XXXX X "); + pbm_line (" X X "); + pbm_line (" XXXXXX "); + pbm_line (" "); + pbm_close (); + return 0; +} diff --git a/20231130/aufgabe-1.pbm b/20231130/aufgabe-1.pbm new file mode 100644 index 0000000000000000000000000000000000000000..bc5b70b1ad6f7236ec9469afac311f05fb056946 Binary files /dev/null and b/20231130/aufgabe-1.pbm differ diff --git a/20231130/aufgabe-1.png b/20231130/aufgabe-1.png new file mode 100644 index 0000000000000000000000000000000000000000..e655af0096cc6e50da81c8f820395dfaed27277f Binary files /dev/null and b/20231130/aufgabe-1.png differ diff --git a/20231130/aufgabe-2.c b/20231130/aufgabe-2.c new file mode 100644 index 0000000000000000000000000000000000000000..abbf364a3db17611e41d086591826e98a8a3672b --- /dev/null +++ b/20231130/aufgabe-2.c @@ -0,0 +1,16 @@ +#include <stdio.h> + +int fak (int n) +{ + if (n <= 0) + return 1; + else + return n * fak (n - 1); +} + +int main (void) +{ + for (int n = 0; n <= 5; n++) + printf ("%d\n", fak (n)); + return 0; +} diff --git a/20231130/aufgabe-3.c b/20231130/aufgabe-3.c new file mode 100644 index 0000000000000000000000000000000000000000..15c90561b94d5a0c1a136f0e6479d3633dc242b1 --- /dev/null +++ b/20231130/aufgabe-3.c @@ -0,0 +1,18 @@ +#include <stdio.h> +#include <string.h> + +void insert_into_string (char src, char *target, int pos) +{ + int len = strlen (target); + for (int i = pos; i < len; i++) + target[i + 1] = target[i]; + target[pos] = src; +} + +int main (void) +{ + char test[100] = "Hochshule Bochum"; + insert_into_string ('c', test, 5); + printf ("%s\n", test); + return 0; +} diff --git a/20231130/hp-20231130.pdf b/20231130/hp-20231130.pdf new file mode 100644 index 0000000000000000000000000000000000000000..66a0a71f6fe530d0c1e6581494b379a7654070ad Binary files /dev/null and b/20231130/hp-20231130.pdf differ diff --git a/20231130/hp-20231130.tex b/20231130/hp-20231130.tex new file mode 100644 index 0000000000000000000000000000000000000000..c878d5d163e8a26275d773eab12032d163964ddf --- /dev/null +++ b/20231130/hp-20231130.tex @@ -0,0 +1,595 @@ +% hp-20231130.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: Algorithmen: Rekursion, Aufwandsabschätzungen + +\documentclass[10pt,t]{beamer} + +\usepackage{pgslides} +\usepackage{tikz} + +\newcommand{\redurl}[1]{\href{#1}{\color{red}\nolinkurl{#1}}} + +\title{Hardwarenahe Programmierung} +\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski} +\date{30.\ November 2023} + +\begin{document} + +\maketitleframe + +\title{Hardwarenahe Programmierung} + +\nosectionnonumber{\inserttitle} + +\begin{frame} + + \shownosectionnonumber + + \begin{itemize} + \item[\textbf{1}] \textbf{Einführung} + \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp}}} + \item[\textbf{2}] \textbf{Einführung in C} + \item[\textbf{3}] \textbf{Bibliotheken} + \item[\textbf{4}] \textbf{Hardwarenahe Programmierung} + \begin{itemize} + \vspace*{-\smallskipamount} + \item[\dots] + \color{medgreen} + \item[4.7] Binärdarstellung von Gleitkommazahlen + \item[4.8] Speicherausrichtung -- Alignment + \end{itemize} + \item[\textbf{5}] \textbf{Algorithmen} + \begin{itemize} + \color{orange} + \item[5.1] Differentialgleichungen + \color{red} + \item[5.2] Rekursion + \item[5.3] Aufwandsabschätzungen + \end{itemize} + \item[\textbf{6}] \textbf{Objektorientierte Programmierung} + \item[\textbf{7}] \textbf{Datenstrukturen} + \end{itemize} + +\end{frame} + +\setcounter{section}{3} +\section{Hardwarenahe Programmierung} +\setcounter{subsection}{6} +\subsection{Binärdarstellung von Gleitkommazahlen} + +\begin{frame}[fragile] + + \showsubsection + +% (Diese Seite wurde unbewußt leer gelassen.) + + Beispiel für Gleitkommazahl: $2{,}351\cdot10^5$ (oder: $2.351\times10^5$) + + \smallskip + + Bezeichnungen: $\text{Mantisse} \cdot 10^{\text{Exponent}}$ + + \smallskip + + C-Schreibweise: \lstinline{2.351e5} (oder: \lstinline{2.351E5}) + +% \pause + \bigskip + + Wie speichert man Gleitkommazahlen? + + \smallskip + + $m$-Bit-Zahl, davon + \begin{itemize} + \item + $e$ Bits für den Exponenten (einschließlich Vorzeichen), + \item + $1$ Bit für das Vorzeichen der Mantisse, + \item + $m - e - 1$ Bits für die Mantisse. + \end{itemize} + +% \pause + \begin{picture}(0,0) + \color{red} + \put(1.95,0.65){\makebox(0,0){\tikz{\draw(0,0)--(0.5,0.25);}}} + \put(1.95,0.65){\makebox(0,0){\tikz{\draw(0,0.25)--(0.5,0);}}} + \end{picture}% + {\color{red}Trick: Mantisse als \newterm{normalisierte Zahl\/} abspeichern} + +% \pause + \bigskip + Vorteil gegenüber ganzen Zahlen:\\ + größerer Wertebereich bei vergleichbarem Speicherplatzbedarf + + \medskip + + Nachteil gegenüber ganzen Zahlen: Rundungsfehler\\ + \textcolor{red}{\textarrow\ + \textbf{ungeeignet} für Anwendungen, bei denen es auf jedes Bit ankommt\\ + \phantom{\textarrow\ }(z.\,B.\ Verschlüsselung)} + \vspace*{-1cm} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Problem beim Arbeiten mit Gleitkommazahlen: Auslöschung von Ziffern + \begin{itemize} + \item + Zahlen aufsummieren:\\ + vorher sortieren, mit der kleinsten Zahl beginnen +% \pause + \item + Ableitungen bilden:\\ + Beim Bilden von Differenzquotienten\\ + verliert man notwendigerweise an Präzision!\\ + \textarrow\ Die Differenzen sehr sorgfältig auswählen.\\ + \textarrow\ Am besten gar nicht ableiten, sondern integrieren.\\ +% \pause + (Trick: Ableiten über Fourier-Transformationen) + \end{itemize} + +\end{frame} + +\subsection{Speicherausrichtung -- Alignment} + +\begin{frame}[fragile] + + \showsubsection + + \begin{lstlisting} + #include <stdint.h> + + uint8_t a; + uint16_t b; + uint8_t c; + \end{lstlisting} + +% \pause + \bigskip + + Speicheradresse durch 2 teilbar -- "`16-Bit-Alignment"' + \begin{itemize} + \item + 2-Byte-Operation: effizienter +% \pause + \item + \dots\ oder sogar nur dann erlaubt +% \pause + \arrowitem + Compiler optimiert Speicherausrichtung + \end{itemize} + + \medskip + +% \pause + \begin{minipage}{3cm} + \begin{lstlisting}[gobble=6] + ¡uint8_t a; + uint8_t dummy; + uint16_t b; + uint8_t c;¿ + \end{lstlisting} + \end{minipage} +% \pause + \begin{minipage}{3cm} + \begin{lstlisting}[gobble=6] + ¡uint8_t a; + uint8_t c; + uint16_t b;¿ + \end{lstlisting} + \end{minipage} + +% \pause + \vspace{-1.75cm} + \strut\hfill + \begin{minipage}{6.5cm} + Fazit: + \begin{itemize} + \item + \textbf{Adressen von Variablen\\ + sind systemabhängig} + \item + Bei Definition von Datenformaten\\ + Alignment beachten \textarrow\ effizienter + \end{itemize} + \end{minipage} + +\end{frame} + +\section{Algorithmen} +\subsection{Differentialgleichungen} + +\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} + \strut + \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} + +\subsection{Rekursion} + +\begin{frame}[fragile] + + \showsubsection + + Vollständige Induktion: + \vspace*{-0.725cm} + \begin{displaymath} + \hspace*{4cm} + \left. + \begin{array}{r} + \mbox{Aussage gilt für $n = 1$}\\[2pt] + \mbox{Schluß von $n - 1$ auf $n$} + \end{array} + \right\} + \mbox{Aussage gilt für alle $n\in\mathbb{N}$} + \end{displaymath} + \vspace*{-0.5cm} + + \pause + + Türme von Hanoi + + \begin{onlyenv}<2> + \begin{center} + \includegraphics[width=12.2cm]{Tower_of_Hanoi.jpeg} + \end{center} + \end{onlyenv} + + \begin{onlyenv}<3-> + \begin{itemize} + \item + 64 Scheiben, 3 Plätze, + \only<3-4>{\hfill\makebox(0,0)[rt]{\includegraphics[width=6cm]{Tower_of_Hanoi.jpeg}}}\\ + immer 1 Scheibe verschieben + \item + Ziel: Turm verschieben + \item + Es dürfen nur kleinere Scheiben\\ + auf größeren liegen. + \bigskip + \pause + \pause + \item + $n = 1$ Scheibe: fertig + \item + Wenn $n - 1$ Scheiben verschiebbar:\\ + schiebe $n - 1$ Scheiben auf Hilfsplatz,\\ + verschiebe die darunterliegende,\\ + hole $n - 1$ Scheiben von Hilfsplatz + \end{itemize} + \begin{onlyenv}<5> + \vspace{-4.3cm} + \begin{lstlisting}[gobble=8,xleftmargin=6.4cm] + void move (int from, int to, int disks) + { + if (disks == 1) + move_one_disk (from, to); + else + { + int help = 0 + 1 + 2 - from - to; + move (from, help, disks - 1); + move (from, to, 1); + move (help, to, disks - 1); + } + } + \end{lstlisting} + \end{onlyenv} +% \begin{onlyenv}<6-> +% \vspace{-5.0cm} +% \hspace*{7.4cm}\begin{minipage}[t]{5cm} +% 32 Scheiben: +% \begin{lstlisting}[gobble=10,style=terminal] +% $ ¡time ./hanoi-9b¿ +% ... +% real 0m30,672s +% user 0m30,662s +% sys 0m0,008s +% \end{lstlisting} +% \pause[7] +% \begin{itemize} +% \arrowitem +% etwas über 1 Minute\\ +% für 64 Scheiben +% \end{itemize} +% \pause +% \vspace*{-0.5cm} +% \begin{picture}(0,0) +% \color{red} +% \put(0,0){\makebox(0,0)[bl]{\tikz[line width=1pt]{\draw(0,0)--(4,0.8);}}} +% \put(0,0.8){\makebox(0,0)[tl]{\tikz[line width=1pt]{\draw(0,0)--(4,-0.8);}}} +% \end{picture} +% +% Für jede zusätzliche Scheibe\\verdoppelt sich die Rechenzeit! +% % 30.672 * 2^32 / 3600 / 24 / 365.25 = 4174.43775518138261464750 +% \begin{itemize} +% \arrowitem +% $\frac{30,672\,\text{s}\,\cdot\,2^{32}}{3600\,\cdot\,24\,\cdot\,365,25} \approx 4174$ +% Jahre\\[\smallskipamount] +% für 64 Scheiben +% \end{itemize} +% \end{minipage} +% \end{onlyenv} + \end{onlyenv} + +\end{frame} + +\subsection{Aufwandsabschätzungen \protect\color{gray}-- Komplexitätsanalyse} + +\begin{frame}[fragile] + +% \newcommand{\w}{\hspace*{0.75pt}} + + \showsubsection + + \begin{picture}(0,0) + \put(7.6,-0.5){% + \begin{minipage}[t]{5.3cm} +% \vspace*{-1.0cm}\includegraphics{landau-symbols.pdf} + \vspace*{-1.0cm}\alt<16->{\includegraphics{landau-symbols-3.pdf}}% + {\alt<15->{\includegraphics{landau-symbols-2.pdf}}% + {\includegraphics{landau-symbols.pdf}}} + \small + \begin{description}\itemsep0pt\leftskip-0.5cm + \item[$n$:] Eingabedaten + \item[$g(n)$:] Rechenzeit + \end{description} + \end{minipage}} + \end{picture} + + \vspace*{-\bigskipamount} + + Wann ist ein Programm "`schnell"'? + + \medskip + + \begin{onlyenv}<1-2> + Türme von Hanoi: $\mathcal{O}(2^n)$ + \par\medskip + Für jede zusätzliche Scheibe\\verdoppelt sich die Rechenzeit! + \begin{itemize} + \arrowitem + $\frac{30,672\,\text{s}\,\cdot\,2^{32}}{3600\,\cdot\,24\,\cdot\,365,25} \approx 4174$ + Jahre\\[\smallskipamount] + für 64 Scheiben + \end{itemize} + + \bigskip + \end{onlyenv} + + \begin{onlyenv}<2-> + Faustregel:\\Schachtelung der Schleifen zählen\\ + $k$ Schleifen ineinander \textarrow\ $\mathcal{O}(n^k)$ + + \bigskip + \end{onlyenv} + + \begin{onlyenv}<3-13> + \textbf{Beispiel: Sortieralgorithmen} + + \smallskip + + Anzahl der Vergleiche bei $n$ Strings + \begin{itemize} + \item + Maximum suchen \pause[4]mit Schummeln\pause: $\mathcal{O}(1)$ + \pause + \item + Maximum suchen\pause: $\mathcal{O}(n)$ + \pause + \item + Selection-Sort\pause: $\mathcal{O}(n^2)$ + \pause + \item + Bubble-Sort\pause: $\mathcal{O}(n)$ bis $\mathcal{O}(n^2)$ + \pause + \item + Quicksort\pause: $\mathcal{O}(n\log n)$ bis $\mathcal{O}(n^2)$ + \end{itemize} + + \end{onlyenv} + + \begin{onlyenv}<14> + \textbf{Wie schnell ist RSA-Verschlüsselung?} + + \smallskip + + \begin{math} + c = m^e\,\%\,N + \end{math} + \quad + ("`$\%$"' = "`modulo"') + + \medskip + + \begin{lstlisting}[gobble=6,xleftmargin=2em] + int c = 1; + for (int i = 0; i < e; i++) + c = (c * m) % N; + \end{lstlisting} + + \smallskip + + \begin{itemize} + \item + $\mathcal{O}(e)$ Iterationen +% \item +% wenn $n$ die Anzahl der Binärziffern (Bits) von $e$ ist: +% $\mathcal{O}(2^n)$ Iterationen + \item + mit Trick: + $\mathcal{O}(\log e)$ Iterationen ($\log e$ = Anzahl der Ziffern von $e$) + \end{itemize} + + \smallskip + + Jede Iteration enthält eine Multiplikation und eine Division.\\ + Aufwand dafür: $\mathcal{O}(\log e)$\\ + \textarrow\ Gesamtaufwand: $\mathcal{O}\bigl((\log e)^2\bigr)$ + + \end{onlyenv} + + \begin{onlyenv}<15-> + + \textbf{Wie schnell ist RSA?}\\ + + \smallskip + + ($n$ = typische beteiligte Zahl, z.\,B. $e,p,q$) + + \begin{itemize} + \item + Ver- und Entschlüsselung (Exponentiation):\\ + \strut\hbox to 3.5cm{\color{red}$\mathcal{O}\!\left((\log n)^2\right)$\hss} + \only<16->{{\color{magenta}$\mathcal{O}(n^2)$}} + \item + Schlüsselerzeugung (Berechnung von $d$):\\ + \strut\hbox to 3.5cm{\color{red}$\mathcal{O}\!\left((\log n)^2\right)$\hss} + \only<16->{{\color{magenta}$\mathcal{O}(n^2)$}} + \item + Verschlüsselung brechen (Primfaktorzerlegung):\\ + \strut\hbox to 3.5cm{\color{red}$\mathcal{O}\bigl(2^{\sqrt{\log n\,\cdot\,\log\log n}}\bigr)$\hss} + \only<16->{{\color{magenta}$\mathcal{O}\bigl(2^{\sqrt{n\log n}}\bigr)$}} + \end{itemize} + + \vspace{0cm plus 1filll} + + \textbf{Die Sicherheit von RSA beruht darauf, + daß das Brechen der Verschlüsselung aufwendiger ist als + \boldmath$\mathcal{O}\bigl((\log n)^k\bigr)$ (für beliebiges $k$).} + + \vspace*{0.65cm} + + \end{onlyenv} + +\end{frame} + +\end{document} diff --git a/20231130/hp-musterloesung-20231130.pdf b/20231130/hp-musterloesung-20231130.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1782abc389d59c3de4999c95356c99baf45cd738 Binary files /dev/null and b/20231130/hp-musterloesung-20231130.pdf differ diff --git a/20231130/hp-musterloesung-20231130.tex b/20231130/hp-musterloesung-20231130.tex new file mode 100644 index 0000000000000000000000000000000000000000..670f107dfce1e3f1111745f6a32fcb58659b3092 --- /dev/null +++ b/20231130/hp-musterloesung-20231130.tex @@ -0,0 +1,375 @@ +% hp-musterloesung-20231130.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: PBM-Grafik, Einfügen in Strings (Ergänzung), Fakultät + +\documentclass[a4paper]{article} + +\usepackage{pgscript} +\usepackage{gnuplot-lua-tikz} + +\begin{document} + + \section*{Hardwarenahe Programmierung\\ + Musterlösung zu den Übungsaufgaben -- 30.\ November 2023} + + \exercise{PBM-Grafik} + + Bei einer PBM-Grafikdatei handelt es sich + um ein abgespeichertes C-Array von Bytes (\lstinline{uint8_t}), + das die Bildinformationen enthält: + \begin{itemize}\itemsep0pt + \item Die Datei beginnt mit der Kennung \lstinline{P4}, + danach folgen Breite und Höhe in Pixel als ASCII-Zahlen, + danach ein Trennzeichen und die eigentlichen Bilddaten. + \item Jedes Bit entspricht einem Pixel. + \item Nullen stehen für Weiß, Einsen für Schwarz. + \item MSB first. + \item Jede Zeile des Bildes wird auf ganze Bytes aufgefüllt. + \end{itemize} + Viele Grafikprogramme können PBM-Dateien öffnen und bearbeiten. + Der Anfang der Datei (Kennung, Breite und Höhe) + ist auch in einem Texteditor lesbar. + + Beispiel (\gitfile{hp}{2023ws/20231130}{aufgabe-1.pbm}):\hfill + \makebox(0,0)[tr]{\framebox{\includegraphics[scale=3]{aufgabe-1.png}}} + \begin{lstlisting} + P4 + 14 14 + <Bilddaten> + \end{lstlisting} + + In dem untenstehenden Programmfragment (\gitfile{hp}{2023ws/20231130}{aufgabe-1.c}) + wird eine Grafik aus Textzeilen zusammengesetzt, + so daß man mit einem Texteditor "`malen"' kann: + \begin{lstlisting} + #include <stdio.h> + + /* ... */ + + int main (void) + { + pbm_open (14, 14, "test.pbm"); + pbm_line (" "); + pbm_line (" XXXXXX "); + pbm_line (" X X "); + pbm_line (" X X "); + pbm_line (" X X "); + pbm_line (" X XX XX X "); + pbm_line (" X X X X "); + pbm_line (" X X "); + pbm_line (" X X X X "); + pbm_line (" X X X X "); + pbm_line (" X XXXX X "); + pbm_line (" X X "); + pbm_line (" XXXXXX "); + pbm_line (" "); + pbm_close (); + return 0; + } + \end{lstlisting} + Ergänzen Sie das Programmfragment so, + daß es eine Datei \file{test.pbm} erzeugt, die die Grafik enthält. + + Das Programm soll typische Benutzerfehler abfangen + (z.\,B.\ weniger Zeilen als in \lstinline{pbm_open} angegeben), + keine fehlerhaften Ausgaben produzieren oder abstürzen, + sondern stattdessen sinnvolle Fehlermeldungen ausgeben. + + Zum Vergleich liegt eine Datei \gitfile{hp}{2023ws/20231130}{aufgabe-1.pbm} + mit dem gewünschten Ergebnis bei,\\ + und die Datei \gitfile{hp}{2023ws/20231130}{aufgabe-1.png} enthält dasselbe Bild. + + \points{10} + + \solution + + Die Datei \gitfile{hp}{2023ws/20231130}{loesung-1.c} enthält eine richtige Lösung. + Man beachte die Aufrufe der Funktion \lstinline{error()} im Falle von + falscher Benutzung der Bibliotheksfunktionen. + Weitere Erklärungen finden Sie als Kommentare im Quelltext. + + Die Datei \gitfile{hp}{2023ws/20231130}{loesung-1f.c} enthält eine falsche Lösung. + (Beide Dateien unterscheiden sich nur in Zeile 46.) + Dieses Programm speichert die Bits in den Bytes von rechts nach links (LSB first). + Richtig wäre von links nach rechts (MBS first). + Das erzeugte Bild ist dementsprechend fehlerhaft. + + \exercise{Fakultät} + + Die Fakultät $n!$ einer ganzen Zahl $n \ge 0$ ist definiert als: + \begin{eqnarray*} + 1 & \mbox{für} & n = 0, \\ + n \cdot (n-1)! & \mbox{für} & n > 0. + \end{eqnarray*} + + Mit anderen Worten: $n! = 1\cdot2\cdot3\cdot\dots\cdot n$. + + Die folgende Funktion \lstinline{fak()} berechnet die Fakultät \emph{rekursiv} + (Datei: \gitfile{hp}{2023ws/20231130}{aufgabe-2.c}): + + \begin{lstlisting} + int fak (int n) + { + if (n <= 0) + return 1; + else + return n * fak (n - 1); + } + \end{lstlisting} + + \begin{enumerate}[\quad(a)] + \item + Schreiben Sie eine Funktion, die die Fakultät \emph{iterativ} berechnet,\\ + d.\,h.\ mit Hilfe einer Schleife anstelle von Rekursion. + \points{3} + \item + Wie viele Multiplikationen (Landau-Symbol) + erfordern beide Versionen der Fakultätsfunktion\\ + in Abhängigkeit von \lstinline$n$? + Begründen Sie Ihre Antwort. + \points{2} + \item + Wieviel Speicherplatz (Landau-Symbol) + erfordern beide Versionen der Fakultätsfunktion\\ + in Abhängigkeit von \lstinline$n$? + Begründen Sie Ihre Antwort. + \points{3} + \end{enumerate} + + \solution + + \begin{itemize} + \item[(a)] + \textbf{Schreiben Sie eine Funktion, die die Fakultät \emph{iterativ} berechnet,\\ + d.\,h.\ mit Hilfe einer Schleife anstelle von Rekursion.} + + Datei: \gitfile{hp}{2023ws/20231130}{loesung-2.c} + \begin{lstlisting}[gobble=8] + int fak (int n) + { + int f = 1; + for (int i = 2; i <= n; i++) + f *= i; + return f; + } + \end{lstlisting} + + \item[(b)] + \textbf{Wie viele Multiplikationen (Landau-Symbol) + erfordern beide Versionen der Fakultätsfunktion\\ + in Abhängigkeit von \lstinline$n$? + Begründen Sie Ihre Antwort.} + + In beiden Fällen werden $n$ Zahlen miteinander multipliziert -- + oder $n - 1$, wenn man Multiplikationen mit 1 ausspart. + In jedem Fall hängt die Anzahl der Multiplikationen + linear von $n$ ab; es sind $\mathcal{O}(n)$ Multiplikationen. + Insbesondere arbeiten also beide Versionen gleich schnell. + + \item[(c)] + \textbf{Wieviel Speicherplatz (Landau-Symbol) + erfordern beide Versionen der Fakultätsfunktion\\ + in Abhängigkeit von \lstinline$n$? + Begründen Sie Ihre Antwort.} + + Die iterative Version der Funktion benötigt 2 Variable vom Typ \lstinline{int}, + nämlich \lstinline{n} und \lstinline{f}. + Dies ist eine konstante Zahl; + der Speicherplatzverbrauch ist daher $\mathcal{O}(1)$. + + Die rekursive Version der Funktion erzeugt + jedesmal, wenn sie sich selbst aufruft, + eine zusätzliche Variable \lstinline{n}. + Es sind $n + 1$ Aufrufe; die Anzahl der Variablen \lstinline{n} + hängt linear von $n$ ab; der Speicherplatzverbrauch ist also $\mathcal{O}(n)$. + \end{itemize} + + \exercise{Einfügen in Strings (Ergänzung)} + + Diese Aufgabe ist eine Ergänzung von Aufgabe 3 der Übung vom 31.\ Oktober + 2022 um die Teilaufgaben (e), (f) und (g). Für den "`Klausur-Modus"' können + Sie die Teilaufgaben (a) bis (d) als "`bereits gelöst"' voraussetzen. + + Wir betrachten das folgende Programm (\gitfile{hp}{2023ws/20231130}{aufgabe-3.c}): +% \begin{lstlisting}[style=numbered] + \begin{lstlisting} + #include <stdio.h> + #include <string.h> + + void insert_into_string (char src, char *target, int pos) + { + int len = strlen (target); + for (int i = pos; i < len; i++) + target[i+1] = target[i]; + target[pos] = src; + } + + int main (void) + { + char test[100] = "Hochshule Bochum"; + insert_into_string ('c', test, 5); + printf ("%s\n", test); + return 0; + } + \end{lstlisting} + Die Ausgabe des Programms lautet: + \lstinline[style=terminal]{Hochschhhhhhhhhhh} + + \begin{enumerate}[\quad(a)] + \item + Erklären Sie, wie die Ausgabe zustandekommt. +% \points{3} +% \workspace{12} + \item + Schreiben Sie die Funktion \lstinline|insert_into_string()| so um, + daß sie den Buchstaben \lstinline{src} an der Stelle \lstinline{pos} + in den String \lstinline{target} einfügt.\par + Die Ausgabe des Programms müßte dann + \lstinline[style=terminal]{Hochschule Bochum} lauten. +% \points{2} +% \workspace{13} + \item + Was kann passieren, wenn Sie die Zeile + \lstinline{char test[100] = "Hochshule Bochum";}\\ + durch + \lstinline{char test[] = "Hochshule Bochum";} ersetzen? + Begründen Sie Ihre Antwort. +% \points{2} +% \workspace{10} + \item + Was kann passieren, wenn Sie die Zeile + \lstinline{char test[100] = "Hochshule Bochum";}\\ + durch + \lstinline{char *test = "Hochshule Bochum";} ersetzen? + Begründen Sie Ihre Antwort. +% \points{2} +% \workspace{10} + \item + Schreiben Sie eine Funktion + \lstinline{void insert_into_string_sorted (char src, char *target)}, + die voraussetzt, daß der String \lstinline{target} alphabetisch sortiert ist + und den Buchstaben \lstinline{src} an der alphabetisch richtigen Stelle + einfügt. Diese Funktion darf die bereits vorhandene Funktion + \lstinline|insert_into_string()| aufrufen.\\ + \points{4}\par + Zum Testen eignen sich die folgenden Zeilen im Hauptprogramm: + \begin{lstlisting}[gobble=8] + char test[100] = ""; + insert_into_string_sorted ('c', test); + insert_into_string_sorted ('a', test); + insert_into_string_sorted ('d', test); + insert_into_string_sorted ('b', test); + \end{lstlisting} + Danach sollte \lstinline{test[]} die Zeichenfolge \lstinline{"abcd"} enthalten. +% \workspace{14} + \goodbreak + \item + Wie schnell (Landau-Symbol in Abhängigkeit von der Länge $n$ des Strings) + arbeitet Ihre Funktion + \lstinline{void insert_into_string_sorted (char src, char *target)}? + Begründen Sie Ihre Antwort. + \points{1} +% \workspace{10} + \item + Beschreiben Sie -- in Worten oder als C-Quelltext --, wie man die Funktion\\ + \lstinline{void insert_into_string_sorted (char src, char *target)} + so gestalten kann,\\ + daß sie in $\mathcal{O}(\log n)$ arbeitet. + \points{3} +% \workspace{35} + \end{enumerate} + + \solution + + \textbf{Bemerkung:} Die in dieser Aufgabe und ihrer Musterlösung vorkommenden + Funktionen prüfen nicht, ob durch das Einfügen eines Zeichens der für den + String reservierte Speicherplatz überläuft. Ein derartiges Verhalten wäre + in einem "`echten"' Programm ein \textbf{Fehler}, der katastrophale Folgen + haben kann. Wenn dergleichen hier nicht berücksichtigt wird, dann nur, um + in einer Klausur nicht den zeitlichen Rahmen zu sprengen. + + \begin{enumerate}[\quad(a)] + \setcounter{enumi}{4} + \item + \textbf{Schreiben Sie eine Funktion + \lstinline{void insert_into_string_sorted (char src, char *target)}, + die voraussetzt, daß der String \lstinline{target} alphabetisch sortiert ist + und den Buchstaben \lstinline{src} an der\break alphabetisch richtigen Stelle + einfügt. Diese Funktion darf die bereits vorhandene Funktion\break + \lstinline|insert_into_string()| aufrufen.} + \begin{lstlisting}{gobble=8} + void insert_into_string_sorted (char src, char *target) + { + int i = 0; + while (target[i] && target[i] < src) + i++; + insert_into_string (src, target, i); + } + \end{lstlisting} + + Die Datei \gitfile{hp}{2023ws/20231130}{loesung-3e.c} enthält die o.\,a.\ Funktion + sowie zusätzliche Tests. + + \item + \textbf{Wie schnell (Landau-Symbol in Abhängigkeit von der Länge $n$ des Strings) + arbeitet Ihre Funktion + \lstinline{void insert_into_string_sorted (char src, char *target)}? + Begründen Sie Ihre Antwort.} + + Die Funktion sucht im Array \textbf{mittels einer Schleife} + nach der korrekten Position zum Einfügen des Zeichens + und hat daher von sich aus $\mathcal{O}(n)$. + + Anschließend ruft sie die Funktion \lstinline{insert_into_string()} auf, + die ebenfalls eine Schleife verwendet, um im Array Platz zu Einfügen zu schaffen, + und daher ebenfalls $\mathcal{O}(n)$ hat. + + Es bleibt daher bei $\mathcal{O}(n)$. + + \item + \textbf{Beschreiben Sie -- in Worten oder als C-Quelltext --, wie man die Funktion\\ + \lstinline{void insert_into_string_sorted (char src, char *target)} + so gestalten kann,\\ + daß sie in $\mathcal{O}(\log n)$ arbeitet.} + + In einem alphabetisch sortierten Array kann man die Suche in der Mitte beginnen + und sich durch Halbieren der Intervalle an die gesuchte Position herantasten. + Wegen des fortwährenden Halbierens geschieht dies in $\mathcal{O}(\log n)$. + (Für eine derartige Antwort gäbe es in der Klausur die volle Punktzahl.) + + Wenn wir allerdings anschließend für das eigentliche Einfügen die Funktion + \lstinline{insert_into_string()} verwenden, die dafür $\mathcal{O}(n)$ benötigt, + kommen wir insgesamt auf $\mathcal{O}(n)$. Ein sortiertes Einfügen in ein Array + ist daher in $\mathcal{O}(\log n)$ nicht möglich. + (Wer dies bemerkt, kann zum einen während der Klausur nachfragen, + wie denn die Aufgabenstellung genau gemeint ist, und sich zum anderen + für die besondere Sorgfalt Zusatzpunkte verdienen.) + + Die Datei \gitfile{hp}{2023ws/20231130}{loesung-3g.c} enthält einen C-Quelltext, + die den o.\,a.\ Algorithmus als Funktion implementiert. + Man beachte die Behandlung des Spezialfalls, + daß das einzufügende Zeichen am Ende angehängt werden muß. + + \end{enumerate} + +\end{document} diff --git a/20231130/hp-uebung-20231130.pdf b/20231130/hp-uebung-20231130.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7a90b036343cf43f9bc7573848921b7c1daccee4 Binary files /dev/null and b/20231130/hp-uebung-20231130.pdf differ diff --git a/20231130/hp-uebung-20231130.tex b/20231130/hp-uebung-20231130.tex new file mode 100644 index 0000000000000000000000000000000000000000..40e876f5c678e32eae661f3b04084212153790bc --- /dev/null +++ b/20231130/hp-uebung-20231130.tex @@ -0,0 +1,262 @@ +% hp-uebung-20231130.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: PBM-Grafik, Einfügen in Strings (Ergänzung), Fakultät + +\documentclass[a4paper]{article} + +\usepackage{pgscript} +\usepackage{gensymb} + +\newcommand{\ItwoC}{I\raisebox{0.5ex}{\footnotesize 2}C} +\newcommand{\ITWOC}{I\raisebox{0.5ex}{\normalsize 2}C} + +\begin{document} + + \thispagestyle{empty} + + \section*{Hardwarenahe Programmierung\\ + Übungsaufgaben -- 30.\ November 2023} + + Diese Übung enthält Punkteangaben wie in einer Klausur. + Um zu "`bestehen"', müssen Sie innerhalb von 75 Minuten + unter Verwendung ausschließlich zugelassener Hilfsmittel + 13 Punkte (von insgesamt \totalpoints) erreichen. + + \exercise{PBM-Grafik} + + Bei einer PBM-Grafikdatei handelt es sich + um ein abgespeichertes C-Array von Bytes (\lstinline{uint8_t}), + das die Bildinformationen enthält: + \begin{itemize}\itemsep0pt + \item Die Datei beginnt mit der Kennung \lstinline{P4}, + danach folgen Breite und Höhe in Pixel als ASCII-Zahlen, + danach ein Trennzeichen und die eigentlichen Bilddaten. + \item Jedes Bit entspricht einem Pixel. + \item Nullen stehen für Weiß, Einsen für Schwarz. + \item MSB first. + \item Jede Zeile des Bildes wird auf ganze Bytes aufgefüllt. + \end{itemize} + Viele Grafikprogramme können PBM-Dateien öffnen und bearbeiten. + Der Anfang der Datei (Kennung, Breite und Höhe) + ist auch in einem Texteditor lesbar. + + Beispiel (\gitfile{hp}{2023ws/20231130}{aufgabe-1.pbm}):\hfill + \makebox(0,0)[tr]{\framebox{\includegraphics[scale=3]{aufgabe-1.png}}} + \begin{lstlisting} + P4 + 14 14 + <Bilddaten> + \end{lstlisting} + + In dem untenstehenden Programmfragment (\gitfile{hp}{2023ws/20231130}{aufgabe-1.c}) + wird eine Grafik aus Textzeilen zusammengesetzt, + so daß man mit einem Texteditor "`malen"' kann: + \begin{lstlisting} + #include <stdio.h> + + /* ... */ + + int main (void) + { + pbm_open (14, 14, "test.pbm"); + pbm_line (" "); + pbm_line (" XXXXXX "); + pbm_line (" X X "); + pbm_line (" X X "); + pbm_line (" X X "); + pbm_line (" X XX XX X "); + pbm_line (" X X X X "); + pbm_line (" X X "); + pbm_line (" X X X X "); + pbm_line (" X X X X "); + pbm_line (" X XXXX X "); + pbm_line (" X X "); + pbm_line (" XXXXXX "); + pbm_line (" "); + pbm_close (); + return 0; + } + \end{lstlisting} + Ergänzen Sie das Programmfragment so, + daß es eine Datei \file{test.pbm} erzeugt, die die Grafik enthält. + + Das Programm soll typische Benutzerfehler abfangen + (z.\,B.\ weniger Zeilen als in \lstinline{pbm_open} angegeben), + keine fehlerhaften Ausgaben produzieren oder abstürzen, + sondern stattdessen sinnvolle Fehlermeldungen ausgeben. + + Zum Vergleich liegt eine Datei \gitfile{hp}{2023ws/20231130}{aufgabe-1.pbm} + mit dem gewünschten Ergebnis bei,\\ + und die Datei \gitfile{hp}{2023ws/20231130}{aufgabe-1.png} enthält dasselbe Bild. + + \points{10} + + Hinweis für die Klausur: + Abgabe in digitaler Form ist erwünscht, aber nicht zwingend. + + \exercise{Fakultät} + + Die Fakultät $n!$ einer ganzen Zahl $n \ge 0$ ist definiert als: + \begin{eqnarray*} + 1 & \mbox{für} & n = 0, \\ + n \cdot (n-1)! & \mbox{für} & n > 0. + \end{eqnarray*} + + Mit anderen Worten: $n! = 1\cdot2\cdot3\cdot\dots\cdot n$. + + Die folgende Funktion \lstinline{fak()} berechnet die Fakultät \emph{rekursiv} + (Datei: \gitfile{hp}{2023ws/20231130}{aufgabe-2.c}): + + \begin{lstlisting} + int fak (int n) + { + if (n <= 0) + return 1; + else + return n * fak (n - 1); + } + \end{lstlisting} + + \begin{enumerate}[\quad(a)] + \item + Schreiben Sie eine Funktion, die die Fakultät \emph{iterativ} berechnet,\\ + d.\,h.\ mit Hilfe einer Schleife anstelle von Rekursion. + \points{3} + \item + Wie viele Multiplikationen (Landau-Symbol) + erfordern beide Versionen der Fakultätsfunktion\\ + in Abhängigkeit von \lstinline$n$? + Begründen Sie Ihre Antwort. + \points{2} + \item + Wieviel Speicherplatz (Landau-Symbol) + erfordern beide Versionen der Fakultätsfunktion\\ + in Abhängigkeit von \lstinline$n$? + Begründen Sie Ihre Antwort. + \points{3} + \end{enumerate} + + \exercise{Einfügen in Strings (Ergänzung)} + + Diese Aufgabe ist eine Ergänzung von Aufgabe 3 der Übung vom 2.\ November 2023 + um die Teilaufgaben (e), (f) und (g). Für den "`Klausur-Modus"' können + Sie die Teilaufgaben (a) bis (d) als "`bereits gelöst"' voraussetzen. + + Wir betrachten das folgende Programm (\gitfile{hp}{2023ws/20231130}{aufgabe-1.c}): +% \begin{lstlisting}[style=numbered] + \begin{lstlisting} + #include <stdio.h> + #include <string.h> + + void insert_into_string (char src, char *target, int pos) + { + int len = strlen (target); + for (int i = pos; i < len; i++) + target[i+1] = target[i]; + target[pos] = src; + } + + int main (void) + { + char test[100] = "Hochshule Bochum"; + insert_into_string ('c', test, 5); + printf ("%s\n", test); + return 0; + } + \end{lstlisting} + Die Ausgabe des Programms lautet: + \lstinline[style=terminal]{Hochschhhhhhhhhhh} + + \begin{enumerate}[\quad(a)] + \item + Erklären Sie, wie die Ausgabe zustandekommt. +% \points{3} +% \workspace{12} + \item + Schreiben Sie die Funktion \lstinline|insert_into_string()| so um, + daß sie den Buchstaben \lstinline{src} an der Stelle \lstinline{pos} + in den String \lstinline{target} einfügt.\par + Die Ausgabe des Programms müßte dann + \lstinline[style=terminal]{Hochschule Bochum} lauten. +% \points{2} +% \workspace{13} + \item + Was kann passieren, wenn Sie die Zeile + \lstinline{char test[100] = "Hochshule Bochum";}\\ + durch + \lstinline{char test[] = "Hochshule Bochum";} ersetzen? + Begründen Sie Ihre Antwort. +% \points{2} +% \workspace{10} + \item + Was kann passieren, wenn Sie die Zeile + \lstinline{char test[100] = "Hochshule Bochum";}\\ + durch + \lstinline{char *test = "Hochshule Bochum";} ersetzen? + Begründen Sie Ihre Antwort. +% \points{2} +% \workspace{10} + \item + Schreiben Sie eine Funktion + \lstinline{void insert_into_string_sorted (char src, char *target)}, + die voraussetzt, daß der String \lstinline{target} alphabetisch sortiert ist + und den Buchstaben \lstinline{src} an der alphabetisch richtigen Stelle + einfügt. Diese Funktion darf die bereits vorhandene Funktion + \lstinline|insert_into_string()| aufrufen.\\ + \points{4}\par + Zum Testen eignen sich die folgenden Zeilen im Hauptprogramm: + \begin{lstlisting}[gobble=8] + char test[100] = ""; + insert_into_string_sorted ('c', test); + insert_into_string_sorted ('a', test); + insert_into_string_sorted ('d', test); + insert_into_string_sorted ('b', test); + \end{lstlisting} + Danach sollte \lstinline{test[]} die Zeichenfolge \lstinline{"abcd"} enthalten. +% \workspace{14} + \goodbreak + \item + Wie schnell (Landau-Symbol in Abhängigkeit von der Länge $n$ des Strings) + arbeitet Ihre Funktion + \lstinline{void insert_into_string_sorted (char src, char *target)}? + Begründen Sie Ihre Antwort. + \points{1} +% \workspace{10} + \item + Beschreiben Sie -- in Worten oder als C-Quelltext --, wie man die Funktion\\ + \lstinline{void insert_into_string_sorted (char src, char *target)} + so gestalten kann,\\ + daß sie in $\mathcal{O}(\log n)$ arbeitet. + \points{3} +% \workspace{35} + \end{enumerate} + + \begin{flushright} + \textit{Viel Erfolg!} + \end{flushright} + + \makeatletter + \immediate\write\@mainaux{\string\gdef\string\totalpoints{\arabic{points}}} + \makeatother + +\end{document} diff --git a/20231130/landau-symbols-2.pdf b/20231130/landau-symbols-2.pdf new file mode 120000 index 0000000000000000000000000000000000000000..6b458b6efd8e274824a6dfcaabc4b9c27d196dc4 --- /dev/null +++ b/20231130/landau-symbols-2.pdf @@ -0,0 +1 @@ +../common/landau-symbols-2.pdf \ No newline at end of file diff --git a/20231130/landau-symbols-3.pdf b/20231130/landau-symbols-3.pdf new file mode 120000 index 0000000000000000000000000000000000000000..46efa409b35ff5df763c744a423599cba515d886 --- /dev/null +++ b/20231130/landau-symbols-3.pdf @@ -0,0 +1 @@ +../common/landau-symbols-3.pdf \ No newline at end of file diff --git a/20231130/landau-symbols.pdf b/20231130/landau-symbols.pdf new file mode 120000 index 0000000000000000000000000000000000000000..ca145425bf07439c680632aa0663f84be601a565 --- /dev/null +++ b/20231130/landau-symbols.pdf @@ -0,0 +1 @@ +../common/landau-symbols.pdf \ No newline at end of file diff --git a/20231130/loesung-1.c b/20231130/loesung-1.c new file mode 100644 index 0000000000000000000000000000000000000000..8d5733e92e6a1c2d28419adc60321c50f5c18129 --- /dev/null +++ b/20231130/loesung-1.c @@ -0,0 +1,80 @@ +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <errno.h> +#include <error.h> + +/* Die Aufgabe besteht darin, die Funktionen pbm_open(), + * pbm_line() und pbm_close() zu schreiben. + */ + +int pbm_width = 0; +int pbm_height = 0; +int line_no = 0; +FILE *pbm_file = NULL; /* globale Variable für die PBM-Datei */ + +void pbm_open (int width, int height, char *filename) +{ + pbm_file = fopen (filename, "w"); + if (!pbm_file) + error (errno, errno, "pbm_open(): cannot open file %s for writing", filename); + pbm_width = width; + pbm_height = height; + fprintf (pbm_file, "P4\n%d %d\n", pbm_width, pbm_height); +} + +void pbm_line (char *line) +{ + if (!pbm_file) + error (1, 0, "pbm_line(): PBM file not open"); + if (!line) + error (1, 0, "pbm_line(): line is NULL"); + if (strlen (line) != pbm_width) + error (1, 0, "pbm_line(): line length does not match width"); + if (line_no >= pbm_height) + error (1, 0, "pbm_line(): too many lines"); + int pbm_bytes = (pbm_width + 7) / 8; /* benötigte Bytes pro Zeile (immer aufrunden) */ + uint8_t buffer[pbm_bytes]; + for (int i = 0; i < pbm_bytes; i++) /* Puffer auf 0 initialisieren */ + buffer[i] = 0; + line_no++; + for (int x = 0; line[x]; x++) + { + int i = x / 8; /* In welches Byte des Puffers gehört dieses Pixel? */ + int b = x % 8; /* Welches Bit innerhalb des Bytes ist dieses Pixel? */ + if (line[x] != ' ') /* Kein Leerzeichen --> Bit auf 1 setzen */ + buffer[i] |= 0x80 >> b; /* MSB first. LSB first wäre 1 << b. */ + } + for (int i = 0; i < pbm_bytes; i++) /* Puffer in Datei ausgeben */ + fprintf (pbm_file, "%c", buffer[i]); +} + +void pbm_close (void) +{ + if (!pbm_file) + error (1, 0, "pbm_close(): PBM file not open"); + if (line_no < pbm_height) + error (1, 0, "pbm_close(): too few lines"); + fclose (pbm_file); +} + +int main (void) +{ + pbm_open (14, 14, "test.pbm"); + pbm_line (" "); + pbm_line (" XXXXXX "); + pbm_line (" X X "); + pbm_line (" X X "); + pbm_line (" X X "); + pbm_line (" X XX XX X "); + pbm_line (" X X X X "); + pbm_line (" X X "); + pbm_line (" X X X X "); + pbm_line (" X X X X "); + pbm_line (" X XXXX X "); + pbm_line (" X X "); + pbm_line (" XXXXXX "); + pbm_line (" "); + pbm_close (); + return 0; +} diff --git a/20231130/loesung-1f.c b/20231130/loesung-1f.c new file mode 100644 index 0000000000000000000000000000000000000000..d358fa1de54ad08a770dc733d089d3d40342bdde --- /dev/null +++ b/20231130/loesung-1f.c @@ -0,0 +1,80 @@ +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <errno.h> +#include <error.h> + +/* Die Aufgabe besteht darin, die Funktionen pbm_open(), + * pbm_line() und pbm_close() zu schreiben. + */ + +int pbm_width = 0; +int pbm_height = 0; +int line_no = 0; +FILE *pbm_file = NULL; /* globale Variable für die PBM-Datei */ + +void pbm_open (int width, int height, char *filename) +{ + pbm_file = fopen (filename, "w"); + if (!pbm_file) + error (errno, errno, "pbm_open(): cannot open file %s for writing", filename); + pbm_width = width; + pbm_height = height; + fprintf (pbm_file, "P4\n%d %d\n", pbm_width, pbm_height); +} + +void pbm_line (char *line) +{ + if (!pbm_file) + error (1, 0, "pbm_line(): PBM file not open"); + if (!line) + error (1, 0, "pbm_line(): line is NULL"); + if (strlen (line) != pbm_width) + error (1, 0, "pbm_line(): line length does not match width"); + if (line_no >= pbm_height) + error (1, 0, "pbm_line(): too many lines"); + int pbm_bytes = (pbm_width + 7) / 8; /* benötigte Bytes pro Zeile (immer aufrunden) */ + uint8_t buffer[pbm_bytes]; + for (int i = 0; i < pbm_bytes; i++) /* Puffer auf 0 initialisieren */ + buffer[i] = 0; + line_no++; + for (int x = 0; line[x]; x++) + { + int i = x / 8; /* In welches Byte des Puffers gehört dieses Pixel? */ + int b = x % 8; /* Welches Bit innerhalb des Bytes ist dieses Pixel? */ + if (line[x] != ' ') /* Kein Leerzeichen --> Bit auf 1 setzen */ + buffer[i] |= 1 << b; + } + for (int i = 0; i < pbm_bytes; i++) /* Puffer in Datei ausgeben */ + fprintf (pbm_file, "%c", buffer[i]); +} + +void pbm_close (void) +{ + if (!pbm_file) + error (1, 0, "pbm_close(): PBM file not open"); + if (line_no < pbm_height) + error (1, 0, "pbm_close(): too few lines"); + fclose (pbm_file); +} + +int main (void) +{ + pbm_open (14, 14, "test.pbm"); + pbm_line (" "); + pbm_line (" XXXXXX "); + pbm_line (" X X "); + pbm_line (" X X "); + pbm_line (" X X "); + pbm_line (" X XX XX X "); + pbm_line (" X X X X "); + pbm_line (" X X "); + pbm_line (" X X X X "); + pbm_line (" X X X X "); + pbm_line (" X XXXX X "); + pbm_line (" X X "); + pbm_line (" XXXXXX "); + pbm_line (" "); + pbm_close (); + return 0; +} diff --git a/20231130/loesung-2.c b/20231130/loesung-2.c new file mode 100644 index 0000000000000000000000000000000000000000..c2d6f6003924627ae97831407c191eaac42a09c1 --- /dev/null +++ b/20231130/loesung-2.c @@ -0,0 +1,16 @@ +#include <stdio.h> + +int fak (int n) +{ + int f = 1; + for (int i = 2; i <= n; i++) + f *= i; + return f; +} + +int main (void) +{ + for (int n = 0; n <= 5; n++) + printf ("%d\n", fak (n)); + return 0; +} diff --git a/20231130/loesung-3e.c b/20231130/loesung-3e.c new file mode 100644 index 0000000000000000000000000000000000000000..bc41fb0e1f5f826a427038a18798e280fd1a096d --- /dev/null +++ b/20231130/loesung-3e.c @@ -0,0 +1,33 @@ +#include <stdio.h> +#include <string.h> + +void insert_into_string (char src, char *target, int pos) +{ + int len = strlen (target); + for (int i = len; i >= pos; i--) + target[i + 1] = target[i]; + target[pos] = src; +} + +void insert_into_string_sorted (char src, char *target) +{ + int i = 0; + while (target[i] && target[i] < src) + i++; + insert_into_string (src, target, i); +} + +int main (void) +{ + char test[100] = ""; + insert_into_string_sorted ('c', test); + insert_into_string_sorted ('a', test); + insert_into_string_sorted ('d', test); + insert_into_string_sorted ('b', test); + printf ("test = \"%s\"\n", test); + for (char ch = 'e'; ch < 'z'; ch += 2) + insert_into_string_sorted (ch, test); + insert_into_string_sorted ('n', test); + printf ("test = \"%s\"\n", test); + return 0; +} diff --git a/20231130/loesung-3g.c b/20231130/loesung-3g.c new file mode 100644 index 0000000000000000000000000000000000000000..4b0c29dfc223fa961cdbf930683e6d79610b002b --- /dev/null +++ b/20231130/loesung-3g.c @@ -0,0 +1,46 @@ +#include <stdio.h> +#include <string.h> + +void insert_into_string (char src, char *target, int pos) +{ + int len = strlen (target); + for (int i = len; i >= pos; i--) + target[i + 1] = target[i]; + target[pos] = src; +} + +void insert_into_string_sorted (char src, char *target) +{ + int l = 0; + int r = 0; + while (target[r]) + r++; + int m = (l + r) / 2; + while (m > l) + { + if (src < target[m]) + r = m; + else + l = m; + m = (l + r) / 2; + } + if (target[m] == 0 || src < target[m]) + insert_into_string (src, target, m); + else + insert_into_string (src, target, m + 1); +} + +int main (void) +{ + char test[100] = ""; + insert_into_string_sorted ('c', test); + insert_into_string_sorted ('a', test); + insert_into_string_sorted ('d', test); + insert_into_string_sorted ('b', test); + printf ("test = \"%s\"\n", test); + for (char ch = 'e'; ch < 'z'; ch += 2) + insert_into_string_sorted (ch, test); + insert_into_string_sorted ('n', test); + printf ("test = \"%s\"\n", test); + return 0; +} diff --git a/20231130/logo-hochschule-bochum-cvh-text-v2.pdf b/20231130/logo-hochschule-bochum-cvh-text-v2.pdf new file mode 120000 index 0000000000000000000000000000000000000000..4aa99b8f81061aca6dcaf43eed2d9efef40555f8 --- /dev/null +++ b/20231130/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/20231130/logo-hochschule-bochum.pdf b/20231130/logo-hochschule-bochum.pdf new file mode 120000 index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1 --- /dev/null +++ b/20231130/logo-hochschule-bochum.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum.pdf \ No newline at end of file diff --git a/20231130/pendulum.pdf b/20231130/pendulum.pdf new file mode 120000 index 0000000000000000000000000000000000000000..7d1d87305cdb8840a248ff2207538d758464f452 --- /dev/null +++ b/20231130/pendulum.pdf @@ -0,0 +1 @@ +../common/pendulum.pdf \ No newline at end of file diff --git a/20231130/pgscript.sty b/20231130/pgscript.sty new file mode 120000 index 0000000000000000000000000000000000000000..95c888478c99ea7fda0fd11ccf669ae91be7178b --- /dev/null +++ b/20231130/pgscript.sty @@ -0,0 +1 @@ +../common/pgscript.sty \ No newline at end of file diff --git a/20231130/pgslides.sty b/20231130/pgslides.sty new file mode 120000 index 0000000000000000000000000000000000000000..5be1416f4216f076aa268901f52a15d775e43f64 --- /dev/null +++ b/20231130/pgslides.sty @@ -0,0 +1 @@ +../common/pgslides.sty \ No newline at end of file