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

Musterlösung 12.11.2018

parent 35fbc41b
Branches
No related tags found
No related merge requests found
File added
% hp-musterloesung-20181112.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences
% Copyright (C) 2013, 2015, 2016, 2017, 2018 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: Text-Grafik-Bibliothek, Datum-Bibliothek, Kondensator
\documentclass[a4paper]{article}
\usepackage{pgscript}
\begin{document}
\section*{Hardwarenahe Programmierung\\
Musterlösung zu den Übungsaufgaben -- 12.\ November 2018}
\exercise{Text-Grafik-Bibliothek}
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}
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:
\begin{lstlisting}[gobble=8]
#define WIDTH 72
#define HEIGHT 24
\end{lstlisting}
\item
Schreiben Sie zusätzlich ein Test-Programm,
das alle Funktionen der Bibliothek benutzt,\\
um ein hübsches Bild (z.\,B.\ ein stilisiertes Gesicht -- "`Smiley"')
auszugeben.
\end{itemize}
\solution
Siehe die Dateien \gitfile{hp}{20181112}{textgraph.c} und \gitfile{hp}{20181112}{textgraph.h} (Bibliothek)
sowie \gitfile{20181112}{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}
Zerlegen Sie die Datum-Bibliothek aus der Übungsaufgabe 3 vom 29.\,10.\,2018
in eine \file{.c}- und eine \file{.h}-Datei.
Hinweis: Schreiben Sie auch hierfür zusätzlich ein Test-Programm.
\exercise{Kondensator}
Ein Kondensator der Kapazität $C = 100\,\mu{\rm F}$
ist auf die Spannung $U = 5\,{\rm V}$ aufgeladen
und wird über einen Widerstand $R = 33\,{\rm k}\Omega$ entladen.
\begin{enumerate}[(a)]
\item
Stellen Sie den zeitlichen Spannungsverlauf in einer Tabelle dar.
\item
Wie lange dauert es, bis die Spannung unter $0.1\,{\rm V}$ gefallen ist?
\item
Vergleichen Sie die berechneten Werte mit der exakten theoretischen Entladekurve:
\begin{math}
U(t) = U_0 \cdot e^{-\frac{t}{RC}}
\end{math}
\end{enumerate}
Hinweise:
\begin{itemize}
\item
Für die Simulation zerlegen wir den Entladevorgang in kurze Zeitintervalle $dt$.
Innerhalb jedes Zeitintervalls betrachten wir den Strom $I$ als konstant
und berechnen, wieviel Ladung $Q$ innerhalb des Zeitintervalls
aus dem Kondensator herausfließt.
Aus der neuen Ladung berechnen wir die Spannung am Ende des Zeitintervalls.
\item
Für den Vergleich mit der exakten theoretischen Entladekurve
benötigen Sie die Exponentialfunktion \lstinline{exp()}.
Diese finden Sie in der Mathematik-Bibliothek:
\lstinline{#include <math.h>} im Quelltext,
beim \lstinline[style=cmd]{gcc}-Aufruf \lstinline[style=cmd]{-lm} mit angeben.
\item
$Q = C \cdot U$,\quad $U = R \cdot I$,\quad $I = \frac{dQ}{dt}$
\end{itemize}
\solution
Siehe die Datei: \gitfile{hp}{20181112}{loesung-3.c}
\end{document}
#include <stdio.h>
#include <math.h>
int main (void)
{
double C = 0.0001;
double U0 = 5.0;
double U = U0;
double R = 33000.0;
double t = 0.1;
double dt = 0.01;
double Q = C * U;
while (U > 0.1)
{
printf ("%10.3lf%10.3lf%10.3lf\n", t, U, U0 * exp (-t / (R * C)));
double I = U / R;
Q -= I * dt;
U = Q / C;
t += dt;
}
return 0;
}
#include <stdio.h>
#include "textgraph.h"
int main (void)
{
clear (' ');
put_point (-5, 10, 'X');
for (int i = 17; i < 23; i++)
put_point (i, 5, '*');
put_point (15, 6, '*');
put_point (14, 7, '*');
put_point (13, 8, '*');
put_point (13, 9, '*');
put_point (14, 10, '*');
put_point (15, 11, '*');
for (int i = 17; i < 23; i++)
put_point (i, 12, '*');
put_point (24, 11, '*');
put_point (25, 10, '*');
put_point (26, 9, '*');
put_point (26, 8, '*');
put_point (25, 7, '*');
put_point (24, 6, '*');
put_point (18, 8, 'O');
put_point (21, 8, 'O');
put_point (17, 10, '`');
for (int i = 18; i < 22; i++)
put_point (i, 10, '-');
put_point (22, 10, '\'');
put_point (13, 42, 'Y');
printf ("get_point (%d, %d): '%c'\n", 13, 9, get_point (13, 9));
printf ("get_point (%d, %d): '%c'\n", 14, 9, get_point (14, 9));
printf ("get_point (%d, %d): '%c'\n", 94, 9, get_point (94, 9));
display ();
return 0;
}
#include <stdio.h>
#include "textgraph.h"
char buffer[HEIGHT][WIDTH];
void clear (char c)
{
for (int y = 0; y < HEIGHT; y++)
for (int x = 0; x < WIDTH; x++)
buffer[y][x] = c;
}
static int check_coordinates (int x, int y, char *function)
{
if (x >= 0 && x < WIDTH && y >= 0 && y < HEIGHT)
return 1;
else
{
fprintf (stderr, "coordinates (%d,%d) out of range in %s\n", x, y, function);
return 0;
}
}
void put_point (int x, int y, char c)
{
if (check_coordinates (x, y, "put_point"))
buffer[y][x] = c;
}
char get_point (int x, int y)
{
if (check_coordinates (x, y, "get_point"))
return buffer[y][x];
else
return 0;
}
void display (void)
{
for (int y = 0; y < HEIGHT; y++)
{
for (int x = 0; x < WIDTH; x++)
printf ("%c", buffer[y][x]);
printf ("\n");
}
}
#ifndef TEXTGRAPH_H
#define TEXTGRAPH_H
#define WIDTH 40
#define HEIGHT 20
extern void clear (char c);
extern void put_point (int x, int y, char c);
extern char get_point (int x, int y);
extern void display (void);
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment