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