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

Vorbereitung 14.11.2024

parent fc012869
No related branches found
No related tags found
No related merge requests found
Showing
with 2161 additions and 0 deletions
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
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)
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)
#include "answer.h"
int answer (void)
{
return 23;
}
extern int answer (void);
eine kleine Hexe.
File added
This diff is collapsed.
File added
% hp-musterloesung-20241114.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences
% Copyright (C) 2013, 2015-2023, 2024 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: 4: Text-Grafik-Bibliothek, Datum-Bibliothek, Ausgabe von Hexadezimal-Zahlen
\documentclass[a4paper]{article}
\usepackage{pgscript}
\begin{document}
\section*{Hardwarenahe Programmierung\\
Musterlösung zu den Übungsaufgaben 4 -- 14.\ November 2024}
\exercise{Text-Grafik-Bibliothek}
\begin{minipage}[t]{0.45\textwidth}
Schreiben Sie eine Bibliothek für "`Text-Grafik"' mit folgenden Funktionen:\vspace*{-\medskipamount}
\begin{itemize}
\item
\lstinline|void clear (char c)|\\
Bildschirm auf Zeichen \lstinline|c| löschen,\\
also komplett mit diesem Zeichen\\
(z.\,B.: Leerzeichen) füllen
\item
\lstinline|void put_point (int x, int y, char c)|\\
Punkt setzen (z.\,B.\ einen Stern (\lstinline{*})\\
an die Stelle $(x,y)$ "`malen"')
\item
\lstinline|char get_point (int x, int y)|\\
Punkt lesen
% \item
% \lstinline|void fill (int x, int y, char c, char o)|\\
% Fläche in der "`Farbe"' \lstinline|o|,
% die den Punkt \lstinline|(x, y)| enthält,
% mit der "`Farbe"' \lstinline|c| ausmalen
\item
\lstinline|void display (void)|\\
das Gezeichnete auf dem Bildschirm\\
ausgeben
\end{itemize}
\points{8}
\end{minipage}\hfill
\begin{minipage}[t]{0.45\textwidth}
\strut\\[-1.2cm]
Hinweise:\vspace*{-\medskipamount}
\begin{itemize}
\item
Eine C-Bibliothek besteht aus (mindestens)
einer \file{.h}-Datei und einer \file{.c}-Datei.
\item
Verwenden Sie ein Array als "`Bildschirm"'.
Vor dem Aufruf der Funktion \lstinline|display()| ist nichts zu sehen;
alle Grafikoperationen erfolgen auf dem Array.
\item
Verwenden Sie Präprozessor-Konstante,
z.\,B.\ \lstinline{WIDTH} und \lstinline{HEIGHT},
um Höhe und Breite des "`Bildschirms"' festzulegen, z.\,B.:
\begin{lstlisting}[gobble=8]
#define WIDTH 72
#define HEIGHT 24
\end{lstlisting}
\item
Schreiben Sie zusätzlich ein Test-Pro\-gramm,
das alle Funktionen der Bibliothek benutzt,
um ein hübsches Bild (z.\,B.\ ein stilisiertes Gesicht -- "`Smiley"')
auszugeben.
\end{itemize}
\end{minipage}
\solution
Siehe die Dateien \gitfile{hp}{2024ws/20241114}{textgraph.c} und \gitfile{hp}{2024ws/20241114}{textgraph.h} (Bibliothek)
sowie \gitfile{hp}{2024ws/20241114}{test-textgraph.c} (Test-Programm).
Diese Lösung erfüllt zusätzlich die Aufgabe,
bei fehlerhafter Benutzung (Koordinaten außerhalb des Zeichenbereichs)
eine sinnvolle Fehlermeldung auszugeben,
anstatt unkontrolliert Speicher zu überschreiben und abzustürzen.
Das Schlüsselwort \lstinline{static}
bei der Deklaration der Funktion \lstinline{check_coordinates()}
bedeutet, daß diese Funktion nur lokal (d.\,h.\ innerhalb der Bibliothek)
verwendet und insbesondere nicht nach außen
(d.\,h.\ für die Benutzung durch das Hauptprogramm) exportiert wird.
Dies dient dazu, nicht unnötig Bezeichner zu reservieren
(Vermeidung von "`Namensraumverschmutzung"').
Man beachte die Verwendung einfacher Anführungszeichen (Apostrophe)
bei der Angabe von \lstinline{char}-Kon"-stanten (\lstinline{'*'})
im Gegensatz zur Verwendung doppelter Anführungszeichen
bei der Angabe von String-Konstanten
(String = Array von \lstinline{char}s, abgeschlossen mit Null-Symbol).
Um das einfache Anführungszeichen selbst als \lstinline{char}-Konstante anzugeben,
ist ein vorangestellter Backslash erforderlich: \lstinline{'\''} ("`Escape-Sequenz"').
Entsprechendes gilt für die Verwendung doppelter Anführungszeichen
innerhalb von String-Konstanten:
\lstinline{printf ("Your name is: \"%s\"", name);}
\exercise{Datum-Bibliothek}
Schreiben Sie eine Bibliothek (\file{.c}-Datei und \file{.h}-Datei)
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.
\points{8}
\solution
Die Dateien \gitfile{hp}{2024ws/20241114}{loesung-2.c},
\gitfile{hp}{2024ws/20241114}{loesung-2.h}
und \gitfile{hp}{2024ws/20241114}{loesung-2-test.c}
enthalten die Bibliothek und das Test-Programm.
Eine detaillierte Anleitung,
wie man auf die Funktion \lstinline{date_next()} kommt,
finden Sie im Skript zur Lehrveranstaltung,
Datei \gitfile{hp}{2024ws/script}{hp-2024ws.pdf},
ab Seite 29.
\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}{2024ws/20241114}{loesung-3-1.c} setzt diesen Zwischenschritt um.
Die Ausgabe der Ziffern erfolgt in \gitfile{hp}{2024ws/20241114}{loesung-3-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}{2024ws/20241114}{loesung-3-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}{2024ws/20241114}{loesung-3-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}{2024ws/20241114}{loesung-3-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
\end{document}
File added
% hp-uebung-20241114.pdf - Exercises on Low-Level Programming / Applied Computer Sciences
% Copyright (C) 2013, 2015-2023, 2024 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: 4: Text-Grafik-Bibliothek, Datum-Bibliothek, Ausgabe von Hexadezimal-Zahlen
\documentclass[a4paper]{article}
\usepackage{pgscript}
\begin{document}
\section*{Hardwarenahe Programmierung\\
Übungsaufgaben 4 -- 14.\ November 2024}
Diese Übung enthält Punkteangaben wie in einer Klausur.
Um zu "`bestehen"', müssen Sie innerhalb von 70 Minuten
unter Verwendung ausschließlich zugelassener Hilfsmittel
12 Punkte (von insgesamt \totalpoints) erreichen.
\thispagestyle{empty}
\exercise{Text-Grafik-Bibliothek}
\begin{minipage}[t]{0.45\textwidth}
Schreiben Sie eine Bibliothek für "`Text-Grafik"' mit folgenden Funktionen:\vspace*{-\medskipamount}
\begin{itemize}
\item
\lstinline|void clear (char c)|\\
Bildschirm auf Zeichen \lstinline|c| löschen,\\
also komplett mit diesem Zeichen\\
(z.\,B.: Leerzeichen) füllen
\item
\lstinline|void put_point (int x, int y, char c)|\\
Punkt setzen (z.\,B.\ einen Stern (\lstinline{*})\\
an die Stelle $(x,y)$ "`malen"')
\item
\lstinline|char get_point (int x, int y)|\\
Punkt lesen
% \item
% \lstinline|void fill (int x, int y, char c, char o)|\\
% Fläche in der "`Farbe"' \lstinline|o|,
% die den Punkt \lstinline|(x, y)| enthält,
% mit der "`Farbe"' \lstinline|c| ausmalen
\item
\lstinline|void display (void)|\\
das Gezeichnete auf dem Bildschirm\\
ausgeben
\end{itemize}
\points{8}
\end{minipage}\hfill
\begin{minipage}[t]{0.45\textwidth}
\strut\\[-1.2cm]
Hinweise:\vspace*{-\medskipamount}
\begin{itemize}
\item
Eine C-Bibliothek besteht aus (mindestens)
einer \file{.h}-Datei und einer \file{.c}-Datei.
\item
Verwenden Sie ein Array als "`Bildschirm"'.
Vor dem Aufruf der Funktion \lstinline|display()| ist nichts zu sehen;
alle Grafikoperationen erfolgen auf dem Array.
\item
Verwenden Sie Präprozessor-Konstante,
z.\,B.\ \lstinline{WIDTH} und \lstinline{HEIGHT},
um Höhe und Breite des "`Bildschirms"' festzulegen, z.\,B.:
\begin{lstlisting}[gobble=8]
#define WIDTH 72
#define HEIGHT 24
\end{lstlisting}
\item
Schreiben Sie zusätzlich ein Test-Pro\-gramm,
das alle Funktionen der Bibliothek benutzt,
um ein hübsches Bild (z.\,B.\ ein stilisiertes Gesicht -- "`Smiley"')
auszugeben.
\end{itemize}
\end{minipage}
\exercise{Datum-Bibliothek}
Schreiben Sie eine Bibliothek (\file{.c}-Datei und \file{.h}-Datei)
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.
\points{8}
\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.)
\makeatletter
\immediate\write\@mainaux{\string\gdef\string\totalpoints{\arabic{points}}}
\makeatother
\end{document}
#include <stdio.h>
#include "loesung-2.h"
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;
}
#include "loesung-2.h"
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;
}
}
}
#include <stdio.h>
typedef struct
{
char day, month;
int year;
}
date;
extern int is_leap_year (int year);
extern int days_in_month (int month, int year);
extern void date_print (date *d);
extern int date_set (date *d, char day, char month, int year);
extern void date_next (date *d);
#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;
}
#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;
}
#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;
}
#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;
}
#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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment