diff --git a/20200123/aufgabe-1.c b/20200123/aufgabe-1.c new file mode 100644 index 0000000000000000000000000000000000000000..82e5b1ca9e2f896bcbec98bc5c34cdf15d086e26 --- /dev/null +++ b/20200123/aufgabe-1.c @@ -0,0 +1,53 @@ +#include <stdio.h> + +#define STACK_SIZE 10 + +int stack[STACK_SIZE]; +int stack_pointer = 0; + +void push (int x) +{ + stack[stack_pointer++] = x; +} + +void show (void) +{ + printf ("stack content:"); + for (int i = 0; i < stack_pointer; i++) + printf (" %d", stack[i]); + if (stack_pointer) + printf ("\n"); + else + printf (" (empty)\n"); +} + +void insert (int x, int pos) +{ + for (int i = pos; i < stack_pointer; i++) + stack[i + 1] = stack[i]; + stack[pos] = x; + stack_pointer++; +} + +void insert_sorted (int x) +{ + int i = 0; + while (i < stack_pointer && x < stack[i]) + i++; + insert (x, i); +} + +int main (void) +{ + push (3); + push (7); + push (137); + show (); + insert (5, 1); + show (); + insert_sorted (42); + show (); + insert_sorted (2); + show (); + return 0; +} diff --git a/20200123/aufgabe-2.c b/20200123/aufgabe-2.c new file mode 100644 index 0000000000000000000000000000000000000000..a1054f2b601850a402dccb6f4878437d1bb6909c --- /dev/null +++ b/20200123/aufgabe-2.c @@ -0,0 +1,22 @@ +#include <stdio.h> + +void foreach (int *a, void (*fun) (int x)) +{ + for (int *p = a; *p >= 0; p++) + fun (*p); +} + +void even_or_odd (int x) +{ + if (x % 2) + printf ("%d ist ungerade.\n", x); + else + printf ("%d ist gerade.\n", x); +} + +int main (void) +{ + int numbers[] = { 12, 17, 32, 1, 3, 16, 19, 18, -1 }; + foreach (numbers, even_or_odd); + return 0; +} diff --git a/20200123/hp-uebung-20200123.pdf b/20200123/hp-uebung-20200123.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2fee05b9b3d4cf6ab2ae29220087e994c5d85adf Binary files /dev/null and b/20200123/hp-uebung-20200123.pdf differ diff --git a/20200123/hp-uebung-20200123.tex b/20200123/hp-uebung-20200123.tex new file mode 100644 index 0000000000000000000000000000000000000000..245ef3b0d3277f8218d540b7b1089866ba454b6a --- /dev/null +++ b/20200123/hp-uebung-20200123.tex @@ -0,0 +1,278 @@ +% hp-uebung-20200123.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: Stack-Operationen, Iteratorfunktionen, dynamisches Bit-Array + +\documentclass[a4paper]{article} + +\usepackage{pgscript} + +\begin{document} + +% \thispagestyle{empty} + + \section*{Hardwarenahe Programmierung\\ + Übungsaufgaben -- 23.\ Januar 2020} + + Diese Übung enthält Punkteangaben wie in einer Klausur. + Um zu "`bestehen"', müssen Sie innerhalb von 90 Minuten + unter Verwendung ausschließlich zugelassener Hilfsmittel + 16 Punkte (von insgesamt \totalpoints) erreichen. + + \exercise{Stack-Operationen} + + Das folgende Programm (\gitfile{hp}{20190121}{aufgabe-1.c}) + implementiert einen Stapelspeicher (Stack). + Dies ist ein Array, das nur bis zu einer variablen Obergrenze (Stack-Pointer) + tatsächlich genutzt wird. + An dieser Obergrenze kann man Elemente hinzufügen (push). + + In dieser Aufgabe sollen zusätzlich Elemente + in der Mitte eingefügt werden (insert). + Die dafür bereits existierenden Funktionen \lstinline{insert()} + und \lstinline{insert_sorted()} sind jedoch fehlerhaft. + + \begin{minipage}[t]{0.5\textwidth} + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + #define STACK_SIZE 10 + + int stack[STACK_SIZE]; + int stack_pointer = 0; + + void push (int x) + { + stack[stack_pointer++] = x; + } + + void show (void) + { + printf ("stack content:"); + for (int i = 0; i < stack_pointer; i++) + printf (" %d", stack[i]); + if (stack_pointer) + printf ("\n"); + else + printf (" (empty)\n"); + } + \end{lstlisting} + \end{minipage}\hfill + \begin{minipage}[t]{0.5\textwidth} + \begin{lstlisting}[gobble=6] + void insert (int x, int pos) + { + for (int i = pos; i < stack_pointer; i++) + stack[i + 1] = stack[i]; + stack[pos] = x; + stack_pointer++; + } + + void insert_sorted (int x) + { + int i = 0; + while (i < stack_pointer && x < stack[i]) + i++; + insert (x, i); + } + + int main (void) + { + push (3); + push (7); + push (137); + show (); + insert (5, 1); + show (); + insert_sorted (42); + show (); + insert_sorted (2); + show (); + return 0; + } + \end{lstlisting} + \end{minipage} + + \begin{enumerate}[\quad(a)] + \item + Korrigieren Sie das Programm so, + daß die Funktion \lstinline{insert()} ihren Parameter \lstinline{x} + an der Stelle \lstinline{pos} in den Stack einfügt + und den sonstigen Inhalt des Stacks verschiebt, aber nicht zerstört. + \points{3} + \item + Korrigieren Sie das Programm so, + daß die Funktion \lstinline{insert_sorted()} ihren Parameter \lstinline{x} + an derjenigen Stelle einfügt, an die er von der Sortierung her gehört. + (Der Stack wird hierbei vor dem Funktionsaufruf als sortiert vorausgesetzt.) + \points{2} + \item + Schreiben Sie eine zusätzliche Funktion \lstinline{int search (int x)}, + die die Position (Index) des Elements \lstinline{x} + innerhalb des Stack zurückgibt -- oder die Zahl + \lstinline{-1}, wenn \lstinline{x} nicht im Stack enthalten ist. + Der Rechenaufwand darf höchstens $\mathcal{O}(n)$ betragen. + \points{3} + \item + Wie (c), aber der Rechenaufwand darf höchstens $\mathcal{O}(\log n)$ betragen. + \points{4} + \end{enumerate} + + \clearpage + + \exercise{Iterationsfunktionen} + + Wir betrachten das folgende Programm (\gitfile{hp}{20190114}{aufgabe-2.c}): + + \begin{minipage}[t]{0.4\textwidth} + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + void foreach (int *a, void (*fun) (int x)) + { + for (int *p = a; *p >= 0; p++) + fun (*p); + } + + void even_or_odd (int x) + { + if (x % 2) + printf ("%d ist ungerade.\n", x); + else + printf ("%d ist gerade.\n", x); + } + \end{lstlisting} + \end{minipage}\hfill + \begin{minipage}[t]{0.52\textwidth} + \begin{lstlisting}[gobble=6] + int main (void) + { + int numbers[] = { 12, 17, 32, 1, 3, 16, 19, 18, -1 }; + foreach (numbers, even_or_odd); + return 0; + } + \end{lstlisting} + \begin{enumerate}[\quad(a)] + \item + Was bedeutet \lstinline{void (*fun) (int x)}, + und welchen Sinn hat seine Verwendung in der Funktion \lstinline{foreach()}? + \points{2} + \item + Schreiben Sie das Hauptprogramm \lstinline{main()} so um, + daß es unter Verwendung der Funktion \lstinline{foreach()} + die Summe aller positiven Zahlen in dem Array berechnet. + Sie dürfen dabei weitere Funktionen sowie globale Variable einführen. + \points{4} + \end{enumerate} + \end{minipage} + + \exercise{Dynamisches Bit-Array} + + Schreiben Sie die folgenden Funktionen zur Verwaltung eines dynamischen Bit-Arrays: + \begin{itemize} + \item + \lstinline{void bit_array_init (int n)}\\ + Das Array initialisieren, so daß man \lstinline{n} Bits darin speichern kann.\\ + Die Array-Größe \lstinline{n} ist keine Konstante, sondern erst im laufenden Programm bekannt.\\ + Die Bits sollen auf den Anfangswert 0 initialisiert werden. + \item + \lstinline{void bit_array_set (int i, int value)}\\ + Das Bit mit dem Index \lstinline{i} auf den Wert \lstinline{value} setzen.\\ + Der Index \lstinline{i} darf von \lstinline{0} bis \lstinline{n - 1} gehen; + der Wert \lstinline{value} darf 1 oder 0 sein. + \item + \lstinline{void bit_array_flip (int i)}\\ + Das Bit mit dem Index \lstinline{i} auf den entgegengesetzten Wert setzen,\\ + also auf 1, wenn er vorher 0 ist, bzw.\ auf 0, wenn er vorher 1 ist.\\ + Der Index \lstinline{i} darf von \lstinline{0} bis \lstinline{n - 1} gehen. + \item + \lstinline{int bit_array_get (int i)}\\ + Den Wert des Bit mit dem Index \lstinline{i} zurückliefern.\\ + Der Index \lstinline{i} darf von \lstinline{0} bis \lstinline{n - 1} gehen. + \item + \lstinline{void bit_array_resize (int new_n)}\\ + Die Größe des Arrays auf \lstinline{new_n} Bits ändern.\\ + Dabei soll der Inhalt des Arrays, soweit er in die neue Größe paßt, erhalten bleiben.\\ + Neu hinzukommende Bits sollen auf 0 initialisiert werden. + \item + \lstinline{void bit_array_done (void)}\\ + Den vom Array belegten Speicherplatz wieder freigeben. + \end{itemize} + Bei Bedarf dürfen Sie den Funktionen zusätzliche Parameter mitgeben, + beispielsweise um mehrere Arrays parallel verwalten zu können. + (In der objektorientierten Programmierung wäre dies der implizite Parameter \lstinline{this}, + der auf die Objekt-Struktur zeigt.) + + Die Bits sollen möglichst effizient gespeichert werden, + z.\,B.\ jeweils 8 Bits in einer \lstinline{uint8_t}-Variablen. + + Die Funktionen sollen möglichst robust sein, + d.\,h.\ das Programm darf auch bei unsinnigen Parameterwerten nicht abstürzen, + sondern soll eine Fehlermeldung ausgeben. + + \medskip + + Die \textbf{Hinweise} auf der nächsten Seite beschreiben + einen möglichen Weg, die Aufgabe zu lösen.\\ + Es seht Ihnen frei, die Aufgabe auch auf andere Weise zu lösen. + + \goodbreak + + Hinweise: + \begin{itemize} + \item + Setzen Sie zunächst voraus, daß das Array die konstante Länge 8 hat, + und schreiben Sie zunächst nur die Funktionen + \lstinline{bit_array_set()}, \lstinline{bit_array_flip()} und + \lstinline{bit_array_get()}. + \item + Verallgemeinern Sie nun auf eine konstante Länge, + bei der es sich um ein Vielfaches von 8 handelt. + \item + Implementieren Sie nun die Überprüfung auf unsinnige Parameterwerte. + Damit können Sie sich gleichzeitig von der Bedingung lösen, + daß die Länge des Arrays ein Vielfaches von 8 sein muß. + \item + Gehen Sie nun von einem statichen zu einem dynamischen Array über, + und implementieren sie die Funktionen \lstinline{bit_array_init()}, + \lstinline{bit_array_done()} und \lstinline{bit_array_reseize()}. + \end{itemize} + + \points{14} + + \medskip + + (Hinweis für die Klausur: + Abgabe in digitaler Form ist erwünscht, aber nicht zwingend.) + + \bigskip + \bigskip + + \begin{flushright} + \textit{Viel Erfolg -- auch in der Klausur!} + \end{flushright} + + \makeatletter + \immediate\write\@mainaux{\string\gdef\string\totalpoints{\arabic{points}}} + \makeatother + +\end{document} diff --git a/20200123/logo-hochschule-bochum-cvh-text-v2.pdf b/20200123/logo-hochschule-bochum-cvh-text-v2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3725a72c764b4d9ab200553474e4262161f7a5b5 Binary files /dev/null and b/20200123/logo-hochschule-bochum-cvh-text-v2.pdf differ diff --git a/20200123/logo-hochschule-bochum.pdf b/20200123/logo-hochschule-bochum.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8cad73dbb48a2b550bf29355b5a6ec895ce091f8 Binary files /dev/null and b/20200123/logo-hochschule-bochum.pdf differ diff --git a/20200123/pgscript.sty b/20200123/pgscript.sty new file mode 120000 index 0000000000000000000000000000000000000000..95c888478c99ea7fda0fd11ccf669ae91be7178b --- /dev/null +++ b/20200123/pgscript.sty @@ -0,0 +1 @@ +../common/pgscript.sty \ No newline at end of file diff --git a/README.md b/README.md index b5b3929d7e4b8ce4f3f4fba38749e12dc63fbb24..6d7fb5b14539c00b1fd140423766eb0d2fb104d5 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ Vortragsfolien und Beispiele: * [02.01.2020: Quantencomputer, Datensicherheit und Datenschutz](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20200102/hp-20200102.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/master/20200102/) * [09.01.2020: Rekursion, Aufwandsabschätzungen, objektorientierte Programmierung](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20200109/hp-20200109.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/master/20200109/) * [16.01.2020: objektorientierte Programmierung, dynamische Speicherverwaltung](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20200116/hp-20200116.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/master/20200116/) + * [23.01.2020: objektorientierte Programmierung, dynamische Speicherverwaltung](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20200123/hp-20200123.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/master/20200123/) * [alle in 1 Datei](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/hp-slides-2019ws.pdf) Übungsaufgaben: @@ -48,6 +49,7 @@ Vortragsfolien und Beispiele: * [19.12.2019: Trickprogrammierung, Thermometer-Baustein an I²C-Bus](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20191219/hp-uebung-20191219.pdf) * [09.01.2020: Speicherformate von Zahlen, Zeigerarithmetik, Personen-Datenbank](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20200109/hp-uebung-20200109.pdf) * [16.01.2020: Fakultät, Länge von Strings (Neuauflage), objektorientierte Tier-Datenbank](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20200116/hp-uebung-20200116.pdf) + * [23.01.2020: Stack-Operationen, Iteratorfunktionen, dynamisches Bit-Array](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20200123/hp-uebung-20200123.pdf) Musterlösungen: ---------------