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

Musterlösung 9.10.2017, Vorbereitung 16.10.2017

parent cd3b2b33
Branches
No related tags found
No related merge requests found
Showing
with 1733 additions and 178 deletions
No preview for this file type
......@@ -26,8 +26,6 @@
\usepackage{pdftricks}
\usepackage{tikz}
\newrgbcolor{orange}{0.8 0.4 0.0}
\begin{psinputs}
\usepackage[utf8]{inputenc}
\usepackage[german]{babel}
......@@ -300,7 +298,7 @@
\hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp.git}}}
\begin{itemize}
\color{medgreen}
\item[1.1] Was ist angewandte Informatik?
\item[1.1] Was ist angewandte Informatik / hardwarenahe Programmierung?
\item[1.2] Programmierung in C
\item[1.3] Zu dieser Lehrveranstaltung
\end{itemize}
......@@ -313,9 +311,9 @@
\item[2.4] Elementares Rechnen
\item[2.5] Verzweigungen
\item[2.6] Schleifen
\item[2.7] Seiteneffekte
\item[2.8] Strukturierte Programmierung
\item[2.7] Strukturierte Programmierung
\item[\dots]
% \item[2.8] Seiteneffekte
% \item[2.9] Funktionen
% \item[2.10] Zeiger
% \item[2.11] Arrays und Strings
......@@ -563,164 +561,6 @@
\end{frame}
\subsection{Seiteneffekte}
\begin{frame}[fragile]
\showsubsection
\begin{lstlisting}
#include <stdio.h>
int main (void)
{
printf ("%d\n", 42);
"\n";
return 0;
}
\end{lstlisting}
\pause
\begin{picture}(0,0)
\color{red}
\put(1.8,1.35){\tikz{\draw[-latex](0.0,0.0)--(-1.7,0);}}
\put(3.6,1.35){\makebox(0,0)[l]{Ausdruck als Anweisung: Wert wird ignoriert}}
\pause
\put(3.15,1.40){\tikz{\draw[-latex](0.0,0.0)--(-0.4,0.2);}}
\end{picture}
\end{frame}
\begin{frame}[fragile]
\showsubsection
\begin{lstlisting}
#include <stdio.h>
int main (void)
{
int a = printf ("%d\n", 42);
printf ("%d\n", a);
return 0;
}
\end{lstlisting}
\pause
\bigskip
\begin{lstlisting}[style=terminal]
$ ¡gcc -Wall -O side-effects-1.c -o side-effects-1¿
$ ¡./side-effects-1¿
42
3
$
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]
\showsubsection
\begin{lstlisting}
#include <stdio.h>
int main (void)
{
int a = printf ("%d\n", 42);
printf ("%d\n", a);
return 0;
}
\end{lstlisting}
\begin{itemize}
\item
\lstinline{printf()} ist eine Funktion.
\pause
\item
"`Haupteffekt"': Wert zurückliefern\\
(hier: Anzahl der ausgegebenen Zeichen)
\pause
\item
\newterm{Seiteneffekt\/}: Ausgabe
\end{itemize}
\end{frame}
\addtocounter{subsection}{-1}
\subsection{Seiteneffekte \protect\color{gray}bei Operatoren}
\begin{frame}[fragile]
\showsubsection
\begin{minipage}[t]{6cm}
Unäre Operatoren:
\begin{itemize}
\item
Negation: \lstinline{-foo}
\item
{\only<2->{\color{red}}Funktionsaufruf}: \lstinline{foo ()}
\item
{\only<2->{\color{red}}Post-Inkrement}: \lstinline{foo++}
\item
{\only<2->{\color{red}}Post-Dekrement}: \lstinline{foo--}
\item
{\only<2->{\color{red}}Prä-Inkrement}: \lstinline{++foo}
\item
{\only<2->{\color{red}}Prä-Dekrement}: \lstinline{--foo}
\end{itemize}
\medskip
Binäre Operatoren:
\begin{itemize}
\item
Rechnen: \lstinline{+ - * / %}
\item
Vergleich: \lstinline{== != < > <= >=}
\item
{\only<2->{\color{red}}Zuweisung}: \lstinline{= += -= *= /= %=}
\item
Ignorieren: \lstinline{,}
\end{itemize}
\pause
\medskip
{\color{red}rot = mit Seiteneffekt}
\end{minipage}
\pause
\begin{minipage}[t]{6cm}
\vspace{-\bigskipamount}
\begin{lstlisting}
int i;
\end{lstlisting}
\bigskip
\begin{lstlisting}
i = 0;
while (i < 10)
{
printf ("%d\n", i);
i++;
}
\end{lstlisting}
\bigskip
\pause
\begin{lstlisting}
for (i = 0; i < 10; i++)
printf ("%d\n", i);
\end{lstlisting}
\bigskip
\pause
\begin{lstlisting}
i = 0;
while (i < 10)
printf ("%d\n", i++);
\end{lstlisting}
\bigskip
\pause
\begin{lstlisting}
for (i = 0; i < 10; printf ("%d\n", i++));
\end{lstlisting}
\end{minipage}
\vspace*{-1cm}
\end{frame}
\subsection{Strukturierte Programmierung}
\begin{frame}[fragile]
......@@ -730,57 +570,57 @@
\begin{minipage}[t]{6cm}
\begin{onlyenv}<2->
\begin{lstlisting}[gobble=8]
i = 0;
¡i = 0;
while (1)
{
if (i >= 10)
break;
printf ("%d\n", i++);
}
}¿
\end{lstlisting}
\end{onlyenv}
\strut
\bigskip
\begin{onlyenv}<3->
\begin{lstlisting}[gobble=8]
i = 0;
¡i = 0;
loop:
if (i >= 10)
goto endloop;
printf ("%d\n", i++);
goto loop;
endloop:
endloop:¿
\end{lstlisting}
\end{onlyenv}
\end{minipage}
\begin{minipage}[t]{6cm}
\vspace{-\bigskipamount}
\begin{lstlisting}
int i;
¡int i;
\end{lstlisting}
\bigskip
\begin{lstlisting}
i = 0;
¡i = 0;
while (i < 10)
{
printf ("%d\n", i);
i++;
}
}¿
\end{lstlisting}
\bigskip
\begin{lstlisting}
for (i = 0; i < 10; i++)
printf ("%d\n", i);
¡for (i = 0; i < 10; i++)
printf ("%d\n", i);¿
\end{lstlisting}
\bigskip
\begin{lstlisting}
i = 0;
¡i = 0;
while (i < 10)
printf ("%d\n", i++);
printf ("%d\n", i++);¿
\end{lstlisting}
\bigskip
\begin{lstlisting}
for (i = 0; i < 10; printf ("%d\n", i++));
¡for (i = 0; i < 10; printf ("%d\n", i++));¿
\end{lstlisting}
\end{minipage}%
\begin{onlyenv}<5->
......@@ -817,7 +657,7 @@
\hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp.git}}}
\begin{itemize}
\color{medgreen}
\item[1.1] Was ist angewandte Informatik?
\item[1.1] Was ist angewandte Informatik / hardwarenahe Programmierung?
\item[1.2] Programmierung in C
\item[1.3] Zu dieser Lehrveranstaltung
\end{itemize}
......@@ -830,9 +670,9 @@
\item[2.4] Elementares Rechnen
\item[2.5] Verzweigungen
\item[2.6] Schleifen
\item[2.7] Seiteneffekte
\item[2.8] Strukturierte Programmierung
\item[2.7] Strukturierte Programmierung
\color{red}
\item[2.8] Seiteneffekte
\item[2.9] Funktionen
\item[2.10] Zeiger
\item[\dots]
......
File added
% hp-musterloesung-20171009.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences
% Copyright (C) 2013, 2015, 2016, 2017 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 / Angewandte Informatik\\
Musterlösung zu den Übungsaufgaben -- 9.\ Oktober 2017}
\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}{20171009}{loesung-2-1.c}, \gitfile{hp}{20171009}{loesung-2-2.c} und \gitfile{hp}{20171009}{loesung-2-3.c}.
(Zum Compilieren von \gitfile{hp}{20171009}{loesung-2-2.c} und \gitfile{hp}{20171009}{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}{20171009}{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}{20171009}{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}{20171009}{loesung-3-1.c} bis \gitfile{hp}{20171009}{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}{20171009}{loesung-3-4.c} und \gitfile{hp}{20171009}{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}{20171009}{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}{20171009}{loesung-3-2.c}
und \gitfile{hp}{20171009}{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 2014 ist kein Schaltjahr.
\item 2015 ist kein Schaltjahr.
\item 2016 ist ein Schaltjahr.
\item 2017 ist kein Schaltjahr.
\end{itemize}
Hier noch ein Hinweis für Unix-Shell-Experten:
\begin{lstlisting}[style=cmd]
for y in 1 2 3 4 5; do
clear
for x in 1900 1902 1904 1996 1998 2000 2002 2004 2014 2015 2016 2017; do
echo $x | ./loesung-3-$y
done
sleep 2s
done
\end{lstlisting}
\end{document}
#include <stdio.h>
int main (void)
{
int a = 1;
int b = 7;
while (a <= 10)
{
printf ("%2d * %d = %2d\n", a, b, a * b);
a++;
}
return 0;
}
#include <stdio.h>
int main (void)
{
int x = 7;
for (int i = 1; i <= 10; i++)
printf ("%2d *%2d =%3d\n", i, x, i * x);
return 0;
}
#include <stdio.h>
int main (void)
{
int x = 7;
for (int i = 1; i <= 10; i++)
{
if (i >= 10)
printf ("%d", i);
else
printf (" %d", i);
printf (" * %d = ", x);
int y = i * x;
if (y >= 10)
printf ("%d", y);
else
printf (" %d", y);
printf ("\n");
}
return 0;
}
#include <stdio.h>
int main (void)
{
int x = 7;
for (int i = 1; i <= 10; i++)
printf ("%d * %d = %d\n", i, x, i * x);
return 0;
}
#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;
}
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;
}
#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;
}
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;
}
#include <stdio.h>
int is_leap_year (int year)
{
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
return 1;
else
return 0;
}
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;
}
#include <stdio.h>
int main (void)
{
int year;
printf ("Bitte geben Sie eine Jahreszahl ein: ");
scanf ("%d", &year);
if (year % 4 == 0)
{
if (year % 100 == 0)
{
if (year % 400 == 0)
printf ("Das Jahr %d ist ein Schaltjahr.\n", year);
else
printf ("Das Jahr %d ist kein Schaltjahr.\n", year);
}
else
printf ("Das Jahr %d ist ein Schaltjahr.\n", year);
}
else
printf ("Das Jahr %d ist kein Schaltjahr.\n", year);
return 0;
}
#include <stdio.h>
int main (void)
{
int year;
printf ("Bitte geben Sie eine Jahreszahl ein: ");
scanf ("%d", &year);
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
printf ("Das Jahr %d ist ein Schaltjahr.\n", year);
else
printf ("Das Jahr %d ist kein Schaltjahr.\n", year);
return 0;
}
#include <stdio.h>
int main (void)
{
for (int i = 10; i = 0; i - 1)
printf ("%d\n", i);
return 0;
}
File added
This diff is collapsed.
File added
% hp-uebung-20171016.pdf - Exercises on Low-Level Programming / Applied Computer Sciences
% Copyright (C) 2013, 2015, 2016, 2017 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}
\thispagestyle{empty}
\begin{document}
\thispagestyle{empty}
\section*{Hardwarenahe Programmierung / Angewandte Informatik\\
Übungsaufgaben -- 16.\ Oktober 2017}
\exercise{Fibonacci-Zahlen}
Die Folge der Fibonacci-Zahlen ist definiert durch:
\begin{quote}
1.\ Zahl: 0\\
2.\ Zahl: 1\\
nächste Zahl = Summe der beiden vorherigen
\end{quote}
Schreiben Sie ein Programm, das die ersten 50 Fibonacci-Zahlen ausgibt.
\exercise{Fehlerhaftes Programm}
Wir betrachten das folgende C-Programm
(Datei: \gitfile{hp}{20171016}{aufgabe-2.c}):
\begin{lstlisting}
#include <stdio.h>
int main (void)
{
for (int i = 10; i = 0; i - 1)
printf ("%d\n", i);
return 0;
}
\end{lstlisting}
\begin{itemize}
\item[(a)]
Was bewirkt dieses Programm und warum?
\item[(b)]
Ändern Sie das Programm so, daß es einen "`Countdown"' von 10 bis 0 ausgibt.
\end{itemize}
\exercise{Hello, world!}
Unter \url{https://gitlab.cvh-server.de/pgerwinski/hp/tree/master/20171016}
finden Sie (unter anderem)\\
die Programme \gitfile{hp}{20171016}{test-1.c},
\gitfile{hp}{20171016}{test-2.c} und \gitfile{hp}{20171016}{test-3.c}.
Was bewirken diese Programme, und warum verhalten sie sich so?
\end{document}
../common/logo-hochschule-bochum-cvh-text.pdf
\ No newline at end of file
../common/logo-hochschule-bochum.pdf
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment