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

Vorbereitung 17.10.2022

parent 77016da3
No related branches found
No related tags found
No related merge requests found
Showing
with 2233 additions and 0 deletions
int fun_1 (char *s1, char *s2)
{
int result = 1;
for (int i = 0; s1[i] && s2[i]; i++)
if (s1[i] != s2[i])
result = 0;
return result;
}
char*f="char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";main(){printf(f,34,f,34,10);}
File added
This diff is collapsed.
File added
This diff is collapsed.
File added
% hp-uebung-20221017.pdf - Exercises on Low-Level Programming / Applied Computer Sciences
% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 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: Seltsame Programme, Kalender-Berechnung, Strings, Programm analysieren
\documentclass[a4paper]{article}
\usepackage{pgscript}
\begin{document}
\thispagestyle{empty}
\section*{Hardwarenahe Programmierung\\
Übungsaufgaben -- 17.\ Oktober 2022}
\exercise{Seltsame Programme}
Unter \url{https://gitlab.cvh-server.de/pgerwinski/hp/tree/2022ws/20211017}
finden Sie (unter anderem)\\
die Programme \gitfile{hp}{2022ws/20221017}{test-1.c},
\gitfile{hp}{2022ws/20221017}{test-2.c} und \gitfile{hp}{2022ws/20221017}{test-3.c}.
Was bewirken diese Programme, und warum verhalten sie sich so?
\exercise{Kalender-Berechnung}
Am 3.\,1.\,2009 meldete \emph{heise online\/}:
\begin{quote}
Kunden des ersten mobilen Media-Players von Microsoft
erlebten zum Jahresende eine böse Überraschung:
Am 31.\ Dezember 2008 fielen weltweit alle Zune-Geräte der ersten Generation aus.
Ursache war ein interner Fehler bei der Handhabung von Schaltjahren.
\strut\hfill\url{http://heise.de/-193332},
\end{quote}
Der Artikel verweist auf ein Quelltextfragment (Datei: \gitfile{hp}{2022ws/20221017}{aufgabe-2.c}),
das für einen gegebenen Wert \lstinline{days}
das Jahr und den Tag innerhalb des Jahres
für den \lstinline{days}-ten Tag nach dem 1.\,1.\,1980 berechnen soll:
\begin{lstlisting}
year = ORIGINYEAR; /* = 1980 */
while (days > 365)
{
if (IsLeapYear (year))
{
if (days > 366)
{
days -= 366;
year += 1;
}
}
else
{
days -= 365;
year += 1;
}
}
\end{lstlisting}
Dieses Quelltextfragment enthält schlechten Programmierstil,
nämlich mehrere Code-Verdopplungen:
\begin{itemize}
\item
Die Anweisung \lstinline{year += 1} taucht an zwei Stellen auf.
\item
Es gibt zwei unabhängige Abfragen \lstinline{days > 365} und \lstinline{days > 366}:\\
eine in einer \lstinline{while}- und die andere in einer \lstinline{if}-Bedingung.
\item
Die Länge eines Jahres wird nicht durch eine Funktion berechnet oder in einer Variablen gespeichert;
stattdessen werden an mehreren Stellen die expliziten numerischen Konstanten 365 und 366 verwendet.
\end{itemize}
Diese Probleme führten am 31.\ Dezember 2008 zu einer Endlosschleife.
Gut hingegen ist die Verwendung einer Konstanten \lstinline{ORIGINYEAR}
anstelle der Zahl 1980
sowie die Kapselung der Berechnung der Schaltjahr-Bedingung
in einer Funktion \lstinline{IsLeapYear()}.
\begin{itemize}
\item[(a)]
Erklären Sie das Zustandekommen der Endlosschleife.
\item[(b)]
Schreiben Sie das Quelltextfragment so um, daß es die beschriebenen Probleme
nicht mehr enthält.
\end{itemize}
\textbf{Hinweis 1:} Verwenden Sie für \lstinline{IsLeapYear()}
Ihre eigene Funktion aus Aufgabe 1 der letzten Übung.
\textbf{Hinweis 2}: Schreiben Sie zusätzlich eine Funktion \lstinline{DaysInYear()}.
\exercise{Strings}
Strings werden in der Programmiersprache C
durch Zeiger auf \lstinline{char}-Variable realisiert.
Wir betrachten die folgende Funktion (Datei: \gitfile{hp}{2022ws/20221017}{aufgabe-3.c}):
\begin{center}
\begin{minipage}{8cm}
\begin{lstlisting}[gobble=8]
int fun_1 (char *s1, char *s2)
{
int result = 1;
for (int i = 0; s1[i] && s2[i]; i++)
if (s1[i] != s2[i])
result = 0;
return result;
}
\end{lstlisting}
\end{minipage}%
\end{center}
\begin{itemize}
\item[(a)]
Was bewirkt die Funktion? % \points{3}
\item[(b)]
Welchen Sinn hat die Bedingung "`\lstinline{s1[i] && s2[i]}"'
in der \lstinline{for}-Schleife? % \points{2}
\item[(c)]
Was würde sich ändern, wenn die Bedingung "`\lstinline{s1[i] && s2[i]}"'
in der \lstinline{for}-Schleife\\
zu "`\lstinline{s1[i]}"' verkürzt würde? % \points{3}
% \item[(d)]
% Von welcher Ordnung (Landau-Symbol) ist die Funktion \lstinline{fun_1()}
% hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen in den Strings
% -- und warum? % \points{2}
\item[(d)]
Schreiben Sie eine eigene Funktion,
die dieselbe Aufgabe erledigt wie \lstinline{fun_1()}, nur effizienter.
% und geben Sie die Ordnung (Landau-Symbol) der von Ihnen geschriebenen Funktion an. % \points{5}
\end{itemize}
\exercise{Programm analysieren}
Wir betrachten das folgende C-Programm (Datei: \gitfile{hp}{2022ws/20221017}{aufgabe-4.c}):
\begin{lstlisting}
char*f="char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";main(){printf(f,34,f,34,10);}
\end{lstlisting}
\vspace{-\medskipamount}
\begin{itemize}
\item[(a)]
Was bewirkt dieses Programm?
\item[(b)]
Wofür stehen die Zahlen?
\item[(c)]
Ergänzen Sie das Programm derart, daß seine \lstinline{main()}-Funktion
\lstinline{int main (void)} lautet und eine \lstinline{return}-Anweisung hat,
wobei die in Aufgabenteil (a) festgestellte Eigenschaft erhalten bleiben soll.
\end{itemize}
\end{document}
#include <stdio.h>
int IsLeapYear (int year)
{
if (year % 4)
return 0;
else if (year % 100)
return 1;
else if (year % 400)
return 0;
else
return 1;
}
int main (void)
{
int ORIGINYEAR = 1980;
int days = 366;
int year;
year = ORIGINYEAR; /* = 1980 */
int DaysInYear;
if (IsLeapYear (year))
DaysInYear = 366;
else
DaysInYear = 365;
while (days > DaysInYear)
{
days -= DaysInYear;
year += 1;
if (IsLeapYear (year))
DaysInYear = 366;
else
DaysInYear = 365;
}
printf ("year = %d\ndays = %d\n", year, days);
return 0;
}
#include <stdio.h>
int IsLeapYear (int year)
{
if (year % 4)
return 0;
else if (year % 100)
return 1;
else if (year % 400)
return 0;
else
return 1;
}
int main (void)
{
int ORIGINYEAR = 1980;
int days = 366;
int year;
year = ORIGINYEAR; /* = 1980 */
int DaysInYear;
while (days > (DaysInYear = IsLeapYear (year) ? 366 : 365))
{
days -= DaysInYear;
year += 1;
}
printf ("year = %d\ndays = %d\n", year, days);
return 0;
}
#include <stdio.h>
int IsLeapYear (int year)
{
if (year % 4)
return 0;
else if (year % 100)
return 1;
else if (year % 400)
return 0;
else
return 1;
}
int DaysInYear (int year)
{
if (IsLeapYear (year))
return 366;
else
return 365;
}
int main (void)
{
int ORIGINYEAR = 1980;
int days = 366;
int year;
year = ORIGINYEAR; /* = 1980 */
while (days > DaysInYear (year))
{
days -= DaysInYear (year);
year += 1;
}
printf ("year = %d\ndays = %d\n", year, days);
return 0;
}
#include <stdio.h>
int IsLeapYear (int year)
{
if (year % 4)
return 0;
else if (year % 100)
return 1;
else if (year % 400)
return 0;
else
return 1;
}
int DaysInYear (int year)
{
if (IsLeapYear (year))
return 366;
else
return 365;
}
int main (void)
{
int ORIGINYEAR = 1980;
int days = 366;
int year;
year = ORIGINYEAR; /* = 1980 */
int d;
while (days > (d = DaysInYear (year)))
{
days -= d;
year += 1;
}
printf ("year = %d\ndays = %d\n", year, days);
return 0;
}
#include <stdio.h>
int IsLeapYear (int year)
{
if (year % 4)
return 0;
else if (year % 100)
return 1;
else if (year % 400)
return 0;
else
return 1;
}
int DaysInYear (int year)
{
if (IsLeapYear (year))
return 366;
else
return 365;
}
int main (void)
{
int ORIGINYEAR = 1980;
int days = 366;
int year;
year = ORIGINYEAR; /* = 1980 */
int d = DaysInYear (year);
while (days > d)
{
days -= d;
year += 1;
d = DaysInYear (year);
}
printf ("year = %d\ndays = %d\n", year, days);
return 0;
}
#include <stdio.h>
int IsLeapYear (int year)
{
if (year % 4)
return 0;
else if (year % 100)
return 1;
else if (year % 400)
return 0;
else
return 1;
}
int main (void)
{
int ORIGINYEAR = 1980;
int days = 366;
int year;
year = ORIGINYEAR; /* = 1980 */
while (days > 365)
{
if (IsLeapYear (year))
{
if (days > 366)
{
days -= 366;
year += 1;
}
}
else
{
days -= 365;
year += 1;
}
}
printf ("year = %d\ndays = %d\n", year, days);
return 0;
}
#include <stdio.h>
int IsLeapYear (int year)
{
if (year % 4)
return 0;
else if (year % 100)
return 1;
else if (year % 400)
return 0;
else
return 1;
}
int main (void)
{
int ORIGINYEAR = 1980;
int days = 366;
int year;
year = ORIGINYEAR; /* = 1980 */
while ((IsLeapYear (year) && days > 366)
|| (!IsLeapYear (year) && days > 365))
{
if (IsLeapYear (year))
{
if (days > 366)
{
days -= 366;
year += 1;
}
}
else
{
days -= 365;
year += 1;
}
}
printf ("year = %d\ndays = %d\n", year, days);
return 0;
}
#include <stdio.h>
int IsLeapYear (int year)
{
if (year % 4)
return 0;
else if (year % 100)
return 1;
else if (year % 400)
return 0;
else
return 1;
}
int main (void)
{
int ORIGINYEAR = 1980;
int days = 366;
int year;
year = ORIGINYEAR; /* = 1980 */
while (days > (IsLeapYear (year) ? 366 : 365))
{
if (IsLeapYear (year))
{
if (days > 366)
{
days -= 366;
year += 1;
}
}
else
{
days -= 365;
year += 1;
}
}
printf ("year = %d\ndays = %d\n", year, days);
return 0;
}
#include <stdio.h>
int fun_1 (char *s1, char *s2)
{
int result = 1;
for (int i = 0; s1[i] && s2[i]; i++)
if (s1[i] != s2[i])
result = 0;
return result;
}
int fun_2 (char *s1, char *s2)
{
int result = 1;
for (int i = 0; s1[i] && s2[i] && result; i++)
if (s1[i] != s2[i])
result = 0;
return result;
}
int fun_3 (char *s1, char *s2)
{
for (int i = 0; s1[i] && s2[i]; i++)
if (s1[i] != s2[i])
return 0;
return 1;
}
int fun_4 (char *s1, char *s2)
{
int result = 1;
for (int i = 0; s1[i] && s2[i]; i++)
if (s1[i] != s2[i])
{
result = 0;
break;
}
return result;
}
int main (void)
{
char *s1 = "Apfel";
char *s2 = "Apfelkuchen";
if (fun_1 (s1, s2) && fun_2 (s1, s2) && fun_3 (s1, s2) && fun_4 (s1, s2))
printf ("OK\n");
else
printf ("failed\n");
s1 = "Apfelkuchen";
s2 = "Apfel";
if (fun_1 (s1, s2) && fun_2 (s1, s2) && fun_3 (s1, s2) && fun_4 (s1, s2))
printf ("OK\n");
else
printf ("failed\n");
s2 = "Birnenmarmelade";
if (fun_1 (s1, s2) || fun_2 (s1, s2) || fun_3 (s1, s2) || fun_4 (s1, s2))
printf ("failed\n");
else
printf ("OK\n");
s1 = s2;
s2 = "Apfelkuchen";
if (fun_1 (s1, s2) || fun_2 (s1, s2) || fun_3 (s1, s2) || fun_4 (s1, s2))
printf ("failed\n");
else
printf ("OK\n");
return 0;
}
char*f="char*f=%c%s%c;int main(void){printf(f,34,f,34,10);return 0;}%c";int main(void){printf(f,34,f,34,10);return 0;}
#include<stdio.h>
char*f="#include<stdio.h>%cchar*f=%c%s%c;int main(void){printf(f,10,34,f,34,10);return 0;}%c";int main(void){printf(f,10,34,f,34,10);return 0;}
../common/logo-hochschule-bochum-cvh-text-v2.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