Skip to content
Snippets Groups Projects
Commit 3cf35913 authored by Peter Gerwinski's avatar Peter Gerwinski
Browse files

Vorbereitung 7.1.2021

parent ee030e43
No related branches found
No related tags found
No related merge requests found
Showing
with 1589 additions and 0 deletions
File added
../common/Tower_of_Hanoi.jpeg
\ No newline at end of file
#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;
}
#include <string.h>
int fun_1 (char *s)
{
int x = 0;
for (int i = 0; i < strlen (s); i++)
x += s[i];
return x;
}
int fun_2 (char *s)
{
int i = 0, x = 0;
int len = strlen (s);
while (i < len)
x += s[i++];
return x;
}
#include <stdio.h>
int main (void)
{
char buffer[100];
fgets (buffer, 100, stdin);
for (char *p = buffer; *p; p++)
printf ("%02x", *p);
printf ("\n");
}
File added
% hp-20210107.pdf - Lecture Slides on Low-Level Programming
% Copyright (C) 2012, 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021 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: Rekursion, Aufwandsabschätzungen
\documentclass[10pt,t]{beamer}
\usepackage{pgslides}
\usepackage{pdftricks}
\usepackage{tikz}
\begin{psinputs}
\usepackage[utf8]{inputenc}
\usepackage[german]{babel}
\usepackage[T1]{fontenc}
\usepackage{helvet}
\renewcommand*\familydefault{\sfdefault}
\usepackage{pstricks,pst-grad}
\end{psinputs}
\title{Hardwarenahe Programmierung}
\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski}
\date{7.\ Januar 2021}
\begin{document}
\maketitleframe
\nosectionnonumber{\inserttitle}
\begin{frame}
\shownosectionnonumber
\begin{itemize}
\item[\textbf{1}] \textbf{Einführung}
\hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp}}}
\item[\textbf{2}] \textbf{Einführung in C}
\item[\textbf{3}] \textbf{Bibliotheken}
\begin{itemize}
\item[3.1] Der Präprozessor
\item[3.2] Bibliotheken einbinden
\item[3.3] Bibliotheken verwenden
\color{medgreen}
\item[3.4] Projekt organisieren: make
\end{itemize}
\item[\textbf{4}] \textbf{Algorithmen}
\begin{itemize}
\color{medgreen}
\item[5.1] Differentialgleichungen
\color{red}
\item[5.2] Rekursion
\item[5.3] Aufwandsabschätzungen
\end{itemize}
\item[\textbf{5}] \textbf{Hardwarenahe Programmierung}
\vspace*{-\smallskipamount}
\item[\textbf{\dots}]
\end{itemize}
\end{frame}
\setcounter{section}{2}
\section{Bibliotheken}
\subsection{Der Präprozessor}
\begin{frame}[fragile]
\showsection
\showsubsection
\lstinline{#include}: %\pause:
Text einbinden
\begin{itemize}
% \pause
\item
\lstinline{#include <stdio.h>}: Standard-Verzeichnisse -- Standard-Header
% \pause
\item
\lstinline{#include "answer.h"}: auch aktuelles Verzeichnis -- eigene Header
\end{itemize}
% \pause
\bigskip
\lstinline{#define VIER 4}: Text ersetzen lassen -- Konstante definieren
\begin{itemize}
% \pause
\item
Kein Semikolon!
% \pause
\item
Berechnungen in Klammern setzen:\\
\lstinline{#define VIER (2 + 2)}
% \pause
\item
Konvention: Großbuchstaben
\end{itemize}
\end{frame}
\subsection{Bibliotheken einbinden}
\begin{frame}[fragile]
\showsection
\showsubsection
Inhalt der Header-Datei: externe Deklarationen
% \pause
\smallskip
\lstinline{extern int answer (void);}
% \pause
\smallskip
\lstinline{extern int printf (__const char *__restrict __format, ...);}
% \pause
\bigskip
Funktion wird "`anderswo"' definiert
\begin{itemize}
% \pause
\item
separater C-Quelltext: mit an \lstinline[style=terminal]{gcc} übergeben
% \pause
\item
Zusammenfügen zu ausführbarem Programm durch den \newterm{Linker}
% \pause
\item
vorcompilierte Bibliothek: \lstinline[style=terminal]{-lfoo}\\
% \pause
= Datei \file{libfoo.a} in Standard-Verzeichnis
\end{itemize}
\end{frame}
\subsection{Bibliothek verwenden (Beispiel: GTK+)}
\begin{frame}[fragile]
\showsubsection
\begin{itemize}
\item
\lstinline{#include <gtk/gtk.h>}
% \pause
\smallskip
\item
Mit \lstinline[style=cmd]{pkg-config --cflags --libs} erfährt man,\\
welche Optionen und Bibliotheken man an \lstinline[style=cmd]{gcc}
übergeben muß\alt<1->{.}{:}
% \pause
\begin{onlyenv}<1>
\begin{lstlisting}[style=terminal,gobble=10]
$ ¡pkg-config --cflags --libs gtk+-3.0¿
-pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-
atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1
.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/
include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/inc
lude/cairo -I/usr/include/pango-1.0 -I/usr/include/harf
buzz -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I
/usr/include/cairo -I/usr/include/pixman-1 -I/usr/inclu
de/freetype2 -I/usr/include/libpng16 -I/usr/include/gdk
-pixbuf-2.0 -I/usr/include/libpng16 -I/usr/include/glib
-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lgtk
-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcai
ro-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject
-2.0 -lglib-2.0
\end{lstlisting}
\vspace*{-3cm}
\end{onlyenv}
\pause
\arrowitem
Compiler-Aufruf:
\begin{onlyenv}<2>
\begin{lstlisting}[style=terminal,gobble=10]
$ ¡gcc -Wall -O hello-gtk.c -pthread -I/usr/include/gtk-
3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-sp
i-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-g
nu/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/inclu
de/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pa
ngo-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.
0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/in
clude/pixman-1 -I/usr/include/freetype2 -I/usr/include/
libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/l
ibpng16 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux
-gnu/glib-2.0/include -lgtk-3 -lgdk-3 -lpangocairo-1.0
-lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pix
buf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -o hello-gtk¿
\end{lstlisting}
\vspace*{-2cm}
\end{onlyenv}
\begin{onlyenv}<3->
\begin{lstlisting}[style=terminal,gobble=10]
$ ¡gcc -Wall -O hello-gtk.c $(pkg-config --cflags --libs
gtk+-3.0) -o hello-gtk¿
\end{lstlisting}
\end{onlyenv}
\begin{onlyenv}<3>
\begin{picture}(0,0)(0.3,0.3)
\color{red}
\put(6.6,-0.6){\makebox(0,0)[bl]{\tikz{\draw[-latex](0,0)--(3,1.5);}}}
\put(6.3,-0.7){\makebox(0,0)[t]{\shortstack{\strut Optionen:\\
\strut u.\,a.\ viele Include-Verzeichnisse:\\
\lstinline[style=cmd]{-I/usr/include/gtk-3.0}}}}
\put(10.0,-2.1){\makebox(0,0)[bl]{\tikz{\draw[-latex](0,0)--(1.5,3);}}}
\put(10.3,-2.2){\makebox(0,0)[t]{\shortstack{\strut Bibliotheken:\\
\strut u.\,a.\ \lstinline[style=cmd]{-lgtk-3 -lcairo}\qquad\strut}}}
\end{picture}
\end{onlyenv}
\pause
\pause
\item
Auf manchen Plattformen kommt es auf die Reihenfolge an:
\begin{lstlisting}[style=terminal,gobble=8]
$ ¡gcc -Wall -O $(pkg-config --cflags gtk+-3.0) \
hello-gtk.c $(pkg-config --libs gtk+-3.0) \
-o hello-gtk¿
\end{lstlisting}
(Backslash = "`Es geht in der nächsten Zeile weiter."')
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\showsubsection
Selbst geschriebene Funktion übergeben: \newterm{Callback}
\bigskip
\begin{lstlisting}[xleftmargin=1em]
gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
{
/* Zeichenbefehle */
...
return FALSE;
}
...
g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
\end{lstlisting}
\medskip
\begin{itemize}
\arrowitem
GTK+ ruft immer dann, wenn es etwas zu zeichnen gibt,\\
die Funktion \lstinline{draw} auf.
\end{itemize}
% \pause
\begin{picture}(0,0)(-0.07,0.2)
\color{red}
\put(5.3,4.8){\makebox(0,0)[bl]{\tikz{\draw[-latex](0,0)--(1.90,1.15);}}}
\put(5.0,4.7){\makebox(0,0)[t]{\shortstack{\strut repräsentiert den\\
\strut Bildschirm, auf den\\
\strut gezeichnet werden soll}}}
% \pause
\put(9.7,5.1){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-0.2,0.85);}}}
\put(9.7,5.0){\makebox(0,0)[t]{\shortstack{\strut optionale Zusatzinformationen\\
\strut für draw(), typischerweise\\
\strut ein Zeiger auf ein struct}}}
\put(10.0,3.5){\makebox(0,0)[tl]{\tikz{\draw[-latex](0,0)--(0.6,-1.25);}}}
\end{picture}
\end{frame}
\begin{frame}[fragile]
\showsubsection
Selbst geschriebene Funktion übergeben: \newterm{Callback}
\bigskip
\begin{lstlisting}[xleftmargin=1em]
gboolean timer (GtkWidget *widget)
{
/* Rechenbefehle */
...
gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
g_timeout_add (50, (GSourceFunc) timer, widget);
return FALSE;
}
...
g_timeout_add (50, (GSourceFunc) timer, drawing_area);
\end{lstlisting}
\medskip
\begin{itemize}
\arrowitem
GTK+ ruft nach 50 Millisekunden
die Funktion \lstinline{timer} auf.
\end{itemize}
% \pause
\begin{picture}(0,0)(-0.07,0.2)
\color{red}
\put(9.7,6.7){\makebox(0,0)[t]{\shortstack{\strut Dieser Bereich soll\\
\strut neu gezeichnet werden.}}}
\put(9.7,5.7){\makebox(0,0)[tr]{\tikz{\draw[-latex](0,0)--(-0.6,-0.8);}}}
% \pause
\put(4.3,3.2){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-0.7,0.6);}}}
\put(4.3,3.1){\makebox(0,0)[t]{\shortstack{\strut In weiteren 50 Millisekunden soll\\
\strut die Funktion erneut aufgerufen werden.}}}
% \pause
\put(9.3,2.9){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-3.3,0.9);}}}
\put(9.8,2.8){\makebox(0,0)[t]{\shortstack{\strut Explizite Typumwandlung\\
\strut eines Zeigers (später)}}}
\end{picture}
\vspace*{-1cm}
\end{frame}
\subsection{Projekt organisieren: make}
\begin{frame}[fragile]
\showsubsection
\begin{itemize}
\item
\only<4->{explizite und implizite} Regeln
\begin{onlyenv}<2>
\smallskip
\begin{lstlisting}[language=make,gobble=10]
philosophy: philosophy.o answer.o
gcc philosophy.o answer.o -o philosophy
answer.o: answer.c answer.h
gcc -Wall -O answer.c -c
philosophy.o: philosophy.c answer.h
gcc -Wall -O philosophy.c -c
\end{lstlisting}
\end{onlyenv}
\begin{onlyenv}<4>
\smallskip
\begin{lstlisting}[language=make,gobble=10]
TARGET = philosophy
OBJECTS = philosophy.o answer.o
HEADERS = answer.h
CFLAGS = -Wall -O
$(TARGET): $(OBJECTS)
gcc $(OBJECTS) -o $(TARGET)
%.o: %.c $(HEADERS)
gcc $(CFLAGS) $< -c
clean:
rm -f $(OBJECTS) $(TARGET)
\end{lstlisting}
\end{onlyenv}
\item
Makros
\begin{onlyenv}<3>
\smallskip
\begin{lstlisting}[language=make,gobble=10]
TARGET = philosophy
OBJECTS = philosophy.o answer.o
HEADERS = answer.h
CFLAGS = -Wall -O
$(TARGET): $(OBJECTS)
gcc $(OBJECTS) -o $(TARGET)
answer.o: answer.c $(HEADERS)
gcc $(CFLAGS) answer.c -c
philosophy.o: philosophy.c $(HEADERS)
gcc $(CFLAGS) philosophy.c -c
clean:
rm -f $(OBJECTS) $(TARGET)
\end{lstlisting}
\vspace*{-1cm}
\end{onlyenv}
\begin{onlyenv}<5->
\smallskip
\arrowitem
3 Sprachen: C, Präprozessor, make
\end{onlyenv}
\end{itemize}
\end{frame}
\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}
\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}
\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}
\begin{itemize}
\item[3.1] Der Präprozessor
\item[3.2] Bibliotheken einbinden
\item[3.3] Bibliotheken verwenden
\color{medgreen}
\item[3.4] Projekt organisieren: make
\end{itemize}
\item[\textbf{4}] \textbf{Algorithmen}
\begin{itemize}
\color{medgreen}
\item[5.1] Differentialgleichungen
\color{red}
\item[5.2] Rekursion
\item[5.3] Aufwandsabschätzungen
\end{itemize}
\item[\textbf{5}] \textbf{Hardwarenahe Programmierung}
\vspace*{-\smallskipamount}
\item[\textbf{\dots}]
\end{itemize}
\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-9a¿
...
real 0m32,712s
user 0m32,708s
sys 0m0,000s
\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!
% 32.712 * 2^32 / 3600 / 24 / 365.25 = 4452.08032888280477602859
\begin{itemize}
\arrowitem
$\frac{32,712\,\text{s}\,\cdot\,2^{32}}{3600\,\cdot\,24\,\cdot\,365,25} \approx 4452$
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!
% 32.712 * 2^32 / 3600 / 24 / 365.25 = 4452.08032888280477602859
\begin{itemize}
\arrowitem
$\frac{32,712\,\text{s}\,\cdot\,2^{32}}{3600\,\cdot\,24\,\cdot\,365,25} \approx 4452$
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}
\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}
\begin{itemize}
\item[3.1] Der Präprozessor
\item[3.2] Bibliotheken einbinden
\item[3.3] Bibliotheken verwenden
\item[3.4] Projekt organisieren: make
\end{itemize}
\item[\textbf{4}] \textbf{Algorithmen}
\begin{itemize}
\item[5.1] Differentialgleichungen
\color{medgreen}
\item[5.2] Rekursion
\item[5.3] Aufwandsabschätzungen
\end{itemize}
\item[\textbf{5}] \textbf{Hardwarenahe Programmierung}
\vspace*{-\smallskipamount}
\item[\textbf{\dots}]
\end{itemize}
\vspace*{-1cm}
\end{frame}
\end{document}
File added
% hp-musterloesung-20210107.pdf - Solutions to the Exercises on Low-Level Programming
% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Peter Gerwinski
%
% This document is free software: you can redistribute it and/or
% modify it either under the terms of the Creative Commons
% Attribution-ShareAlike 3.0 License, or under the terms of the
% GNU General Public License as published by the Free Software
% Foundation, either version 3 of the License, or (at your option)
% any later version.
%
% This document is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this document. If not, see <http://www.gnu.org/licenses/>.
%
% You should have received a copy of the Creative Commons
% Attribution-ShareAlike 3.0 Unported License along with this
% document. If not, see <http://creativecommons.org/licenses/>.
% README: Fakultät, Länge von Strings (Neuauflage), Hexdumps
\documentclass[a4paper]{article}
\usepackage{pgscript}
\usepackage{gnuplot-lua-tikz}
\begin{document}
\section*{Hardwarenahe Programmierung\\
Musterlösung zu den Übungsaufgaben -- 7.\ Januar 2021}
\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}{2020ws/20210107}{aufgabe-1.c}):
\begin{lstlisting}
int fak (int n)
{
if (n <= 0)
return 1;
else
return n * fak (n - 1);
}
\end{lstlisting}
\begin{enumerate}[\quad(a)]
\item
Schreiben Sie eine Funktion, die die Fakultät \emph{iterativ} berechnet,\\
d.\,h.\ mit Hilfe einer Schleife anstelle von Rekursion.
\points{3}
\item
Wie viele Multiplikationen (Landau-Symbol)
erfordern beide Versionen der Fakultätsfunktion\\
in Abhängigkeit von \lstinline$n$?
Begründen Sie Ihre Antwort.
\points{2}
\item
Wieviel Speicherplatz (Landau-Symbol)
erfordern beide Versionen der Fakultätsfunktion\\
in Abhängigkeit von \lstinline$n$?
Begründen Sie Ihre Antwort.
\points{3}
\end{enumerate}
\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}{2020ws/20210107}{loesung-1.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{Länge von Strings}
Diese Aufgabe ist eine Neuauflage von Aufgabe 3 der
Übung vom 14.\ November 2019,\\
ergänzt um die Teilaufgaben (f) und (g).
\medskip
Strings werden in der Programmiersprache C durch Zeiger auf \lstinline{char}-Variable realisiert.
Beispiel: \lstinline{char *hello_world = "Hello, world!\n"}
Die Systembibliothek stellt eine Funktion \lstinline{strlen()} zur Ermittlung der Länge von Strings\\
zur Verfügung (\lstinline{#include <string.h>}).
\begin{enumerate}[\quad(a)]
\item
Auf welche Weise ist die Länge eines Strings gekennzeichnet?
\points{1}
\item
Wie lang ist die Beispiel-String-Konstante \lstinline{"Hello, world!\n"},
und wieviel Speicherplatz belegt sie?\\
\points{2}
\item
Schreiben Sie eine eigene Funktion \lstinline{int strlen (char *s)},
die die Länge eines Strings zurückgibt.\\
\points{3}
\end{enumerate}
\goodbreak
Wir betrachten nun die folgenden Funktionen (Datei: \gitfile{hp}{2020ws/20210107}{aufgabe-2.c}):
\begin{center}
\begin{minipage}{8cm}
\begin{lstlisting}[gobble=8]
int fun_1 (char *s)
{
int x = 0;
for (int i = 0; i < strlen (s); i++)
x += s[i];
return x;
}
\end{lstlisting}
\end{minipage}%
\begin{minipage}{6cm}
\vspace*{-1cm}
\begin{lstlisting}[gobble=8]
int fun_2 (char *s)
{
int i = 0, x = 0;
int len = strlen (s);
while (i < len)
x += s[i++];
return x;
}
\end{lstlisting}
\vspace*{-1cm}
\end{minipage}
\end{center}
\begin{enumerate}[\quad(a)]\setcounter{enumi}{3}
\item
Was bewirken die beiden Funktionen?
\points{2}
\item
Schreiben Sie eine eigene Funktion,
die dieselbe Aufgabe erledigt wie \lstinline{fun_2()},\\
nur effizienter.
\points{4}
\item
Von welcher Ordnung (Landau-Symbol) sind die beiden Funktionen
hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen im String?
Begründen Sie Ihre Antwort.
Sie dürfen für \lstinline{strlen()} Ihre eigene Version der Funktion voraussetzen.
\points{3}
\item
Von welcher Ordnung (Landau-Symbol) ist Ihre effizientere Funktion?\\
Begründen Sie Ihre Antwort.
\points{1}
\end{enumerate}
\solution
\begin{itemize}
\item[(a)]
\textbf{Auf welche Weise ist die Länge eines Strings gekennzeichnet?}
Ein String ist ein Array von \lstinline{char}s.
Nach den eigentlichen Zeichen des Strings enthält das Array
\textbf{ein Null-Symbol} (Zeichen mit Zahlenwert 0,
nicht zu verwechseln mit der Ziffer \lstinline{'0'}) als Ende-Markierung.
Die Länge eines Strings ist die Anzahl der Zeichen
\emph{vor\/} diesem Symbol.
\item[(b)]
{\bf Wie lang ist die Beispiel-String-Konstante \lstinline{"Hello, world!\n"},
und wieviel Speicherplatz belegt sie?}
Sie ist 14 Zeichen lang (\lstinline{'\n'} ist nur 1 Zeichen;
das Null-Symbol, das das Ende markiert, zählt hier nicht mit)
und belegt Speicherplatz für 15 Zeichen
(15 Bytes -- einschließlich Null-Symbol / Ende-Markierung).
\item[(c)]
\textbf{Schreiben Sie eine eigene Funktion \lstinline{int strlen (char *s)},
die die Länge eines Strings zurückgibt.}
Siehe die Dateien \gitfile{hp}{2020ws/20210107}{loesung-2c-1.c} (mit Array-Index)
und \gitfile{hp}{2020ws/20210107}{loesung-2c-2.c} (mit Zeiger-Arithmetik).
Beide Lösungen sind korrekt und arbeiten gleich schnell.
Die Warnung \lstinline[style=terminal]{conflicting types for built-in function "strlen"}
kann normalerweise ignoriert werden;
auf manchen Systemen (z.\,B.\ MinGW) hat jedoch die eingebaute Funktion \lstinline{strlen()}
beim Linken Vorrang vor der selbstgeschriebenen,
so daß die selbstgeschriebene Funktion nie aufgerufen wird.
In solchen Fällen ist es zulässig, die selbstgeschriebene Funktion
anders zu nennen (z.\,B.\ \lstinline{my_strlen()}).
\item[(d)]
\textbf{Was bewirken die beiden Funktionen?}
Beide addieren die Zahlenwerte der im String enthaltenen Zeichen
und geben die Summe als Funktionsergebnis zurück.
Im Falle des Test-Strings \lstinline{"Hello, world!\n"}
lautet der Rückgabewert 1171 (siehe \gitfile{hp}{2020ws/20210107}{loesung-2d-1.c} und \gitfile{hp}{2020ws/20210107}{loesung-2d-2.c}).
\item[(e)]
\textbf{Schreiben Sie eine eigene Funktion,
die dieselbe Aufgabe erledigt wie \lstinline{fun_2()},
nur effizienter.}
Die Funktion wird effizienter,
wenn man auf den Aufruf von \lstinline{strlen()} verzichtet
und stattdessen die Ende-Prüfung in derselben Schleife vornimmt,
in der man auch die Zahlenwerte der Zeichen des Strings aufsummiert.
Die Funktion \lstinline{fun_3()} in der Datei \gitfile{hp}{2020ws/20210107}{loesung-2e-1.c}
realisiert dies mit einem Array-Index,
Die Funktion \lstinline{fun_4()} in der Datei \gitfile{hp}{2020ws/20210107}{loesung-2e-2.c}
mit Zeiger-Arithmetik.
Beide Lösungen sind korrekt und arbeiten gleich schnell.
\textbf{Bemerkung:} Die effizientere Version der Funktion
arbeitet doppelt so schnell wie die ursprüngliche,
hat aber ebenfalls die Ordnung $\mathcal{O}(n)$ -- siehe unten.
\item[(f)]
\textbf{Von welcher Ordnung (Landau-Symbol) sind die beiden Funktionen
hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen im String?
Begründen Sie Ihre Antwort.
Sie dürfen für \lstinline{strlen()} Ihre eigene Version der Funktion voraussetzen.}
Vorüberlegung: \lstinline{strlen()} greift in einer Schleife
auf alle Zeichen des Strings der Länge $n$ zu,
hat also $\mathcal{O}(n)$.
\lstinline{fun_1()} ruft in jedem Schleifendurchlauf
(zum Prüfen der \lstinline{while}-Bedingung) einmal \lstinline{strlen()} auf
und greift anschließend auf ein Zeichen des Strings zu,
hat also $\mathcal{O}\bigl(n\cdot(n+1)\bigr) = \mathcal{O}(n^2)$.
\lstinline{fun_2()} ruft einmalig \lstinline{strlen()} auf
und greift anschließend in einer Schleife auf alle Zeichen des Strings zu,
hat also $\mathcal{O}(n+n) = \mathcal{O}(n)$.
\item[(g)]
\textbf{Von welcher Ordnung (Landau-Symbol) ist Ihre effizientere Funktion?\\
Begründen Sie Ihre Antwort.}
In beiden o.\,a.\ Lösungsvarianten
-- \gitfile{hp}{2020ws/20210107}{loesung-2e-1.c}
und \gitfile{hp}{2020ws/20210107}{loesung-2e-2.c} --
arbeitet die Funktion mit einer einzigen Schleife,
die gleichzeitig die Zahlenwerte addiert und das Ende des Strings sucht.
Mit jeweils einer einzigen Schleife
haben beide Funktionen die Ordnung $\mathcal{O}(n)$.
\end{itemize}
\exercise{Hexdumps}
Das folgende Programm (\gitfile{hp}{2020ws/20210107}{aufgabe-2.c}) liest
einen String ein und gibt die ASCII-Werte der Buchstaben hexadezimal aus.
(Anders als z.\,B.\ \lstinline{scanf()}
akzeptiert die Funktion \lstinline{fgets()} zum Lesen von Strings auch Leerzeichen,
und sie vermeidet Pufferüberläufe.)
\begin{lstlisting}[style=numbered]
#include <stdio.h>
int main (void)
{
char buffer[100];
fgets (buffer, 100, stdin);
for (char *p = buffer; *p; p++)
printf ("%02x", *p);
printf ("\n");
}
\end{lstlisting}
Beispiel: Bei der Eingabe von \lstinline[style=cmd]{Dies ist ein Test.}
erscheint die Ausgabe\\
\lstinline[style=terminal]{44696573206973742065696e20546573742e0a}.
Schreiben Sie ein Programm, das diese Umwandlung in umgekehrter Richtung vornimmt,
also z.\,B.\ bei Eingabe von \lstinline[style=cmd]{44696573206973742065696e20546573742e0a}
wieder \lstinline[style=terminal]{Dies ist ein Test.} ausgibt.
\points{6}
Hinweis für die Klausur:
Abgabe in digitaler Form ist erwünscht, aber nicht zwingend.
\solution
Siehe \gitfile{hp}{2020ws/20210107}{loesung-2.c}.
Das Programm macht mehrfach davon Gebrauch,
daß in C Zeichen und Zahlen äquivalent sind.
Wenn z.\,B.\ die \lstinline{char}-Variable \lstinline{c}
den Wert \lstinline{'3'} (Ziffer 3) enthält,
dann hat der Ausdruck \lstinline{c - '0'} den Wert \lstinline{3} (Zahlenwert 3).
Hierfür ist es insbesondere nicht nötig, vorauszusetzen,
daß wir den ASCII-Zeichensatz verwenden und \lstinline{'0'}
den Wert \lstinline{48} hat.
Bei Eingabe von \lstinline[style=cmd]{44696573206973742065696e20546573742e0a}
gibt das Programm zusätzlich eine Leerzeile aus.
Die liegt daran, daß das \lstinline[style=cmd]{0a} am Ende
bereits eine Zeilenschaltung enthält und das Programm mit
\lstinline{printf ("\n")} eine zusätzliche Zeilenschaltung ausgibt.
\end{document}
File added
% hp-uebung-20210107.pdf - Exercises on Low-Level Programming
% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Peter Gerwinski
%
% This document is free software: you can redistribute it and/or
% modify it either under the terms of the Creative Commons
% Attribution-ShareAlike 3.0 License, or under the terms of the
% GNU General Public License as published by the Free Software
% Foundation, either version 3 of the License, or (at your option)
% any later version.
%
% This document is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this document. If not, see <http://www.gnu.org/licenses/>.
%
% You should have received a copy of the Creative Commons
% Attribution-ShareAlike 3.0 Unported License along with this
% document. If not, see <http://creativecommons.org/licenses/>.
% README: Fakultät, Länge von Strings (Neuauflage), Hexdumps
\documentclass[a4paper]{article}
\usepackage{pgscript}
\begin{document}
% \thispagestyle{empty}
\section*{Hardwarenahe Programmierung\\
Übungsaufgaben -- 7.\ Januar 2021}
Diese Übung enthält Punkteangaben wie in einer Klausur.
Um zu "`bestehen"', müssen Sie innerhalb von 85 Minuten
unter Verwendung ausschließlich zugelassener Hilfsmittel
15 Punkte (von insgesamt \totalpoints) erreichen.
\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}{2020ws/20210107}{aufgabe-1.c}):
\begin{lstlisting}
int fak (int n)
{
if (n <= 0)
return 1;
else
return n * fak (n - 1);
}
\end{lstlisting}
\begin{enumerate}[\quad(a)]
\item
Schreiben Sie eine Funktion, die die Fakultät \emph{iterativ} berechnet,\\
d.\,h.\ mit Hilfe einer Schleife anstelle von Rekursion.
\points{3}
\item
Wie viele Multiplikationen (Landau-Symbol)
erfordern beide Versionen der Fakultätsfunktion\\
in Abhängigkeit von \lstinline$n$?
Begründen Sie Ihre Antwort.
\points{2}
\item
Wieviel Speicherplatz (Landau-Symbol)
erfordern beide Versionen der Fakultätsfunktion\\
in Abhängigkeit von \lstinline$n$?
Begründen Sie Ihre Antwort.
\points{3}
\end{enumerate}
\exercise{Länge von Strings}
Diese Aufgabe ist eine Neuauflage von Aufgabe 3 der
Übung vom 10.\ Dezember 2020,\\
ergänzt um die Teilaufgaben (f) und (g).
\medskip
Strings werden in der Programmiersprache C durch Zeiger auf \lstinline{char}-Variable realisiert.
Beispiel: \lstinline{char *hello_world = "Hello, world!\n"}
Die Systembibliothek stellt eine Funktion \lstinline{strlen()} zur Ermittlung der Länge von Strings\\
zur Verfügung (\lstinline{#include <string.h>}).
\begin{enumerate}[\quad(a)]
\item
Auf welche Weise ist die Länge eines Strings gekennzeichnet?
\points{1}
\item
Wie lang ist die Beispiel-String-Konstante \lstinline{"Hello, world!\n"},
und wieviel Speicherplatz belegt sie?\\
\points{2}
\item
Schreiben Sie eine eigene Funktion \lstinline{int strlen (char *s)},
die die Länge eines Strings zurückgibt.\\
\points{3}
\end{enumerate}
\goodbreak
Wir betrachten nun die folgenden Funktionen (Datei: \gitfile{hp}{2020ws/20210107}{aufgabe-2.c}):
\begin{center}
\begin{minipage}{8cm}
\begin{lstlisting}[gobble=8]
int fun_1 (char *s)
{
int x = 0;
for (int i = 0; i < strlen (s); i++)
x += s[i];
return x;
}
\end{lstlisting}
\end{minipage}%
\begin{minipage}{6cm}
\vspace*{-1cm}
\begin{lstlisting}[gobble=8]
int fun_2 (char *s)
{
int i = 0, x = 0;
int len = strlen (s);
while (i < len)
x += s[i++];
return x;
}
\end{lstlisting}
\vspace*{-1cm}
\end{minipage}
\end{center}
\begin{enumerate}[\quad(a)]\setcounter{enumi}{3}
\item
Was bewirken die beiden Funktionen?
\points{2}
\item
Schreiben Sie eine eigene Funktion,
die dieselbe Aufgabe erledigt wie \lstinline{fun_2()},\\
nur effizienter.
\points{4}
\item
Von welcher Ordnung (Landau-Symbol) sind die beiden Funktionen
hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen im String?
Begründen Sie Ihre Antwort.
Sie dürfen für \lstinline{strlen()} Ihre eigene Version der Funktion voraussetzen.
\points{3}
\item
Von welcher Ordnung (Landau-Symbol) ist Ihre effizientere Funktion?\\
Begründen Sie Ihre Antwort.
\points{1}
\end{enumerate}
\exercise{Hexdumps}
Das folgende Programm (\gitfile{hp}{2020ws/20210107}{aufgabe-3.c}) liest
einen String ein und gibt die ASCII-Werte der Buchstaben hexadezimal aus.
(Anders als z.\,B.\ \lstinline{scanf()}
akzeptiert die Funktion \lstinline{fgets()} zum Lesen von Strings auch Leerzeichen,
und sie vermeidet Pufferüberläufe.)
\begin{lstlisting}[style=numbered]
#include <stdio.h>
int main (void)
{
char buffer[100];
fgets (buffer, 100, stdin);
for (char *p = buffer; *p; p++)
printf ("%02x", *p);
printf ("\n");
}
\end{lstlisting}
Beispiel: Bei der Eingabe von \lstinline[style=cmd]{Dies ist ein Test.}
erscheint die Ausgabe\\
\lstinline[style=terminal]{44696573206973742065696e20546573742e0a}.
Schreiben Sie ein Programm, das diese Umwandlung in umgekehrter Richtung vornimmt,
also z.\,B.\ bei Eingabe von \lstinline[style=cmd]{44696573206973742065696e20546573742e0a}
wieder \lstinline[style=terminal]{Dies ist ein Test.} ausgibt.
\points{6}
Hinweis für die Klausur:
Abgabe in digitaler Form ist erwünscht, aber nicht zwingend.
\begin{flushright}
\textit{Viel Erfolg!}
\end{flushright}
\makeatletter
\immediate\write\@mainaux{\string\gdef\string\totalpoints{\arabic{points}}}
\makeatother
\end{document}
../common/landau-symbols-2.pdf
\ No newline at end of file
../common/landau-symbols-3.pdf
\ No newline at end of file
../common/landau-symbols.pdf
\ No newline at end of file
#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;
}
#include <stdio.h>
int strlen (char *s)
{
int l = 0;
while (s[l])
l++;
return l;
}
int main (void)
{
printf ("%d\n", strlen ("Hello, world!\n"));
return 0;
}
#include <stdio.h>
int strlen (char *s)
{
char *s0 = s;
while (*s)
s++;
return s - s0;
}
int main (void)
{
printf ("%d\n", strlen ("Hello, world!\n"));
return 0;
}
#include <stdio.h>
int strlen (char *s)
{
int l = 0;
while (s[l])
l++;
return l;
}
int fun_1 (char *s)
{
int x = 0;
for (int i = 0; i < strlen (s); i++)
x += s[i];
return x;
}
int fun_2 (char *s)
{
int i = 0, x = 0;
int len = strlen (s);
while (i < len)
x += s[i++];
return x;
}
int main (void)
{
printf ("%d\n", fun_1 ("Hello, world!\n"));
printf ("%d\n", fun_2 ("Hello, world!\n"));
return 0;
}
#include <stdio.h>
int strlen (char *s)
{
char *s0 = s;
while (*s)
s++;
return s - s0;
}
int fun_1 (char *s)
{
int x = 0;
for (int i = 0; i < strlen (s); i++)
x += s[i];
return x;
}
int fun_2 (char *s)
{
int i = 0, x = 0;
int len = strlen (s);
while (i < len)
x += s[i++];
return x;
}
int main (void)
{
printf ("%d\n", fun_1 ("Hello, world!\n"));
printf ("%d\n", fun_2 ("Hello, world!\n"));
return 0;
}
#include <stdio.h>
int fun_3 (char *s)
{
int i = 0, x = 0;
while (s[i])
x += s[i++];
return x;
}
int main (void)
{
printf ("%d\n", fun_3 ("Hello, world!\n"));
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment