diff --git a/20191107/hp-musterloesung-20191107.pdf b/20191107/hp-musterloesung-20191107.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9905f60c857257ddeb36f9ab2da2da55e8276971 Binary files /dev/null and b/20191107/hp-musterloesung-20191107.pdf differ diff --git a/20191107/hp-musterloesung-20191107.tex b/20191107/hp-musterloesung-20191107.tex new file mode 100644 index 0000000000000000000000000000000000000000..aa38dd6b720f07db83c81af10c35766a2d620409 --- /dev/null +++ b/20191107/hp-musterloesung-20191107.tex @@ -0,0 +1,212 @@ +% hp-musterloesung-20191107.pdf - Solutions to the Exercises on Low-Level Programming +% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019 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: Arrays mit Zahlen, Datum-Bibliothek + +\documentclass[a4paper]{article} + +\usepackage{pgscript} + +\begin{document} + + \section*{Hardwarenahe Programmierung\\ + Musterlösung zu den Übungsaufgaben -- 7.\ November 2019} + + \exercise{Arrays mit Zahlen} + + \begin{minipage}[t]{0.4\textwidth} + Wir betrachten das folgende Programm\\ + (Datei: \gitfile{hp}{20191107}{aufgabe-1.c}): + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + void f (int *s0, int *s1) + { + while (*s0 >= 0) + { + int *s = s1; + while (*s >= 0) + if (*s0 == *s++) + printf ("%d ", *s0); + s0++; + } + printf ("\n"); + } + + int main (void) + { + int a[] = { 10, 4, 3, 7, 12, 0, 1, -1 }; + int b[] = { 7, 14, 0, 8, 9, 22, 10, -1 }; + f (a, b); + return 0; + } + \end{lstlisting} + \end{minipage}\hfill + \begin{minipage}[t]{0.55\textwidth} + \vspace*{-\bigskipamount} + \begin{enumerate}[\quad(a)] + \item + Was bewirkt die Funktion \lstinline{f},\\ + und wie funktioniert sie? + \points{4} +% \item +% Von welcher Ordnung (Landau-Symbol) ist die Funktion? +% Begründen Sie Ihre Antwort. +% +% Wir beziehen uns hierbei auf die Anzahl der Vergleiche +% in Abhängigkeit von der Länge der Eingabedaten \lstinline{s0} und \lstinline{s1}. +% Für die Rechnung dürfen Sie beide Längen mit $n$ gleichsetzen, +% obwohl sie normalerweise nicht gleich sind. +% \points{2} + \item + Was passiert, wenn Sie beim Aufruf der Funktion für einen der + Parameter den Wert \lstinline{NULL} übergeben? + Begründen Sie Ihre Antwort. + \points{2} + \item + Was kann passieren, wenn Sie das Hauptprogramm wie folgt abändern + (\gitfile{hp}{20191107}{aufgabe-1c.c})? + Begründen Sie Ihre Antwort. + \begin{lstlisting}[gobble=8] + int main (void) + { + int a[] = { 10, 4, 3, 7, 12, 0, 1 }; + int b[] = { 7, 14, 0, 8, 9, 22, 10 }; + f (a, b); + return 0; + } + \end{lstlisting} + \points{2} +% \item +% Beschreiben Sie -- in Worten und/oder als C-Quelltext --, wie +% sich die Funktion \lstinline{f} effizienter gestalten läßt, +% wenn man die ihr übergebenen Arrays \lstinline{s0} und +% \lstinline{s1} als sortiert voraussetzt. +% \points{5} +% +% Hinweis: Wie würden Sie als Mensch die Aufgabe erledigen? +% \item +% Von welcher +% Ordnung (Landau-Symbol) ist Ihre effizientere Version der Funktion und warum? +% \points{2} + \end{enumerate} + \end{minipage} + + \solution + + \begin{enumerate}[\quad(a)] + \item + \textbf{Was bewirkt die Funktion \lstinline{f}, und wie funktioniert sie?} + + Die Funktion gibt alle Zahlen aus, die sowohl im Array \lstinline{s0} + als auch im Array \lstinline{s1} vorkommen (Schnittmenge). + + Dies geschieht, indem der Zeiger \lstinline{s0} das gesamte Array durchläuft + (äußere Schleife). + Für jedes Element des ersten Arrays durchläuft der Zeiger \lstinline{s} + das gesamte zweite Array (innere Schleife). + Auf diese Weise wird jedes Element von \lstinline{s0} + mit jedem von \lstinline{s1} verglichen und bei Gleichheit ausgegeben. + + Um die Schleifen abbrechen zu können, enthalten beide Arrays + als Ende-Markierung eine negative Zahl (\lstinline{-1}). + + \item + \textbf{Was passiert, wenn Sie beim Aufruf der Funktion für einen der + Parameter den Wert \lstinline{NULL} übergeben? + Begründen Sie Ihre Antwort.} + + In dem Moment, wo auf den jeweiligen Parameter-Zeiger zugegriffen wird + (\lstinline{while (*s0 >= 0)} für \lstinline{s0} bzw.\ + \lstinline{int *s = s1; while (*s >= 0)} für \lstinline{s1}), + kommt es zu einem Absturz (Speicherzugriffsfehler). + Die Dereferenzierung eines Zeigers mit dem Wert \lstinline{NULL} + ist nicht zulässig. + + \item + \textbf{Was kann passieren, wenn Sie das Hauptprogramm wie folgt abändern + (\gitfile{hp}{20191107}{aufgabe-1c.c})? + Begründen Sie Ihre Antwort.} + + \begin{minipage}{0.35\textwidth} + \begin{lstlisting}[gobble=10] + int main (void) + { + int a[] = { 10, 4, 3, 7, 12, 0, 1 }; + int b[] = { 7, 14, 0, 8, 9, 22, 10 }; + f (a, b); + return 0; + } + \end{lstlisting} + \end{minipage}\hfill + \begin{minipage}{0.575\textwidth} + Durch die fehlenden Ende-Markierungen der Arrays + laufen die Schleifen immer weiter, + bis sie irgendwann zufällig auf Speicherzellen stoßen, + die sich als Ende-Markierungen interpretieren lassen (negative Zahlen). + Dadurch kann es zu einem Lesezugriff auf Speicher kommen, + für den das Programm kein Lesezugriffsrecht hat, + also zu einem Absturz (Speicherzugriffsfehler). + \end{minipage} + \end{enumerate} + + \exercise{Datum-Bibliothek} + + Schreiben Sie eine Bibliothek (= Sammlung von Deklarationen und Funktionen) + zur Behandlung von Datumsangaben. + + Diese soll enthalten: + \begin{itemize} + \item + einen \lstinline{struct}-Datentyp \lstinline{date}, + der eine Datumsangabe speichert, + \item + eine Funktion \lstinline{void date_print (date *d)}, die ein Datum ausgibt, + \item + eine Funktion \lstinline{int date_set (date *d, int day, int month, int year)}, + die ein Datum auf einen gegebenen Tag setzt + und zurückgibt, ob es sich um ein gültiges Datum handelt (0 = nein, 1 = ja), + \item + eine Funktion \lstinline{void date_next (date *d)}, + die ein Datum auf den nächsten Tag vorrückt. + \end{itemize} + + Schreiben Sie auch ein Programm, das die o.\,a.\ Funktionen testet. + + \solution + + Die Datei \gitfile{hp}{20191107}{loesung-2.c} + enthält die Bibliothek zusammen mit einem Test-Programm. + + Eine detaillierte Anleitung, + wie man auf die Funktion \lstinline{date_next()} kommt, + finden Sie im Skript zur Lehrveranstaltung, Datei \gitfile{hp}{script}{hp-2019ws.pdf}, + ab Seite 29. + + (Die Vorgehensweise, + die Bibliothek und das Hauptprogramm in dieselbe Datei zu schreiben, + hat den Nachteil, + daß man die Bibliothek in jedes weitere Programm, das sie benutzt, + kopieren und auch dort aktuell halten muß. + Eine sinnvollere Lösung wird demnächst in der Vorlesung vorgestellt werden.) + +\end{document} diff --git a/20191107/loesung-2.c b/20191107/loesung-2.c new file mode 100644 index 0000000000000000000000000000000000000000..151c965980df79b5d0e04188f7bf6ac7a3b836a9 --- /dev/null +++ b/20191107/loesung-2.c @@ -0,0 +1,109 @@ +#include <stdio.h> + +typedef struct +{ + char day, month; + int year; +} +date; + +int is_leap_year (int year) +{ + if (year % 4 == 0) + if (year % 100 == 0) + if (year % 400 == 0) + return 1; + else + return 0; + else + return 1; + else + return 0; +} + +int days_in_month (int month, int year) +{ + if (month == 2) + if (is_leap_year (year)) + return 29; + else + return 28; + else if (month == 4 || month == 6 || month == 9 || month == 11) + return 30; + else + return 31; +} + +void date_print (date *d) +{ + printf ("%02d.%02d.%04d", d->day, d->month, d->year); +} + +int date_set (date *d, char day, char month, int year) +{ + d->year = year; + if (month > 0 && month <= 12) + d->month = month; + else + return 0; + if (day > 0 && day <= days_in_month (month, year)) + d->day = day; + else + return 0; + return 1; +} + +void date_next (date *d) +{ + d->day++; + if (d->day > days_in_month (d->month, d->year)) + { + d->month++; + d->day = 1; + if (d->month > 12) + { + d->year++; + d->month = 1; + } + } +} + +void check (char day, char month, int year) +{ + date d; + if (date_set (&d, day, month, year)) + { + date_print (&d); + printf (" --> "); + date_next (&d); + date_print (&d); + printf ("\n"); + } + else + printf ("%02d.%02d.%04d: invalid date\n", day, month, year); +} + +int main (void) +{ + check (6, 11, 2018); + check (29, 11, 2018); + check (30, 11, 2018); + check (31, 11, 2018); + check (29, 12, 2018); + check (30, 12, 2018); + check (31, 12, 2018); + check (28, 2, 2016); + check (29, 2, 2016); + check (30, 2, 2016); + check (28, 2, 2015); + check (29, 2, 2015); + check (30, 2, 2015); + check (31, 12, 2008); + check (28, 2, 2000); + check (29, 2, 2000); + check (30, 2, 2000); + check (28, 2, 1900); + check (29, 2, 1900); + check (30, 2, 1900); + return 0; +} diff --git a/20191107/photo-20191107-172458.txt b/20191107/photo-20191107-172458.txt new file mode 100644 index 0000000000000000000000000000000000000000..2be9224d8d9fffdd1006037948f89a5d6f948c3f --- /dev/null +++ b/20191107/photo-20191107-172458.txt @@ -0,0 +1 @@ +README: Beispiele für Bit-Manipulation diff --git a/README.md b/README.md index 90aa25e944941caddd025610c8c5ddf28e18814e..f5c1981f04e18aaef8bd7675ffdfda89c1790dfc 100644 --- a/README.md +++ b/README.md @@ -39,10 +39,11 @@ Musterlösungen: * [17.10.2019: Schaltjahr ermitteln, Multiplikationstabelle, Fibonacci-Zahlen, fehlerhaftes Programm](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20191017/hp-musterloesung-20191017.pdf) * [24.10.2019: Seltsame Programme, Kalender-Berechnung](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20191024/hp-musterloesung-20191024.pdf) * [31.10.2019: Strings, Programm analysieren, fehlerhaftes Primzahl-Programm](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20191031/hp-musterloesung-20191031.pdf) + * [07.11.2019: Arrays mit Zahlen, Datum-Bibliothek](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20191107/hp-musterloesung-20191107.pdf) Tafelbilder: ------------ -(keine) + * [07.11.2019: Beispiele für Bit-Manipulation](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20191107/photo-20191107-172458.jpg) Praktikumsunterlagen: ---------------------