Commit 86bee2bc authored by Peter Gerwinski's avatar Peter Gerwinski

Wintersemester 2019/20

parent fa7edb52
#include <stdio.h>
int main (void)
{
int a;
printf ("Bitte eine Zahl eingeben: ");
scanf ("%d", &a);
a = 2 * a;
printf ("Das Doppelte ist: %d\n", a);
return 0;
}
#include <stdio.h>
int main (void)
{
double a;
printf ("Bitte eine Zahl eingeben: ");
scanf ("%d", &a);
a = 2 * a;
printf ("Das Doppelte ist: %lf\n", a);
return 0;
}
#include <stdio.h>
int main (void)
{
double a;
printf ("Bitte eine Zahl eingeben: ");
scanf ("%d", &a);
a = 2 * a;
printf ("Das Doppelte ist: %d\n", a);
return 0;
}
#include <stdio.h>
int main (void)
{
int a;
printf ("Bitte eine Zahl eingeben: ");
scanf ("%lf", &a);
a = 2 * a;
printf ("Das Doppelte ist: %lf\n", a);
return 0;
}
#include <stdio.h>
int main (void)
{
long long int a;
printf ("Bitte eine Zahl eingeben: ");
scanf ("%lf", &a);
a = 2 * a;
printf ("Das Doppelte ist: %lf\n", a);
return 0;
}
#include <stdio.h>
int main (void)
{
printf ("Hello, world!\n");
return 0;
}
.file "hello-1.c"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "Hello, world!"
.text
.globl main
.type main, @function
main:
.LFB11:
.cfi_startproc #include <stdio.h>
subq $8, %rsp
.cfi_def_cfa_offset 16 int main (void)
leaq .LC0(%rip), %rdi {
call puts@PLT printf ("Hello, world!\n");
movl $0, %eax return 0;
addq $8, %rsp }
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE11:
.size main, .-main
.ident "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
.section .note.GNU-stack,"",@progbits
#include <stdio.h>
int main (void)
{
puts ("Hello, world!");
return 0;
}
.file "hello-2.c"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "Hello, world!"
.text
.globl main
.type main, @function
main:
.LFB11:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
leaq .LC0(%rip), %rdi
call puts@PLT
movl $0, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE11:
.size main, .-main
.ident "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
.section .note.GNU-stack,"",@progbits
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
void draw (void)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f (1.0, 1.0, 0.0);
glRasterPos2f (-0.65, -0.1);
char *hello = "Hello, world!";
while (*hello)
glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, *hello++);
glFlush ();
glutSwapBuffers ();
}
void timer_handler (int data)
{
exit (0);
}
int main (int argc, char **argv)
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize (320, 200);
glutCreateWindow ("Hello");
glutDisplayFunc (draw);
glutTimerFunc (5000, timer_handler, 0);
glutMainLoop ();
return 0;
}
% hp-musterloesung-20181008.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/>.
\documentclass[a4paper]{article}
\usepackage{pgscript}
\begin{document}
\thispagestyle{empty}
\section*{Hardwarenahe Programmierung\\
Musterlösung zu den Übungsaufgaben -- 8.\ Oktober 2018}
\addtocounter{exercise}{1}
\exercise{Multiplikationstabelle}
Geben Sie mit Hilfe einer Schleife ein "`Einmaleins"' aus.\\
Dabei sollen die Faktoren und Ergebnisse rechtsbündig untereinander stehen:
\begin{lstlisting}[style=terminal]
1 * 7 = 7
2 * 7 = 14
...
10 * 7 = 70
\end{lstlisting}
Hinweis: Verwenden Sie Formatspezifikationen wie z.\,B.\ \lstinline{%3d}\\
(siehe dazu die Dokumentation zu \lstinline{printf()},
z.\,B.\ \,\lstinline[style=cmd]{man 3 printf}\,)
\solution
Drei verschiedene richtige Lösungen finden Sie in den Dateien
\gitfile{hp}{20181008}{loesung-2-1.c}, \gitfile{hp}{20181008}{loesung-2-2.c} und \gitfile{hp}{20181008}{loesung-2-3.c}.
(Zum Compilieren von \gitfile{hp}{20181008}{loesung-2-2.c} und \gitfile{hp}{20181008}{loesung-2-3.c}
ist mindestens der C99-Standard erforderlich; bitte nötigenfalls
in \file{gcc} die Option \lstinline[style=cmd]{-std=c99} mit angeben.)
Die Lösung in \gitfile{hp}{20181008}{loesung-2-3.c} ist zwar richtig,
aber unnötig kompliziert und daher nicht empfohlen.
Eine \textbf{falsche} Lösung finden Sie in der Datei \gitfile{hp}{20181008}{loesung-2-f4.c}:
In der Ausgabe dieses Programms stehen die Faktoren und Ergebnisse
nicht rechtsbündig untereinander.
\exercise{Schaltjahr ermitteln}
Schreiben Sie ein Programm, das eine Jahreszahl erfragt
und ausgibt, ob es sich um ein Schaltjahr handelt.
\begin{itemize}
\item Wenn die Jahreszahl durch 4 teilbar ist, ist das Jahr zunächst einmal ein Schaltjahr.
\item Ausnahme: Wenn die Jahreszahl durch 100 teilbar ist, ist das Jahr kein Schaltjahr.
\item Ausnahme von der Ausnahme: Wenn die Jahreszahl durch 400 teilbar ist,\\
ist das Jahr doch wieder ein Schaltjahr.
\end{itemize}
\solution
Am einfachsten ist es, die Aufgabenstellung in geschachtelte
\lstinline{if}-Verzweigungen zu übersetzen.
Im folgenden finden Sie eine Funktion \lstinline{is_leap_year()},
der man das Jahr übergibt und die für Schaltjahre \lstinline{1}
zurückgibt und für Nicht-Schaltjahre \lstinline{0}.
\begin{lstlisting}
#include <stdio.h>
int is_leap_year (int year)
{
int leap_year = 0;
if (year % 4 == 0)
{
leap_year = 1;
if (year % 100 == 0)
{
leap_year = 0;
if (year % 400 == 0)
leap_year = 1;
}
}
return leap_year;
}
\end{lstlisting}
(In C steht \lstinline{0} für den Wahrheitswert "`falsch"'
und jeder Wert ungleich \lstinline{0} für den Wahrheitswert "`wahr'";
die Zeile \lstinline{leap_year = 0} steht daher wörtlich und
selbsterklärend für "`ist kein Schaltjahr"'.)
Unter Verwendung von \lstinline{else} läßt sich dies verkürzen zu:
\begin{lstlisting}
#include <stdio.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;
}
\end{lstlisting}
Eine andere Möglichkeit ist es, die Schaltjahr-Bedingung in eine
Kette von "`und"'- und "`oder"'-Verknüpfungen
(C-Operatoren \lstinline{&&} und \lstinline{||}) zu übersetzen:
\begin{lstlisting}
int is_leap_year (int year)
{
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
return 1;
else
return 0;
}
\end{lstlisting}
Dies ist zwar kürzer, aber nicht unbedingt übersichtlicher.
Der erzeugte Code ist übrigens \emph{nicht\/} kürzer und/oder
effizienter als bei der Verwendung mehrerer
\lstinline{if}-Verzweigungen.
Wir empfehlen, daß Sie immer so programmieren,
daß Sie selbst den maximalen Überblick über Ihr Programm behalten.
\goodbreak
Ein Hauptprogramm, das die o.\,a.\ Funktion aufruft,
könnte dann wie folgt aussehen:
\begin{lstlisting}
int main (void)
{
int year;
printf ("Bitte geben Sie eine Jahreszahl ein: ");
scanf ("%d", &year);
if (is_leap_year (year))
printf ("Das Jahr %d ist ein Schaltjahr.\n", year);
else
printf ("Das Jahr %d ist kein Schaltjahr.\n", year);
return 0;
}
\end{lstlisting}
In den Dateien \gitfile{hp}{20181008}{loesung-3-1.c} bis \gitfile{hp}{20181008}{loesung-3-3.c}
finden Sie lauffähige Programme, die die o.\,a.\ Funktionen aufrufen.
Beachten Sie, daß die Funktion \emph{vor\/} dem Hauptprogramm
deklariert werden muß, damit das Hauptprogramm sie kennt.
(Es gibt Tricks, mit denen es auch anders geht,
aber was hätten wir in diesem Zusammenhang davon?)
In \gitfile{hp}{20181008}{loesung-3-4.c} und \gitfile{hp}{20181008}{loesung-3-5.c}
findet die Schaltjahr-Prüfung direkt im Hauptprogramm statt.
Dies ist ebenfalls eine richtige Lösung der Aufgabe,
schränkt aber die Wiederverwertbarkeit des Codes ein.
Die Datei \gitfile{hp}{20181008}{loesung-3-4.c} enthält darüberhinaus Codeverdopplungen,
nämlich mehrere identische \lstinline{printf()}-Auf"-rufe
an unterschiedlichen Stellen.
Dies ist schlechter Programmierstil ("`Cut-and-paste-Programmierung"').
Die besten Lösungen sind \gitfile{hp}{20181008}{loesung-3-2.c}
und \gitfile{hp}{20181008}{loesung-3-3.c}.
\goodbreak
Zum Testen:\vspace*{-\medskipamount}
\begin{itemize}\itemsep0pt
\item 1900 ist kein Schaltjahr.
\item 1902 ist kein Schaltjahr.
\item 1904 ist ein Schaltjahr.
\item 1996 ist ein Schaltjahr.
\item 1998 ist kein Schaltjahr.
\item 2000 ist ein Schaltjahr.
\item 2002 ist kein Schaltjahr.
\item 2004 ist ein Schaltjahr.
\item 2015 ist kein Schaltjahr.
\item 2016 ist ein Schaltjahr.
\item 2017 ist kein Schaltjahr.
\item 2018 ist kein Schaltjahr.
\end{itemize}