snp-lab-code/main.tex

4084 lines
146 KiB
TeX
Raw Normal View History

2022-02-17 11:38:42 +01:00
%% Generated by Sphinx.
\def\sphinxdocclass{report}
\documentclass[a4paper,10pt,english]{report}
\ifdefined\pdfpxdimen
\let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen
\fi \sphinxpxdimen=.75bp\relax
\ifdefined\pdfimageresolution
\pdfimageresolution= \numexpr \dimexpr1in\relax/\sphinxpxdimen\relax
\fi
%% let collapsible pdf bookmarks panel have high depth per default
\PassOptionsToPackage{bookmarksdepth=5}{hyperref}
\PassOptionsToPackage{warn}{textcomp}
\usepackage[utf8]{inputenc}
\ifdefined\DeclareUnicodeCharacter
% support both utf8 and utf8x syntaxes
\ifdefined\DeclareUnicodeCharacterAsOptional
\def\sphinxDUC#1{\DeclareUnicodeCharacter{"#1}}
\else
\let\sphinxDUC\DeclareUnicodeCharacter
\fi
\sphinxDUC{00A0}{\nobreakspace}
\sphinxDUC{2500}{\sphinxunichar{2500}}
\sphinxDUC{2502}{\sphinxunichar{2502}}
\sphinxDUC{2514}{\sphinxunichar{2514}}
\sphinxDUC{251C}{\sphinxunichar{251C}}
\sphinxDUC{2572}{\textbackslash}
\fi
\usepackage{cmap}
\usepackage[T1]{fontenc}
\usepackage{amsmath,amssymb,amstext}
\usepackage{babel}
\usepackage{amsmath,amsfonts,amssymb,amsthm}
\usepackage{fncychap}
\usepackage{sphinx}
\sphinxsetup{hmargin={0.7in,0.7in}, vmargin={1in,1in}, verbatimwithframe=true, TitleColor={rgb}{0,0,0}, HeaderFamily=\rmfamily\bfseries, InnerLinkColor={rgb}{0,0,1}, OuterLinkColor={rgb}{0,0,1}}
\fvset{fontsize=auto}
\usepackage{geometry}
% Include hyperref last.
\usepackage{hyperref}
% Fix anchor placement for figures with captions.
\usepackage{hypcap}% it must be loaded after hyperref.
% Set up styles of URL: it should be placed after hyperref.
\urlstyle{same}
\addto\captionsenglish{\renewcommand{\contentsname}{Contents:}}
\usepackage{sphinxmessages}
\setcounter{tocdepth}{2}
%% %% %% %% %% %% %% %% %% %% Meher %% %% %% %% %% %% %% %% %%
%% %add number to subsubsection 2=subsection, 3=subsubsection
%% % below subsubsection is not good idea.
\setcounter{secnumdepth}{3}
%
%% %% Table of content upto 2=subsection, 3=subsubsection
\setcounter{tocdepth}{2}
\usepackage{amsmath,amsfonts,amssymb,amsthm}
\usepackage{graphicx}
%% % r educe spaces for Table of contents, figures and tables
%% % i t is used "\addtocontents{toc}{\vskip -1.2cm}" etc. in the document
\usepackage[notlot,nottoc,notlof]{}
\usepackage{color}
\usepackage{transparent}
\usepackage{eso-pic}
\usepackage{lipsum}
\usepackage{footnotebackref} %% link at the footnote to go to the place of footnote in the text
%% spacing between line
\usepackage{setspace}
%% %% \onehalfspacing
%% %% \doublespacing
\singlespacing
%% %% %% %% %% % d atetime
\usepackage{datetime}
\newdateformat{MonthYearFormat}{%
\monthname[\THEMONTH], \THEYEAR}
%% RO, LE will not work for 'oneside' layout.
%% Change oneside to twoside in document class
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhf{}
%% % Alternating Header for oneside
\fancyhead[L]{\ifthenelse{\isodd{\value{page}}}{ \small \nouppercase{\leftmark} }{}}
\fancyhead[R]{\ifthenelse{\isodd{\value{page}}}{}{ \small \nouppercase{\rightmark} }}
%% % Alternating Header for two side
%\fancyhead[RO]{\small \nouppercase{\rightmark}}
%\fancyhead[LE]{\small \nouppercase{\leftmark}}
%% for oneside: change footer at right side. If you want to use Left and right then use same as header defined above.
%% %\fancyfoot[R]{\ifthenelse{\isodd{\value{page}}}{{\tiny Meher Krishna Patel} }{\href{http://pythondsp.readthedocs.io/en/latest/pythondsp/toc.html}{\tiny PythonDSP}}}
%% % Alternating Footer for two side
%\fancyfoot[RO, RE]{\scriptsize Meher Krishna Patel (mekrip@gmail.com)}
%% % page number
\fancyfoot[CO, CE]{\thepage}
\renewcommand{\headrulewidth}{0.5pt}
\renewcommand{\footrulewidth}{0.5pt}
\RequirePackage{tocbibind} %% % c omment this to remove page number for following
\addto\captionsenglish{\renewcommand{\contentsname}{Table of contents}}
\addto\captionsenglish{\renewcommand{\listfigurename}{List of figures}}
\addto\captionsenglish{\renewcommand{\listtablename}{List of tables}}
% \addto\captionsenglish{\renewcommand{\chaptername}{Chapter}}
%% reduce spacing for itemize
\usepackage{enumitem}
\setlist{nosep}
%% %% %% %% %% % Quote Styles at the top of chapter
\usepackage{epigraph}
\setlength{\epigraphwidth}{0.8\columnwidth}
\newcommand{\chapterquote}[2]{\epigraphhead[60]{\epigraph{\textit{#1}}{\textbf {\textit{--#2}}}}}
%% %% %% %% %% % Quote for all places except Chapter
\newcommand{\sectionquote}[2]{{\quote{\textit{``#1''}}{\textbf {\textit{--#2}}}}}
\title{SNP Laboratories}
\date{Feb 17, 2022}
\release{}
\author{}
\newcommand{\sphinxlogo}{\sphinxincludegraphics{en-zhaw-ines-rgb.png}\par}
\renewcommand{\releasename}{ }
\makeindex
\begin{document}
\ifdefined\shorthandoff
\ifnum\catcode`\=\string=\active\shorthandoff{=}\fi
\ifnum\catcode`\"=\active\shorthandoff{"}\fi
\fi
\pagestyle{empty}
\pagenumbering{Roman} %% % to avoid page 1 conflict with actual page 1
\begin{titlepage}
\centering
\vspace*{40mm} %% % * is used to give space from top
\textbf{\Huge {SNP Laboratories}}
\vspace{0mm}
\begin{figure}[!h]
\centering
\includegraphics[scale=0.5]{en-zhaw-ines-rgb.png}
\end{figure}
\begin{figure}[!h]
\centering
\textbf{ welo, donn, bohe, bazz, grop, huno, giei, fisa, kocb }
\end{figure}
\vspace*{20mm}
\vspace{20mm}
\vspace*{0mm}
\small Last updated : \MonthYearFormat\today
%% \vfill adds at the bottom
\vfill
\small \textit{More documents are available at }{\href{https://github.zhaw.ch/SNP/snp/tree/master/praktika}{github.zhaw.ch}}
\end{titlepage}
\clearpage
\pagenumbering{roman}
\tableofcontents
%% %\listoffigures
%% %\listoftables
\clearpage
\pagenumbering{arabic}
\pagestyle{plain}
\pagestyle{normal}
\phantomsection\label{\detokenize{index::doc}}
\chapter{01 \sphinxhyphen{} Erste Schritte mit C}
\label{\detokenize{P01_Erste_Schritte_mit_C/README:erste-schritte-mit-c}}\label{\detokenize{P01_Erste_Schritte_mit_C/README::doc}}
\bigskip\hrule\bigskip
\section{1. Übersicht}
\label{\detokenize{P01_Erste_Schritte_mit_C/README:ubersicht}}
\sphinxAtStartPar
In diesem Praktikum erstellen Sie mehrere kleine C\sphinxhyphen{}Programme, in denen Sie Input\sphinxhyphen{} und Output\sphinxhyphen{}Funktionen der C Standard Library verwenden.
\sphinxAtStartPar
Arbeiten Sie in Zweiergruppen und diskutieren Sie ihre Lösungsansätze miteinander, bevor Sie diese umsetzen.
\sphinxAtStartPar
Bevor Sie mit den Programmieraufgaben beginnen, setzen Sie eine virtuelle Maschine mit der vorbereiteten Praktikumsumgebung auf.
\bigskip\hrule\bigskip
\section{2. Lernziele}
\label{\detokenize{P01_Erste_Schritte_mit_C/README:lernziele}}
\sphinxAtStartPar
In diesem Praktikum schreiben Sie selbst von Grund auf einige einfache C\sphinxhyphen{}Programme und wenden verschiedene Kontrollstrukturen an.
\begin{itemize}
\item {}
\sphinxAtStartPar
Sie können mit \sphinxstyleemphasis{\#include} Funktionen der C Standard Library einbinden
\item {}
\sphinxAtStartPar
Sie können mit \sphinxstyleemphasis{\#define} Macros definieren und diese anwenden
\item {}
\sphinxAtStartPar
Sie wenden die \sphinxstyleemphasis{Input\sphinxhyphen{}} und \sphinxstyleemphasis{Output\sphinxhyphen{}Funktionen} von C an, um Tastatur\sphinxhyphen{}Input einzulesen und formatierte Ausgaben zu machen.
\item {}
\sphinxAtStartPar
Sie verwenden die Kommandozeile, um ihren Sourcecode in ein ausführbares Programm umzuwandeln.
\item {}
\sphinxAtStartPar
Sie wenden for\sphinxhyphen{}und while\sphinxhyphen{}Loops sowie if\sphinxhyphen{}then\sphinxhyphen{}else\sphinxhyphen{}Verzweigungen an.
\item {}
\sphinxAtStartPar
Sie setzen eine Programmieraufgabe selbständig in ein funktionierendes Programm um.
\end{itemize}
\bigskip\hrule\bigskip
\section{3. Aufgabe 1: virtuelle Maschine}
\label{\detokenize{P01_Erste_Schritte_mit_C/README:aufgabe-1-virtuelle-maschine}}
\sphinxAtStartPar
Im Moodle\sphinxhyphen{}Kurs “Systemnahe Programmierung” finden Sie unter “Praktika” eine Installationsanleitung für die virtuelle Maschine, die wir Ihnen zur Verfügung stellen. Die virtuelle Maschine enthält ein Ubuntu Linux\sphinxhyphen{}Betriebssystem und die für das Praktikum benötigten Frameworks.
\sphinxAtStartPar
Folgen sie der Anleitung, um die virtuelle Maschine auf ihrem Rechner zu installieren.
\bigskip\hrule\bigskip
\section{4. Aufgabe 2: Hello World}
\label{\detokenize{P01_Erste_Schritte_mit_C/README:aufgabe-2-hello-world}}
\sphinxAtStartPar
Schreiben Sie ein C\sphinxhyphen{}Programm, das “Hello World” auf die Standardausgabe schreibt. Verwenden Sie die printf\sphinxhyphen{}Funktion aus der Standard Library. In den Vorlesungsfolien finden Sie bei Bedarf eine Vorlage.
\sphinxAtStartPar
Erstellen sie das Source\sphinxhyphen{}File mit einem beliebigen Editor, sie benötigen nicht unbedingt eine IDE. Speichern Sie das Source\sphinxhyphen{}File mit der Endung \sphinxcode{\sphinxupquote{.c}}.
\sphinxAtStartPar
Um ihr Source\sphinxhyphen{}File zu kompilieren, verwenden Sie den GNU Compiler auf der Kommandozeile:
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdl{}\PYGZgt{} gcc hello.c
\end{sphinxVerbatim}
\sphinxAtStartPar
Der Compiler übersetzt ihr Programm in eine ausführbare Datei \sphinxcode{\sphinxupquote{a.out}}, die Sie mit
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdl{}\PYGZgt{} ./a.out
\end{sphinxVerbatim}
\sphinxAtStartPar
ausführen können. Sie können den Namen der ausführbaren Datei wählen, indem Sie die Option \sphinxcode{\sphinxupquote{\sphinxhyphen{}o}} verwenden:
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdl{}\PYGZgt{} gcc hello.c \PYGZhy{}o hello
\end{sphinxVerbatim}
\sphinxAtStartPar
erzeugt die ausführbare Datei \sphinxcode{\sphinxupquote{hello}}.
\sphinxAtStartPar
Verwenden Sie die Option \sphinxcode{\sphinxupquote{\sphinxhyphen{}Wall}}, um alle Warnungen des Compilers auszugeben. Dies weist Sie auf allfällige Programmierfehler hin.
\bigskip\hrule\bigskip
\section{5. Aufgabe 3: Tabellenausgabe}
\label{\detokenize{P01_Erste_Schritte_mit_C/README:aufgabe-3-tabellenausgabe}}
\sphinxAtStartPar
Schreiben Sie ein Programm in C, das von \sphinxcode{\sphinxupquote{stdin}} einen Umrechnungsfaktor zwischen CHF und Bitcoin einliest und danach eine Tabelle von Franken\sphinxhyphen{} und Bitcoin\sphinxhyphen{}Beträgen ausgibt. Die Tabelle soll sauber formatiert sein, z.B. so:
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Enter} \PYG{n}{conversion} \PYG{n}{rate} \PYG{p}{(}\PYG{l+m+mf}{1.00} \PYG{n}{BTC} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}} \PYG{n}{CHF}\PYG{p}{)}\PYG{p}{:} \PYG{l+m+mf}{43158.47}
\PYG{l+m+mi}{200} \PYG{n}{CHF} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mf}{0.00463} \PYG{n}{BTC}
\PYG{l+m+mi}{400} \PYG{n}{CHF} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mf}{0.00927} \PYG{n}{BTC}
\PYG{l+m+mi}{600} \PYG{n}{CHF} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mf}{0.01390} \PYG{n}{BTC}
\PYG{l+m+mi}{800} \PYG{n}{CHF} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mf}{0.01854} \PYG{n}{BTC}
\PYG{l+m+mi}{1000} \PYG{n}{CHF} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mf}{0.02317} \PYG{n}{BTC}
\PYG{l+m+mi}{1200} \PYG{n}{CHF} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mf}{0.02780} \PYG{n}{BTC}
\PYG{l+m+mi}{1400} \PYG{n}{CHF} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mf}{0.03244} \PYG{n}{BTC}
\PYG{l+m+mi}{1600} \PYG{n}{CHF} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mf}{0.03707} \PYG{n}{BTC}
\end{sphinxVerbatim}
\begin{itemize}
\item {}
\sphinxAtStartPar
Verwenden Sie eine Schleife und die \sphinxcode{\sphinxupquote{printf}}\sphinxhyphen{}Funktion für die Tabellenausgabe
\item {}
\sphinxAtStartPar
Definieren Sie ein Makro \sphinxcode{\sphinxupquote{NUM\_ROWS}}, um an zentraler Stelle im Source\sphinxhyphen{}Code zu definieren, wie viele Einträge die Tabelle in der Ausgabe haben soll.
\item {}
\sphinxAtStartPar
Lesen Sie den Umrechnungsfaktor mit der \sphinxcode{\sphinxupquote{scanf}}\sphinxhyphen{}Funktion als \sphinxcode{\sphinxupquote{double}} von der Kommandozeile ein.
\end{itemize}
\bigskip\hrule\bigskip
\section{6. Aufgabe 4: Zeichen und Wörter zählen}
\label{\detokenize{P01_Erste_Schritte_mit_C/README:aufgabe-4-zeichen-und-worter-zahlen}}
\sphinxAtStartPar
Schreiben Sie ein C\sphinxhyphen{}Programm, welches die Zeichen und Wörter einer mit der Tastatur eingegebenen Zeile zählt. Wortzwischenräume sind entweder Leerzeichen ( ) oder Tabulatoren (\textbackslash{}t). Die Eingabe der Zeile mit einem newline\sphinxhyphen{}character (\textbackslash{}n) abgeschlossen. Danach soll ihr Programm die Anzahl Zeichen und die Anzahl Wörter ausgeben und terminieren.
\begin{itemize}
\item {}
\sphinxAtStartPar
Verwenden Sie die \sphinxcode{\sphinxupquote{char getchar(void)}} Funktion aus der \sphinxcode{\sphinxupquote{stdio.h}} Library, um die Zeichen einzeln einzulesen. Die Funktion \sphinxcode{\sphinxupquote{getchar}} kehrt nicht gleich bei Eingabe des ersten Zeichens zurück, sondern puffert die Daten, bis die Eingabe einer kompletten Zeile mit Return abgeschlossen wird. Dann wird das erste Zeichen aus dem Puffer zurückgegeben und mit weiteren Aufrufen von getchar können die nachfolgenden Zeichen aus dem Puffer gelesen werden. Gibt \sphinxcode{\sphinxupquote{getchar}} das Zeichen \sphinxcode{\sphinxupquote{\textbackslash{}n}} zurück, ist die Zeile komplett zurückgegeben und der Puffer ist wieder leer.
\item {}
\sphinxAtStartPar
Setzen Sie eine Schleife ein, die beim Zeichen \textbackslash{}n terminiert.
\item {}
\sphinxAtStartPar
Benutzen Sie if\sphinxhyphen{}then\sphinxhyphen{}else\sphinxhyphen{}Strukturen um die Wörter zu zählen.
\end{itemize}
\bigskip\hrule\bigskip
\section{7. Bewertung}
\label{\detokenize{P01_Erste_Schritte_mit_C/README:bewertung}}
\sphinxAtStartPar
Die gegebenenfalls gestellten Theorieaufgaben und der funktionierende Programmcode müssen der Praktikumsbetreuung gezeigt werden. Die Lösungen müssen mündlich erklärt werden.
\chapter{02: Funktionen, Datentyp “enum”}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:funktionen-datentyp-enum}}\label{\detokenize{P02_Funktionen_Datentyp_enum/README::doc}}
\bigskip\hrule\bigskip
\sphinxAtStartPar
\sphinxincludegraphics{{random_number}.png}
\sphinxAtStartPar
(Copyright Bild: xkcd.com)
\bigskip\hrule\bigskip
\section{1. Übersicht}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:ubersicht}}
\sphinxAtStartPar
In diesem Praktikum sind zwei Themen im Fokus: Funktionen und der Datentyp enum.
\sphinxAtStartPar
Funktionen sind der wesentlichste Bestandteil der C Programmierung welcher eine strukturierte Programmierung ermöglicht:
\begin{itemize}
\item {}
\sphinxAtStartPar
Eine Funktion ein Teil eines C Codes, der eine spezielle Aufgabe ausführt. Sie kann aus dem Hauptprogramm, oder aus anderen Funktionen, aufgerufen werden.
\item {}
\sphinxAtStartPar
Jede Funktion besitzt einen eindeutigen Namen, eine eindeutige Signatur (Typen und Reihenfolge der Parameter) und einen Rückgabewert (int falls nichts angegeben wird).
\item {}
\sphinxAtStartPar
Eine Funktion kann Werte aus dem aufrufendem Kontext übernehmen und bei Bedarf einen Wert an den aufrufenden Kontext zurückliefern.
Beispiel einer Additions\sphinxhyphen{}Funktion:
\end{itemize}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{c+c1}{\PYGZsh{}include \PYGZlt{}stdio.h\PYGZgt{}}
\PYG{o}{/}\PYG{o}{*} \PYG{n}{Funktionsdeklaration} \PYG{o}{*}\PYG{o}{/}
\PYG{n+nb}{int} \PYG{n}{add}\PYG{p}{(}\PYG{n+nb}{int} \PYG{n}{a}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{b}\PYG{p}{)}\PYG{p}{;}
\PYG{n+nb}{int} \PYG{n}{main}\PYG{p}{(}\PYG{n}{void}\PYG{p}{)} \PYG{p}{\PYGZob{}}
\PYG{n+nb}{int} \PYG{n}{aa} \PYG{o}{=} \PYG{l+m+mi}{1}\PYG{p}{,} \PYG{n}{bb} \PYG{o}{=} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{n}{cc}\PYG{p}{;}
\PYG{n}{printf}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+si}{\PYGZpc{}a}\PYG{l+s+s2}{a + }\PYG{l+s+s2}{\PYGZpc{}}\PYG{l+s+s2}{bb = }\PYG{l+s+si}{\PYGZpc{}c}\PYG{l+s+s2}{c}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{aa}\PYG{p}{,} \PYG{n}{bb}\PYG{p}{,} \PYG{n}{add}\PYG{p}{(}\PYG{n}{aa}\PYG{p}{,} \PYG{n}{bb}\PYG{p}{)}\PYG{p}{;}\PYG{p}{)}\PYG{p}{;}
\PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;}
\PYG{p}{\PYGZcb{}}
\PYG{o}{/}\PYG{o}{*} \PYG{n}{Funktionsdefinition} \PYG{o}{*}\PYG{o}{/}
\PYG{n+nb}{int} \PYG{n}{add}\PYG{p}{(}\PYG{n+nb}{int} \PYG{n}{a}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{b}\PYG{p}{)} \PYG{p}{\PYGZob{}}
\PYG{k}{return} \PYG{n}{a} \PYG{o}{+} \PYG{n}{b}\PYG{p}{;}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}
\sphinxAtStartPar
Der Daten typt enum wird verwendet um die Lesbarkeit von Programmen zu erhöhen:
\sphinxAtStartPar
Beispiel eines enum:
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{enum} \PYG{n}{Ampeln} \PYG{o}{=} \PYG{p}{\PYGZob{}}\PYG{n}{rot} \PYG{o}{=}\PYG{l+m+mi}{1}\PYG{p}{,} \PYG{n}{gelb}\PYG{p}{,} \PYG{n}{gruen}\PYG{p}{\PYGZcb{}}\PYG{p}{;}
\PYG{n+nb}{int} \PYG{n}{main}\PYG{p}{(}\PYG{n}{void}\PYG{p}{)} \PYG{p}{\PYGZob{}}
\PYG{n}{Ampeln} \PYG{n}{ampel1}\PYG{p}{;}
\PYG{k}{if} \PYG{p}{(}\PYG{n}{ampel1} \PYG{o}{==} \PYG{n}{rot}\PYG{p}{)} \PYG{p}{\PYGZob{}}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{\PYGZcb{}}
\PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}
\bigskip\hrule\bigskip
\section{2. Lernziele}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:lernziele}}
\sphinxAtStartPar
In diesem Praktikum lernen Sie Funktionen zu definieren und aufzurufen, sowie enum anzuwenden.
\begin{itemize}
\item {}
\sphinxAtStartPar
Sie können ein Programm schreiben welches aus mehreren Funktionen besteht.
\item {}
\sphinxAtStartPar
Sie können Funktionen deklarieren, definieren und aufrufen.
\item {}
\sphinxAtStartPar
Sie können enum Typen definieren und deren Werte bestimmen und abfragen.
\end{itemize}
\bigskip\hrule\bigskip
\section{3. Aufgaben}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:aufgaben}}
\begin{figure}[htbp]
\centering
\noindent\sphinxincludegraphics[width=600\sphinxpxdimen]{{kalender-108_v-ARDFotogalerie}.jpg}
\end{figure}
\sphinxAtStartPar
(Copyright Bild: www.planet\sphinxhyphen{}wissen.de)
\subsection{3.1 Aufgabe 1 Tage pro Monat}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:aufgabe-1-tage-pro-monat}}
\sphinxAtStartPar
In der ersten Aufgabe berechnen Sie die Tag pro Monat einer beliebigen Kombination Monat / Jahr.
Erweitern Sie dazu das Programm um folgende Aspekte:
\begin{itemize}
\item {}
\sphinxAtStartPar
Bereichsprüfung von Jahr und Monat
\item {}
\sphinxAtStartPar
Funktion istSchaltjahr, welche berechnet, ob das Jahr eine Schaljahr ist
\item {}
\sphinxAtStartPar
Funktion tageProMonat, welche die Anzahl Tage des gegebenen Monats und Jahres berechnet.
\end{itemize}
\sphinxAtStartPar
Vorgaben:
\begin{itemize}
\item {}
\sphinxAtStartPar
Die Funktion istSchaltjahr nimmt ein Integer (jahr) entgegen und gibt 1 im Falle eiens Schltjahres und 0 im andreren Fall zurück
\item {}
\sphinxAtStartPar
Die Funktion tageProMonat nimmt zwei integer (monat und jahr) entgegeben und gibt die Anzahl Tage als Integer zurück
\item {}
\sphinxAtStartPar
Die Jahreszahl, welche den Funktionen übergeben wird, muss überprüft werden und grösser gleich 1599 und kleiner als 10000 sein
\item {}
\sphinxAtStartPar
Der übergebene Monat muss grösser als 0 und kleine als 13 sein.
\end{itemize}
\sphinxAtStartPar
Die Regeln für die Schaltjahrberechnung:
\begin{itemize}
\item {}
\sphinxAtStartPar
Schaltjahre sind alle Jahre, die durch 4 teilbar sind.
\item {}
\sphinxAtStartPar
Eine Ausnahme bilden die Jahrhunderte (1600, 1700…). Diese sind keine Schltjahre.
\item {}
\sphinxAtStartPar
zu den 100er gibt es ebenfalls Ausnahmen: Diese sind immer Schaltjahre, wenn sie durch 400 teilbar sind
… also zum Beispiel 1600 ist eines, nicht jedoch 1700. Weiterführende Details finden Sie unter https://de.wikipedia.org/wiki/Gregorianischer\_Kalender
\end{itemize}
\sphinxAtStartPar
Gegeben ist die main Funktion des Programms. Ergänzen Sie die enum Definition und die fehlenden Funktionen:
\begin{itemize}
\item {}
\sphinxAtStartPar
gibIntWert: Die Funktion soll einen Int Wert zurückgeben. Der Bereich, wie auch Fehleingaben sollen sollen berücksichtigt werden. (atoi unfd fgets sind hier hilfreich)
\item {}
\sphinxAtStartPar
istSchaltjahr: Die Funktion gibt 1 im Falle eines Schltjahr und o im anderen Falle zurück.
\item {}
\sphinxAtStartPar
tageProMonat: Die Funktion gibt den die Tage des Monats für das definierte Jahr zurück. Verwenden Sie die Switchanweisung , sowie den enum Datentypen
\end{itemize}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
int main (int argc, char *argv[]) \PYGZob{}
int monat, jahr;
// Monat einlesen und Bereich ueberpruefen
monat = gibIntWert(\PYGZdq{}Monat\PYGZdq{}, 1, 12);
jahr = gibIntWert(\PYGZdq{}Jahr\PYGZdq{}, 1600, 9999);
// Ausgabe zum Test
printf(\PYGZdq{}Monat: \PYGZpc{}d, Jahr: \PYGZpc{}d \PYGZbs{}n\PYGZdq{}, monat, jahr);
// Ausgabe zum Test (hier mit dem ternaeren Operator \PYGZdq{}?:\PYGZdq{})
printf(\PYGZdq{}\PYGZpc{}d ist \PYGZpc{}s Schaltjahr\PYGZbs{}n\PYGZdq{}, jahr, istSchaltjahr(jahr) ? \PYGZdq{}ein\PYGZdq{} : \PYGZdq{}kein\PYGZdq{});
// Ausgabe
printf(\PYGZdq{}Der Monat \PYGZpc{}02d\PYGZhy{}\PYGZpc{}d hat \PYGZpc{}d Tage.\PYGZbs{}n\PYGZdq{}, monat, jahr, tageProMonat(jahr, monat));
return 0;
\PYGZcb{}
\end{sphinxVerbatim}
\sphinxAtStartPar
Tipp: Angenommen Sie verwenden den enum month\_t \{ JAN=1, FEB, MAR, APR, MAI, JUN, JUL, AUG, SEP, OKT, NOV, DEZ \};
Dann können Sie im Programm direkt die Konstanten verwenden:
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{if} \PYG{p}{(}\PYG{n}{m} \PYG{o}{==} \PYG{l+m+mi}{2}\PYG{p}{)} \PYG{o}{.}\PYG{o}{.}\PYG{o}{.} \PYG{o}{/}\PYG{o}{/} \PYG{n}{schlecht} \PYG{n}{lesbar}
\PYG{k}{if} \PYG{p}{(}\PYG{n}{monat} \PYG{o}{==} \PYG{l+m+mi}{2}\PYG{p}{)} \PYG{o}{.}\PYG{o}{.}\PYG{o}{.} \PYG{o}{/}\PYG{o}{/} \PYG{n}{besserer} \PYG{n}{Variablenname}
\PYG{k}{if} \PYG{p}{(}\PYG{n}{monat} \PYG{o}{==} \PYG{n}{FEB}\PYG{p}{)} \PYG{o}{.}\PYG{o}{.}\PYG{o}{.} \PYG{o}{/}\PYG{o}{/} \PYG{n}{am} \PYG{n}{besten} \PYG{n}{lesbar}
\end{sphinxVerbatim}
\sphinxAtStartPar
Als Abnahme müssen die Tests unverändert ohne Fehler ausgeführt werden (\sphinxcode{\sphinxupquote{make test}})
\bigskip\hrule\bigskip
\subsection{3.2 Aufgabe 2 Bestimmen des Wochentags}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:aufgabe-2-bestimmen-des-wochentags}}
\sphinxAtStartPar
Erweitern Sie das vorgegebene zweite Programm Gerüst an den bezeichneten Stellen so, dass das Programm von der Kommando Zeile ein Argument entgegennimmt, es auf Gültigkeit überprüft und schliesslich den Wochentag für das gegebene Datum berechnet und ausgibt.
Prüfen Sie die Umsetzung beider Teilaufgaben mittels make test.
\subsubsection{3.2.1 Teilaufgabe Argumente Parsen und auf Korrektheit prüfen}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:teilaufgabe-argumente-parsen-und-auf-korrektheit-prufen}}
\sphinxAtStartPar
Das Argument stellt ein gültiges Datum unseres Gregorianischen Kalenders dar (d.h. ein Datum ab Donnerstag, den 15. Oktober 1582, mit der Gregorianischen Schaltjahr Regel).
Wenn kein Argument gegeben ist oder wenn das eingegebene Datum nicht gültig ist, soll das Programm einem Hilfetext auf stderr ausgeben und mit EXIT\_FAILURE Exit Code terminieren. Wenn ein gültiges Datum erkannt wurde terminiert das Programm mit Exit Code EXIT\_SUCCESS.
\paragraph{3.2.1.1 Argument Format}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:argument-format}}
\sphinxAtStartPar
Das Format des Kommando Zeilen Arguments soll yyyy\sphinxhyphen{}mm\sphinxhyphen{}dd sein, wobei yyyy für das vier\sphinxhyphen{}stellige Jahr, mm für einen 1\sphinxhyphen{}2\sphinxhyphen{}stelligen Monat (1…12) und dd für einen Tag des Monats, begin\sphinxhyphen{}nend mit 01. Z.B. 2020\sphinxhyphen{}02\sphinxhyphen{}29.
\paragraph{3.2.1.2 Korrektes Datum}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:korrektes-datum}}
\sphinxAtStartPar
Das Datum muss alle folgenden Bedingungen erfüllen damit es als korrekt erkannt wird:
\begin{itemize}
\item {}
\sphinxAtStartPar
Obergrenze für ein «sinnvolles» Datum ist das Jahr 9999
\item {}
\sphinxAtStartPar
es muss Gregorianisch sein, d.h. ab 15. Oktober 1582 (inklusive)
\item {}
\sphinxAtStartPar
es darf nur Monate von 1 für Januar bis 12 für Dezember beinhalten
\item {}
\sphinxAtStartPar
der Tag muss grösser oder gleich 1 sein
\item {}
\sphinxAtStartPar
der Tag darf nicht grösser als 31 sein für Monate mit einer Länge von 31 Tagen
\item {}
\sphinxAtStartPar
der Tag darf nicht grösser als 30 sein für Monate mit einer Länge von 30 Tagen
\item {}
\sphinxAtStartPar
der Tag darf für den Februar nicht grösser sein als 29 für ein Schaltjahr
\item {}
\sphinxAtStartPar
der Tag darf für den Februar nicht grösser sein als 28 für ein Nicht\sphinxhyphen{}Schaltjahr
\end{itemize}
\paragraph{3.2.1.3 Vorgaben an die Umsetzung}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:vorgaben-an-die-umsetzung}}\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Definieren Sie einen enum Typen mit (typedef) Namen month\_t dessen Werte die Englischen 3\sphinxhyphen{}Zeichen Abkürzungen der Monate sind, nämlich Jan, Feb, … Dec und stellen Sie sicher dass die Abkürzungen für die uns geläufigen Monatsnummer stehen.
\item {}
\sphinxAtStartPar
Definierend Sie einen struct Typen mit (typedef) Namen date\_t und den int Elementen year, month, day. Lesen Sie das Argument (falls vorhanden) via sscanf und dem Formatstring “\%d\sphinxhyphen{}\%d\sphinxhyphen{}\%d” in die drei Elemente einer Date Variable. Siehe dazu die Hinweise im Anhang.
\item {}
\sphinxAtStartPar
Für die Berechnung der Monatslänge implementieren Sie die Hilfsfunktion is\_leap\_year(date\_t date) (nach obigen Vorgaben). Der Return Wert 0 bedeutet «Kein Schaltjahr», 1 bedeutet «Schaltjahr».
\item {}
\sphinxAtStartPar
Implementieren Sie die Funktion \sphinxcode{\sphinxupquote{int get\_month\_length(date\_t date)}}. Diese soll für den Monat des Datums die Monatslänge (was dem letzten Tag des Monats ent\sphinxhyphen{}spricht) ausgeben \textendash{} geben Sie 0 für ungültige Monatswerte zurück.
\item {}
\sphinxAtStartPar
Schliesslich implementieren Sie die Funktion int is\_gregorian\_date(date\_t date) welche prüft, ob ein gegebenes Datum im Bereich 15. Oktober 1582 und dem Jahr 9999 ist (0 = nein, 1 = ja).
\item {}
\sphinxAtStartPar
Implementieren Sie eine Funktion int is\_valid\_date(date\_t date), welche obige Bedingungen für ein gültiges Datum umsetzt. Der Return Wert 0 bedeutet «Kein gültiges Datum», 1 bedeutet «Gültiges Datum». Benutzen Sie für die Prüfung des Datums die \sphinxcode{\sphinxupquote{month\_t}} Werte wo immer möglich und sinnvoll. Verwenden Sie die oben implemen\sphinxhyphen{}tierten Hilfsfunktionen.
\end{enumerate}
\paragraph{3.2.1.4 Hinweise}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:hinweise}}
\sphinxAtStartPar
Beachten Sie die Kommentare im Code für die geforderten Implementierungs\sphinxhyphen{}Details.
\subsubsection{3.2.2 Teilaufgabe Wochentag Berechnung}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:teilaufgabe-wochentag-berechnung}}
\sphinxAtStartPar
Schreiben Sie eine Funktion welche zu einem Datum den Wochentag berechnet.
Die Formel wird Georg Glaeser zugeschrieben, möglicherweise angelehnt an eine Formel von Carl Friedrich Gauss.
\begin{figure}[htbp]
\centering
\noindent\sphinxincludegraphics[width=600\sphinxpxdimen]{{Wochentagsberechnung}.jpg}
\end{figure}
\sphinxAtStartPar
(Quelle: https://de.wikipedia.org/wiki/Wochentagsberechnung)
\sphinxAtStartPar
Hier ist eine für C abgewandelte Variante davon.
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{weekday} \PYG{o}{=} \PYG{p}{(}\PYG{p}{(}\PYG{n}{day} \PYG{o}{+} \PYG{p}{(}\PYG{l+m+mi}{13} \PYG{o}{*} \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1}\PYG{p}{)} \PYG{o}{/} \PYG{l+m+mi}{5} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{y} \PYG{o}{/} \PYG{l+m+mi}{4} \PYG{o}{+} \PYG{n}{c} \PYG{o}{/} \PYG{l+m+mi}{4} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{c}\PYG{p}{)} \PYG{o}{\PYGZpc{}} \PYG{l+m+mi}{7} \PYG{o}{+} \PYG{l+m+mi}{7}\PYG{p}{)} \PYG{o}{\PYGZpc{}} \PYG{l+m+mi}{7}
\PYG{n}{alle} \PYG{n}{Zahlen} \PYG{n}{sind} \PYG{n+nb}{int} \PYG{n}{Werte} \PYG{n}{und} \PYG{n}{alles} \PYG{n}{basiert} \PYG{n}{auf} \PYG{n+nb}{int}\PYG{o}{\PYGZhy{}}\PYG{n}{Arithmetik}
\PYG{n}{m} \PYG{o}{=} \PYG{l+m+mi}{1} \PYG{o}{+} \PYG{p}{(}\PYG{n}{month} \PYG{o}{+} \PYG{l+m+mi}{9}\PYG{p}{)} \PYG{o}{\PYGZpc{}} \PYG{l+m+mi}{12}
\PYG{n}{a} \PYG{o}{=} \PYG{n}{year} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1} \PYG{p}{(}\PYG{n}{für} \PYG{n}{month} \PYG{o}{\PYGZlt{}} \PYG{n}{Mar}\PYG{p}{)}\PYG{p}{,} \PYG{n}{ansonsten} \PYG{n}{year}
\PYG{n}{y} \PYG{o}{=} \PYG{n}{a} \PYG{o}{\PYGZpc{}} \PYG{l+m+mi}{100}
\PYG{n}{c} \PYG{o}{=} \PYG{n}{a} \PYG{o}{/} \PYG{l+m+mi}{100}
\end{sphinxVerbatim}
\sphinxAtStartPar
Erweitern sie das Programm so, dass vor dem erfolgreichen Terminieren des Programms fol\sphinxhyphen{}gende Zeile (inklusive Zeilenumbruch) ausgegeben wird: yyyy\sphinxhyphen{}mm\sphinxhyphen{}dd is a Ddd, wobei yyyy für das Jahr, mm für die Nummer des Monats (01…12) und dd für den Tag im Monat (01…). Z.B. 2020\sphinxhyphen{}02\sphinxhyphen{}29 is a Sat.
Vorgaben an die Umsetzung
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Definieren Sie einen enum Typen mit (typedef) Namen weekday\_t dessen Werte die Englischen 3\sphinxhyphen{}Zeichen Abkürzungen der Tage sind, nämlich Sun, Mon, … Sat und stel\sphinxhyphen{}len Sie sicher dass die Abkürzungen für die Werte 0…6 stehen.
\item {}
\sphinxAtStartPar
Schreiben Sie eine Funktion weekday\_t calculate\_weekday(date\_t date) nach der Beschreibung der obigen Formel. Das date Argument ist als gültig angenom\sphinxhyphen{}men, d.h. es ist ein Programmier\sphinxhyphen{}Fehler, wenn das Programm diese Funktion mit einem ungültigen Datum aufruft. Machen Sie dafür als erste Codezeile in der Funktion eine Zu\sphinxhyphen{}sicherung (assert(is\_valid\_date(date));)
\item {}
\sphinxAtStartPar
Schreiben Sie eine Funktion void print\_weekday(weekday\_t day), welche für jeden gülteigen Tag eine Zeile auf stdout schreibt mit den Englischen 3\sphinxhyphen{}Zeichen Ab\sphinxhyphen{}kürzungen für den Wochentag, z.B. Sonntag: Sun, Montag: Mon, etc. Wenn ein ungülti\sphinxhyphen{}ger Wert für day erkannt wird, soll assert(!”day is out\sphinxhyphen{}of\sphinxhyphen{}range”); aufgeru\sphinxhyphen{}fen werden.
Hinweise
• Für interessierte, siehe: https://de.wikipedia.org/wiki/Wochentagsberechnung
\end{enumerate}
\bigskip\hrule\bigskip
\section{4. Bewertung}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:bewertung}}
\sphinxAtStartPar
Die gegebenenfalls gestellten Theorieaufgaben und der funktionierende Programmcode müssen der Praktikumsbetreuung gezeigt werden. Die Lösungen müssen mündlich erklärt werden können.
\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
\hline
\sphinxstyletheadfamily
\sphinxAtStartPar
Aufgabe
&\sphinxstyletheadfamily
\sphinxAtStartPar
Kriterium
&\sphinxstyletheadfamily
\sphinxAtStartPar
Gewicht
\\
\hline
\sphinxAtStartPar
alle
&
\sphinxAtStartPar
Sie können das funktionierende Programm inklusive funktionierende Tests demonstrieren und erklären.
&
\sphinxAtStartPar
\\
\hline
\sphinxAtStartPar
gibIntWert
&
\sphinxAtStartPar
Eingabe, Bereichsüberprüfung korrekt
&
\sphinxAtStartPar
1
\\
\hline
\sphinxAtStartPar
istSchaltjahr
&
\sphinxAtStartPar
Funktion korrekt
&
\sphinxAtStartPar
1
\\
\hline
\sphinxAtStartPar
TageProMonat
&
\sphinxAtStartPar
Funktion korrekt
&
\sphinxAtStartPar
1
\\
\hline
\sphinxAtStartPar
Aufgabe 2
&
\sphinxAtStartPar
Fehlenden Teile ergänzt und lauffähig
&
\sphinxAtStartPar
1
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
\bigskip\hrule\bigskip
\section{5. Anhang}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:anhang}}
\subsection{5.1 Sprach Element}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:sprach-element}}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
...
\PYGZcb{} argc: Anzahl Einträge in argv.
argv: Array von Command Line Argumenten.
argv[0]: wie das Programm gestartet wurde
argv[1]: erstes Argument
argv[argc\PYGZhy{}1]: letztes Argument
int a = 0;
int b = 0;
int c = 0;
int res = sscanf(argv[1]
, \PYGZdq{}\PYGZpc{}d\PYGZhy{}\PYGZpc{}d\PYGZhy{}\PYGZpc{}d\PYGZdq{}
, \PYGZam{}a, \PYGZam{}b, \PYGZam{}c
);
if (res != 3) \PYGZob{}
// Fehler Behandlung...
// ...
\PYGZcb{}
\end{sphinxVerbatim}
\subsection{5.2 Beschreibung}
\label{\detokenize{P02_Funktionen_Datentyp_enum/README:beschreibung}}
\sphinxAtStartPar
Siehe man 3 sscanf.
Die Funktion sscanf gibt die Anzahl erfolgreich erkannte Argumente zurück. Unbedingt prüfen und angemessen darauf reagieren.
Die gelesenen Werte werden in a, b und c, gespeichert, dazu müssen Sie die Adresse der Variablen übergeben. Mehr Details dazu werden später erklärt.
fprintf(stderr, “Usage: \%s…\textbackslash{}n”, argv{[}0{]}); Siehe man 3 fprintf.
Schreibt formatierten Text auf den stderr Stream.
\bigskip\hrule\bigskip
\sphinxAtStartPar
Version: 15.02.2022
\chapter{03 \sphinxhyphen{} Bit Operationen, Struct, Typedef}
\label{\detokenize{P03_Bit_Operation_struct_typedef/README:bit-operationen-struct-typedef}}\label{\detokenize{P03_Bit_Operation_struct_typedef/README::doc}}
\bigskip\hrule\bigskip
\section{1. Bit Operationen}
\label{\detokenize{P03_Bit_Operation_struct_typedef/README:bit-operationen}}
\sphinxAtStartPar
\sphinxincludegraphics{{135oALYhkYyXB2aG0F-qrwA}.jpeg}
\sphinxAtStartPar
Bit Operationen sind allgegenwärtig in den Computer\sphinxhyphen{}Wissenschaften und finden in vielen der grossen Disziplinen Anwendung. Folgend ein kleiner Auszug aus den wichtigsten Themen:
\begin{itemize}
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Bit Felder}: Sind die effizienteste Art, etwas darzustellen, dessen Zustand durch mehrere “wahr” oder “falsch” definiert werden kann. Besonders auf Systemen mit begrenzten Ressourcen sollte jede überflüssige Speicher\sphinxhyphen{}Allozierung vermieden werden.
\sphinxAtStartPar
Beispiel:
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{o}{/}\PYG{o}{/} \PYG{n}{primary} \PYG{n}{colors}
\PYG{c+c1}{\PYGZsh{}define BLUE 0b100}
\PYG{c+c1}{\PYGZsh{}define GREEN 0b010}
\PYG{c+c1}{\PYGZsh{}define RED 0b001}
\PYG{o}{/}\PYG{o}{/} \PYG{n}{mixed} \PYG{n}{colors}
\PYG{c+c1}{\PYGZsh{}define BLACK 0 /* 000 */}
\PYG{c+c1}{\PYGZsh{}define YELLOW (RED | GREEN) /* 011 */}
\PYG{c+c1}{\PYGZsh{}define MAGENTA (RED | BLUE) /* 101 */}
\PYG{c+c1}{\PYGZsh{}define CYAN (GREEN | BLUE) /* 110 */}
\PYG{c+c1}{\PYGZsh{}define WHITE (RED | GREEN | BLUE) /* 111 */}
\end{sphinxVerbatim}
\end{itemize}
\sphinxAtStartPar
\sphinxurl{https://de.wikipedia.org/wiki/Bitfeld}
\begin{itemize}
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Kommunikation}:
\begin{itemize}
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Prüfsummen/Paritätsbit}: Übertragungsfehler und Integrität können bis zu einem definiertem Grad erkannt werden. Je nach Komplexität der Berechnung können mehrere Fehler erkannt oder auch korrigiert werden.
\sphinxurl{https://de.wikipedia.org/wiki/Parit\%C3\%A4tsbit}, \sphinxurl{https://de.wikipedia.org/wiki/Pr\%C3\%BCfsumme}
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Stoppbit}: Markieren bei asynchronen seriellen Datenübertragungen das Ende bzw. Start eines definierten Blocks.
\sphinxurl{https://de.wikipedia.org/wiki/Stoppbit}
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Datenflusssteuerung}: Unterschiedliche Verfahren, mit denen die Datenübertragung von Endgeräten an einem Datennetz, die nicht synchron arbeiten, so gesteuert wird, dass eine möglichst kontinuierliche Datenübermittlung ohne Verluste erfolgen kann.
\sphinxurl{https://de.wikipedia.org/wiki/Datenflusssteuerung}
\item {}
\sphinxAtStartPar
\end{itemize}
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Datenkompression}: Bei der Datenkompression wird versucht, redundante Informationen zu entfernen. Dazu werden die Daten in eine Darstellung überführt, mit der sich alle \textendash{} oder zumindest die meisten \textendash{} Information in kürzerer Form darstellen lassen.
\sphinxurl{https://de.wikipedia.org/wiki/Datenkompression}
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Kryptographie}: Konzeption, Definition und Konstruktion von Informationssystemen, die widerstandsfähig gegen Manipulation und unbefugtes Lesen sind. \sphinxurl{https://de.wikipedia.org/wiki/Verschl\%C3\%BCsselung}
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Grafik\sphinxhyphen{}Programmierung}: XOR (oder \textasciicircum{}) ist hier besonders interessant, weil eine zweite Eingabe derselben Eingabe die erste rückgängig macht. Ältere GUIs verwendeten dies für die Hervorhebung von Auswahlen und andere Überlagerungen, um kostspielige Neuzeichnungen zu vermeiden. Sie sind immer noch nützlich in langsamen Grafikprotokollen (z. B. Remote\sphinxhyphen{}Desktop).
\end{itemize}
\subsection{1.1 Übungen}
\label{\detokenize{P03_Bit_Operation_struct_typedef/README:ubungen}}
\sphinxAtStartPar
\sphinxurl{https://blog.tarkalabs.com/real-world-uses-of-bitwise-operators-c41429df507f}
\subsubsection{1. Basis Operationen}
\label{\detokenize{P03_Bit_Operation_struct_typedef/README:basis-operationen}}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{c+c1}{\PYGZsh{}include \PYGZlt{}stdlib.h\PYGZgt{}}
\PYG{c+c1}{\PYGZsh{}include \PYGZlt{}stdio.h\PYGZgt{}}
\PYG{n+nb}{int} \PYG{n}{main}\PYG{p}{(}\PYG{p}{)}\PYG{p}{\PYGZob{}}
\PYG{o}{/}\PYG{o}{/} \PYG{n}{Setting} \PYG{n}{a} \PYG{n}{bit}
\PYG{n}{number} \PYG{o}{|}\PYG{o}{=} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}\PYGZlt{}} \PYG{n}{x}\PYG{p}{;}
\PYG{o}{/}\PYG{o}{/} \PYG{n}{Clearing} \PYG{n}{a} \PYG{n}{bit}
\PYG{n}{number} \PYG{o}{\PYGZam{}}\PYG{o}{=} \PYG{o}{\PYGZti{}}\PYG{p}{(}\PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}\PYGZlt{}} \PYG{n}{x}\PYG{p}{)}\PYG{p}{;}
\PYG{o}{/}\PYG{o}{/} \PYG{n}{Toggling} \PYG{n}{a} \PYG{n}{bit}
\PYG{n}{number} \PYG{o}{\PYGZca{}}\PYG{o}{=} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}\PYGZlt{}} \PYG{n}{x}\PYG{p}{;}
\PYG{k}{return} \PYG{n}{EXIT\PYGZus{}SUCCESS}\PYG{p}{;}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}
\subsubsection{2. Variablen tauschen (ohne Dritt\sphinxhyphen{}Variable)}
\label{\detokenize{P03_Bit_Operation_struct_typedef/README:variablen-tauschen-ohne-dritt-variable}}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{c+cp}{\PYGZsh{}}\PYG{c+cp}{include} \PYG{c+cpf}{\PYGZlt{}stdlib.h\PYGZgt{}}
\PYG{c+cp}{\PYGZsh{}}\PYG{c+cp}{include} \PYG{c+cpf}{\PYGZlt{}stdio.h\PYGZgt{}}
\PYG{k+kt}{int} \PYG{n+nf}{main}\PYG{p}{(}\PYG{p}{)}\PYG{p}{\PYGZob{}}
\PYG{k+kt}{int} \PYG{n}{a}\PYG{o}{=}\PYG{l+m+mi}{3}\PYG{p}{,} \PYG{n}{b}\PYG{o}{=}\PYG{l+m+mi}{4}\PYG{p}{;}
\PYG{n}{printf}\PYG{p}{(}\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{a: \PYGZpc{}d; b: \PYGZpc{}d}\PYG{l+s+se}{\PYGZbs{}n}\PYG{l+s}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{;}
\PYG{c+cm}{/* a == 0011; b == 0100 */}
\PYG{n}{a} \PYG{o}{\PYGZca{}}\PYG{o}{=} \PYG{n}{b}\PYG{p}{;} \PYG{c+cm}{/* a == 0111; b == 0100 */}
\PYG{n}{b} \PYG{o}{\PYGZca{}}\PYG{o}{=} \PYG{n}{a}\PYG{p}{;} \PYG{c+cm}{/* a == 0111; b == 0011 */}
\PYG{n}{a} \PYG{o}{\PYGZca{}}\PYG{o}{=} \PYG{n}{b}\PYG{p}{;} \PYG{c+cm}{/* a == 0100; b == 0011 */}
\PYG{n}{printf}\PYG{p}{(}\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{a: \PYGZpc{}d; b: \PYGZpc{}d}\PYG{l+s+se}{\PYGZbs{}n}\PYG{l+s}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{;}
\PYG{k}{return} \PYG{n}{EXIT\PYGZus{}SUCCESS}\PYG{p}{;}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}
\subsubsection{3. Lower\sphinxhyphen{} / Uppercase}
\label{\detokenize{P03_Bit_Operation_struct_typedef/README:lower-uppercase}}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{c+cp}{\PYGZsh{}}\PYG{c+cp}{include} \PYG{c+cpf}{\PYGZlt{}stdlib.h\PYGZgt{}}
\PYG{c+cp}{\PYGZsh{}}\PYG{c+cp}{include} \PYG{c+cpf}{\PYGZlt{}stdio.h\PYGZgt{}}
\PYG{k+kt}{int} \PYG{n+nf}{main}\PYG{p}{(}\PYG{p}{)}\PYG{p}{\PYGZob{}}
\PYG{k+kt}{char} \PYG{n}{word}\PYG{p}{[}\PYG{l+m+mi}{8}\PYG{p}{]} \PYG{o}{=} \PYG{l+s}{\PYGZdq{}}\PYG{l+s}{sREedEv}\PYG{l+s}{\PYGZdq{}}\PYG{p}{;}
\PYG{k+kt}{char} \PYG{o}{*}\PYG{n}{wordptr} \PYG{o}{=} \PYG{o}{\PYGZam{}}\PYG{n}{word}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{p}{;}
\PYG{k}{while}\PYG{p}{(}\PYG{n}{wordptr} \PYG{o}{\PYGZlt{}} \PYG{o}{\PYGZam{}}\PYG{n}{word}\PYG{p}{[}\PYG{l+m+mi}{7}\PYG{p}{]}\PYG{p}{)} \PYG{p}{\PYGZob{}}
\PYG{n}{printf}\PYG{p}{(}\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{UPPERCASE: \PYGZpc{}c}\PYG{l+s+se}{\PYGZbs{}n}\PYG{l+s}{\PYGZdq{}}\PYG{p}{,} \PYG{o}{*}\PYG{n}{wordptr} \PYG{o}{\PYGZam{}} \PYG{l+s+sc}{\PYGZsq{}}\PYG{l+s+sc}{\PYGZus{}}\PYG{l+s+sc}{\PYGZsq{}}\PYG{p}{)}\PYG{p}{;} \PYG{c+c1}{// converts the char into uppercase regardless of the current casing}
\PYG{n}{printf}\PYG{p}{(}\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{LOWERCASE: \PYGZpc{}c}\PYG{l+s+se}{\PYGZbs{}n}\PYG{l+s}{\PYGZdq{}}\PYG{p}{,} \PYG{o}{*}\PYG{n}{wordptr} \PYG{o}{|} \PYG{l+s+sc}{\PYGZsq{}}\PYG{l+s+sc}{ }\PYG{l+s+sc}{\PYGZsq{}}\PYG{p}{)}\PYG{p}{;} \PYG{c+c1}{// converts the char into lowercase regardless of the current casing}
\PYG{n}{wordptr}\PYG{o}{+}\PYG{o}{+}\PYG{p}{;}
\PYG{p}{\PYGZcb{}}
\PYG{k}{return} \PYG{n}{EXIT\PYGZus{}SUCCESS}\PYG{p}{;}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}
\subsubsection{4. Prüfen auf 2\sphinxhyphen{}er Potenz}
\label{\detokenize{P03_Bit_Operation_struct_typedef/README:prufen-auf-2-er-potenz}}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{c+cp}{\PYGZsh{}}\PYG{c+cp}{include} \PYG{c+cpf}{\PYGZlt{}stdio.h\PYGZgt{}}
\PYG{c+cp}{\PYGZsh{}}\PYG{c+cp}{include} \PYG{c+cpf}{\PYGZlt{}stdlib.h\PYGZgt{}}
\PYG{k+kt}{int} \PYG{n+nf}{main}\PYG{p}{(}\PYG{p}{)}\PYG{p}{\PYGZob{}}
\PYG{k+kt}{int} \PYG{n}{a}\PYG{o}{=}\PYG{l+m+mi}{32}\PYG{p}{;}
\PYG{k}{if}\PYG{p}{(}\PYG{n}{a} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{\PYGZam{}}\PYG{o}{\PYGZam{}} \PYG{p}{(}\PYG{n}{a} \PYG{o}{\PYGZam{}} \PYG{p}{(}\PYG{n}{a} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1}\PYG{p}{)}\PYG{p}{)} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{0}\PYG{p}{)}\PYG{p}{\PYGZob{}}
\PYG{n}{printf}\PYG{p}{(}\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{\PYGZpc{}d is a power of 2}\PYG{l+s}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{a}\PYG{p}{)}\PYG{p}{;}
\PYG{p}{\PYGZcb{}}
\PYG{k}{return} \PYG{n}{EXIT\PYGZus{}SUCCESS}\PYG{p}{;}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}
\section{2. Struct \& typedef}
\label{\detokenize{P03_Bit_Operation_struct_typedef/README:struct-typedef}}
\subsection{2.1 Übungen}
\label{\detokenize{P03_Bit_Operation_struct_typedef/README:id1}}
\subsubsection{1. Bit Operationen Rechner}
\label{\detokenize{P03_Bit_Operation_struct_typedef/README:bit-operationen-rechner}}\begin{itemize}
\item {}
\sphinxAtStartPar
Bitweise Operationen mit 2 Operanden
\item {}
\sphinxAtStartPar
Rechnung wird als ein String über scanf dem Programm übergeben
\begin{itemize}
\item {}
\sphinxAtStartPar
String wird in Token zerstückelt und in struct gespeichert:
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{typedef} \PYG{k}{struct} \PYG{p}{\PYGZob{}}
\PYG{k+kt}{unsigned} \PYG{k+kt}{int} \PYG{n}{operand\PYGZus{}1}\PYG{p}{;}
\PYG{k+kt}{unsigned} \PYG{k+kt}{int} \PYG{n}{operand\PYGZus{}2}\PYG{p}{;}
\PYG{k+kt}{char} \PYG{n}{operation}\PYG{p}{;}
\PYG{p}{\PYGZcb{}} \PYG{n}{Expression}\PYG{p}{;}
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Ausgabe in 3 verschiedenen Formaten:
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n+nl}{Bin}\PYG{p}{:}
\PYG{l+m+mo}{0000\PYGZsq{}0000\PYGZsq{}0000\PYGZsq{}0001}
\PYG{o}{\PYGZam{}} \PYG{l+m+mo}{0000\PYGZsq{}0000\PYGZsq{}0000\PYGZsq{}0011}
\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}
\PYG{l+m+mo}{0000\PYGZsq{}0000\PYGZsq{}0000\PYGZsq{}0001}
\PYG{n}{Hex}
\PYG{l+m+mh}{0x01} \PYG{o}{\PYGZam{}} \PYG{l+m+mh}{0x03} \PYG{o}{=} \PYG{l+m+mh}{0x01}
\PYG{n}{Dec}
\PYG{l+m+mi}{1} \PYG{o}{\PYGZam{}} \PYG{l+m+mi}{3} \PYG{o}{=} \PYG{l+m+mi}{1}
\end{sphinxVerbatim}
\end{itemize}
\end{itemize}
\chapter{04 \sphinxhyphen{} Modularisieren von C Code}
\label{\detokenize{P04_Modularisieren_von_C_Code/new_P04/P04_Modularisieren_von_C_Code:modularisieren-von-c-code}}\label{\detokenize{P04_Modularisieren_von_C_Code/new_P04/P04_Modularisieren_von_C_Code::doc}}
\bigskip\hrule\bigskip
\section{1. Übersicht}
\label{\detokenize{P04_Modularisieren_von_C_Code/new_P04/P04_Modularisieren_von_C_Code:ubersicht}}
\sphinxAtStartPar
In diesem Praktikum wird eine kleine Sammlung von Funktionen als Modul erstellt.
\sphinxAtStartPar
In der ersten Aufgabe schreiben Sie zu einem bestehenden C Programm die notwendigen Header Files plus passen das Makefile so an, dass die entsprechenden Module mit kompiliert werden.
\sphinxAtStartPar
In der zweiten Aufgabe erstellen Sie Makefile Regeln um aus Konfigurationsdateien graphischen Darstellungen zu erzeugen.
\bigskip\hrule\bigskip
\section{2. Lernziele}
\label{\detokenize{P04_Modularisieren_von_C_Code/new_P04/P04_Modularisieren_von_C_Code:lernziele}}
\sphinxAtStartPar
In diesem Praktikum lernen Sie die Handgriffe um ein Programm zu modularisieren, d.h. in mehrere Module aufzuteilen.
\begin{itemize}
\item {}
\sphinxAtStartPar
Sie wissen, dass ein Modul aus einem C\sphinxhyphen{}File und einem passenden H\sphinxhyphen{}File bestehen.
\item {}
\sphinxAtStartPar
Sie können Header Files korrekt strukturieren.
\item {}
\sphinxAtStartPar
Sie wissen wie \sphinxstylestrong{Include Guards} anzuwenden sind.
\item {}
\sphinxAtStartPar
Sie können Module im \sphinxstylestrong{Makefile} zur Kompilation hinzufügen.
\item {}
\sphinxAtStartPar
Sie können anhand einer Beschreibung Typen und Funktionen in den passenden Header Files deklarieren.
\item {}
\sphinxAtStartPar
Sie können \sphinxstylestrong{Makefile} Regeln schreiben.
\end{itemize}
\sphinxAtStartPar
Die Bewertung dieses Praktikums ist am Ende angegeben.
\sphinxAtStartPar
Erweitern Sie die vorgegebenen Code Gerüste, welche im \sphinxstylestrong{git} Repository \sphinxstylestrong{snp\sphinxhyphen{}lab\sphinxhyphen{}code} verfügbar sind.
\bigskip\hrule\bigskip
\section{3. Aufgabe 1: Modularisieren}
\label{\detokenize{P04_Modularisieren_von_C_Code/new_P04/P04_Modularisieren_von_C_Code:aufgabe-1-modularisieren}}
\sphinxAtStartPar
\sphinxincludegraphics{{P04_Aufgabenstellung}.png}
\subsection{3.1 Teilaufgabe Modules einbinden, Header Files schreiben}
\label{\detokenize{P04_Modularisieren_von_C_Code/new_P04/P04_Modularisieren_von_C_Code:teilaufgabe-modules-einbinden-header-files-schreiben}}\begin{itemize}
\item {}
\sphinxAtStartPar
src/objects.h
\begin{itemize}
\item {}
\sphinxAtStartPar
2 Datenstukturen definieren
\item {}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{struct point}} mit 2 double für x und y Koordinate
\item {}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{struct line}} mit 2 point
\end{itemize}
\item {}
\sphinxAtStartPar
src/functions.h und .c
\begin{itemize}
\item {}
\sphinxAtStartPar
2 Funktionen deklarieren und definieren
\item {}
\sphinxAtStartPar
Berechnung der Länge \sphinxcode{\sphinxupquote{get\_length}}einer Linie (Annahme: Koordinaten sind alle positiv)
\begin{itemize}
\item {}
\sphinxAtStartPar
l = sqrt(h\textasciicircum{} 2 + b\textasciicircum{} 2)
\item {}
\sphinxAtStartPar
ev. muss hier in den Anhang \sphinxcode{\sphinxupquote{\#include \textless{}math.h\textgreater{}}}
\end{itemize}
\item {}
\sphinxAtStartPar
Berechnung der Steigung \sphinxcode{\sphinxupquote{get\_slope}} der Linie gegenüber dem Koordinatensystem
\begin{itemize}
\item {}
\sphinxAtStartPar
m = h / b
\end{itemize}
\end{itemize}
\item {}
\sphinxAtStartPar
tests vorgeben
\item {}
\sphinxAtStartPar
src/objects.h
\begin{itemize}
\item {}
\sphinxAtStartPar
Include Guard
\item {}
\sphinxAtStartPar
Includes
\item {}
\sphinxAtStartPar
Struct für Punkt und Linie
\item {}
\sphinxAtStartPar
Include Guard
\end{itemize}
\item {}
\sphinxAtStartPar
src/functions.h
\begin{itemize}
\item {}
\sphinxAtStartPar
Include Guard
\item {}
\sphinxAtStartPar
Includes
\item {}
\sphinxAtStartPar
Deklarationen der Funktionen für Berechnung der Länge und Steigung
\item {}
\sphinxAtStartPar
Include Guard
\end{itemize}
\item {}
\sphinxAtStartPar
src/functions.c
\begin{itemize}
\item {}
\sphinxAtStartPar
Includes
\item {}
\sphinxAtStartPar
Definitionen der Funktionen für Berechnung der Länge und Steigung
\item {}
\sphinxAtStartPar
Include Guard
\end{itemize}
\end{itemize}
\bigskip\hrule\bigskip
\section{4. Aufgabe 2: Makefile Regeln}
\label{\detokenize{P04_Modularisieren_von_C_Code/new_P04/P04_Modularisieren_von_C_Code:aufgabe-2-makefile-regeln}}
\sphinxAtStartPar
Makefile ergänzen, damit Modul \sphinxcode{\sphinxupquote{functions}} korrekt eingebunden und kompiliert wird.
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Kompilieren Sie das ganze mittels \sphinxstylestrong{make clean default}. Es sollten keine Compiler Fehler auftreten.
\end{enumerate}
\subsection{4.1 Neue Regeln hinzufügen}
\label{\detokenize{P04_Modularisieren_von_C_Code/new_P04/P04_Modularisieren_von_C_Code:neue-regeln-hinzufugen}}\begin{itemize}
\item {}
\sphinxAtStartPar
Vorraussetzung: tab2svg.sh aus Praktikum 3 wird um die Möglichkeit erweitert eine Linie zu zeichnen (\sphinxcode{\sphinxupquote{line:x1:y1:x2:y2:color}})
\item {}
\sphinxAtStartPar
Studierende erstellen
\begin{itemize}
\item {}
\sphinxAtStartPar
mind. 2 Files \sphinxcode{\sphinxupquote{long.line}} und \sphinxcode{\sphinxupquote{short.line}} mit 2 unterschiedlichen Linien
\item {}
\sphinxAtStartPar
Makefile Regeln um aus einem File \sphinxcode{\sphinxupquote{.line}} ein File \sphinxcode{\sphinxupquote{.svg}} mit Hilfe des Scripts zu erstellen
\item {}
\sphinxAtStartPar
PHONY Regel \sphinxcode{\sphinxupquote{display}} um beide \sphinxcode{\sphinxupquote{.svg}} mit Firefox darzustellen
\begin{itemize}
\item {}
\sphinxAtStartPar
Vorgabe: sie sollen eine Variable für die Input\sphinxhyphen{}Dateien nutzen
\end{itemize}
\end{itemize}
\end{itemize}
\sphinxAtStartPar
Nachdem das Programm in Aufgabe 1 umgesetzt ist, geht es nun darum, im \sphinxstylestrong{Makefile} Regeln zu definieren welche die einzelnen Schritte von den Source Files zu den \sphinxstylestrong{png} Files ausführen.
\sphinxAtStartPar
Prüfen Sie schliesslich die Umsetzung mittels \sphinxcode{\sphinxupquote{make display}}.
\bigskip\hrule\bigskip
\section{5. Aufgabe 3}
\label{\detokenize{P04_Modularisieren_von_C_Code/new_P04/P04_Modularisieren_von_C_Code:aufgabe-3}}\begin{itemize}
\item {}
\sphinxAtStartPar
Studierende sollen Ausgabe von \sphinxcode{\sphinxupquote{make doc}} analysieren und die Include Diagramme erklären können
\end{itemize}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{make} \PYG{n}{doc}
\PYG{n}{firefox} \PYG{n}{doc}\PYG{o}{/}\PYG{n}{index}\PYG{o}{.}\PYG{n}{html} \PYG{o}{\PYGZam{}}
\end{sphinxVerbatim}
\bigskip\hrule\bigskip
\section{6. Bewertung}
\label{\detokenize{P04_Modularisieren_von_C_Code/new_P04/P04_Modularisieren_von_C_Code:bewertung}}
\sphinxAtStartPar
Die gegebenenfalls gestellten Theorieaufgaben und der funktionierende Programmcode müssen der Praktikumsbetreuung gezeigt werden. Die Lösungen müssen mündlich erklärt werden.
\bigskip\hrule\bigskip
\section{7. Erweiterung Doxyfile für Abhängigkeitsanalyse}
\label{\detokenize{P04_Modularisieren_von_C_Code/new_P04/P04_Modularisieren_von_C_Code:erweiterung-doxyfile-fur-abhangigkeitsanalyse}}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}} \PYG{o}{/}\PYG{n}{home}\PYG{o}{/}\PYG{n}{vagrant}\PYG{o}{/}\PYG{n}{huno}\PYG{o}{/}\PYG{n}{snp}\PYG{o}{\PYGZhy{}}\PYG{n}{new}\PYG{o}{/}\PYG{n}{snp}\PYG{o}{/}\PYG{n}{praktika}\PYG{o}{/}\PYG{n}{Shared}\PYG{o}{/}\PYG{n}{work}\PYG{o}{/}\PYG{n}{Doxyfile} \PYG{l+m+mi}{2022}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{02}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{07} \PYG{l+m+mi}{21}\PYG{p}{:}\PYG{l+m+mi}{16}\PYG{p}{:}\PYG{l+m+mf}{42.343302707} \PYG{o}{+}\PYG{l+m+mi}{0100}
\PYG{o}{+}\PYG{o}{+}\PYG{o}{+} \PYG{o}{/}\PYG{n}{home}\PYG{o}{/}\PYG{n}{vagrant}\PYG{o}{/}\PYG{n}{snp}\PYG{o}{/}\PYG{n}{Doxyfile} \PYG{l+m+mi}{2022}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{02}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{07} \PYG{l+m+mi}{22}\PYG{p}{:}\PYG{l+m+mi}{22}\PYG{p}{:}\PYG{l+m+mf}{36.266839126} \PYG{o}{+}\PYG{l+m+mi}{0100}
\PYG{o}{@}\PYG{o}{@} \PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{297}\PYG{p}{,}\PYG{l+m+mi}{14} \PYG{o}{+}\PYG{l+m+mi}{297}\PYG{p}{,}\PYG{l+m+mi}{14} \PYG{o}{@}\PYG{o}{@}
\PYG{n}{UML\PYGZus{}LOOK} \PYG{o}{=} \PYG{n}{NO}
\PYG{n}{UML\PYGZus{}LIMIT\PYGZus{}NUM\PYGZus{}FIELDS} \PYG{o}{=} \PYG{l+m+mi}{10}
\PYG{n}{TEMPLATE\PYGZus{}RELATIONS} \PYG{o}{=} \PYG{n}{NO}
\PYG{o}{\PYGZhy{}}\PYG{n}{INCLUDE\PYGZus{}GRAPH} \PYG{o}{=} \PYG{n}{NO}
\PYG{o}{\PYGZhy{}}\PYG{n}{INCLUDED\PYGZus{}BY\PYGZus{}GRAPH} \PYG{o}{=} \PYG{n}{NO}
\PYG{o}{+}\PYG{n}{INCLUDE\PYGZus{}GRAPH} \PYG{o}{=} \PYG{n}{YES}
\PYG{o}{+}\PYG{n}{INCLUDED\PYGZus{}BY\PYGZus{}GRAPH} \PYG{o}{=} \PYG{n}{YES}
\PYG{n}{CALL\PYGZus{}GRAPH} \PYG{o}{=} \PYG{n}{NO}
\PYG{n}{CALLER\PYGZus{}GRAPH} \PYG{o}{=} \PYG{n}{NO}
\PYG{o}{\PYGZhy{}}\PYG{n}{GRAPHICAL\PYGZus{}HIERARCHY} \PYG{o}{=} \PYG{n}{NO}
\PYG{o}{\PYGZhy{}}\PYG{n}{DIRECTORY\PYGZus{}GRAPH} \PYG{o}{=} \PYG{n}{NO}
\PYG{o}{+}\PYG{n}{GRAPHICAL\PYGZus{}HIERARCHY} \PYG{o}{=} \PYG{n}{YES}
\PYG{o}{+}\PYG{n}{DIRECTORY\PYGZus{}GRAPH} \PYG{o}{=} \PYG{n}{YES}
\PYG{n}{DOT\PYGZus{}IMAGE\PYGZus{}FORMAT} \PYG{o}{=} \PYG{n}{png}
\PYG{o}{\PYGZhy{}}\PYG{n}{INTERACTIVE\PYGZus{}SVG} \PYG{o}{=} \PYG{n}{NO}
\PYG{o}{+}\PYG{n}{INTERACTIVE\PYGZus{}SVG} \PYG{o}{=} \PYG{n}{YES}
\PYG{n}{DOT\PYGZus{}PATH} \PYG{o}{=}
\PYG{n}{DOTFILE\PYGZus{}DIRS} \PYG{o}{=}
\PYG{n}{MSCFILE\PYGZus{}DIRS} \PYG{o}{=}
\end{sphinxVerbatim}
\chapter{05 \sphinxhyphen{} Arrays/Strings/TicTacToe}
\label{\detokenize{P05_TicTacToe/README:arrays-strings-tictactoe}}\label{\detokenize{P05_TicTacToe/README::doc}}
\bigskip\hrule\bigskip
\section{1. Übersicht}
\label{\detokenize{P05_TicTacToe/README:ubersicht}}
\sphinxAtStartPar
In diesem Praktikum werden Sie in der ersten Aufgabe ein Programm zum Einlesen, Sortieren und Ausgeben von Strings von Grund auf entwickeln.
\sphinxAtStartPar
In der zweiten Aufgabe werden Sie einen Programmrahmen zu einem funktionierenden TicTacToe\sphinxhyphen{}Spiel erweitern. Sie implementieren hierbei die fehlenden Funktionen bis alle Tests erfolgreich durchlaufen. Die gewählte Vorgehensweise entspricht somit Test\sphinxhyphen{}Driven\sphinxhyphen{}Development (TDD). D.h. es existieren zuerst Tests, welche alle fehlschlagen. Schrittweise werden die Funktionen implementiert bis alle Tests erfolgreich durchlaufen. Wenn die Tests erfolgreich durchlaufen, wird auch das Programm funktionieren.
\bigskip\hrule\bigskip
\section{2. Lernziele}
\label{\detokenize{P05_TicTacToe/README:lernziele}}
\sphinxAtStartPar
In diesem Praktikum schreiben Sie selbst von Grund auf ein C\sphinxhyphen{}Programme, das mit Strings operiert. Ferner ergänzen Sie ein bestehendes und lernen dabei den Zugriff auf Arrays.
\begin{itemize}
\item {}
\sphinxAtStartPar
Sie können mit Arrays von Strings umgehen.
\item {}
\sphinxAtStartPar
Sie können String\sphinxhyphen{}Funktionen aus der Standard Library verwenden.
\item {}
\sphinxAtStartPar
Sie können anhand einer Beschreibung im Code die fehlenden Funktionen die auf Arrays zugreifen implementieren.
\end{itemize}
\bigskip\hrule\bigskip
\section{3. Aufgabe 1: Sortieren von Strings}
\label{\detokenize{P05_TicTacToe/README:aufgabe-1-sortieren-von-strings}}
\sphinxAtStartPar
Schreiben Sie ein C\sphinxhyphen{}Programm, das bis zu 10 Wörter mit einer maximalen Länge von jeweils 20 char von der Tastatur einliest, diese in Grossbuchstaben umwandelt, in einem Array der Reihe nach ablegt und zum Schluss im Array alphabetisch sortiert und ausgibt. Wiederholt eingegebene Wörter sollen dabei ignoriert werden. Das Ende der Eingabe soll durch das Erreichen der zehn unterschiedlichen Wörter oder durch die Eingabe von „ZZZ“ erfolgen. Die Ausgabe der sortierten Wörter soll direkt nach Beendigung der Eingabe erfolgen.
\sphinxAtStartPar
Hinweise:
\begin{itemize}
\item {}
\sphinxAtStartPar
Zur Speicherung der Wörter sollten Sie ein zweidimensionales Array verwenden.
\item {}
\sphinxAtStartPar
Verwenden Sie die String\sphinxhyphen{}Funktionen der C Standard Library (include \textless{}string.h\textgreater{}), z.B. um Strings alphabetisch zu vergleichen.
\item {}
\sphinxAtStartPar
Wenn Sie aus anderen Vorlesungen bereits einen effizienten Sortieralgorithmus kennen, können Sie diesen natürlich verwenden. Sonst erfinden Sie einfach einen eigenen.
\item {}
\sphinxAtStartPar
Strukturieren Sie das Programm durch geeignete Funktionen.
\end{itemize}
\bigskip\hrule\bigskip
\section{4. Aufgabe 2: TicTacToe}
\label{\detokenize{P05_TicTacToe/README:aufgabe-2-tictactoe}}
\sphinxAtStartPar
Das zu ergänzende Programm tic\sphinxhyphen{}tac\sphinxhyphen{}toe hat folgende Funktionalität:
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
es stellt ein 3x3 TicTacToe Spielbrett auf dem Terminal dar
\item {}
\sphinxAtStartPar
es liest von stdin eine Ziffer 0…9 ein, wobei 0 für Programm\sphinxhyphen{}Terminieren, die übrigen Ziffern für die Wahl eines Feldes stehen
\item {}
\sphinxAtStartPar
der erste Spielzug wird von Spieler A geführt, danach wechselt das Programm zwischen den Spielern A und B
\item {}
\sphinxAtStartPar
bei Gewinn oder bei vollem Brett ist das Spiel vorbei
\end{enumerate}
\sphinxAtStartPar
Erweitern Sie die vorgegebenen Code Gerüste, welche im git Repository snp\sphinxhyphen{}lab\sphinxhyphen{}code verfügbar sind.
\sphinxAtStartPar
Wenn die Aufgabe erfolgreich umgesetzt ist, können Sie das Spiel ausführen:
\begin{sphinxVerbatim}[commandchars=\\\{\}]
bin/tic\PYGZhy{}tac\PYGZhy{}toe
\end{sphinxVerbatim}
\sphinxAtStartPar
\sphinxincludegraphics{{TicTacToe}.png}
\sphinxAtStartPar
Als Abnahme müssen die Tests unverändert ohne Fehler ausgeführt werden (\sphinxcode{\sphinxupquote{make test}}).
\sphinxAtStartPar
Die Architektur des Programms folgt dem MVC \textendash{} Model\sphinxhyphen{}View\sphinxhyphen{}Control Paradigma. Dieses Paradigma besagt, dass die View (Eingabe und Darstellung) über Control (Vermittler) das Modell (die eigentliche Programm\sphinxhyphen{}Logik) steuert und darstellt. Dabei sind folgende Abhängigkeiten gegeben:
\sphinxAtStartPar
\sphinxincludegraphics{{MVC_pattern}.png}
\bigskip\hrule\bigskip
\subsection{4.1 Teilaufgabe test\_model\_init}
\label{\detokenize{P05_TicTacToe/README:teilaufgabe-test-model-init}}
\sphinxAtStartPar
Das Programm besteht aus folgenden Files:
\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline
\sphinxstyletheadfamily
\sphinxAtStartPar
Datei
&\sphinxstyletheadfamily
\sphinxAtStartPar
ToDo
\\
\hline
\sphinxAtStartPar
Makefile
&
\sphinxAtStartPar
\sphinxhyphen{}\textgreater{} gegeben, d.h. nichts anzupassen
\\
\hline
\sphinxAtStartPar
tests/tests.c
&
\sphinxAtStartPar
\sphinxhyphen{}\textgreater{} gegeben, d.h. nichts anzupassen
\\
\hline
\sphinxAtStartPar
src/main.c
&
\sphinxAtStartPar
\sphinxhyphen{}\textgreater{} gegeben, d.h. nichts anzupassen
\\
\hline
\sphinxAtStartPar
src/view.h
&
\sphinxAtStartPar
\sphinxhyphen{}\textgreater{} gegeben, d.h. nichts anzupassen
\\
\hline
\sphinxAtStartPar
src/view.c
&
\sphinxAtStartPar
\sphinxhyphen{}\textgreater{} gegeben, d.h. nichts anzupassen
\\
\hline
\sphinxAtStartPar
src/control.h
&
\sphinxAtStartPar
\sphinxhyphen{}\textgreater{} gegeben, d.h. nichts anzupassen
\\
\hline
\sphinxAtStartPar
src/control.c
&
\sphinxAtStartPar
\sphinxhyphen{}\textgreater{} gegeben, d.h. nichts anzupassen
\\
\hline
\sphinxAtStartPar
src/model.h
&
\sphinxAtStartPar
\sphinxhyphen{}\textgreater{} gegeben, d.h. nichts anzupassen
\\
\hline
\sphinxAtStartPar
src/model.c
&
\sphinxAtStartPar
\sphinxhyphen{}\textgreater{} \sphinxstylestrong{anzupassen:} umsetzen gemäss den Angaben unten
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Führen Sie \sphinxcode{\sphinxupquote{make test}} aus
\end{enumerate}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Suite: lab \PYG{n+nb}{test}
Test: test\PYGZus{}model\PYGZus{}init ...
init\PYGZus{}model:... \PYG{l+m}{0}/0 FAILED
\PYG{l+m}{1}. tests/tests.c:62 \PYGZhy{} CU\PYGZus{}ASSERT\PYGZus{}EQUAL\PYGZus{}FATAL\PYG{o}{(}instance\PYGZhy{}\PYGZgt{}board\PYG{o}{[}row\PYG{o}{]}\PYG{o}{[}col\PYG{o}{]},model\PYGZus{}state\PYGZus{}none\PYG{o}{)}
Test: test\PYGZus{}model\PYGZus{}get\PYGZus{}state ...FAILED
\PYG{l+m}{1}. tests/tests.c:62 \PYGZhy{} CU\PYGZus{}ASSERT\PYGZus{}EQUAL\PYGZus{}FATAL\PYG{o}{(}instance\PYGZhy{}\PYGZgt{}board\PYG{o}{[}row\PYG{o}{]}\PYG{o}{[}col\PYG{o}{]},model\PYGZus{}state\PYGZus{}none\PYG{o}{)}
Test: test\PYGZus{}model\PYGZus{}get\PYGZus{}winner ...FAILED
\PYG{l+m}{1}. tests/tests.c:62 \PYGZhy{} CU\PYGZus{}ASSERT\PYGZus{}EQUAL\PYGZus{}FATAL\PYG{o}{(}instance\PYGZhy{}\PYGZgt{}board\PYG{o}{[}row\PYG{o}{]}\PYG{o}{[}col\PYG{o}{]},model\PYGZus{}state\PYGZus{}none\PYG{o}{)}
Test: test\PYGZus{}model\PYGZus{}can\PYGZus{}move ...FAILED
\PYG{l+m}{1}. tests/tests.c:62 \PYGZhy{} CU\PYGZus{}ASSERT\PYGZus{}EQUAL\PYGZus{}FATAL\PYG{o}{(}instance\PYGZhy{}\PYGZgt{}board\PYG{o}{[}row\PYG{o}{]}\PYG{o}{[}col\PYG{o}{]},model\PYGZus{}state\PYGZus{}none\PYG{o}{)}
Test: test\PYGZus{}model\PYGZus{}move ...FAILED
\PYG{l+m}{1}. tests/tests.c:62 \PYGZhy{} CU\PYGZus{}ASSERT\PYGZus{}EQUAL\PYGZus{}FATAL\PYG{o}{(}instance\PYGZhy{}\PYGZgt{}board\PYG{o}{[}row\PYG{o}{]}\PYG{o}{[}col\PYG{o}{]},model\PYGZus{}state\PYGZus{}none\PYG{o}{)}
Test: test\PYGZus{}model\PYGZus{}get\PYGZus{}win\PYGZus{}line ...FAILED
\PYG{l+m}{1}. tests/tests.c:62 \PYGZhy{} CU\PYGZus{}ASSERT\PYGZus{}EQUAL\PYGZus{}FATAL\PYG{o}{(}instance\PYGZhy{}\PYGZgt{}board\PYG{o}{[}row\PYG{o}{]}\PYG{o}{[}col\PYG{o}{]},model\PYGZus{}state\PYGZus{}none\PYG{o}{)}
Run Summary: Type Total Ran Passed Failed Inactive
suites \PYG{l+m}{1} \PYG{l+m}{1} n/a \PYG{l+m}{0} \PYG{l+m}{0}
tests \PYG{l+m}{6} \PYG{l+m}{6} \PYG{l+m}{0} \PYG{l+m}{6} \PYG{l+m}{0}
asserts \PYG{l+m}{6} \PYG{l+m}{6} \PYG{l+m}{0} \PYG{l+m}{6} n/a
\end{sphinxVerbatim}
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Konzentrieren Sie sich auf den ersten Test der fehlschlägt. Dies ist ein Unit Test, welcher die Funktion \sphinxstylestrong{model\_init()} prüft. Suchen Sie die Funktion in \sphinxstylestrong{src/model.h} und \sphinxstylestrong{src/model.c}.
\item {}
\sphinxAtStartPar
Was ist die geforderte Funktionalität und wie ist sie implementiert?
\end{enumerate}
\sphinxAtStartPar
Suchen Sie die darin aufgerufene \sphinxstylestrong{model\_init()} Funktion und implementieren Sie diese.
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kt}{void} \PYG{n+nf}{model\PYGZus{}init}\PYG{p}{(}\PYG{n}{model\PYGZus{}t} \PYG{o}{*}\PYG{n}{instance}\PYG{p}{)}
\PYG{p}{\PYGZob{}}
\PYG{n}{assert}\PYG{p}{(}\PYG{n}{instance}\PYG{p}{)}\PYG{p}{;}
\PYG{c+c1}{// Instructions to the students:}
\PYG{c+c1}{// set all fields of the board to model\PYGZus{}state\PYGZus{}none}
\PYG{c+c1}{// BEGIN\PYGZhy{}STUDENTS\PYGZhy{}TO\PYGZhy{}ADD\PYGZhy{}CODE}
\PYG{c+c1}{// END\PYGZhy{}STUDENTS\PYGZhy{}TO\PYGZhy{}ADD\PYGZhy{}CODE}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Führen Sie \sphinxcode{\sphinxupquote{make test}} und korrigieren Sie obige Funktion, bis der Test nicht mehr fehlschlägt.
\end{enumerate}
\bigskip\hrule\bigskip
\subsection{4.2 Teilaufgabe test\_model\_get\_state und test\_model\_get\_winner}
\label{\detokenize{P05_TicTacToe/README:teilaufgabe-test-model-get-state-und-test-model-get-winner}}
\sphinxAtStartPar
Gehen Sie analog zur ersten Teilaufgabe vor:
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Führen Sie \sphinxcode{\sphinxupquote{make test}} aus.
\item {}
\sphinxAtStartPar
Suchen Sie die Funktion \sphinxstylestrong{model\_get\_state()} in \sphinxstylestrong{model.h} und \sphinxstylestrong{model.c}.
\item {}
\sphinxAtStartPar
Implementieren Sie die intern benutzte Funktion \sphinxstylestrong{get\_state()} gemäss der Anleitung im Code.
\end{enumerate}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{model\PYGZus{}state\PYGZus{}t} \PYG{n+nf}{model\PYGZus{}get\PYGZus{}state}\PYG{p}{(}\PYG{n}{model\PYGZus{}t} \PYG{o}{*}\PYG{n}{instance}\PYG{p}{,} \PYG{n}{model\PYGZus{}pos\PYGZus{}t} \PYG{n}{pos}\PYG{p}{)}
\PYG{p}{\PYGZob{}}
\PYG{n}{assert}\PYG{p}{(}\PYG{n}{instance}\PYG{p}{)}\PYG{p}{;}
\PYG{n}{assert\PYGZus{}pos}\PYG{p}{(}\PYG{n}{pos}\PYG{p}{)}\PYG{p}{;}
\PYG{c+c1}{// Instructions to the students:}
\PYG{c+c1}{// replace the stub implementation my access to the field at the given position.}
\PYG{c+c1}{// BEGIN\PYGZhy{}STUDENTS\PYGZhy{}TO\PYGZhy{}ADD\PYGZhy{}CODE}
\PYG{k}{return} \PYG{n}{model\PYGZus{}state\PYGZus{}none}\PYG{p}{;} \PYG{c+c1}{// stub}
\PYG{c+c1}{// END\PYGZhy{}STUDENTS\PYGZhy{}TO\PYGZhy{}ADD\PYGZhy{}CODE}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}
\bigskip\hrule\bigskip
\subsection{4.3 Teilaufgabe test\_model\_can\_move}
\label{\detokenize{P05_TicTacToe/README:teilaufgabe-test-model-can-move}}
\sphinxAtStartPar
Gehen Sie analog den obigen Teilaufgaben vor und implementieren Sie, gemäss Vorgaben im Code, die Funktion \sphinxstylestrong{model\_can\_move()}.
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kt}{int} \PYG{n+nf}{model\PYGZus{}can\PYGZus{}move}\PYG{p}{(}\PYG{n}{model\PYGZus{}t} \PYG{o}{*}\PYG{n}{instance}\PYG{p}{)}
\PYG{p}{\PYGZob{}}
\PYG{n}{assert}\PYG{p}{(}\PYG{n}{instance}\PYG{p}{)}\PYG{p}{;}
\PYG{k}{if} \PYG{p}{(}\PYG{n}{model\PYGZus{}get\PYGZus{}winner}\PYG{p}{(}\PYG{n}{instance}\PYG{p}{)} \PYG{o}{=}\PYG{o}{=} \PYG{n}{model\PYGZus{}state\PYGZus{}none}\PYG{p}{)} \PYG{p}{\PYGZob{}}
\PYG{c+c1}{// Instructions to the students:}
\PYG{c+c1}{// scan all fields: return 1 with first field which equals model\PYGZus{}state\PYGZus{}none}
\PYG{c+c1}{// BEGIN\PYGZhy{}STUDENTS\PYGZhy{}TO\PYGZhy{}ADD\PYGZhy{}CODE}
\PYG{c+c1}{// END\PYGZhy{}STUDENTS\PYGZhy{}TO\PYGZhy{}ADD\PYGZhy{}CODE}
\PYG{p}{\PYGZcb{}}
\PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}
\bigskip\hrule\bigskip
\subsection{4.4 Teilaufgabe test\_model\_move und test\_model\_get\_win\_line}
\label{\detokenize{P05_TicTacToe/README:teilaufgabe-test-model-move-und-test-model-get-win-line}}
\sphinxAtStartPar
Schliesslich gehen Sie auch hier analog den obigen Teilaufgaben vor und implementieren Sie, gemäss Vorgaben im Code, die Funktion \sphinxstylestrong{set\_state()}.
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{c+cm}{/**}
\PYG{c+cm}{ * @brief Sets the field on the board to the given state.}
\PYG{c+cm}{ * @param instance [INOUT] The instance which holds the state.}
\PYG{c+cm}{ * @param pos [IN] The affected field.}
\PYG{c+cm}{ * @param state [IN] The new state of the field.}
\PYG{c+cm}{ */}
\PYG{k}{static} \PYG{k+kt}{void} \PYG{n}{set\PYGZus{}state}\PYG{p}{(}\PYG{n}{model\PYGZus{}t} \PYG{o}{*}\PYG{n}{instance}\PYG{p}{,} \PYG{n}{model\PYGZus{}pos\PYGZus{}t} \PYG{n}{pos}\PYG{p}{,} \PYG{n}{model\PYGZus{}state\PYGZus{}t} \PYG{n}{state}\PYG{p}{)}
\PYG{p}{\PYGZob{}}
\PYG{n}{assert\PYGZus{}pos}\PYG{p}{(}\PYG{n}{pos}\PYG{p}{)}\PYG{p}{;}
\PYG{c+c1}{// Instructions to the students:}
\PYG{c+c1}{// set the field of the board to the new state}
\PYG{c+c1}{// BEGIN\PYGZhy{}STUDENTS\PYGZhy{}TO\PYGZhy{}ADD\PYGZhy{}CODE}
\PYG{c+c1}{// END\PYGZhy{}STUDENTS\PYGZhy{}TO\PYGZhy{}ADD\PYGZhy{}CODE}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}
\sphinxAtStartPar
Wenn die beiden obigen Teilaufgaben erfolgreich umgesetzt sind, laufen die Tests ohne Fehler durch und das Spiel kann gespielt werden.
\bigskip\hrule\bigskip
\section{5. Bewertung}
\label{\detokenize{P05_TicTacToe/README:bewertung}}
\sphinxAtStartPar
Der funktionierende Programmcode muss der Praktikumsbetreuung gezeigt werden. Die Lösungen müssen mündlich erklärt werden.
\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
\hline
\sphinxstyletheadfamily
\sphinxAtStartPar
Aufgabe
&\sphinxstyletheadfamily
\sphinxAtStartPar
Kriterium
&\sphinxstyletheadfamily
\sphinxAtStartPar
Punkte
\\
\hline
\sphinxAtStartPar
Sortieren von Strings
&
\sphinxAtStartPar
Sie können das funktionierende Programm demonstrieren und erklären.
&
\sphinxAtStartPar
2
\\
\hline
\sphinxAtStartPar
TicTacToe
&
\sphinxAtStartPar
Sie können das funktionierende Programm inklusive funktionierende Tests demonstrieren und erklären.
&
\sphinxAtStartPar
\\
\hline
\sphinxAtStartPar
TicTacToe
&
\sphinxAtStartPar
Teilaufgabe test\_model\_init
&
\sphinxAtStartPar
0.5
\\
\hline
\sphinxAtStartPar
TicTacToe
&
\sphinxAtStartPar
Teilaufgabe test\_model\_get\_state und test\_model\_get\_winner
&
\sphinxAtStartPar
0.5
\\
\hline
\sphinxAtStartPar
TicTacToe
&
\sphinxAtStartPar
Teilaufgabe test\_model\_can\_move
&
\sphinxAtStartPar
0.5
\\
\hline
\sphinxAtStartPar
TicTacToe
&
\sphinxAtStartPar
Teilaufgabe test\_model\_move und test\_model\_get\_win\_line
&
\sphinxAtStartPar
0.5
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
\bigskip\hrule\bigskip
\sphinxAtStartPar
Version: 14.02.2022
\chapter{06 \sphinxhyphen{} Personen Verwaltung \textendash{} Linked List}
\label{\detokenize{P06_Personen_Verwaltung_Linked_List/README:personen-verwaltung-linked-list}}\label{\detokenize{P06_Personen_Verwaltung_Linked_List/README::doc}}
\bigskip\hrule\bigskip
\sphinxAtStartPar
\sphinxincludegraphics{{linked_list}.png}
\bigskip\hrule\bigskip
\section{1. Übersicht}
\label{\detokenize{P06_Personen_Verwaltung_Linked_List/README:ubersicht}}
\sphinxAtStartPar
In diesem Praktikum schreiben Sie eine einfache Personenverwaltung. Dabei werden Sie etliche Elemente von C anwenden:
\begin{itemize}
\item {}
\sphinxAtStartPar
Header Files selber schreiben, inklusive Include Guard
\item {}
\sphinxAtStartPar
Typen definieren
\item {}
\sphinxAtStartPar
Funktionen mit \sphinxcode{\sphinxupquote{by value}} und \sphinxcode{\sphinxupquote{by reference}} Parametern deklarieren und definieren
\item {}
\sphinxAtStartPar
einfache Variablen, Pointer Variablen, struct Variablen und Array Variablen benutzen
\item {}
\sphinxAtStartPar
Strukturen im Speicher dynamisch allozieren und freigeben
\item {}
\sphinxAtStartPar
I/O und String Funktionen aus der Standard Library anwenden
\item {}
\sphinxAtStartPar
Anwender Eingaben verarbeiten
\item {}
\sphinxAtStartPar
Fehlerbehandlung
\end{itemize}
\bigskip\hrule\bigskip
\section{2. Lernziele}
\label{\detokenize{P06_Personen_Verwaltung_Linked_List/README:lernziele}}
\sphinxAtStartPar
In diesem Praktikum wenden Sie viele der bisher gelernten C Elemente an.
\begin{itemize}
\item {}
\sphinxAtStartPar
Sie können anhand dieser Beschreibung ein vollständiges C Programm schreiben.
\item {}
\sphinxAtStartPar
Sie können Unit Tests schreiben welche die wesentlichen Funktionen des Programms individuell testen.
\item {}
\end{itemize}
\sphinxAtStartPar
Die Bewertung dieses Praktikums ist am Ende angegeben.
\sphinxAtStartPar
Erweitern Sie die vorgegebenen Code Gerüste, welche im \sphinxcode{\sphinxupquote{git}} Repository \sphinxcode{\sphinxupquote{snp\sphinxhyphen{}lab\sphinxhyphen{}code}} verfügbar sind.
\bigskip\hrule\bigskip
\section{3. Personenverwaltung}
\label{\detokenize{P06_Personen_Verwaltung_Linked_List/README:personenverwaltung}}
\bigskip\hrule\bigskip
\subsection{3.1 Programmfunktion}
\label{\detokenize{P06_Personen_Verwaltung_Linked_List/README:programmfunktion}}
\sphinxAtStartPar
Das Programm soll in einer Schleife dem Benutzer jeweils folgende Auswahl bieten, wovon eine Aktion mit Eingabe des entsprechenden Buchstabens ausgelöst wird:
\sphinxAtStartPar
\sphinxstylestrong{I}(nsert), \sphinxstylestrong{R}(emove), \sphinxstylestrong{S}(how), \sphinxstylestrong{C}(lear), \sphinxstylestrong{E}(nd):
\begin{itemize}
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Insert}: der Benutzer wird aufgefordert, eine Person einzugeben
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Remove}: der Benutzer wird aufgefordert, die Daten einer zu löschenden Person einzu\sphinxhyphen{}geben
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Show}: eine komplette Liste aller gespeicherten Personen wird in alphabetischer Rei\sphinxhyphen{}henfolge ausgegeben
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Clear}: alle Personen werden gelöscht
\item {}
\sphinxAtStartPar
\sphinxstylestrong{End}: das Programm wird beendet
\end{itemize}
\bigskip\hrule\bigskip
\subsection{3.2 Designvorgaben}
\label{\detokenize{P06_Personen_Verwaltung_Linked_List/README:designvorgaben}}
\sphinxAtStartPar
\sphinxstylestrong{Verkettete Liste}
Da zur Kompilierzeit nicht bekannt ist, ob 10 oder 10000 Personen eingegeben werden, wäre es keine gute Idee, im Programm einen statischen Array mit z.B. 10000 Personen\sphinxhyphen{}Einträgen zu allozieren. Dies wäre ineffizient und umständlich beim sortierten Einfügen von Personen. In solchen Situationen arbeitet man deshalb mit dynamischen Datenstrukturen, die zur Laufzeit beliebig (solange Speicher vorhanden ist) wachsen und wieder schrumpfen können. Eine sehr populäre dynamische Datenstruktur ist die \sphinxstylestrong{verkettete Liste} und genau die werden wir in diesem Praktikum verwenden.
\sphinxAtStartPar
\sphinxincludegraphics{{a}.png}
\sphinxAtStartPar
\sphinxincludegraphics{{b}.png}
\sphinxAtStartPar
\sphinxincludegraphics{{c}.png}
\sphinxAtStartPar
\sphinxincludegraphics{{d}.png}
Abbildung 1: Zyklisch verkettete Liste
\sphinxAtStartPar
Eine verkettete Liste bedeutet, dass ein Knoten der verketten Liste einen Datensatz einer Person speichert und zusätzlich einen Pointer auf den nächsten Knoten in der Liste aufweist (siehe Abbildung 1). In dieser Pointer Variablen (\sphinxcode{\sphinxupquote{next}} in der \sphinxcode{\sphinxupquote{node\_t}} Struktur unten) steht also einfach die Adresse des nächsten Knotens.
\sphinxAtStartPar
Die leere Liste besteht aus einem einzelnen Element, welches keine spezifische Person abspeichert und welches auf sich selbst zeigt (Abbildung 1 a). Dieses Element ist der Einstiegspunkt der Liste (auch Anker oder Wurzel genannt) und ist das einzige Element, das Sie im Programm direkt kennen und einer Variablen zuweisen. Dieses Element können Sie statisch allozieren (z.B. \sphinxcode{\sphinxupquote{node\_t anchor}};, siehe Details weiter unten), denn es existiert während der gesamten Ausführungszeit. Alle anderen Elemente erreichen Sie ausgehend vom Anker, indem Sie einmal, den Pointern folgend, im Kreis herum gehen. Abbildung 1 b zeigt die Liste nach dem Einfügen der Person \sphinxcode{\sphinxupquote{Max Mueller, 40}} Jahre. Nach dem Einfügen von zwei weiteren Personen sieht die Datenstruktur aus wie in Abbildung 1 c. Das Entfernen der Person \sphinxcode{\sphinxupquote{Arno Bosshard}} führt zu Abbildung 1 d.
\sphinxAtStartPar
Eine Person kann \sphinxstylestrong{zugefügt} werden, indem dynamisch ein neuer Knoten erzeugt wird und dieser in die verkettete Liste eingefügt wird. Beim Einfügen müssen die Adressen der Knoten so den Pointern zugewiesen werden, dass die Kette intakt bleibt.
\sphinxAtStartPar
Ein Knoten wird \sphinxstylestrong{entfernt}, indem der entsprechende Knoten aus der Verkettung herausgelöst wird (\sphinxcode{\sphinxupquote{next}} des Vorgängerknotens soll neu auf \sphinxcode{\sphinxupquote{next}} des herauszulösenden Knotens zeigen) und dann der Speicher des entsprechenden Knotens freigegeben wird.
\sphinxAtStartPar
\sphinxstylestrong{Personen und Knoten Records}
\sphinxAtStartPar
Die für je eine Person zu speichernden Daten sollen in folgendem C \sphinxcode{\sphinxupquote{struct}} zusammengefasst sein.
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{c+cp}{\PYGZsh{}}\PYG{c+cp}{define NAME\PYGZus{}LEN 20}
\PYG{k}{typedef} \PYG{k}{struct} \PYG{p}{\PYGZob{}}
\PYG{k+kt}{char} \PYG{n}{name}\PYG{p}{[}\PYG{n}{NAME\PYGZus{}LEN}\PYG{p}{]}\PYG{p}{;}
\PYG{k+kt}{char} \PYG{n}{first\PYGZus{}name}\PYG{p}{[}\PYG{n}{NAME\PYGZus{}LEN}\PYG{p}{]}\PYG{p}{;}
\PYG{k+kt}{unsigned} \PYG{k+kt}{int} \PYG{n}{age}\PYG{p}{;}
\PYG{p}{\PYGZcb{}} \PYG{n}{person\PYGZus{}t}\PYG{p}{;}
\end{sphinxVerbatim}
\sphinxAtStartPar
Jeder Knoten der verketteten Liste soll aus folgendem C \sphinxcode{\sphinxupquote{struct}} bestehen.
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{typedef} \PYG{k}{struct} \PYG{n+nc}{node} \PYG{p}{\PYGZob{}}
\PYG{n}{person\PYGZus{}t} \PYG{n}{content}\PYG{p}{;} \PYG{c+c1}{// in diesem Knoten gespeicherte Person}
\PYG{k}{struct} \PYG{n+nc}{node} \PYG{o}{*}\PYG{n}{next}\PYG{p}{;} \PYG{c+c1}{// Pointer auf den nächsten Knoten in der Liste}
\PYG{p}{\PYGZcb{}} \PYG{n}{node\PYGZus{}t}\PYG{p}{;}
\end{sphinxVerbatim}
\sphinxAtStartPar
\sphinxstylestrong{Vorschlag: zyklisch verkettete Liste}
\sphinxAtStartPar
Erkennen des Endes der Liste: bei der zyklisch verketteten Liste zeigt das letzte Element wie\sphinxhyphen{}der auf den Anker, die Liste bildet also einen Kreis. Dies ist in Abbildung 1 so abgebildet.
\sphinxAtStartPar
Alternativ könnte man das Ende erkennbar machen, indem die Kette anstelle von zyklisch, mit einem NULL Pointer endet.
\sphinxAtStartPar
Die Wahl ist ihnen überlassen ob sie die eine oder andere Art der End\sphinxhyphen{}Erkennung implementieren. In der Beschreibung wird angenommen, dass es sich um eine zyklisch verkettete Liste handelt.
\sphinxAtStartPar
\sphinxstylestrong{Sortiertes Einfügen}
\sphinxAtStartPar
Die Personen Records sollen sortiert in die Liste eingefügt werden. Dies bedeutet, dass vom Anker her gesucht werden soll, bis der erste Knoten gefunden wurde dessen Nachfolgeknoten entweder „grösser“ ist als der einzufügende Knoten, oder wo das Ende der Liste erreicht ist. Die Ordnung (grösser, gleich, kleiner) soll so definiert sein:
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{c+c1}{// if (p1 \PYGZgt{} p2) \PYGZob{} ... \PYGZcb{}}
\PYG{k}{if} \PYG{p}{(}\PYG{n}{person\PYGZus{}compare}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{p1}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{p2}\PYG{p}{)} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{p}{)} \PYG{p}{\PYGZob{}} \PYG{p}{.}\PYG{p}{.}\PYG{p}{.} \PYG{p}{\PYGZcb{}}
\PYG{c+cm}{/**}
\PYG{c+cm}{ * @brief Compares two persons in this sequence: 1st=name, 2nd=first\PYGZus{}name, 3rd=age}
\PYG{c+cm}{ * @param a [IN] const reference to 1st person in the comparison}
\PYG{c+cm}{ * @param b [IN] const reference to 2nd person in the comparison}
\PYG{c+cm}{ * @return =0 if all record fields are the same}
\PYG{c+cm}{ * \PYGZgt{}0 if all previous fields are the same, but for this field, a is greater}
\PYG{c+cm}{ * \PYGZlt{}0 if all previous fields are the same, but for this field, b is greater}
\PYG{c+cm}{ * @remark strncmp() is used for producing the result of string field comparisons}
\PYG{c+cm}{ * @remark a\PYGZhy{}\PYGZgt{}age \textendash{} b\PYGZhy{}\PYGZgt{}age is used for producing the result of age comparison}
\PYG{c+cm}{ */}
\PYG{k+kt}{int} \PYG{n}{person\PYGZus{}compare}\PYG{p}{(}\PYG{k}{const} \PYG{n}{person\PYGZus{}t} \PYG{o}{*}\PYG{n}{a}\PYG{p}{,} \PYG{k}{const} \PYG{n}{person\PYGZus{}t} \PYG{o}{*}\PYG{n}{b}\PYG{p}{)}\PYG{p}{;}
\end{sphinxVerbatim}
\sphinxAtStartPar
\sphinxstylestrong{Eingabe}
\sphinxAtStartPar
\sphinxstylestrong{Fehlerhafte Wahl der Operation} in der Hauptschleife soll gemeldet werden, ansonsten aber ignoriert werden.
\sphinxAtStartPar
\sphinxstylestrong{Fehlerhafte Eingabe der Personenangaben} sollen gemeldet werden und die gesamte Operation (z.B. Insert) verworfen werden.
\sphinxAtStartPar
Zu prüfende Fehler bei Personeneingaben:
\begin{itemize}
\item {}
\sphinxAtStartPar
für die Namen
\begin{itemize}
\item {}
\sphinxAtStartPar
zu lange Namen
\end{itemize}
\item {}
\sphinxAtStartPar
für das Alter
\begin{itemize}
\item {}
\sphinxAtStartPar
keine Zahl
\end{itemize}
\item {}
\sphinxAtStartPar
Duplikat
\begin{itemize}
\item {}
\sphinxAtStartPar
derselbe Record soll nicht doppelt in der Liste vorkommen
\end{itemize}
\end{itemize}
\sphinxAtStartPar
Weitergehende Prüfungen sind nicht erwartet.
\sphinxAtStartPar
\sphinxstylestrong{Zu beachten:} bei fehlerhafter Eingabe darf kein „Memory Leak“ entstehen, d.h. potentiell auf dem Heap allozierter Speicher muss im Fehlerfall freigegeben werden.
\bigskip\hrule\bigskip
\subsection{3.3 Bestehender Programmrahmen}
\label{\detokenize{P06_Personen_Verwaltung_Linked_List/README:bestehender-programmrahmen}}
\sphinxAtStartPar
Der Programmrahmen besteht aus den unten aufgelisteten Files. Es sollen weitere Module in \sphinxcode{\sphinxupquote{src}} hinzugefügt werden und die bestehenden Files ergänzt werden gemäss den Aufgaben.
\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline
\sphinxAtStartPar
&
\sphinxAtStartPar
\\
\hline
\sphinxAtStartPar
Makefile
&
\sphinxAtStartPar
\sphinxhyphen{}\textgreater{} \sphinxstylestrong{zu ergänzen} mit neuen Modulen
\\
\hline
\sphinxAtStartPar
tests/tests.c
&
\sphinxAtStartPar
\sphinxhyphen{}\textgreater{} \sphinxstylestrong{zu ergänzen} gemäss Aufgaben (implementieren von Unit Tests)
\\
\hline
\sphinxAtStartPar
src/main.c
&
\sphinxAtStartPar
\sphinxhyphen{}\textgreater{} \sphinxstylestrong{zu ergänzen} gemäss Aufgaben (Hauptprogramm)
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
\bigskip\hrule\bigskip
\section{4. Aufgabe 1: Modularisierung \textendash{} API und Implementation main.c}
\label{\detokenize{P06_Personen_Verwaltung_Linked_List/README:aufgabe-1-modularisierung-api-und-implementation-main-c}}
\sphinxAtStartPar
Kreieren Sie folgende Files in \sphinxcode{\sphinxupquote{src}} und implementieren Sie \sphinxcode{\sphinxupquote{main.c}} basierend auf dem unten von Ihnen gegebenen API.
\sphinxAtStartPar
\sphinxstylestrong{File person.h}
\sphinxAtStartPar
Typ Definitionen:
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{person\PYGZus{}t}\PYG{p}{.}\PYG{p}{.}\PYG{p}{.} \PYG{c+c1}{// siehe Beschreibung oben}
\end{sphinxVerbatim}
\sphinxAtStartPar
Funktionsdeklarationen:
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{c+c1}{// siehe Beschreibung oben}
\PYG{k+kt}{int} \PYG{n+nf}{person\PYGZus{}compare}\PYG{p}{(}\PYG{k}{const} \PYG{n}{person\PYGZus{}t} \PYG{o}{*}\PYG{n}{a}\PYG{p}{,} \PYG{k}{const} \PYG{n}{person\PYGZus{}t} \PYG{o}{*}\PYG{n}{b}\PYG{p}{)}\PYG{p}{;}
\end{sphinxVerbatim}
\begin{itemize}
\item {}
\sphinxAtStartPar
gegebenenfalls weitere Funktionen für die Bearbeitung von Personen
\end{itemize}
\sphinxAtStartPar
\sphinxstylestrong{File list.h}
\sphinxAtStartPar
Typ Definitionen:
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{person\PYGZus{}t}\PYG{p}{.}\PYG{p}{.}\PYG{p}{.} \PYG{c+c1}{// siehe Beschreibung oben}
\end{sphinxVerbatim}
\sphinxAtStartPar
Funktionsdeklarationen:
\begin{itemize}
\item {}
\sphinxAtStartPar
Funktionen für \sphinxcode{\sphinxupquote{insert}}, \sphinxcode{\sphinxupquote{remove}}, \sphinxcode{\sphinxupquote{clear}} Operationen auf der Liste
\end{itemize}
\bigskip\hrule\bigskip
\sphinxAtStartPar
Das Hauptprogramm soll die Eingabeschleife implementieren und die obigen Funktionen (wo angebracht) aufrufen.
\bigskip\hrule\bigskip
\section{5. Aufgabe 2: Implementierung von person.c und list.c}
\label{\detokenize{P06_Personen_Verwaltung_Linked_List/README:aufgabe-2-implementierung-von-person-c-und-list-c}}
\sphinxAtStartPar
Fügen Sie die beiden Implementationsfiles \sphinxcode{\sphinxupquote{person.c}} und \sphinxcode{\sphinxupquote{list.c}} zu \sphinxcode{\sphinxupquote{src}}. Fügen Sie die beiden Module im \sphinxcode{\sphinxupquote{Makefile}} zu der vorgegebenen Variablen \sphinxcode{\sphinxupquote{MODULES}} hinzu, so dass sie beim \sphinxcode{\sphinxupquote{make}} Aufruf auch berücksichtigt werden.
\bigskip\hrule\bigskip
\subsection{5.1 Teilaufgabe: Implementierung von person.c}
\label{\detokenize{P06_Personen_Verwaltung_Linked_List/README:teilaufgabe-implementierung-von-person-c}}
\sphinxAtStartPar
Implementieren Sie die Funktionen aus \sphinxcode{\sphinxupquote{person.h}}.
\sphinxAtStartPar
Falls nötig, stellen Sie weitere statische Hilfsfunktionen in \sphinxcode{\sphinxupquote{person.c}} zur Verfügung.
\bigskip\hrule\bigskip
\subsection{5.2 Teilaufgabe: Implementierung von list.c}
\label{\detokenize{P06_Personen_Verwaltung_Linked_List/README:teilaufgabe-implementierung-von-list-c}}
\sphinxAtStartPar
Implementieren Sie die Funktionen aus \sphinxcode{\sphinxupquote{list.h}}.
\sphinxAtStartPar
Falls nötig, stellen Sie weitere statische Hilfsfunktionen in \sphinxcode{\sphinxupquote{list.c}} zur Verfügung.
\bigskip\hrule\bigskip
\section{6. Aufgabe 3: Unit Tests}
\label{\detokenize{P06_Personen_Verwaltung_Linked_List/README:aufgabe-3-unit-tests}}
\sphinxAtStartPar
Schreiben Sie Unit Tests für mindestens die folgenden Funktionen
\begin{itemize}
\item {}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{person.h:}}
\begin{itemize}
\item {}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{person\_compare}}
\end{itemize}
\item {}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{list.h:}}
\begin{itemize}
\item {}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{list\_insert}}
\item {}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{list\_remove}}
\item {}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{list\_clear}}
\end{itemize}
\end{itemize}
\sphinxAtStartPar
Es existieren in \sphinxcode{\sphinxupquote{tests/tests.c}} schon vier Test Rahmen für diese Test Cases.
\sphinxAtStartPar
In diese Test Cases sollen die entsprechenden Funktionen unter verschiedenen Bedingungen isoliert aufgerufen werden und deren Verhalten überprüft werden.
\sphinxAtStartPar
Verwenden Sie für die Überprüfung die CUnit \sphinxcode{\sphinxupquote{CU\_ASSERT\_...}} Makros.
\sphinxAtStartPar
Siehe dazu auch \sphinxcode{\sphinxupquote{man CUnit}}.
\sphinxAtStartPar
Wenn die obigen Teilaufgaben erfolgreich umgesetzt sind, laufen die Tests ohne Fehler durch.
\bigskip\hrule\bigskip
\section{7. Bewertung}
\label{\detokenize{P06_Personen_Verwaltung_Linked_List/README:bewertung}}
\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
\hline
\sphinxstyletheadfamily
\sphinxAtStartPar
Aufgabe
&\sphinxstyletheadfamily
\sphinxAtStartPar
Kriterium
&\sphinxstyletheadfamily
\sphinxAtStartPar
Punkte
\\
\hline
\sphinxAtStartPar
&
\sphinxAtStartPar
Sie können das funktionierende Programm inklusive funktionierende Tests demonstrieren und erklären.
&
\sphinxAtStartPar
\\
\hline
\sphinxAtStartPar
1
&
\sphinxAtStartPar
API von list.h und person.h plus die Implementation von main.c
&
\sphinxAtStartPar
2
\\
\hline
\sphinxAtStartPar
2
&
\sphinxAtStartPar
Teilaufgabe: person.c
&
\sphinxAtStartPar
2
\\
\hline
\sphinxAtStartPar
2
&
\sphinxAtStartPar
Teilaufgabe: list.c
&
\sphinxAtStartPar
2
\\
\hline
\sphinxAtStartPar
3
&
\sphinxAtStartPar
Unit Tests
&
\sphinxAtStartPar
2
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
\bigskip\hrule\bigskip
\sphinxAtStartPar
Version: 11.01.2022
\chapter{07 \sphinxhyphen{} Prozesse und Threads}
\label{\detokenize{P07_Prozesse_und_Threads/README:prozesse-und-threads}}\label{\detokenize{P07_Prozesse_und_Threads/README::doc}}
\bigskip\hrule\bigskip
\sphinxAtStartPar
\sphinxincludegraphics{{ein_mann_orchester}.png}
\sphinxAtStartPar
\sphinxhref{https://www.wikiwand.com/de/Ein-Mann-Orchester}{Quelle: https://www.wikiwand.com/de/Ein\sphinxhyphen{}Mann\sphinxhyphen{}Orchester}
\bigskip\hrule\bigskip
\section{1. Übersicht}
\label{\detokenize{P07_Prozesse_und_Threads/README:ubersicht}}
\sphinxAtStartPar
In diesem Praktikum werden wir uns mit Prozessen, Prozesshierarchien und Threads beschäftigen, um ein gutes Grundverständnis dieser Abstraktionen zu erhalten. Sie werden bestehenden Code analysieren und damit experimentieren. D.h. dies ist nicht ein «Codierungs»\sphinxhyphen{}Praktikum, sondern ein «Analyse»\sphinxhyphen{} und «Experimentier»\sphinxhyphen{}Praktikum.
\bigskip\hrule\bigskip
\subsection{1.1 Nachweis}
\label{\detokenize{P07_Prozesse_und_Threads/README:nachweis}}
\sphinxAtStartPar
Dieses Praktikum ist eine leicht abgewandelte Variante des ProcThreads Praktikum des Moduls BSY, angepasst an die Verhältnisse des SNP Moduls. Die Beispiele und Beschreibungen wurden, wo möglich, eins\sphinxhyphen{}zu\sphinxhyphen{}ein übernommen.
\sphinxAtStartPar
Als Autoren des BSY Praktikums sind genannt: M. Thaler, J. Zeman.
\bigskip\hrule\bigskip
\section{2. Lernziele}
\label{\detokenize{P07_Prozesse_und_Threads/README:lernziele}}
\sphinxAtStartPar
In diesem Praktikum werden Sie sich mit Prozessen, Prozesshierarchien und Threads beschäftigen. Sie erhalten einen vertieften Einblick und Verständnis zur Erzeugung, Steuerung und Terminierung von Prozessen unter Unix/Linux und Sie werden die unterschiedlichen Eigenschaften von Prozessen und Threads kennenlernen.
\begin{itemize}
\item {}
\sphinxAtStartPar
Sie können Prozesse erzeugen und die Prozesshierarchie erklären
\item {}
\sphinxAtStartPar
Sie wissen was beim Erzeugen eines Prozesses vom Elternprozess vererbt wird
\item {}
\sphinxAtStartPar
Sie wissen wie man auf die Terminierung von Kindprozessen wartet
\item {}
\sphinxAtStartPar
Sie kennen die Unterschiede zwischen Prozessen und Threads
\end{itemize}
\bigskip\hrule\bigskip
\section{3. Aufgaben}
\label{\detokenize{P07_Prozesse_und_Threads/README:aufgaben}}
\sphinxAtStartPar
Das Betriebssystem bietet Programme um die aktuellen Prozesse und Threads darzustellen.
\sphinxAtStartPar
Die Werkzeuge kommen mit einer Vielzahl von Optionen für die Auswahl und Darstellung der Daten, z.B. ob nur Prozesse oder auch Threads aufgelistet werden sollen, und ob alle Prozesse oder nur die «eigenen» Prozesse ausgewählt werden sollen, etc.
\sphinxAtStartPar
Siehe die entsprechenden \sphinxcode{\sphinxupquote{man}} Pages für weitere Details.
\sphinxAtStartPar
Eine Auswahl, welche unter Umständen für die folgenden Aufgaben nützlich sind:
\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline
\sphinxAtStartPar
&
\sphinxAtStartPar
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ps}}
&
\sphinxAtStartPar
Auflisten der Prozess Zustände zum gegebenen Zeitpunkt.
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{pstree}}
&
\sphinxAtStartPar
Darstellung der gesamten Prozesshierarchie.
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{top}}
&
\sphinxAtStartPar
Wie \sphinxcode{\sphinxupquote{ps}}, aber die Darstellung wird in Zeitintervallen aufdatiert.
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{htop}}
&
\sphinxAtStartPar
Wie \sphinxcode{\sphinxupquote{top}}, aber zusätzlich dazu die Auslastung der CPU in einem System mit mehreren CPUs.
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{lscpu}}
&
\sphinxAtStartPar
Auflisten der CPUs.
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{cat}}/\sphinxcode{\sphinxupquote{proc}}/\sphinxcode{\sphinxupquote{cpuinfo}}
&
\sphinxAtStartPar
Ähnlich zu \sphinxcode{\sphinxupquote{lscpu}}, aber mit Zusatzinformationen wie enthaltene CPU Bugs (z.B. \sphinxcode{\sphinxupquote{bugs: cpu\_meltdown spectre\_v1 spect\sphinxhyphen{}re\_v2 spec\_store\_bypass l1tf mds swapgs itlb\_multihit}})
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
\bigskip\hrule\bigskip
\subsection{3.1 Aufgabe 1: Prozess mit fork() erzeugen}
\label{\detokenize{P07_Prozesse_und_Threads/README:aufgabe-1-prozess-mit-fork-erzeugen}}
\sphinxAtStartPar
\sphinxstylestrong{Ziele}
\begin{itemize}
\item {}
\sphinxAtStartPar
Verstehen, wie mit \sphinxcode{\sphinxupquote{fork()}} Prozesse erzeugt werden.
\item {}
\sphinxAtStartPar
Einfache Prozesshierarchien kennenlernen.
\item {}
\sphinxAtStartPar
Verstehen, wie ein Programm, das \sphinxcode{\sphinxupquote{fork()}} aufruft, durchlaufen wird.
\end{itemize}
\sphinxAtStartPar
\sphinxstylestrong{Aufgaben}
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Studieren Sie zuerst das Programm \sphinxcode{\sphinxupquote{ProcA1.c}} und beschrieben Sie was geschieht.
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Notieren Sie sich, was ausgegeben wird. Starten Sie das Programm und vergleichen Sie die Ausgabe mit ihren Notizen? Was ist gleich, was anders und wieso?
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\end{enumerate}
\bigskip\hrule\bigskip
\subsection{3.2 Aufgabe 2: Prozess mit fork() und exec(): Programm Image ersetzen}
\label{\detokenize{P07_Prozesse_und_Threads/README:aufgabe-2-prozess-mit-fork-und-exec-programm-image-ersetzen}}
\sphinxAtStartPar
\sphinxstylestrong{Ziele}
\begin{itemize}
\item {}
\sphinxAtStartPar
An einem Beispiel die Funktion \sphinxcode{\sphinxupquote{execl()}} kennenlernen.
\item {}
\sphinxAtStartPar
Verstehen, wie nach \sphinxcode{\sphinxupquote{fork()}} ein neues Programm gestartet wird.
\sphinxstylestrong{Aufgaben}
\end{itemize}
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Studieren Sie zuerst die Programme \sphinxcode{\sphinxupquote{ProcA2.c}} und \sphinxcode{\sphinxupquote{ChildProcA2.c}}.
\item {}
\sphinxAtStartPar
Starten Sie \sphinxcode{\sphinxupquote{ProcA2.e}} und vergleichen Sie die Ausgabe mit der Ausgabe unter Aufgabe 1. Diskutieren und erklären Sie was gleich ist und was anders.
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Benennen Sie \sphinxcode{\sphinxupquote{ChildProcA2.e}} auf \sphinxcode{\sphinxupquote{ChildProcA2.f}} um (Shell Befehl \sphinxcode{\sphinxupquote{mv}}) und überlegen Sie, was das Programm nun ausgibt. Starten Sie \sphinxcode{\sphinxupquote{ProcA2.e}} und vergleichen Sie Ihre Überlegungen mit der Programmausgabe.
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Nennen Sie das Kindprogramm wieder \sphinxcode{\sphinxupquote{ChildProcA2.e}} und geben Sie folgenden Befehl ein: \sphinxcode{\sphinxupquote{chmod \sphinxhyphen{}x ChildProcA2.e}}. Starten Sie wiederum \sphinxcode{\sphinxupquote{ProcA2.e}} und analysieren Sie die Ausgabe von \sphinxcode{\sphinxupquote{perror("...")}}. Wieso verwenden wir \sphinxcode{\sphinxupquote{perror()}}?
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\end{enumerate}
\bigskip\hrule\bigskip
\subsection{3.3 Aufgabe 3: Prozesshierarchie analysieren}
\label{\detokenize{P07_Prozesse_und_Threads/README:aufgabe-3-prozesshierarchie-analysieren}}
\sphinxAtStartPar
\sphinxstylestrong{Ziele}
\begin{itemize}
\item {}
\sphinxAtStartPar
Verstehen, was \sphinxcode{\sphinxupquote{fork()}} wirklich macht.
\item {}
\sphinxAtStartPar
Verstehen, was Prozesshierarchien sind.
\end{itemize}
\sphinxAtStartPar
\sphinxstylestrong{Aufgaben}
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Studieren Sie zuerst Programm \sphinxcode{\sphinxupquote{ProcA3.c}} und zeichnen Sie die entstehende Prozesshierarchie (Baum) von Hand auf. Starten Sie das Programm und verifizieren Sie ob Ihre Prozesshierarchie stimmt.
\item {}
\sphinxAtStartPar
Mit dem Befehl \sphinxcode{\sphinxupquote{ps f}} oder \sphinxcode{\sphinxupquote{pstree}} können Sie die Prozesshierarchie auf dem Bildschirm ausgeben. Damit die Ausgabe von \sphinxcode{\sphinxupquote{pstree}} übersichtlich ist, müssen Sie in dem Fenster, wo Sie das Programm \sphinxcode{\sphinxupquote{ProcA3.e}} starten, zuerst die PID der Shell erfragen, z.B. über \sphinxcode{\sphinxupquote{echo \$\$}}. Wenn Sie nun den Befehl \sphinxcode{\sphinxupquote{pstree \sphinxhyphen{}n \sphinxhyphen{}p pid\sphinxhyphen{}von\sphinxhyphen{}oben}} eingeben, wird nur die Prozesshierarchie ausgehend von der Bash Shell angezeigt: \sphinxcode{\sphinxupquote{\sphinxhyphen{}n}} sortiert die Prozesse numerisch, \sphinxcode{\sphinxupquote{\sphinxhyphen{}p}} zeigt für jeden Prozess die PID an.
\end{enumerate}
\sphinxAtStartPar
\sphinxstylestrong{Hinweis:} alle erzeugten Prozesse müssen arbeiten (d.h. nicht terminiert sein), damit die Darstellung gelingt. Wie wird das im gegebenen Programm erreicht?
\bigskip\hrule\bigskip
\subsection{3.4 Aufgabe 4: Zeitlicher Ablauf von Prozessen}
\label{\detokenize{P07_Prozesse_und_Threads/README:aufgabe-4-zeitlicher-ablauf-von-prozessen}}
\sphinxAtStartPar
\sphinxstylestrong{Ziele}
\begin{itemize}
\item {}
\sphinxAtStartPar
Verstehen, wie Kind\sphinxhyphen{} und Elternprozesse zeitlich ablaufen.
\end{itemize}
\sphinxAtStartPar
\sphinxstylestrong{Aufgaben}
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Studieren Sie Programm \sphinxcode{\sphinxupquote{ProcA4.c.}} Starten Sie nun mehrmals hintereinander das Programm \sphinxcode{\sphinxupquote{ProcA4.e}} und vergleichen Sie die jeweiligen Outputs (leiten Sie dazu auch die Ausgabe auf verschiedene Dateien um). Was schliessen Sie aus dem Resultat?
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\end{enumerate}
\sphinxAtStartPar
\sphinxstylestrong{Anmerkung:} Der Funktionsaufruf \sphinxcode{\sphinxupquote{selectCPU(0)}} erzwingt die Ausführung des Eltern\sphinxhyphen{} und Kindprozesses auf CPU 0 (siehe Modul \sphinxcode{\sphinxupquote{setCPU.c}}). Die Prozedur \sphinxcode{\sphinxupquote{justWork(HARD\_WORK)}} simuliert CPU\sphinxhyphen{}Load durch den Prozess (siehe Modul \sphinxcode{\sphinxupquote{workerUtils.c}}).
\bigskip\hrule\bigskip
\subsection{3.5 Aufgabe 5: Waisenkinder (Orphan Processes)}
\label{\detokenize{P07_Prozesse_und_Threads/README:aufgabe-5-waisenkinder-orphan-processes}}
\sphinxAtStartPar
\sphinxstylestrong{Ziele}
\begin{itemize}
\item {}
\sphinxAtStartPar
Verstehen, was mit verwaisten Kindern geschieht.
\end{itemize}
\sphinxAtStartPar
\sphinxstylestrong{Aufgaben}
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Analysieren Sie Programm \sphinxcode{\sphinxupquote{ProcA5.c}}: was läuft ab und welche Ausgabe erwarten Sie?
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Starten Sie \sphinxcode{\sphinxupquote{ProcA5.e}}: der Elternprozess terminiert: was geschieht mit dem Kind?
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Was geschieht, wenn der Kindprozess vor dem Elternprozess terminiert? Ändern Sie dazu im \sphinxcode{\sphinxupquote{sleep()}} Befehl die Zeit von 2 Sekunden auf 12 Sekunden und verfolgen Sie mit top das Verhalten der beiden Prozesse, speziell auch die Spalte S.
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\end{enumerate}
\bigskip\hrule\bigskip
\subsection{3.6 Aufgabe 6: Terminierte, halbtote Prozesse (Zombies)}
\label{\detokenize{P07_Prozesse_und_Threads/README:aufgabe-6-terminierte-halbtote-prozesse-zombies}}
\sphinxAtStartPar
\sphinxstylestrong{Ziele}
\begin{itemize}
\item {}
\sphinxAtStartPar
Verstehen, was ein Zombie ist.
\item {}
\sphinxAtStartPar
Eine Möglichkeit kennenlernen, um Zombies zu verhindern.
\end{itemize}
\sphinxAtStartPar
\sphinxstylestrong{Aufgaben}
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Analysieren Sie das Programm \sphinxcode{\sphinxupquote{ProcA6.c}}.
\item {}
\sphinxAtStartPar
Starten Sie das Script \sphinxcode{\sphinxupquote{mtop}} bzw. \sphinxcode{\sphinxupquote{mtop aaaa.e}}. Es stellt das Verhalten der Prozesse dynamisch dar.
\sphinxAtStartPar
\sphinxstylestrong{Hinweis:} \sphinxcode{\sphinxupquote{\textless{}defunct\textgreater{}}} = Zombie.
\item {}
\sphinxAtStartPar
Starten Sie \sphinxcode{\sphinxupquote{aaaa.e}} und verfolgen Sie im \sphinxcode{\sphinxupquote{mtop}}\sphinxhyphen{}Fenster was geschieht. Was beachten Sie?
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
In gewissen Fällen will man nicht auf die Terminierung eines Kindes mit \sphinxcode{\sphinxupquote{wait()}}, bzw. \sphinxcode{\sphinxupquote{waitpid()}} warten. Überlegen Sie sich, wie Sie in diesem Fall verhindern können, dass ein Kind zum Zombie wird.
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\end{enumerate}
\bigskip\hrule\bigskip
\subsection{3.7 Aufgabe 7: Auf Terminieren von Kindprozessen warten}
\label{\detokenize{P07_Prozesse_und_Threads/README:aufgabe-7-auf-terminieren-von-kindprozessen-warten}}
\sphinxAtStartPar
\sphinxstylestrong{Vorbemerkung:} Diese Aufgabe verwendet Funktionen welche erst in der Vorlesung über \sphinxstyleemphasis{Inter\sphinxhyphen{}Process\sphinxhyphen{}Communication (IPC)} im Detail behandelt werden.
\sphinxAtStartPar
Sie können diese Aufgabe bis dann aufsparen oder die verwendeten Funktionen selber via \sphinxcode{\sphinxupquote{man}} Pages im benötigten Umfang kennenlernen: \sphinxcode{\sphinxupquote{man 2 kill}} und \sphinxcode{\sphinxupquote{man 7 signal}}.
\sphinxAtStartPar
\sphinxstylestrong{Ziele}
\begin{itemize}
\item {}
\sphinxAtStartPar
Verstehen, wie Informationen zu Kindprozessen abgefragt werden können.
\item {}
\sphinxAtStartPar
Die Befehle \sphinxcode{\sphinxupquote{wait()}} und \sphinxcode{\sphinxupquote{waitpid()}} verwenden können.
\end{itemize}
\sphinxAtStartPar
\sphinxstylestrong{Aufgaben}
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Starten Sie das Programm \sphinxcode{\sphinxupquote{ProcA7.e}} und analysieren Sie wie die Ausgabe im Hauptprogramm zustande kommt und was im Kindprozess \sphinxcode{\sphinxupquote{ChildProcA7.c}} abläuft.
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Starten Sie \sphinxcode{\sphinxupquote{ProcA7.e}} und danach nochmals mit \sphinxcode{\sphinxupquote{1}} als erstem Argument. Dieser Argument Wert bewirkt, dass im Kindprozess ein ”Segmentation Error” erzeugt wird, also eine Speicherzugriffsverletzung. Welches Signal wird durch die Zugriffsverletzung an das Kind geschickt? Diese Information finden Sie im Manual mit \sphinxcode{\sphinxupquote{man 7 signal}}. Schalten Sie nun core dump ein (siehe README) und starten Sie \sphinxcode{\sphinxupquote{ProcA7.e 1}} erneut und analysieren Sie die Ausgabe.
\end{enumerate}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\sphinxAtStartPar
\sphinxstylestrong{Hinweis:} ein core Dump ist ein Abbild des Speichers z.B. zum Zeitpunkt, wenn das Programm abstürzt (wie oben mit der Speicher Zugriff Verletzung). Der Dump wird im File \sphinxstylestrong{core} abgelegt und kann mit dem \sphinxstylestrong{gdb} (GNU\sphinxhyphen{}Debugger) gelesen werden (siehe \sphinxcode{\sphinxupquote{README}}). Tippen Sie nach dem Starten des Command Line UI des \sphinxcode{\sphinxupquote{gdb where}} gefolgt von list ein, damit sie den Ort des Absturzes sehen. Mit \sphinxcode{\sphinxupquote{quit}} verlassen Sie \sphinxstylestrong{gdb} wieder.
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Wenn Sie \sphinxcode{\sphinxupquote{ProcA7.e 2}} starten, sendet das Kind das Signal 30 an sich selbst. Was geschieht?
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Wenn Sie \sphinxcode{\sphinxupquote{ProcA7.e 3}} starten, sendet ProcA7.e das Signal SIGABRT (abort) an das Kind: was geschieht in diesem Fall?
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Mit \sphinxcode{\sphinxupquote{ProcA7.e 4}} wird das Kind gestartet und terminiert nach 5 Sekunden. Analysieren Sie wie in ProcA7.e der Lauf\sphinxhyphen{} bzw. Exit\sphinxhyphen{}Zustand des Kindes abgefragt wird (siehe dazu auch \sphinxcode{\sphinxupquote{man 3 exit}}).
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\end{enumerate}
\bigskip\hrule\bigskip
\subsection{3.8 Aufgabe 8: Kindprozess als Kopie des Elternprozesses}
\label{\detokenize{P07_Prozesse_und_Threads/README:aufgabe-8-kindprozess-als-kopie-des-elternprozesses}}
\sphinxAtStartPar
\sphinxstylestrong{Ziele}
\begin{itemize}
\item {}
\sphinxAtStartPar
Verstehen, wie Prozessräume vererbt werden.
\item {}
\sphinxAtStartPar
Unterschiede zwischen dem Prozessraum von Eltern und Kindern erfahren.
\end{itemize}
\sphinxAtStartPar
\sphinxstylestrong{Aufgaben}
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Analysieren Sie Programm \sphinxcode{\sphinxupquote{ProcA8\_1.c}}: was gibt das Programm aus?
\begin{itemize}
\item {}
\sphinxAtStartPar
Starten Sie \sphinxcode{\sphinxupquote{ProcA8\_1.e }}und überprüfen Sie Ihre Überlegungen.
\item {}
\sphinxAtStartPar
Waren Ihre Überlegungen richtig? Falls nicht, was könnten Sie falsch überlegt haben?
\end{itemize}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Analysieren Sie Programm \sphinxcode{\sphinxupquote{ProcA8\_2.c}}: was gibt das Programm aus?
\begin{itemize}
\item {}
\sphinxAtStartPar
Starten Sie \sphinxcode{\sphinxupquote{ProcA8\_2.e}} und überprüfen Sie Ihre Überlegungen.
\item {}
\sphinxAtStartPar
Waren Ihre Überlegungen richtig? Falls nicht, was könnten Sie falsch gemacht haben?
\item {}
\sphinxAtStartPar
Kind und Eltern werden in verschiedener Reihenfolge ausgeführt: ist ein Unterschied ausser der Reihenfolge festzustellen?
\end{itemize}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Analysieren Sie Programm \sphinxcode{\sphinxupquote{ProcA8\_3.c}} und Überlegen Sie, was in die Datei \sphinxcode{\sphinxupquote{AnyOutPut.txt}} geschrieben wird, wer schreibt alles in diese Datei (sie wird ja vor \sphinxcode{\sphinxupquote{fork()}} geöffnet) und wieso ist das so?
\begin{itemize}
\item {}
\sphinxAtStartPar
Starten Sie \sphinxcode{\sphinxupquote{ProcA8\_3.e}} und überprüfen Sie Ihre Überlegungen.
\item {}
\sphinxAtStartPar
Waren Ihre Überlegungen richtig? Falls nicht, wieso nicht?
\end{itemize}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\end{enumerate}
\bigskip\hrule\bigskip
\subsection{3.9 Aufgabe 9: Unterschied von Threads gegenüber Prozessen}
\label{\detokenize{P07_Prozesse_und_Threads/README:aufgabe-9-unterschied-von-threads-gegenuber-prozessen}}
\sphinxAtStartPar
\sphinxstylestrong{Ziele}
\begin{itemize}
\item {}
\sphinxAtStartPar
Den Unterschied zwischen Thread und Prozess kennenlernen.
\item {}
\sphinxAtStartPar
Problemstellungen um Threads kennenlernen.
\item {}
\sphinxAtStartPar
Die \sphinxcode{\sphinxupquote{pthread}}\sphinxhyphen{}Implementation kennen lernen.
\end{itemize}
\sphinxAtStartPar
\sphinxstylestrong{Aufgaben}
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Studieren Sie Programm \sphinxcode{\sphinxupquote{ProcA9.c}} und überlegen Sie, wie die Programmausgabe aussieht. Vergleichen Sie Ihre Überlegungen mit denjenigen aus Aufgabe 8.2 b) (\sphinxcode{\sphinxupquote{Pro\sphinxhyphen{}cA8\_2.e}}).
\begin{itemize}
\item {}
\sphinxAtStartPar
Starten Sie \sphinxcode{\sphinxupquote{ProcA9.e}} und vergleichen das Resultat mit Ihren Überlegungen.
\item {}
\sphinxAtStartPar
Was ist anders als bei \sphinxcode{\sphinxupquote{ProcA8\_2.e}}?
\end{itemize}
\end{enumerate}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Setzen Sie in der Thread\sphinxhyphen{}Routine vor dem Befehl \sphinxcode{\sphinxupquote{pthread\_exit()}} eine unendliche Schleife ein, z.B. \sphinxcode{\sphinxupquote{while(1) \{ \}}}; .
\begin{itemize}
\item {}
\sphinxAtStartPar
Starten Sie das Programm und beobachten Sie das Verhalten mit \sphinxcode{\sphinxupquote{top}}. Was beobachten Sie und was schliessen Sie daraus?
\sphinxAtStartPar
\sphinxstylestrong{Hinweis:} wenn Sie in \sphinxcode{\sphinxupquote{top}} den Buchstaben H eingeben, werden die Threads einzeln dargestellt.
\item {}
\sphinxAtStartPar
Kommentieren Sie im Hauptprogram die beiden \sphinxcode{\sphinxupquote{pthread\_join()}} Aufrufe aus und starten Sie das Programm. Was geschieht? Erklären Sie das Verhalten.
\end{itemize}
\end{enumerate}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\bigskip\hrule\bigskip
\subsection{3.10 Aufgabe 10 (optional):}
\label{\detokenize{P07_Prozesse_und_Threads/README:aufgabe-10-optional}}
\subsubsection{3.10.1 Übersicht}
\label{\detokenize{P07_Prozesse_und_Threads/README:id1}}
\sphinxAtStartPar
Dieser Teil des Praktikums behandelt spezielle Prozesse: die Dämon Prozesse («daemon pro\sphinxhyphen{}cesses»). Es ist gedacht als Zusatz zum Basis Praktikum über Prozesse und Threads.
\sphinxAtStartPar
Auch dieser Teil ist ein «Analyse»\sphinxhyphen{} und «Experimentier»\sphinxhyphen{}Praktikum.
\bigskip\hrule\bigskip
\paragraph{3.10.1.1 Nachweis}
\label{\detokenize{P07_Prozesse_und_Threads/README:id2}}
\sphinxAtStartPar
Dieses Praktikum ist eine leicht abgewandelte Variante des ProcThreads Praktikum des Moduls BSY, angepasst an die Verhältnisse des SNP Moduls. Die Beispiele und Beschreibungen wurden, wo möglich, eins\sphinxhyphen{}zu\sphinxhyphen{}ein übernommen.
\sphinxAtStartPar
Als Autoren des BSY Praktikums sind genannt: M. Thaler, J. Zeman.
\bigskip\hrule\bigskip
\subsubsection{3.10.2 Lernziele}
\label{\detokenize{P07_Prozesse_und_Threads/README:id3}}
\sphinxAtStartPar
In diesem Praktikum werden Sie sich mit Dämon Prozessen beschäftigen.
\begin{itemize}
\item {}
\sphinxAtStartPar
Sie können die Problemstellung der Dämon Prozesse erklären
\item {}
\sphinxAtStartPar
Sie können einen Dämon Prozess kreieren
\item {}
\sphinxAtStartPar
Sie können aus dem Dämon Prozess mit der Umgebung kommunizieren
\item {}
\end{itemize}
\bigskip\hrule\bigskip
\subsubsection{3.10.3 Aufgabe: Dämon Prozesse}
\label{\detokenize{P07_Prozesse_und_Threads/README:aufgabe-damon-prozesse}}
\sphinxAtStartPar
\sphinxstylestrong{Ziele}
\begin{itemize}
\item {}
\sphinxAtStartPar
Problemstellungen um Daemons kennenlernen:
\begin{itemize}
\item {}
\sphinxAtStartPar
wie wird ein Prozess zum Daemon?
\item {}
\sphinxAtStartPar
wie erreicht man, dass nur ein Daemon vom gleichen Typ aktiv ist?
\item {}
\sphinxAtStartPar
wie teilt sich ein Daemon seiner Umwelt mit?
\item {}
\sphinxAtStartPar
wo “lebt” ein Daemon?
\end{itemize}
\end{itemize}
\sphinxAtStartPar
\sphinxstylestrong{Einleitung}
\sphinxAtStartPar
Für diese Aufgabe haben wir einen Daemon implementiert: \sphinxstylestrong{MrTimeDaemon} gibt auf Anfrage die Systemzeit Ihres Rechners bekannt. Abfragen können Sie diese Zeit mit dem Programm \sphinxcode{\sphinxupquote{WhatsTheTimeMr localhost}}. Die Kommunikation zwischen den beiden Prozessen haben wir mit TCP/IP Sockets implementiert. Weitere Infos zum Daemon finden Sie nach den Aufgaben.
\sphinxAtStartPar
Im Abschnitt 4 finden Sie Zusatzinformationen über diese Implementation eines Dämon Prozesses plus weiterführende Informationen.
\sphinxAtStartPar
\sphinxstylestrong{Aufgaben}
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Für die folgende Aufgabe benötigen Sie mindestens zwei Fenster (Kommandozeilen\sphinxhyphen{}Konsolen). Übersetzen Sie die Programme mit \sphinxcode{\sphinxupquote{make}} und starten Sie das Programm \sphinxstylestrong{PlapperMaul} in einem der Fenster. Das Programm schreibt (ca.) alle 0.5 Sekunden \sphinxstyleemphasis{Hallo, ich bins…. Pidi} plus seine Prozess\sphinxhyphen{}ID auf den Bildschirm. Mit dem Shell Befehl \sphinxcode{\sphinxupquote{ps}} können Sie Ihre aktiven Prozesse auflisten, auch \sphinxstylestrong{PlapperMaul}. Überlegen Sie sich zuerst, was mit \sphinxstylestrong{PlapperMaul} geschieht, wenn Sie das Fenster schliessen: läuft \sphinxstylestrong{PlapperMaul} weiter? Was geschieht mit \sphinxstylestrong{PlapperMaul} wenn Sie sich ausloggen und wieder einloggen? Testen Sie Ihre Überlegungen, in dem Sie die entsprechenden Aktionen durchführen. Stimmen Ihre Überlegungen?
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Starten Sie nun das Programm bzw. den Daemon \sphinxstylestrong{MrTimeDaemon}. Stellen Sie die gleichen Überlegungen an wie mit \sphinxstylestrong{PlapperMaul} und testen Sie wiederum, ob Ihre Überlegungen stimmen. Ob \sphinxstylestrong{MrTimeDaemon} noch läuft können Sie feststellen, indem Sie die Zeit abfragen oder den Befehl \sphinxcode{\sphinxupquote{ps ajx | grep MrTimeDaemon}} eingeben: was fällt Ihnen am Output auf? Was schliessen Sie aus Ihren Beobachtungen?
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Starten Sie \sphinxstylestrong{MrTimeDaemon} erneut, was geschieht?
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Stoppen Sie nun \sphinxstylestrong{MrTimeDaemon} mit \sphinxcode{\sphinxupquote{killall MrTimeDaemon}}.
\item {}
\sphinxAtStartPar
Starten Sie \sphinxstylestrong{MrTimeDaemon} und fragen Sie mit \sphinxcode{\sphinxupquote{WhatsTheTimeMr localhost}} oder mit \sphinxcode{\sphinxupquote{WhatsTheTimeMr 127.0.0.1}} die aktuelle Zeit auf Ihrem Rechner ab.
\sphinxAtStartPar
\sphinxstylestrong{Optional:}
Fragen Sie die Zeit bei einem Ihrer Kollegen ab. Dazu muss beim Server (dort wo \sphinxstylestrong{MrTimeDaemon} läuft) ev. die Firewall angepasst werden. Folgende Befehle müssen dazu mit \sphinxstylestrong{root\sphinxhyphen{}Privilegien} ausgeführt werden:
\begin{sphinxVerbatim}[commandchars=\\\{\}]
iptables\PYGZhy{}save \PYGZgt{} myTables.txt \PYG{c+c1}{\PYGZsh{} sichert die aktuelle Firewall}
iptables \PYGZhy{}I INPUT \PYG{l+m}{1} \PYGZhy{}p tcp \PYGZhy{}\PYGZhy{}dport \PYG{l+m}{65534} \PYGZhy{}j ACCEPT
iptables \PYGZhy{}I OUTPUT \PYG{l+m}{2} \PYGZhy{}p tcp \PYGZhy{}\PYGZhy{}sport \PYG{l+m}{65534} \PYGZhy{}j ACCEPT
\end{sphinxVerbatim}
\sphinxAtStartPar
Nun sollten Sie über die IP\sphinxhyphen{}Nummer oder über den Rechner\sphinxhyphen{}Namen auf den \sphinxstylestrong{TimeServer} mit \sphinxcode{\sphinxupquote{WhatsTheTimeMr}} zugreifen können.
Die Firewall können Sie mit folgendem Befehl wiederherstellen:
\begin{sphinxVerbatim}[commandchars=\\\{\}]
iptables\PYGZhy{}restore myTables.txt
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Studieren Sie \sphinxcode{\sphinxupquote{MrTimeDaemon.c}}, \sphinxcode{\sphinxupquote{Daemonizer.c}} und \sphinxcode{\sphinxupquote{TimeDaemon.c}} und analysieren Sie, wie die Daemonisierung abläuft. Entfernen Sie die Kommentare im Macro \sphinxcode{\sphinxupquote{Out\sphinxhyphen{}PutPIDs}} am Anfang des Moduls \sphinxcode{\sphinxupquote{Daemonizer.c}}. Übersetzen Sie die Programme mit make und starten Sie \sphinxcode{\sphinxupquote{MrTimeDaemon}} erneut. Analysieren Sie die Ausgabe, was fällt Ihnen auf? Notieren Sie alle für die vollständige Daemonisierung notwendigen Schritte.
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\item {}
\sphinxAtStartPar
Setzen Sie beim Aufruf von \sphinxcode{\sphinxupquote{Daemonizer()}} in \sphinxcode{\sphinxupquote{MrTimeDaemon.c}} anstelle von \sphinxcode{\sphinxupquote{lock\sphinxhyphen{}FilePath}} den Null\sphinxhyphen{}Zeiger \sphinxcode{\sphinxupquote{NULL}} ein. Damit wird keine lock\sphinxhyphen{}Datei erzeugt. Übersetzen Sie die Programme und starten Sie erneut \sphinxcode{\sphinxupquote{MrTimedaemon}}. Was geschieht bzw. wie können Sie feststellen, was geschehen ist?
\sphinxAtStartPar
\sphinxstylestrong{Hinweis:} lesen Sie das log\sphinxhyphen{}File: \sphinxcode{\sphinxupquote{/tmp/timeDaemon.log.}}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\end{sphinxVerbatim}
\sphinxAtStartPar
Wenn Sie noch Zeit und Lust haben: messen Sie die Zeit, zwischen Start der Zeitanfrage und Eintreffen der Antwort. Dazu müssen Sie die Datei \sphinxcode{\sphinxupquote{WhatsTheTimeMr.c}} entsprechend anpassen.
\end{enumerate}
\bigskip\hrule\bigskip
\subsubsection{3.10.4 Zusatzinformationen}
\label{\detokenize{P07_Prozesse_und_Threads/README:zusatzinformationen}}
\bigskip\hrule\bigskip
\paragraph{3.10.4.1 Diese Implementation}
\label{\detokenize{P07_Prozesse_und_Threads/README:diese-implementation}}
\sphinxAtStartPar
Dieser Daemon besteht aus den 3 Komponenten.
\sphinxAtStartPar
\sphinxstylestrong{Hauptprogramm: MrTimeDaemon.c}
\sphinxAtStartPar
Hier werden die Pfade für die lock\sphinxhyphen{}Datei, die log\sphinxhyphen{}Datei und der ”Aufenthaltsort” des Daemons gesetzt. Die lock\sphinxhyphen{}Datei wird benötigt um sicherzustellen, dass der Daemon nur einmal gestartet werden kann. In die lock\sphinxhyphen{}Datei schreibt der Daemon z.B. seine PID und sperrt sie dann für Schreiben. Wird der Daemon ein zweites Mal gestartet und will seine PID in diese Datei schreiben, erhält er eine Fehlermeldung und terminiert (es soll ja nur ein Daemon arbeiten). Terminiert der Daemon, wird die Datei automatisch freigegeben. Weil Daemonen sämtliche Kontakte mit ihrer Umwelt im Normalfall abbrechen und auch kein Kontrollterminal besitzen, ist es sinnvoll, zumindest die Ausgabe des Daemons in eine log\sphinxhyphen{}Datei umzuleiten. Dazu stehen einige Systemfunktionen für Logging zur Verfügung. Der Einfachheit halber haben wir hier eine normale Datei im Verzeichnis \sphinxcode{\sphinxupquote{/tmp}} gewählt.
\begin{quote}
\sphinxAtStartPar
\sphinxstylestrong{Anmerkung:} die Wahl des Verzeichnisses \sphinxcode{\sphinxupquote{/tmp}} für die lock\sphinxhyphen{} und log\sphinxhyphen{}Datei ist für den normalen Betrieb problematisch, weil der Inhalt dieses Verzeichnisses jederzeit gelöscht werden kann, bzw. darf. Wir haben dieses Verzeichnis gewählt, weil wir die beiden Dateien nur für die kurze Zeit des Praktikums benötigen.
\end{quote}
\sphinxAtStartPar
Der Daemon erbt sein Arbeitsverzeichnis vom Elternprozesse, er sollte deshalb in ein festes Verzeichnis des Systems wechseln, um zu verhindern, dass er sich in einem montierten (gemounteten) Verzeichnis aufhält, das dann beim Herunterfahren nicht demontiert werden könnte (wir haben hier wiederum \sphinxcode{\sphinxupquote{/tmp}} gewählt).
\sphinxAtStartPar
\sphinxstylestrong{Daemonizer: Daemonizer.c}
\sphinxAtStartPar
Der Daemonizer macht aus dem aktuellen Prozess einen Daemon. Z.B. sollte er Signale (eine Art Softwareinterrupts) ignorieren: wenn Sie die CTRL\sphinxhyphen{}C Taste während dem Ausführen eines Vordergrundprozess drücken, erhält dieser vom Betriebssystem das Signal SIGINT und bricht seine Ausführung ab. Weiter sollte er die Dateierzeugungsmaske auf 0 setzen (Dateizugriffsrechte), damit kann er beim Öffnen von Dateien beliebige Zugriffsrechte verlangen (die Dateierzeugungsmaske erbt er vom Elternprozess). Am Schluss startet der Daemonizer das eigentliche Daemonprogramm: TimeDaemon.e.
\sphinxAtStartPar
\sphinxstylestrong{Daemonprogramm: TimeDaemon.c}
\sphinxAtStartPar
Das Daemonprogramm wartet in einer unendlichen Schleife auf Anfragen zur Zeit und schickt die Antwort an den Absender zurück. Die Datenkommunikation ist, wie schon erwähnt, mit Sockets implementiert, auf die wir aber im Rahmen dieses Praktikums nicht weiter eingehen wollen (wir stellen lediglich Hilfsfunktionen zur Verfügung).
\bigskip\hrule\bigskip
\paragraph{3.10.4.2 Zusatzinformation zu Dämon Prozessen}
\label{\detokenize{P07_Prozesse_und_Threads/README:zusatzinformation-zu-damon-prozessen}}
\sphinxAtStartPar
Dämonen oder englisch Daemons sind eine spezielle Art von Prozessen, die vollständig unabhängig arbeiten, d.h. ohne direkte Interaktion mit dem Anwender. Dämonen sind Hintergrundprozesse und terminieren i.A. nur, wenn das System heruntergefahren wird oder abstürzt. Dämonen erledigen meist Aufgaben, die periodisch ausgeführt werden müssen, z.B. Überwachung von Systemkomponenten, abfragen, ob neue Mails angekommen sind, etc.
\sphinxAtStartPar
Ein typisches Beispiel unter Unix ist der Printer Daemon \sphinxcode{\sphinxupquote{lpd}}, der periodisch nachschaut, ob ein Anwender eine Datei zum Ausdrucken hinterlegt hat. Wenn ja, schickt er die Datei auf den Drucker.
\sphinxAtStartPar
Hier wird eine weitere Eigenschaft von Daemons ersichtlich: meist kann nur ein Dämon pro Aufgabe aktiv sein: stellen Sie sich vor, was passiert, wenn zwei Druckerdämonen gleichzeitig arbeiten. Andererseits muss aber auch dafür gesorgt werden, dass ein Dämon wieder gestartet wird, falls er stirbt.
\bigskip\hrule\bigskip
\bigskip\hrule\bigskip
\section{4. Bewertung}
\label{\detokenize{P07_Prozesse_und_Threads/README:bewertung}}
\sphinxAtStartPar
Die gegebenenfalls gestellten Theorieaufgaben und der funktionierende Programmcode müssen der Praktikumsbetreuung gezeigt werden. Die Lösungen müssen mündlich erklärt werden.
\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
\hline
\sphinxstyletheadfamily
\sphinxAtStartPar
Aufgabe
&\sphinxstyletheadfamily
\sphinxAtStartPar
Kriterium
&\sphinxstyletheadfamily
\sphinxAtStartPar
Punkte
\\
\hline
\sphinxAtStartPar
&
\sphinxAtStartPar
Sie können die gestellten Fragen erklären.
&
\sphinxAtStartPar
\\
\hline
\sphinxAtStartPar
1
&
\sphinxAtStartPar
Prozess mit \sphinxcode{\sphinxupquote{fork()}} erzeugen
&
\sphinxAtStartPar
0.5
\\
\hline
\sphinxAtStartPar
2
&
\sphinxAtStartPar
Prozess mit \sphinxcode{\sphinxupquote{fork()}} und \sphinxcode{\sphinxupquote{exec()}}: Programm Image ersetzen
&
\sphinxAtStartPar
0.5
\\
\hline
\sphinxAtStartPar
3
&
\sphinxAtStartPar
Prozesshierarchie analysieren
&
\sphinxAtStartPar
0.5
\\
\hline
\sphinxAtStartPar
4
&
\sphinxAtStartPar
Zeitlicher Ablauf von Prozessen
&
\sphinxAtStartPar
0.5
\\
\hline
\sphinxAtStartPar
5
&
\sphinxAtStartPar
Waisenkinder (Orphan Processes)
&
\sphinxAtStartPar
0.5
\\
\hline
\sphinxAtStartPar
6
&
\sphinxAtStartPar
Terminierte, halbtote Prozesse (Zombies)
&
\sphinxAtStartPar
0.5
\\
\hline
\sphinxAtStartPar
7
&
\sphinxAtStartPar
Auf Terminieren von Kindprozessen warten
&
\sphinxAtStartPar
0.5
\\
\hline
\sphinxAtStartPar
8
&
\sphinxAtStartPar
Kindprozess als Kopie des Elternprozesses
&
\sphinxAtStartPar
0.5
\\
\hline
\sphinxAtStartPar
9
&
\sphinxAtStartPar
Unterschied von Threads gegenüber Prozessen
&
\sphinxAtStartPar
0.5
\\
\hline
\sphinxAtStartPar
10
&
\sphinxAtStartPar
Dämon Prozesse
&
\sphinxAtStartPar
(4)
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
\bigskip\hrule\bigskip
\sphinxAtStartPar
Version: 11.01.2022
\chapter{08 \sphinxhyphen{} Synchronisationsprobleme}
\label{\detokenize{P08_Sync/README:synchronisationsprobleme}}\label{\detokenize{P08_Sync/README::doc}}
\bigskip\hrule\bigskip
\section{1. Übersicht}
\label{\detokenize{P08_Sync/README:ubersicht}}
\sphinxAtStartPar
\sphinxincludegraphics{{synchronisationsprobleme}.png}
\sphinxAtStartPar
\sphinxhref{https://commons.wikimedia.org/wiki/File:Velgast-suedbahn.jpg}{Quelle: https://commons.wikimedia.org/wiki/File:Velgast\sphinxhyphen{}suedbahn.jpg}
\sphinxAtStartPar
In diesem Praktikum lernen sie zuerst am Beispiel eines Kaffee\sphinxhyphen{}Automaten verschiedene grundlegende Synchronisationsprobleme kennen und mit Hilfe von Locks (Mutexes) und Semaphoren lösen:
\begin{itemize}
\item {}
\sphinxAtStartPar
gegenseitiger Ausschluss mit einem Lock
\item {}
\sphinxAtStartPar
Erzwingen einer einfachen Reihenfolge
\item {}
\sphinxAtStartPar
Erzwingen einer erweiterten Reihenfolge
\end{itemize}
\sphinxAtStartPar
Im zweiten Teil werden sie auf Basis dieser Grundlagen ein komplexeres Synchronisationsproblem bearbeiten, diesmal am Beispiel von Bank Transaktionen.
\bigskip\hrule\bigskip
\subsection{1.1 Nachweis}
\label{\detokenize{P08_Sync/README:nachweis}}
\sphinxAtStartPar
Dieses Praktikum ist eine leicht abgewandelte Variante des Sync Praktikum des Moduls BSY, angepasst an die Verhältnisse des SNP Moduls. Die Beispiele und Beschreibungen wurden, wo möglich, eins\sphinxhyphen{}zu\sphinxhyphen{}ein übernommen.
\sphinxAtStartPar
Als Autor des BSY Praktikums ist genannt: M. Thaler.
\bigskip\hrule\bigskip
\section{2. Lernziele}
\label{\detokenize{P08_Sync/README:lernziele}}
\sphinxAtStartPar
In diesem Praktikum werden sie Synchronisationsprobleme lösen
\begin{itemize}
\item {}
\sphinxAtStartPar
Sie wissen wie man systematisch Synchronisationsprobleme analysiert
\item {}
\sphinxAtStartPar
Sie wissen wann ein potentieller Deadlock entstehen kann
\item {}
\sphinxAtStartPar
Sie können Mutex mit Threads anwenden
\item {}
\sphinxAtStartPar
Sie können Semaphoren mit Prozessen anwenden
\end{itemize}
\bigskip\hrule\bigskip
\section{3. Einführung}
\label{\detokenize{P08_Sync/README:einfuhrung}}
\sphinxAtStartPar
Das Lösen von Synchronisationsproblemen ist oft nicht einfach, weil Prozesse bzw. Threads gleichzeitig ablaufen, ihre Aktivitäten jedoch nach Vorgaben koordiniert werden müssen: man verliert schnell den Überblick. Systematisches Vorgehen mit Aufzeichnen der Abläufe und Synchronisationsbedingungen bewährt ich sich in diesem Fall.
\bigskip\hrule\bigskip
\subsection{3.1 Wie löst man Synchronisationsprobleme?}
\label{\detokenize{P08_Sync/README:wie-lost-man-synchronisationsprobleme}}
\sphinxAtStartPar
Gehen sie beim Lösen von Synchronisationsproblemen in folgenden Schritten vor:
\begin{itemize}
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Schritt 1: Prozesse (Threads) der Problemstellung identifizieren.}\\
Prozesse sind die Aktivitäten, die gleichzeitig ausgeführt werden. In diesem Sinne sind sie eigenständige Ausführungs\sphinxhyphen{}Einheiten, deren zeitliches Verhalten synchronisiert werden muss.
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Schritt 2: Ausführungsschritte der einzelnen Prozesse (Threads) ermitteln.}\\
Erstellen sie eine Liste mit einer Spalte für jeden Prozess. Notieren sie für jeden Prozess stichwortartig die wesentlichen Aktionen in der gewünschten zeitlichen Reihenfolge. Tragen sie noch keine Synchronisationsoperationen ein, sondern Texte wie warten auf Geld, etc. Übertragen sie anschliessend die Liste in einen Ablaufgraphen (Siehe Beispiel in Abbildung 1).
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Schritt 3: Synchronisationsbedingungen ermitteln.}\\
Eine Synchronisationsbedingung ist eine zeitliche Beziehung (Abhängigkeit) zwischen Aktionen verschiedener Prozesse, die für das korrekte Arbeiten erforderlich ist. Zeichnen sie diese Beziehungen mit Pfeilen in den Ablaufgraphen aus Schritt 2 ein (Siehe Abbildung 1).
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Schritt 4: Benötigte Semaphore definieren.}\\
Für jede Synchronisationsbedingung wird ein eigener Semaphor benötigt. Notieren sie für jeden Semaphor einen Namen und den Wert, mit dem er initialisiert werden muss.
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Schritt 5: Prozesse mit Semaphore Operationen ergänzen.}\\
Erweitern sie nun alle Prozesse aus Schritt 2 mit den notwendigen Semaphore Operati\sphinxhyphen{}onen (Siehe Pseudocode in Abbildung 1).
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Schritt 6: Implementation.}\\
Implementieren und testen sie das vollständige Programm.
\end{itemize}
\sphinxAtStartPar
\sphinxincludegraphics{{coffee_customer}.png}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{coin} \PYG{o}{=} \PYG{n}{sem\PYGZus{}open}\PYG{p}{(}\PYG{p}{.}\PYG{p}{.}\PYG{p}{.}\PYG{p}{,}\PYG{l+m+mi}{0}\PYG{p}{)}\PYG{p}{;}
\PYG{n}{coffee} \PYG{o}{=} \PYG{n}{sem\PYGZus{}open}\PYG{p}{(}\PYG{p}{.}\PYG{p}{.}\PYG{p}{.}\PYG{p}{,}\PYG{l+m+mi}{0}\PYG{p}{)}\PYG{p}{;}
\end{sphinxVerbatim}
\sphinxAtStartPar
Ablaufgraph und Pseudocode für 2 Prozesse und zwei Semaphore\\
\sphinxincludegraphics{{sequence_graph}.png}
\section{4. Der Kaffee\sphinxhyphen{}Automat}
\label{\detokenize{P08_Sync/README:der-kaffee-automat}}
\sphinxAtStartPar
Als Beispiel verwenden wir einen Automaten, der Kaffee verkauft. Der Kunde muss zum Kauf eines Kaffees zuerst eine bzw. mehrere Münzen einwerfen und anschliessend den gewünsch\sphinxhyphen{}ten Kaffee wählen. Der Automat gibt dann das entsprechende Getränk aus.
\sphinxAtStartPar
Im ersten Beispiel werden der Automat und die Kunden mit Threads modelliert und tauschen Daten über gemeinsame Speichervariablen aus. Im zweiten und dritten Beispiel werden der Automat und die Kunden mit Prozessen modelliert, dabei wird der Ablauf mit Hilfe von Sema\sphinxhyphen{}phoren gesteuert bzw. erzwungen.
\sphinxAtStartPar
\sphinxstylestrong{Hinweis:} die Programme zu den folgenden Aufgaben können alle mit \sphinxstylestrong{startApp.e} gestartet werden. Dieses Programm startet und stoppt Threads und Prozesse, alloziert und dealloziert die Ressourcen (Mutexes, Semaphore).
\bigskip\hrule\bigskip
\subsection{4.1 Aufgabe: Mutual Exclusion}
\label{\detokenize{P08_Sync/README:aufgabe-mutual-exclusion}}
\sphinxAtStartPar
Greifen mehrere Threads (oder Prozesse) auf gemeinsame Daten zu, können sogenannte Race Conditions entstehen. Das Resultat ist in diesem Fall abhängig von der Reihenfolge, in der die Threads (Prozesse) ausgeführt werden.
\sphinxAtStartPar
Im vorliegenden Beispiel wirft der Kunde eine 1 Euro Münze ein und drückt anschliessend auf eine von zwei Kaffeewahltasten. Dabei wird die Anzahl Münzen (\sphinxstyleemphasis{coinCount}) und die gewählte Kaffeesorte (\sphinxstyleemphasis{selCount1}, \sphinxstyleemphasis{selCount2}) inkrementiert. Diese Variablen sind in der Datenstruktur \sphinxstyleemphasis{cData} abgelegt, auf die gemeinsam Kaffee\sphinxhyphen{}Automat und Kunden zugreifen können. Der Auto\sphinxhyphen{}mat überprüft, ob die Anzahl Münzen und die Anzahl der Kaffeewahlen gleich gross sind, falls nicht, wird eine Fehlermeldung ausgegeben und alle Zähler auf \sphinxstyleemphasis{Null} gesetzt.
\subsubsection{Aufgaben}
\label{\detokenize{P08_Sync/README:aufgaben}}\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Übersetzen sie die Programme im Verzeichnis \sphinxstyleemphasis{mutex} mit \sphinxstyleemphasis{make} und starten sie den Kaffee\sphinxhyphen{}Automaten mit \sphinxstylestrong{startApp.e} mehrmals hintereinander.
Analysieren sie die Datenwerte in den Fehlermeldungen, beschreiben sie was die Gründe dafür sind bzw. sein können.
\item {}
\sphinxAtStartPar
Schützen sie nun den Zugriff auf die gemeinsamen Daten mit einem Mutex so, dass alle Threads eine konsistente Sicht der Daten haben.
Wir haben für sie einen Mutex vorbereitet: die Datenstruktur \sphinxstyleemphasis{cData} enthält die Mutex\sphinxhyphen{}Variable \sphinxstyleemphasis{mutex}, die in \sphinxstylestrong{startApp.c} initialisiert wird. Die Funktionen für das Schliessen und das Öffnen des Mutex (Locks) aus der \sphinxstyleemphasis{pthread} Bibliothek sind:
\end{enumerate}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{pthread} \PYG{n}{mutex} \PYG{n}{lock}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{p}{(}\PYG{n}{cD}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{lock}\PYG{p}{)}\PYG{p}{)}\PYG{p}{;}
\end{sphinxVerbatim}
\begin{itemize}
\item {}
\sphinxAtStartPar
und
\end{itemize}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{pthread} \PYG{n}{mutex} \PYG{n}{unlock}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{p}{(}\PYG{n}{cD}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{lock}\PYG{p}{)}\PYG{p}{)}\PYG{p}{;}
\end{sphinxVerbatim}
\sphinxAtStartPar
Überprüfen sie, ob der Kaffee\sphinxhyphen{}Automat nun keine Fehlermeldungen mehr ausgibt. Erhö\sphinxhyphen{}hen sie dazu auch die Anzahl Kunden \sphinxstyleemphasis{CUSTOMERS} in \sphinxstylestrong{commonDefs.h}, z.B. auf 10.
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Im Thread des Kaffee\sphinxhyphen{}Automaten wird an verschiedenen Orten mehrmals auf die gemeinsamen Daten in \sphinxstyleemphasis{cD} zugegriffen. Wenn sie die gemeinsamen Daten in lokale Variablen kopieren und dann nur noch auf diese lokalen Variablen zugreifen würden, könn\sphinxhyphen{}ten sie dann auf die Synchronisation mit dem Mutex verzichten?
\item {}
\sphinxAtStartPar
Wie oft kann ein einzelner Kunde einen Kaffee beziehen, bis der nächste Kunde an die Reihe kommt? Hier reicht eine qualitative Aussage.
\end{enumerate}
\subsection{4.2 Aufgabe: Einfache Reihenfolge}
\label{\detokenize{P08_Sync/README:aufgabe-einfache-reihenfolge}}
\sphinxAtStartPar
Wie sie im ersten Beispiel festgestellt haben, verhindert ein Mutex zwar, dass Race Conditions auftreten, die Verarbeitungsreihenfolge der Threads lässt sich jedoch nicht beeinflussen und ist zufällig.
Im Folgenden soll eine erzwungene Verarbeitungsreihenfolge implementiert werden:
\begin{itemize}
\item {}
\sphinxAtStartPar
Ein Kunde benutzt den Automat für einen Kaffeekauf exklusiv, d.h. alle Schritte des Kunden werden innerhalb eines Mutexes ausgeführt. Ist ein Kunde an der Reihe, wartet er bis der Automat bereit ist, wirft eine Münze ein, wartet auf den Kaffee und gibt anschlies\sphinxhyphen{}send den Automaten für den nächsten Kunden frei.
\item {}
\sphinxAtStartPar
Der Automat meldet zuerst in einer Endlos\sphinxhyphen{}Schleife, dass er für die Geld\sphinxhyphen{}Eingabe bereit ist, wartet dann auf die Eingabe einer Münze, gibt den Kaffee aus und meldet anschliessend wieder, wenn er bereit ist, etc.
\end{itemize}
\sphinxAtStartPar
Für die Lösung dieses Problems benötigen wir Semaphore, die, im Gegensatz zu Mutexes, auch in verschiedenen Prozessen gesetzt bzw. zurückgesetzt werden dürfen. Den Kaffee\sphinxhyphen{}Automat und die Kunden implementieren wir mit Prozessen. sie finden die entsprechenden Prozesse im Verzeichnis \sphinxstylestrong{basicSequence}.
\subsubsection{Aufgaben}
\label{\detokenize{P08_Sync/README:id1}}\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Beschreiben sie den Kaffee\sphinxhyphen{}Automaten mit Hilfe der 6 Schritte aus Abschnitt 3 auf Papier, dokumentieren sie dabei alle Schritte schriftlich.
\item {}
\sphinxAtStartPar
Implementieren sie nun den Kaffee\sphinxhyphen{}Automaten. Ergänzen sie dazu den \sphinxstyleemphasis{coffeeTeller} und den \sphinxstyleemphasis{customer} Prozess so mit vier Semaphoren, dass die vorgegebenen Ablaufbedingungen eingehalten werden. Mit welchen Werten müssen die Semaphore initialisiert werden?
Wir haben für sie vier Semaphore vorbereitet: Achtung, sie sind aber noch auskommentiert (siehe commonDefs.h und startApp.c. Die benötigten Semaphor\sphinxhyphen{}Funktionen aus der POSIX Bibliothek sind:
\end{enumerate}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{sem\PYGZus{}wait}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{semaphor}\PYG{p}{)}\PYG{p}{;}
\end{sphinxVerbatim}
\sphinxAtStartPar
und
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{sem\PYGZus{}post}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{semaphor}\PYG{p}{)}\PYG{p}{;}
\end{sphinxVerbatim}
\sphinxAtStartPar
Analysieren sie die Ausgabe der Prozesse (mehrmals starten). Was fällt auf?
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Gibt Ihr Programm den Output in der korrekten Reihenfolge aus? Falls nicht, wie könnte das gelöst werden?
\end{enumerate}
\subsection{4.3 Aufgabe: Erweiterte Reihenfolge}
\label{\detokenize{P08_Sync/README:aufgabe-erweiterte-reihenfolge}}
\sphinxAtStartPar
Die Preise steigen dauernd … auch der Kaffee wird immer teurer, er kostet nun 3 Euro. Da der Automat nur 1 Euro Stücke annehmen kann, muss der Kunde 3 Münzen einwerfen. Erweitern sie die Prozesse aus Aufgabe 4.2 so, dass eine vordefinierte Anzahl Münzen eingegeben werden muss (die Anzahl Münzen ist in \sphinxstyleemphasis{commonDefs.h} als \sphinxstyleemphasis{NUM\_COINS} definiert). Verwenden sie keine zusätzlichen Semaphore, sondern nutzen sie, dass wir Counting Semaphore verwenden. Die vordefinierten Prozesse finden sie im Verzeichnis \sphinxstyleemphasis{advancedSequence}.
\subsubsection{Aufgabe}
\label{\detokenize{P08_Sync/README:aufgabe}}\begin{itemize}
\item {}
\sphinxAtStartPar
Passen sie den coffeeTeller und den customer Prozess so an, dass der Kunde mehrere Münzen einwerfen muss, bis der Automat einen Kaffee ausgeben kann.
\end{itemize}
\sphinxAtStartPar
\sphinxstylestrong{Hinweis:} POSIX Semaphore sind Counting Semaphore, können aber nicht auf vordefinierte Werte gesetzt werden (ausser bei der Initialisierung). Abhilfe schafft hier das mehrmalige Aufrufen von \sphinxstyleemphasis{sem\_post()}, z.B. in einer for\sphinxhyphen{}Schleife.
\subsection{4.4 Zusammenfassung}
\label{\detokenize{P08_Sync/README:zusammenfassung}}
\sphinxAtStartPar
Wir haben drei grundlegenden Typen von Synchronisationsproblemen kennen gelernt:
\begin{itemize}
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Mutex} nur ein Prozess bzw. Thread kann gleichzeitig auf gemeinsame Daten zugreifen.
\begin{itemize}
\item {}
\sphinxAtStartPar
Beispiel: entweder liest der Kaffee\sphinxhyphen{}Automat die Daten oder ein Kunde verändert sie.
\end{itemize}
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Einfache Reihenfolge} ein Prozess wartet auf die Freigabe durch einen anderen Prozess.
\begin{itemize}
\item {}
\sphinxAtStartPar
Beispiel: der Kaffee\sphinxhyphen{}Automat wartet auf die Eingabe einer Münze.
\end{itemize}
\item {}
\sphinxAtStartPar
\sphinxstylestrong{Erweiterte Reihenfolge} ein Prozess wartet auf mehrere Freigaben durch einen anderen Pro\sphinxhyphen{}zess.
\begin{itemize}
\item {}
\sphinxAtStartPar
Beispiel: der Kaffee\sphinxhyphen{}Automat wartet auf die Eingabe von drei Münzen.
\end{itemize}
\end{itemize}
\bigskip\hrule\bigskip
\section{5. International Banking}
\label{\detokenize{P08_Sync/README:international-banking}}
\sphinxAtStartPar
Die International Bank of Transfer (IBT) besitzt in 128 Ländern Filialen und stellt für 2048 spezielle Handels\sphinxhyphen{}Kunden in jeder Filiale ein Konto zur Verfügung. Gelder dieser Kunden werden dauernd zwischen den Filialen hin und her transferiert, dazu beschäftigt die Bank sogenannte Pusher. Pusher heben Geldbeträge von Konten in einer Filiale ab und buchen sie auf den entsprechenden Konten in irgendeiner (auch in der eigenen) Filiale wieder ein. Die Beträge liegen zwischen 1000 und 100000 Dollar und werden zufällig ausgewählt, die Wahl der beiden Filialen ist ebenfalls zufällig.
\subsection{5.1 Implementation}
\label{\detokenize{P08_Sync/README:implementation}}
\sphinxAtStartPar
Im Folgenden arbeiten wir mit einer \sphinxstyleemphasis{pthread}\sphinxhyphen{}basierten Implementation der IBT, die Pusher werden dabei mit Threads implementiert. Die Filialen der Bank sind als Array von Strukturen implementiert, wobei pro Filiale ein Lock (\sphinxstyleemphasis{branchLock}) und ein Array von Konten (Accounts) definiert ist. Die Konten sind wiederum Strukturen mit dem Kontostand (\sphinxstyleemphasis{account}) und dem Lock (\sphinxstyleemphasis{acntLock}), siehe dazu auch den Source Code. Die Zugriffe auf die Gelder sind imple\sphinxhyphen{}mentiert (Funktionen \sphinxstyleemphasis{withdraw()}, \sphinxstyleemphasis{deposit()}, \sphinxstyleemphasis{transfer()}), aber nicht synchronisiert.
\sphinxstylestrong{Hinweis:} es ist von Vorteil hier mit mehreren CPUs zu arbeiten. Falls sie eine VM verwenden, setzen sie die Anzahl CPUs auf das Maximum.
\subsection{5.2 Aufgabe: Konto Synchronisation}
\label{\detokenize{P08_Sync/README:aufgabe-konto-synchronisation}}\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Wechseln sie ins Verzeichnis \sphinxstylestrong{banking/a1}, übersetzen sie das Programm und starten sie es mit dem Skript \sphinxcode{\sphinxupquote{./startApp}}. Analysieren und erklären sie die Resultate. Notie\sphinxhyphen{}ren sie sich zudem die Laufzeiten für 1, 2 und 4 Threads.
\item {}
\sphinxAtStartPar
Synchronisieren sie die Kontenzugriffe so, dass möglichst viele Zugriffe gleichzeitig ausgeführt werden können und die Zugriffe atomar sind. Sie dürfen nur eines der beiden Locks \sphinxstyleemphasis{branchLock} bzw. \sphinxstyleemphasis{acntLock} verwenden: welches wählen sie und wieso? Be\sphinxhyphen{}gründen sie ihre Antwort und testen sie ihre Lösung.
\end{enumerate}
\subsection{5.3 Aufgabe: Filialen Zugriff in Critical Section}
\label{\detokenize{P08_Sync/README:aufgabe-filialen-zugriff-in-critical-section}}
\sphinxAtStartPar
Ihr Chef meint, dass es wohl aus Sicherheitsgründen besser wäre, sowohl die Filialen und die jeweiligen Kontenzugriffen zu ”locken”.
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Wechseln sie ins Verzeichnis banking/a2 und kopieren sie banking.c aus Aufgabe 5.2. Implementieren sie diese zusätzlichen Anforderungen. Analysieren sie die Resultate. Was stellen sie fest im Vergleich mit den Resultaten aus der Aufgabe 5.2? Was raten sie ihrem Chef?
\item {}
\sphinxAtStartPar
Ein Kollege meint, es wäre effizienter beim Abheben des Betrags zuerst das Konto zu locken und dann die Filiale, hingegen beim Einbuchen zuerst die die Filiale und dann das Konto. Was für eine Antwort geben sie ihrem Kollegen?\sphinxstylestrong{Hinweis:} falls sie nicht sicher sind: probieren sie es aus.
\end{enumerate}
\subsection{5.4 Aufgabe: Refactoring der Synchronisation}
\label{\detokenize{P08_Sync/README:aufgabe-refactoring-der-synchronisation}}
\sphinxAtStartPar
Das International Banking Committe (IBC) erlässt neue Richtlinien, die unter anderem fordern, dass die Gesamtbilanz einer Bank über sämtliche Filialen zu jeder Zeit konsistent sein muss.
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {}
\sphinxAtStartPar
Erklären sie wieso die Implementationen aus Aufgabe 5.2 und 5.3 diese Anforderungen nicht erfüllen.
\item {}
\sphinxAtStartPar
Ihr Entwicklungsteam kommt zum Schluss, dass den Pushern neu nur noch eine Funktion \sphinxstyleemphasis{transfer()} für die Überweisung von Beträgen zwischen den Filialen und Konten zur Verfügung gestellt werden darf.
Welche Locks bzw. welches Lock muss verwendet werden, damit die Forderung des IBC erfüllt werden kann? Wechseln sie ins Verzeichnis \sphinxstyleemphasis{banking/a3} und ergänzen sie die Funktion \sphinxstyleemphasis{transfer()} in banking.c um die entsprechenden Lock\sphinxhyphen{}Funktionen.
Wichtiger
\sphinxstylestrong{Hinweis:} es darf kein neues Lock eingeführt werden und die Gesamtbilanz über sämtliche Filialen muss jederzeit konsistent sein.
\item {}
\sphinxAtStartPar
Testen und analysieren sie das Programm und vergleichen sie die Resultate (Funktionalität, Laufzeit) mit den Lösungen aus Aufgabe 5.2 und 5.3. Notieren sie sich, was ihnen bei dieser Aufgabe wichtig erscheint.
\item {}
\end{enumerate}
\bigskip\hrule\bigskip
\section{6. Bewertung}
\label{\detokenize{P08_Sync/README:bewertung}}
\sphinxAtStartPar
Die gegebenenfalls gestellten Theorieaufgaben und der funktionierende Programmcode müssen der Praktikumsbetreuung gezeigt werden. Die Lösungen müssen mündlich erklärt werden.
\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
\hline
\sphinxstyletheadfamily
\sphinxAtStartPar
Aufgabe
&\sphinxstyletheadfamily
\sphinxAtStartPar
Kriterium
&\sphinxstyletheadfamily
\sphinxAtStartPar
Gewicht
\\
\hline
\sphinxAtStartPar
&
\sphinxAtStartPar
Sie können die gestellten Fragen erklären.
&
\sphinxAtStartPar
\\
\hline
\sphinxAtStartPar
4
&
\sphinxAtStartPar
4.1 Aufgabe: Mutual Exclusion4.2 Aufgabe: Einfache Reihenfolge4.3 Aufgabe: Erweiterte Reihenfolge
&
\sphinxAtStartPar
4
\\
\hline
\sphinxAtStartPar
5
&
\sphinxAtStartPar
5.2 Aufgabe: Konto Synchronisation5.3 Aufgabe: Filialen Zugriff in Critical Section5.4 Aufgabe: Refactoring der Synchronisation
&
\sphinxAtStartPar
4
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
\bigskip\hrule\bigskip
\bigskip\hrule\bigskip
\sphinxAtStartPar
Version: 18.08.2021
\chapter{09 \sphinxhyphen{} File Operations}
\label{\detokenize{P09_File_Operations/README:file-operations}}\label{\detokenize{P09_File_Operations/README::doc}}
\bigskip\hrule\bigskip
\bigskip\hrule\bigskip
\section{1. Übersicht}
\label{\detokenize{P09_File_Operations/README:ubersicht}}
\bigskip\hrule\bigskip
\section{2. Lernziele}
\label{\detokenize{P09_File_Operations/README:lernziele}}
\bigskip\hrule\bigskip
\section{3. Aufgabe 1:}
\label{\detokenize{P09_File_Operations/README:aufgabe-1}}
\bigskip\hrule\bigskip
\section{4. Bewertung}
\label{\detokenize{P09_File_Operations/README:bewertung}}
\sphinxAtStartPar
Die gegebenenfalls gestellten Theorieaufgaben und der funktionierende Programmcode müssen der Praktikumsbetreuung gezeigt werden. Die Lösungen müssen mündlich erklärt werden.
\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
\hline
\sphinxstyletheadfamily
\sphinxAtStartPar
Aufgabe
&\sphinxstyletheadfamily
\sphinxAtStartPar
Kriterium
&\sphinxstyletheadfamily
\sphinxAtStartPar
Punkte
\\
\hline
\sphinxAtStartPar
&
\sphinxAtStartPar
Sie können das funktionierende Programm inklusive funktionierende Tests demonstrieren und erklären.
&
\sphinxAtStartPar
\\
\hline
\sphinxAtStartPar
1
&
\sphinxAtStartPar
\sphinxhyphen{}
&
\sphinxAtStartPar
\sphinxhyphen{}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
\bigskip\hrule\bigskip
\sphinxAtStartPar
Version: 16.02.2022
\chapter{10 \sphinxhyphen{} IPC}
\label{\detokenize{P10_IPC/README:ipc}}\label{\detokenize{P10_IPC/README::doc}}
\bigskip\hrule\bigskip
\section{1. Übersicht}
\label{\detokenize{P10_IPC/README:ubersicht}}
\bigskip\hrule\bigskip
\section{2. Lernziele}
\label{\detokenize{P10_IPC/README:lernziele}}
\bigskip\hrule\bigskip
\section{3. Aufgabe 1:}
\label{\detokenize{P10_IPC/README:aufgabe-1}}
\bigskip\hrule\bigskip
\section{4. Bewertung}
\label{\detokenize{P10_IPC/README:bewertung}}
\sphinxAtStartPar
Die gegebenenfalls gestellten Theorieaufgaben und der funktionierende Programmcode müssen der Praktikumsbetreuung gezeigt werden. Die Lösungen müssen mündlich erklärt werden.
\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
\hline
\sphinxstyletheadfamily
\sphinxAtStartPar
Aufgabe
&\sphinxstyletheadfamily
\sphinxAtStartPar
Kriterium
&\sphinxstyletheadfamily
\sphinxAtStartPar
Punkte
\\
\hline
\sphinxAtStartPar
&
\sphinxAtStartPar
Sie können das funktionierende Programm inklusive funktionierende Tests demonstrieren und erklären.
&
\sphinxAtStartPar
\\
\hline
\sphinxAtStartPar
1
&
\sphinxAtStartPar
\sphinxhyphen{}
&
\sphinxAtStartPar
\sphinxhyphen{}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
\bigskip\hrule\bigskip
\sphinxAtStartPar
Version: 16.02.2022
\renewcommand{\indexname}{Index}
\printindex
\end{document}