diff --git a/basics/arith.tex b/basics/arith.tex deleted file mode 100644 index 63a5091..0000000 --- a/basics/arith.tex +++ /dev/null @@ -1,89 +0,0 @@ -\lesson{Arithmetik} - -Wir haben in der vergangenen Lektion Variablen vom Typ \texttt{std::string} -kennengelernt. Zeichenketten zu speichern ist schon einmal ein guter Anfang, -aber wir wollen auch rechnen können, wir brauchen also mehr Typen für -Variablen. - -\Cpp unterstützt eine Unmenge an Datentypen und hat auch die Möglichkeit, -eigene zu definieren. Wir wollen uns hier nur mit den wichtigsten beschäftigen. - -Fangen wir mit dem wohl meist genutzten Datentyp an: Einem \texttt{int}, oder -\texttt{integer}. Dieser speichert eine ganze Zahl (mit bestimmten Grenzen, an -die wir aber erst einmal nicht stossen werden, von daher ignorieren wir sie -erst einmal frech). Mit \texttt{int}s können wir rechnen, das funktioniert in -\Cpp mit ganz normalen Rechenausdrücken, wie wir sie aus der Schule kennen, -plus den bereits angetroffenen Zuweisungen: - -\inputcpp{arith1.cpp} - -Wichtig ist hier, zu beachten, dass wir dem Computer ein in Reihenfolge -abgearbeitetes Programm geben, keine Reihe von Aussagen. Das bedeutet in diesem -konkreten Fall, dass wir z.B. nicht die Aussage treffen „\texttt{a} ist gleich -7“, sondern dass wir sagen „lasse zuerst \texttt{a} den Wert 7 haben. Lasse -dann \texttt{b} den Wert 19 haben. Lasse dann \texttt{c} den Wert haben, der -heraus kommt, wenn man den Wert von \texttt{b} vom Wert von \texttt{a} -abzieht“. Besonders deutlich wird dieser Unterschied bei einem Beispiel wie -diesem: - -\inputcpp{arith2.cpp} - -\begin{praxis} - \begin{enumerate} - \item Was gibt dieses Programm aus? Überlegt es euch zuerst und kompiliert - es dann, um es auszuprobieren. - \end{enumerate} - - Obwohl \texttt{a = a + 19} mathematisch überhaupt keinen Sinn ergibt, ist doch - klar, was passiert, wenn man sich den Quellcode eben nicht als Reihe von - Aussagen, sondern als Folge von \emph{Anweisungen} vorstellt. Das - Gleichheitszeichen bedeutet dann nicht, dass beide Seiten gleich sein sollen, - sondern dass der Wert auf der linken Seite den Wert auf der rechten Seite - annehmen soll. - - Wie wir in diesem Beispiel ausserdem sehen, können wir nicht nur Strings - ausgeben, sondern auch Zahlen. \texttt{std::cout} gibt sie in einer Form aus, - in der wir etwas damit anfangen können. Genauso können wir auch über - \texttt{std::cin} Zahlen vom Benutzer entgegen nehmen: - - \inputcpp{arith3.cpp} - - Langsam aber sicher tasten wir uns an nützliche Programme heran! - - \begin{enumerate}[resume] - \item Schreibt ein Programm, welches von der Nutzerin zwei ganze Zahlen - entgegen nimmt und anschließend Summe, Differenz, Produkt und Quotient - ausspuckt. - \item Was fällt auf, wenn ihr z.B. 19 und 7 eingebt? - \item Findet heraus (Google ist euer Freund), wie man in \Cpp Division mit - Rest durchführt und gebt diese zusätzlich zu den bisherigen Operationen - mit aus\footnote{Falls ihr nicht weiterkommt, hilft euch vielleicht das - Stichwort „modulo“ oder „modulo-operator“ weiter.}. - \item Was passiert, wenn ihr als zweite Zahl eine 0 eingebt? - \end{enumerate} -\end{praxis} - -\begin{spiel} -\begin{enumerate} - \item Findet heraus, was die größte positive (und was die kleinste - negative) Zahl ist, die ihr in einem \texttt{int} speichern könnt. - Faulpelze nutzen Google, Lernbegierige versuchen sie experimentell zu - ermitteln. Was passiert, wenn ihr eine größere Zahl eingebt? - \item Wir arbeiten bisher nur mit \texttt{int}s für ganze Zahlen. Wenn wir - mit gebrochenen Zahlen rechnen wollen brauchen wir den Datentyp - \texttt{double}. Schreibt euer Mini Rechenprogramm so um, dass es statt - \texttt{int}s nur noch \texttt{double} benutzt und probiert es aus. - Achtet darauf, dass es Dezimalpunkte und Dezimalkommata gibt, wenn ihr - überraschende Ergebnisse erhaltet. -\end{enumerate} -\end{spiel} - -\textbf{Quiz 7}\\ -\textit{Was passiert, wenn ihr \texttt{int} verwendet, aber eine Kommazahl eingebt?} -\begin{enumerate}[label=\alph*)] - \item Alles hinter dem Komma wird abgeschnitten - \item Es tritt ein Fehler auf - \item Das Programm kompiliert nicht - \item statt \texttt{int} wird automatisch \texttt{double} genommen -\end{enumerate} - diff --git a/basics/arrays.tex b/basics/arrays.tex deleted file mode 100644 index 61f204a..0000000 --- a/basics/arrays.tex +++ /dev/null @@ -1,85 +0,0 @@ -\lesson{\texttt{C}-Arrays} - -Als nächstes wichtiges Konzept in \Cpp werden wir uns \emph{Arrays} anschauen. -Arrays sind eine Möglichkeit, mehrere Elemente des gleichen Typs zusammen zu -fassen. Statt also einer Stelle im Speicher, an der ein \texttt{int} liegt, -habt ihr einen ganzen Speicherbereich, in dem 100 (oder eine beliebige andere -Anzahl an) \texttt{int}s liegen. - -Die Elemente in einem Array sind durchnummeriert, man nennt die Nummer eines -Arrayelements seinen \emph{Index}. Das erste Element hat den Index 0, das -zweite den Index 1 und das 100te hat den Index 99 -- Vorsicht also, der höchste -Index in einem Array mit 100 Elementen ist 99, nicht 100! Um ein Array zu -definieren, schreibt ihr hinter seinen Namen eine eckige Klammer auf, die -Anzahl an Elementen, die es enthalten soll, und eine eckige Klammer zu. Auf ein -bestimmtes Arrayelement zuzugreifen könnt ihr tun, indem ihr seinen Index in -eckigen Klammern hinter den Namen schreibt. Folgendes Programm macht -hoffentlich die Syntax klar: -\inputcpp{array.cpp} - -Es gibt einige Dinge, zu beachnten, wenn ihr mit Arrays arbeitet. Das -wichtigste ist oben schon genannt -- sich davon verwirren zu lassen, dass -Indizes bei 0 anfangen und aus Versehen über das Array hinaus schreiben oder -lesen ist ein so häufiger Fehler, dass er seinen eigenen Namen bekommen hat: -„Off-by-one error“. Wichtig ist, dass der Compiler diesen Zugriff nicht -verhindern wird! Das ist von daher eine sehr fiese Sache, als dass dieser -Fehler auch beim Ausführen nicht immer Probleme machen wird -- aber manchmal -lässt er auch euer Programm spontan abstürzen in einem so genannten -\emph{segmentation fault}. - -Eine Limitation von Arrays, die ihr beachten solltet, ist, dass bereits zur -Compilezeit fest stehen muss, wie viele Elemente sie enthalten sollen. Ihr -könnt also z.B. nicht die Nutzerin fragen, wie viele Elemente in das Array -passen soll, denn dies würde erst zur Laufzeit feststehen (wir werden später -noch Wege um diese Limitation kennen lernen). - -Ihr könnt auch Arrays von Arrays (so genannte zweidimensionale Arrays) -erstellen, indem ihr zweimal in eckigen Klammern die Größe des Arrays -hinschreibt. Die erste Größe gibt dann die Anzahl der Zeilen an, die zweite die -Anzahl der Spalten. Auch beim Zugriff auf Arrayelemente müsst ihr dann zwei -Indizes angeben. Wir werden dies später noch nutzen, hier sei erst einmal nur -die generelle Möglichkeit genannt. - -\textbf{Praxis:} -Wir wollen die Seite \url{http://www.ich-kann-mich-nicht-entscheiden.de/} -nachmachen und eine Entscheidungshilfe programmieren, die aus mehreren von der -Nutzerin gegebenen Möglichkeiten eine per Zufall auswählt. - -\begin{enumerate} - \item Schreibt zunächst ein Programm, welches ein Array aus 10 Strings - erstellt und die Nutzerin 10 mal nach einer Antwortmöglichkeit fragt - und die gegebenen Antworten nacheinander in das Array schreibt. - \item Fügt nun die Möglichkeit zu, weniger Antworten anzugeben. Dazu könnt - ihr zum Beispiel zuerst fragen, wie viele Antwortmöglichkeiten es geben - soll und dann so oft fragen (und natürlich einen Fehler ausgeben, wenn - es mehr als 10 Antworten geben soll). - \item Ihr könnt dann (so wie in dem Programm oben) eine Zufallszahl - erzeugen. Um sicher zu gehen, dass sie nicht zu groß wird, könnt ihr - den Rest bei Teilung durch Anzahl der eingegebenen Antworten nehmen - (sind z.B. 7 Antworten angegeben und die Zufallszahl ist 25778, so wäre - der resultierende Index \texttt{25778 \% 7 == 4}). Gebt dann die - Antwortmöglichkeit aus, die dem zufallsgeneriertem Index - entspricht. -\end{enumerate} - -Sollte euer Programm einmal nicht korrekt kompilieren, denkt daran die -Fehlermeldung sorgfältig zu lesen, damit sie euch Aufschluss über die -Fehlerursache gibt. Sollte euer Programm zwar kompilieren, sich dann aber -komisch verhalten, denkt daran, den debugger zu benutzen und es Schritt für -Schritt durchzugehen, um die Fehlerquelle zu finden. Solltet ihr trotz alledem -nicht weiter kommen, oder nicht wissen, was von euch erwartet wird, fragt einen -von uns. - -\textbf{Spiel:} -\begin{enumerate} - \item Schreibt ein Progamm, welches ein Array beliebiger Größe erstellt und - dann auf einen Index weit ausserhalb des erlaubten Bereichs schreibt. - Was beobachtet ihr?\footnote{Es wird natürlich Quark sein was dabei - rauskommt, es geht hier haupsächlich darum das ihr seht was für - einen Fehler das gibt} - \item Implementiert das \emph{Sieb des Eratosthenes} - \footnote{\url{https://de.wikipedia.org/wiki/Sieb_des_Eratosthenes}}, - wenn ihr noch nicht ausgelastet seid. - Denkt daran, es initial zu befüllen und denkt euch eine clevere - Möglichkeit aus, das „Streichen“ zu realisieren. -\end{enumerate} diff --git a/basics/compiling.tex b/basics/compiling.tex deleted file mode 100644 index dbf198b..0000000 --- a/basics/compiling.tex +++ /dev/null @@ -1,122 +0,0 @@ -\lesson{Preprocessing, Compiler, Assembler, Linker} - -In der letzten Lektion klang es bereits an -- was der Befehl \texttt{g++} -eigentlich tut, ist mehr, als nur Kompilieren im strengen Sinne des Wortes. Wir -wollen jetzt kurz erkunden, welche anderen Schritte in den Prozess vom -Quellcode in die ausführbare Datei notwendig sind und wie sie geschehen. Das -ist im Alltag nicht sehr wichtig, kann uns aber helfen, einige Fehlermeldungen -besser zu verstehen. Von daher müsst ihr auch nicht alles hier beschriebene -vollständig verstehen. - -In Lektion 1 haben wir vereinfacht dargestellt, dass der Compiler eine -Quelltextdatei mit der Endung \texttt{.cpp} nimmt und daraus direkt eine -ausführbare Datei erstellt. Die Schritte, die hier eigentlich in einem Befehl -durchgeführt werden, aber zu trennen sind, sind das \emph{Preprocessing}, das \emph{Kompilieren}, das -\emph{Assemblieren} und das \emph{Linken}. - -Beim Preprocessing werden alle \texttt{\#include}-Anweisungen aufgelöst und so etwas wie Makros ersetzt. Das ist der erste Schritt, der passiert, wenn wir \texttt{g++} aufrufen. Das Ergebnis des Preprocessings ist ein \Cpp-Programm, das nur noch die \Cpp-Features enthält, die wir auch wirklich benutzen. Das ist der Grund, warum wir in den bisherigen Lektionen immer \texttt{g++ -o helloworld helloworld.cpp} benutzt haben, obwohl wir in \texttt{helloworld.cpp} auch \texttt{\#include } stehen haben -- der Compiler hat das schon für uns erledigt. - -Das Kompilieren übersetzt unseren \Cpp-Code in eine Zwischenform, so genannten -\emph{Assembler}. In Lektion 1 haben wir den Maschinencode angesprochen, in der -Befehle und Parameter an Befehle in 1en und 0en dargestellt werden. Assembler -ist quasi die nächst höhere Evolutionsstufe -- statt die Befehle binär zu -kodieren, gibt es für jeden Befehl ein so genanten \emph{mnemonic}, also ein -merkbares kurzes Wort. Ein Befehl ist allerdings deutlich weniger mächtig, als -z.B. eine Anweisung in \Cpp. Früher wurden ganze Betriebssysteme in Assembler -geschrieben, da es einfach nichts Besseres gab, heutzutage ist Assembler bis -auf die exotischsten Anwendungsfelder eigentlich ausgestorben, da es viel zu -anstrengend und Fehleranfällig ist. Der Compiler tut aber noch mehr, als -einfach nur in diese Zwischensprache zu übersetzen -- er führt auch -\emph{Optimierungen} durch, d.h. er sortiert Anweisungen um, damit der Code -schneller läuft, aber das Gleiche tut. Dieser Prozess ist sehr umständlich, -aber heutige Compiler sind tatsächlich so gut im Optimieren, dass sie meistens -deutlich schnelleren Code erzeugen, als ein Mensch es je könnte. - -Der nächste Schritt ist dann das Assemblieren. Das übersetzt den Assembler des -ersten Schrittes tatsächlich in Maschinensprache (genauer: In ein Dateiformat, -welches ELF heißt, welches dann die Maschinensprache plus einiger -Meta-Informationen enthält). Der Assembler erzeugt so genannte -\emph{Objectfiles}, die meistens die Endung \texttt{.o} haben (und im -ELF-Format sind). Ein Objectfile enthält dann mehrere Funktionen (in -Maschinencode) und Variablen, die es \emph{exportieren} kann, d.h. Funktionen -anderer Objectfiles die dagegen (im nächsten Schritt) gelinkt werden, können -diese Variablen und Funktionen sehen. Der Vorteil, diesen Schritt vom -vorhergehenden zu trennen ist, dass wir wenn wir wollen auch nur kompilieren -können und den resultierenden Assembler betrachten -- das kann uns helfen, -Engpässe in unserem Code, an denen der Compiler nicht hinreichend gut optimiert -zu erkennen und möglicherweise zu verbessern. z.B. in der Spielentwicklung ist -sehr schnell laufender Code wichtig. - -Der letzte Schritt ist das Linken. Hier werden mehrere Objectfiles genommen und -miteinander verbunden, zu einer ausführbaren Datei. Wenn in einer der -Objectfiles eine \texttt{main}-Funktion existiert, wird diese als -Eintrittspunkt für das Programm genommen, sonst gibt es einen -\emph{Linkerfehler}. Ein Linkerfehler tritt auch auf, wenn wir versuchen, eine -Funktion zu verwenden, die es nicht gibt (z.B. indem wir sie mittels -\texttt{extern} deklarieren, ohne später das relevante Objectfile mit -anzugeben). Linkerfehler deuten also darauf hin, dass wir vergessen haben, alle -relevanten Dateien auf der Kommandozeile anzugeben, oder dass eine -\texttt{main}-Funktion fehlt, oder dass wir in mehren Dateien eine Funktion -gleichen Namens haben, oder\dots - -Um das Diagramm aus der ersten Lektion zu ergänzen, dies ist der Weg, den euer -Programm durch die verschiedenen Phasen geht: - -\begin{tikzpicture} - \tikzstyle{block} = [ shape=rectangle, rounded corners = 0.1cm, draw=black, inner xsep=0.5cm, inner ysep = 0.3cm ]; - \tikzstyle{arr} = [ ->, thick, shorten >= 2pt, shorten <= 2pt ]; - - \node (nHelloWorldCpp) [block] {\texttt{helloworld.cpp}}; - \node (nHelloWorldS) [block, right of = nHelloWorldCpp, node distance = 12cm] {\texttt{helloworld.S}}; - \draw [arr] (nHelloWorldCpp) -- (nHelloWorldS) node [midway,above,font=\small] {\texttt{g++ -S -o helloworld.S helloworld.cpp}}; - \node (nHelloWorldO) [block, below of = nHelloWorldCpp, node distance = 2cm] {\texttt{helloworld.o}}; - \draw [arr] (nHelloWorldS) -- (nHelloWorldO) node [pos=0.56,above,sloped,font=\small] {\texttt{g++ -c -o helloworld.o helloworld.S}}; - \node (nAnderesO) [block, below of = nHelloWorldO, node distance = 1cm] {\texttt{anderes.o}}; - \node (nHelloWorld) [block, below of = nHelloWorldS, node distance = 2cm] {\texttt{helloworld}}; - \draw [arr] (nHelloWorldO) -- (nHelloWorld) node [midway,below,font=\small] {\texttt{g++ -o helloworld helloworld.o anderes.o}}; - \draw [arr] (nAnderesO) -| (nHelloWorld) node {}; -\end{tikzpicture} - -Der bisherige Befehl, den wir zum Kompilieren benutzt haben, ist tatsächlich -nur ein Spezialfall von diesem: Geben wir nämlich auf der Kommandozeile eine -input-Datei an, so rät \texttt{g++} anhand der Dateierweiterung und der -Parameter, was wir damit tun wollen. Er führt dann alle Schritte, um von -unserer input-Datei zu der gewünschten zu kommen automatisch aus, wenn wir also -\texttt{g++ -o helloworld helloworld.cpp} eingeben, dann weiß der Compiler, -dass wir eine ausführbare Datei wünschen (da wir weder \texttt{-c} noch -\texttt{-S} angegeben haben) und dass er dafür kompilieren, assemblieren und -linken muss (da wir ihm eine \texttt{.cpp} Datei gegeben haben). Genauso konnte -er in der vorigen Lektion raten, dass \texttt{g++ -o tictactoe tictactoe.cpp - tictactoe.o} heißt, dass wir eine ausführbare Datei wollen, die aus einem -kompilierten und assemblierten \texttt{tictactoe.cpp} zusammen gelinkt mit -\texttt{tictactoe.o} bestehen soll. - -\begin{praxis} - \begin{enumerate} - \item \texttt{assemble.cpp} enthält ein kleines (ziemlich nutzloses) - Programm, welches zwei Zahlen addiert und das Ergebnis ausgibt. - Kompiliert es (nun nur der erste Schritt in dem Diagramm, nicht so, wie - in den vergangenen Lektionen) und schaut euch das resultierende - \texttt{.S}-file in einem Editor an. Ihr müsst nicht verstehen, - was genau hier überall passiert, aber vielleicht findet ihr ja die - \texttt{main}-Funktion, die Definition der Variablen und die Addition? - - Wir können nun mal Optimierung anschalten -- gebt dazu zusätzlich den - Parameter \texttt{-O3} direkt nach dem \texttt{g++} an. Schaut euch das - \texttt{.S}-file nun wieder im Editor an. Was fällt euch - (im Vergleich zu vorher) auf? - \item Assembliert eines der im vorigen Schritt erzeugten \texttt{.S} files - in ein \texttt{.o}-File. - \item Benennt in einem eurer bisherigen Programme die - \texttt{main}-Funktion um und versucht, es zu kompilieren (wie in den - bisherigen Lektionen, also alle Schritte auf einmal). Schaut euch die - resultierenden Fehlermeldungen an. Wo wird euch der Linkerfehler - ausgegeben? - \item Macht die Umbenennung wieder rückgängig und kompiliert das Programm - erneut -- übergebt aber dieses mal den Quellcode doppelt (also z.B. - \texttt{g++ -o helloworld helloworld.cpp helloworld.cpp}). Was - beobachtet ihr? Könnt ihr die Beobachtung erklären? - \end{enumerate} - - \inputcpp{assemble.cpp} -\end{praxis} \ No newline at end of file diff --git a/basics/fehler.tex b/basics/fehler.tex deleted file mode 100644 index b1f0d97..0000000 --- a/basics/fehler.tex +++ /dev/null @@ -1,115 +0,0 @@ -\lesson{Fehlermeldungen und häufige Fehler} - -Wenn ihr in den vergangen Lektionen ein bisschen herumprobiert habt, wird es -euch sicher das ein oder andere mal passiert sein, dass euch der Compiler statt -eines funktionierenden Programms eine Riesenmenge Fehlermeldungen ausgespuckt -hat und ihr einen Schreck bekamt und schon dachtet, ihr hättet alles kaputt -gemacht. - -\texttt{g++} ist leider bei Fehlermeldungen immer sehr ausführlich und gibt -euch lieber viel zu viel, als viel zu wenig aus. Das kann im ersten Blick ein -bisschen überwältigend wirken, aber wenn man einmal gelernt hat, wie die -Fehlermeldungen am Besten zu lesen sind, ist das alles gar nicht mehr so -schlimm. - -Wir schieben deswegen eine Lektion über häufige Fehlerquellen ein und wie man -Fehlermeldungen von \texttt{g++} liest, um möglichst schnell die Ursache des -Fehlers zu finden. - -Nehmen wir z.B. mal folgendes Programm: - -\inputcpp{fehler1.cpp} - -Wenn wir versuchen, dieses zu kompilieren, gibt uns \texttt{g++} folgendes aus: - -\begin{textcode*}{label=g++ -o fehler1 fehler1.cpp} - fehler1.cpp: In function 'int main()': - fehler1.cpp:2:5: error: 'cout' is not a member of 'std' - fehler1.cpp:2:35: error: 'endl' is not a member of 'std' -\end{textcode*} - -Wenn wir diese Fehlermeldung verstehen wollen, fangen wir immer ganz oben an, -egal wie viel Text uns der Compiler ausspucken mag. In diesem Fall sagt uns die -erste Zeile, in welcher Datei (\texttt{fehler1.cpp}) der Fehler aufgetreten ist -und in welcher Funktion (\texttt{int main()}). Die beiden Zeilen -danach sind sogar noch spezifischer: Sie enthalten zu Beginn den Dateinamen, -dann einen Doppelpunkt, gefolgt von einer Zeilennummer, gefolgt von einer -Spaltennummer. Das gibt euch ganz genau die Stelle an, an der der Compiler -etwas an eurem Code zu bemängeln hat. In diesen Fall ist, was der Compiler -bemängelt, dass \texttt{cout} bzw. \texttt{endl} nicht in \texttt{std} sind. -Was genau \texttt{std} bedeutet muss uns nicht interessieren, aber der Rest -sagt uns (mit ein bisschen Erfahrung) dass wir die Definition von \texttt{cout} -und \texttt{endl} nicht haben - was nicht weiter verwunderlich ist, denn diese -beiden Dinge werden in der Datei \texttt{iostream} definiert, die wir früher -immer includiert haben. - -Damit wissen wir jetzt auch (endlich) was das \mint{c++}|#include | -zu bedeuten hatte. Offenbar brauchen wir das, wenn wir Konsolen input und -output machen wollen, da es die Definitionen von \texttt{cout}, \texttt{cin}, -\texttt{endl} und ähnlichem enthält. - -Der nächste sehr häufig vorkommende Fehler ist subtiler: - -\inputcpp{fehler2.cpp} - -Wenn wir versuchen, dies zu kompilieren, bekommen wir vom Compiler -entgegengespuckt: - -\begin{textcode*}{label=g++ -o fehler2 fehler2.cpp} - fehler2.cpp: In function 'int main()': - fehler2.cpp:5:1: error: expected ';' before '}' token -\end{textcode*} - -Wiederum sagt uns die erste Zeile, in welcher Datei und Funktion der Fehler -aufgetreten ist. Die zweite Zeile sagt uns wo, nämlich in Zeile 5, direkt am -Anfang. Die Beschwerde des Compilers ist, dass er ein Semikolon erwartet hat, -aber eine geschlossene geschweifte Klammer gefunden hat. Der Grund dafür ist, -dass in \Cpp erwartet wird, dass jede Anweisung mit einem Semikolon abgeschlossen -wird. Wenn ihr euch die bisherigen Quellcodedateien anschaut, werdet ihr -feststellen, dass hinter den allermeisten Zeilen ein solches Semikolon steht. -Hier fehlt es allerdings nach der Ausgabe in Zeile 4. Sobald wir es hinzufügen, -beschwert sich der Compiler nicht mehr. - -Hier zeigt sich eine ein bisschen verwirrende Angewohnheit von Fehlermeldungen -von \Cpp: Obwohl der Compiler behauptete, der Fehler läge in Zeile 5, lag er in -Wahrheit bereits in Zeile 4. Hier müsst ihr dem dummen Compiler ein wenig -nachsichtig sein - er kann es einfach nicht besser wissen. Wenn ihr also mal in -der richtigen Zeilennummer nachschlagt, aber nicht wisst, wo dort der Fehler -sein sollte, schaut vielleicht mal ein oder zwei Zeilen darüber, vielleicht -wusste der Compiler es einfach nicht besser. - -\textbf{Praxis:} -\begin{enumerate} - \item Versucht, folgende Dateien zu kompilieren und schaut euch die - Fehlermeldung an. In welcher Zeile, in welcher Spalte liegt der Fehler? - Was gibt euch der Compiler als Fehlermeldung aus? - \item Versucht, die aufgetretenen Fehler zu korrigieren. Bekommt ihr es - hin, dass der Compiler sich nicht mehr beschwert und das Programm - korrekt arbeitet (schaut euch ggf. die bisher gezeigten Quellcodes an)? -\end{enumerate} - -\inputcpp{fehler3.cpp} -\inputcpp{fehler4.cpp} - -\begin{spiel} -\begin{enumerate} - \item Das folgende Programm enthält mehrere Fehler. Bekommt ihr trotzdem - raus, welche das sind und könnt ihr sie beheben (Tipp: „c++ math“ zu - \href{http://lmgtfy.com/?q=c\%2B\%2B+math}{googlen} kann euch hier vielleicht weiter bringen)? - \item Wenn ihr in den vergangenen Lektionen ein bisschen gespielt habt und - vereinzelt versucht habt, Dinge zu löschen, werden euch viele - Fehlermeldungen begegnet sein, versucht, diese zu lesen und - interpretiert, was euch der compiler hier sagen will. -\end{enumerate} -\end{spiel} - -\inputcpp{fehler5.cpp} - -\textbf{Quiz 4}\\ -\textit{Was hiervon sind Fehler, die dazu führen, dass eine Datei nicht kompiliert werden kann?} -\begin{enumerate}[label=\alph*)] - \item Semikolon vergessen - \item include vergessen - \item return vergessen - \item Einrückung falsch -\end{enumerate} diff --git a/basics/funktionen.tex b/basics/funktionen.tex deleted file mode 100644 index edee670..0000000 --- a/basics/funktionen.tex +++ /dev/null @@ -1,114 +0,0 @@ -\lesson{Funktionen} - -Aus der Mathematik kennt ihr bereits Funktionen, wie zum Beispiel $f(x) = x^2$. -Eine wichtige Idee dahinter ist es, einfach $f(2.5)$ zu schreiben, wenn man eigentlich $2.5^2$ meint. -In diesem simplen Beispiel bilden wir einfach eine reelle Zahl ab und erhalten als Ergebnis wieder eine reelle Zahl. -So ähnlich findet sich das Konzept von Funktionen auch in Programmiersprachen wie \Cpp wieder. - -Eine Funktion in \Cpp besteht aus zwei Teilen: der \emph{Signatur} und dem \emph{Funktionsrumpf}. -Die Kombination von Parametertypen und Rückgabetyp bildet die Signatur einer Funktion. -Parameter sind Werte, die der Funktion übergeben werden, zum Beispiel das $x$ in $f(x)$. -Für eine Funktion \cppinline{my_func}, die $x^n$ berechnen soll, könnte eine Signatur so aussehen: -\[ - \smashoperator{\mathop{\underbrace{\text{\cppinline{double}}}}_{\text{Rückgabetyp}}}\quad - \smashoperator{\mathop{\overbrace{\text{\cppinline{my_func}}}}^{\text{Name}}} - (\smashoperator{\mathop{\underbrace{\text{\cppinline{double x}}}}_{\text{Parameter 1}}},\ - \smashoperator{\mathop{\overbrace{\text{\cppinline{int n}}}^{\text{Parameter 2}}}}) -\] -%sorry etwas hässlich - -\begin{itemize} - \item Rückgabetyp: Bestimmt welchen Datentyp die Rückgabe der Funktion hat - \item Name: Ein frei wählbarer Name für die Funktion - \item Parameter: Besteht aus dem Datentype des Parameters und dem beliebig wählbaren Parameternamen. \\Mehrere Parameter können angegeben werden, indem man diese durch Kommata voneinander trennt. -\end{itemize} - -In diesem Fall ist also \texttt{double} der Rückgabewert, \cppinline{my_func} der Name, \cppinline{x} ein Parameter mit dem Typ \texttt{double} und \cppinline{n} ein Paramter mit dem Typ \texttt{int}. -Damit können dann Werte an die Funktion in der Form \cppinline{my_func(1.41, 2)} übergeben werden. - -An dieser Stelle ist der Unterschied zwischen Rückgabe und Ausgabe wichtig: Eine Ausgabe (gekennzeichnet durch \cppinline{std::cout}) gibt Informationen auf dem Bildschirm für die Nutzerin aus, eine Rückgabe (gekennzeichnet durch \texttt{return}) gibt hingegen ein bestimmtes Ergebnis an einen anderen Teil des Programms zurück, damit dieser dort in einer Variable gespeichert oder direkt weiter verarbeitet werden kann. - -Der Funktionsrumpf beinhaltet den Code, der beim Funktionsaufruf tatsächlich ausgeführt wird. -Dieser wird wie in einer Schleife von \mintinline{c++}|{| und \mintinline{c++}|}| umschlossen. -Innerhalb dieser Klammern kann dann beliebiger Code ausgeführt werden, wie auch in der \texttt{main}-Funktion. -Dabei kann auf die Parameter einfach mit dem in der Signatur definierten Namen zugegriffen werden. -Also in unserem Beispiel mit \cppinline{x} und \cppinline{n}. -Vor dem Ende des Funktionsrumpfes muss eine Rückgabe mit \texttt{return} ausgeführt werden.\\ -\newpage -Eine Funktion, die $ x^n $ berechnet und ein paar mal aufgerufen wird, könnte dann wie folgt aussehen: - -\inputcpp{beispielfunktion.cpp} - -Unsere Funktion wird in diesem Beispiel 4-mal aufgerufen. -Das erste mal werden konkrete Werte als Parameter übergeben.\\ -Beim zweiten Aufruf übergeben wir eine Variable, anstelle eines konkreten Werts.\\ -Und dann? In Zeile 14 rufen wir \cppinline{my_func} mit dem Ergebnis eines weiteren Funktionsaufrufs auf, ohne dieses zuerst in einer Variablen zwischenzuspeichern. -Dabei kann man sich vorstellen, dass der Funktionsaufruf nach dem die Funktion ausgeführt wurde durch den Rückgabewert ersetzt wird. -Dies könnte für die Funktion \cppinline{my_func} folgendermaßen aussehen: - -\begin{center} - \cppinline{f(5.0 + f(3.0, 2), 3)} $\mapsto$ \cppinline{f(5.0 + 9.0, 3)} $\mapsto$ \cppinline{f(14.0, 3)} $\mapsto$ \cppinline{2744} -\end{center} - - - - -Funktionen werden beispielsweise benötigt, wenn bestimmte Programmteile häufiger mit verschiedenen Parametern ausgeführt werden sollen. -Die Collatz-Vermutung\footnote{\url{https://de.wikipedia.org/wiki/Collatz-Vermutung}} besagt für die Folge: -\[ - x_n = - \begin{cases} - \frac{x_{n-1}}{2} & x_{n-1} \text{ ist gerade} \\ - 3 \cdot x_{n-1} + 1 & x_{n-1} \text{ ist ungerade} - \end{cases} -\] -dass jeder Startwert $x_1$ aus den natürlichen Zahlen nach endlich vielen Schritten bei der $1$ angelangt. -Zum Beispiel für den Startwert $x_1 = 42$: - -\[ - 42 \mapsto 21 \mapsto 64 \mapsto 32 \mapsto 16 \mapsto 8 \mapsto 4 \mapsto 2 \mapsto 1 \mapsto 4 \mapsto 2 \mapsto 1 \mapsto \ldots -\] - -Wenn nun die Frage aufkommt was die nächsten Folgenglieder von verschiedenen Zahlen sind, wäre ein möglicher Lösungsweg eine Funktion zu schreiben, die der Nutzerin die nächste Zahl in dieser Folge zurückgibt. - -\inputcpp{funktion.cpp} - -\textbf{Praxis:}\footnote{In dieser Lektion gibt es ein paar mehr Aufgaben als in anderen Lektionen, lasst euch davon nicht entmutigen!} -\begin{enumerate} - \item Verändert das Programm in \texttt{funktion.cpp} so, dass es nicht die einzelnen Zahlen \texttt{x1}, \texttt{x2} und \texttt{x3}, sondern die Summe dieser ausgibt. -%Wirkt wie Kinderkram nicht zum Funktionskapitel, möchte aber nochmal den Unterschied zwischen Ausgabe und Rückgabe dadurch nochmal klarer machen - \item Kompiliert das angepasste Programm und lasst es im debugger Schritt für Schritt durchlaufen, setzt dafür wieder einen breakpoint für die \texttt{main}-Funktion. - Sobald der debugger euch anzeigt, als nächstes die Funktion ausführen zu wollen, \texttt{step} statt \texttt{next} aufrufen, sodass der debugger in die Funktion hineinspringt. - \item Schreibt eine Funktion die ein \texttt{double} entgegen nimmt und das Quadrat davon zurück gibt. - (Hierbei sollt ihr keine Pakete wie \texttt{math.h} oder \texttt{cmath} benutzen.) -\end{enumerate} - -\begin{spiel} -\begin{enumerate} - \item Schreibt eine Funktion (nach der Funktion \texttt{collatz} und vor \texttt{main}), die einen \texttt{int} entgegen nimmt und die Anzahl der Schritte bestimmt bis die Folge bei der 1 angekommen ist und diese als \texttt{int} zurückgibt. - (Die Funktion sollte also die Signatur \cppinline{int schritte(int x)} haben.) - Probiert die Funktion aus. - \item Versucht jetzt zwei Zahlen von der Nutzerin entgegen zu nehmen und vergleicht mithilfe von der gerade geschriebenen Funktion, welche Zahl mehr Schritte bis zur 1 braucht. - \item Was passiert, wenn ihr in einer Funktion den \texttt{return}-Ausdruck vor dem Ende eurer Funktion benutzt? - \item Vertauscht in \texttt{funktion.cpp} die Funktion \texttt{collatz} mit der Funktion \texttt{main} (verschiebt also die gesamte Funktion \texttt{collatz} an das Ende der Datei). - Versucht, die Datei zu kompilieren. - Was ist die Fehlermeldung des Compilers? - \item Verschiebt die Funktion \texttt{collatz} \emph{in} die \texttt{main}-Funktion (also irgendwo nach der öffnenden geschweiften Klammern, aber vor die dazu gehörige schließende). - Versucht, die Datei zu kompilieren. Was ist die Fehlermeldung des Compilers? - \item Implementiert die Funktion, die $x^n$ umsetzt, ignoriert dabei zunächst negative Exponenten. \\ - (Wie in Praxis 3, sollt ihr auch hier keine vorgefertigten Pakete benutzen. \emph{Tipp:} Die Signatur ist bereits oben gegeben, für den Funktionsrumpf könnten sich Schleifen eignen.) - \item Eure Funktion kann sich auch selbst aufrufen. Versucht damit eure Funktion auf negative Exponenten zu erweitern, indem ihr benutzt, dass gilt $x^{-n} = \Bigl(\frac{1.0}{x}\Bigr)^n$. - \item Schaut euch eure bisherigen Lösungen an. - Findet ihr noch häufiger Stellen, an denen ihr einzelne Teilprogramme in Funktionen auslagern könnt? -\end{enumerate} -\end{spiel} - -\textbf{Quiz 13}\\ -\textit{Welche Aussagen sind korrekt?} -\begin{enumerate}[label=\alph*)] - \item Unabhängig von den Parametern geben Funktionen immer den gleichen Wert zurück - \item Rückgaben einer Funktion müssen erst in einer Variable gespeichert werden, bevor sie weiterverwendet werden - \item Der Rückgabetyp muss mit einem der Parametertypen übereinstimmen - \item Eine Funktion kann beliebig viele Parameter haben -\end{enumerate} - diff --git a/basics/gdb.tex b/basics/gdb.tex deleted file mode 100644 index 1228bba..0000000 --- a/basics/gdb.tex +++ /dev/null @@ -1,96 +0,0 @@ -\lesson{Der Debugger} - -\textbf{Fehlerklassen} - -Es ist wichtig, früh zu verstehen, dass es verschiedene Klassen von Fehlern in -einem \Cpp Programm gibt, die sich alle zu unterschiedlichen Zeitpunkten -auswirken. Die Hauptsächliche Klasse von Fehlern, die wir bisher betrachtet -haben, sind \emph{Compilerfehler}. Sie treten -- wie der Name nahe legt -- zur -Compilezeit auf, also wenn ihr euer Programm kompilieren wollt. Meistens -handelt es sich hier um relativ einfach erkennbare Fehler in der Syntax (wie -zum Beispiel ein vergessenes Semikolon, oder eine vergessene geschweifte -Klammer), um fehlende header (wie die \verb|\#include <...>| heißen) oder um -undefinierte Variablen. - -Eine andere, besonders fiese Klasse von Fehlern haben wir in der Lektion des Kontrollflusses gelernt. -Wenn wir nämlich durch eine Variable teilen, und in -dieser Variable erst beim Programmlauf (zur \emph{Laufzeit}) eine 0 steht, so -tritt eine so genannte \emph{floating point exception} auf. Der Compiler hat -hier keine Chance, diesen Fehler zu erkennen - er weiß ja nicht, was der -Benutzer später hier eingibt! Da diese Klasse von Fehlern zur Laufzeit auftritt -heißen sie Laufzeitfehler. Und sie sind immer ein Zeichen von fundamentalen -Fehlern im Programm. Sie sind also die am schwersten aufzutreibenden Fehler, da -es keine automatischen Tools gibt, die uns bei ihrer Suche helfen. - -\textbf{gdb} - -Wir haben zwar bereits bei einem so offensichtlichen Fehler bereits gelernt, -wie wir diesen beheben können, dies ist allerdings nicht immer so einfach. -Wir lernen nun ein wichtiges Tool kennen, um Laufzeitfehler auch bei komplexeren Programmen -aufzuspüren, sodass wir wissen, wo wir mit der Lösung -ansetzen müssen: Den \emph{GNU debugger}, oder kurz gdb. - -Der Debugger ist eine Möglichkeit, unser Programm in einer besonderen Umgebung -laufen zu lassen, die es uns erlaubt es jederzeit anzuhalten. So kann man den Inhalt von -Variablen untersuchen oder auch Anweisung für Anweisung das Programm durchgehen. - -Damit wir das können, braucht der Compiler ein paar zusätzliche -Informationen über den Quellcode, die normalerweise verloren gehen. Wir müssen -dem Compiler dafür ein paar zusätzliche Optionen mitgeben: -\begin{minted}{bash} -g++ -O0 -g3 -o debugger debugger.cpp -\end{minted} -(Beachtet, dass im ersten Parameter erst ein großer Buchstabe o, dann eine 0 stehen) - -\newpage - -\begin{praxis} - - Wir möchten uns nun den Ablauf des Programms \texttt{debugger.cpp} anschauen. - \inputcpp{debugger.cpp} - - \begin{enumerate} - \item Kompiliert das Programm mit den neuen Optionen für den debugger. Ihr - könnt es dann mittels \verb|gdb ./debugger| im gdb starten. Ihr solltet - nun ein wenig Text ausgegeben bekommen und einen anderen prompt - (\texttt{(gdb)}). Ihr könnt den debugger jederzeit wieder verlassen, - indem ihr \texttt{quit} eingebt (falls ihr gefragt werdet, ob ihr euch - sicher seid, gebt \texttt{y} ein und drückt enter) - \item Zu allererst müssen wir einen so genannten \emph{breakpoint} setzen, - das ist ein Punkt im Programmablauf, an dem es stoppen soll, damit wir - entscheiden können, was wir tun wollen. \texttt{main} ist für die - meisten unserer Programme eine sichere Wahl: - \mint{text}|break main| - Dann können wir das Programm mit \texttt{run} starten. Wir sollten die - erste Anweisung unseres Programmes angezeigt bekommen. - \item Der Debugger wird euch jetzt immer sagen, welches die nächste - Anweisung ist, die er ausführen möchte. Mit \texttt{next} könnt ihr sie - ausführen lassen, mit \texttt{print a} könnt ihr euch den Inhalt von - \texttt{a} zu diesem Zeitpunkt anschauen, mit \texttt{print b} den von - \texttt{b} und so weiter. Geht das Programm Schritt für Schritt durch - und lasst euch die Werte von \texttt{a}, \texttt{b} und \texttt{c} in - jedem Schritt ausgeben. Wenn der debugger euch sagt, dass euer Programm - beendet wurde, gebt \texttt{quit} ein und beendet ihn. - \end{enumerate} -\end{praxis} - -\begin{spiel} -\begin{enumerate} - \item Im folgenden Programm \texttt{factorial.cpp} haben sich zwei Fehler eingeschlichen. Versucht diese mit \texttt{gdb} zu finden und zu beheben. - - \inputcpp{factorial.cpp} - - \item Ihr habt nun schon einige Programme kennen gelernt. Kompiliert sie - für den Debugger neu und untersucht sie genauso wie obiges Programm, - solange ihr Lust habt. -\end{enumerate} -\end{spiel} - -\textbf{Quiz 11}\\ -\textit{Was kann der Debugger?} -\begin{enumerate}[label=\alph*)] - \item Beim Fehler finden helfen - \item Fehler automatisch korrigieren - \item Das Programm Befehl für Befehl durchgehen - \item Dateien, die eigentlich einen Fehler werfen kompilieren -\end{enumerate} diff --git a/basics/hello_world.tex b/basics/hello_world.tex deleted file mode 100644 index ef6c74c..0000000 --- a/basics/hello_world.tex +++ /dev/null @@ -1,131 +0,0 @@ -\lesson{Hello world} - -Die erste Lektion beschäftigt sich alleine mit der Frage, was eigentlich eine -Programmiersprache überhaupt ist und wie wir den Computer dazu bringen können, -daraus etwas zu machen, was er ausführen kann. -Traditionell wird hierfür ein Programm herangezogen, das „Hallo Welt!“ ausgibt. \\ - - -\textbf{Wie entsteht ein Programm?} - -Wie bringen wir also den Computer dazu, diese Ausgabe zu generieren? - intern besteht er aus -vielen Transistoren (wenn ihr nicht wisst, was das ist, denkt an winzige -Schalter - näheres folgt im späteren Studium), die nur die Zustände „an“ und „aus“ kennen. -Wir müssen also die Anweisung „gebe Hallo Welt aus“ in ein Format übersetzen, was nur „an“ und -„aus“ bzw. „0“ und „1“ benutzt. - -Nun ist es umständlich, ein umfangreiches Programm in 0en und 1en zu schreiben. Deswegen benutzt man -heutzutage so genannte Hochsprachen, um Programme zu beschreiben. Wir -beschreiben also den Programmablauf in einer von Menschen lesbaren und -(leicht) verstehbaren Sprache, welche später in 0en und 1en übersetzt wird und anschließend vom Computer lesbar ist und ausgeführt werden kann. -Wir benutzen die Hochsprache \Cpp. Die Programmbeschreibung in -\Cpp legen wir dabei in einer einfachen Textdatei ab. Damit wir auf anhieb erkennen, um welche Hochsprache es sich handelt, hat es sich etabliert die Endung -\texttt{.cpp} an den Dateinamen anzuhängen. - -Die Übersetzung aus der von Menschen lesbarer Hochsprache in Maschinensprache erledigt für uns der \emph{Compiler}. -Der Compiler generiert aus der Textdatei also Maschinencode generiert. Der Compiler für \Cpp, den wir in diesem Kurs -benutzen wollen, heißt \texttt{g++}. - -Vereinfacht sieht der Prozess zur Programmerstellung also wie folgt aus: - -\begin{tikzpicture} - \node (1) at (0,0) [rectangle, draw] {Programmcode schreiben (Hochsprache)}; - \node (2) at (6,0) [rectangle, draw] {Kompilieren}; - \node (3) at (9,0) [rectangle, draw] {Ausführen}; - \draw[->, blue!50, very thick] (1) to (2); - \draw[->, blue!50, very thick] (2) to (3); -\end{tikzpicture} \\ - -\textbf{Wie gehe ich dabei vor?} - -Um den Programmcode in eine Textdatei zu schreiben verwenden wir einen Texteditor. -Dies kann mit fast jedem einfachen Texteditor bewerkstelligt werden. Populäre konsolenbasierte Editoren sind \texttt{vim} und \texttt{nano}. Es existieren aber auch grafische Editoren, die speziell für das Schreiben von Programmcode entwickelt wurden, wie \texttt{Visual Studio Code} oder \texttt{CLion}\footnote{https://www.jetbrains.com/community/education}. -Um dem Compiler zusagen, welche Textdatei er in ein Programm übersetzen soll, verwenden wir die sogenannte Shell. Vorerst reicht uns zu wissen, dass die Shell -ein Werkzeug ist, um dem Computer spezifisch zu sagen, was er machen soll (mehr dazu im folgenden Kapitel). In Ubuntu verwenden wir hierzu das Terminal, ebenso in MacOS, -unter Windows CMD oder Powershell. Ein Befehl für \texttt{g++} (dem Compiler für \Cpp) sieht beispielsweise wie folgt aus: - -\begin{center} - \texttt{g++ -o outputDatei zuKompilierendeDatei.cpp} -\end{center} -Hierbei legen wir mit dem Parameter \texttt{-o} (o für output) und dem ersten darauf folgenden Argument den Namen der Ausgabedatei fest. - -Nachdem \texttt{g++} uns also ein Maschinencodefile -- die \texttt{outputDatei} -- -erzeugt hat, können wir es zur Ausführung bringen. Dies kann im Terminal mit einem Punkt und einem Slash vor dem Dateinamen geschehen. Also: -\begin{center} - \texttt{./outputDatei} -\end{center} - - - -\begin{praxis} - - \textbf{Erstes Programm in \Cpp schreiben} - - \begin{enumerate} - \item Erstelle eine neue, leere Datei in einem Editor deiner Wahl. - - \item Kopiere folgenden Programmcode in den Texteditor und speichere ihn in einer Datei mit dem Namen „helloworld.cpp“ ab. - Das nähere Verständnis des Programmcodes ist an dieser Stelle nicht notwendig. - \end{enumerate} - - \inputcpp{helloworld.cpp} - - \textbf{\Cpp-Code komplieren und Programm erstellen } - - \begin{enumerate} - \item Öffne ein Terminal (Konsole), ihr findet das Terminal unter Ubuntu oben links unter „Applications“ als „Terminal“ oder mittig unten als das zweite Symbol von links. - \item Wechselt mit dem Befehl \texttt{cd [PFAD]} in das Verzeichnis (Ordner), indem ihr eure Textdatei erstellt habt (\texttt{[PFAD]} muss hierbei durch den Speicherort der Datei ersetzt werden). - Was dieser Befehl genau tut und wie er funktioniert, erfahrt ihr in Lektion 2. - \item In diesem Verzeichnis liegt nun eine Datei mit dem Namen \texttt{helloworld.cpp}. - Benutzt \texttt{g++}, um diese zu einer Datei (in diesem Fall dem Programm) \texttt{hello} zu - kompilieren. Orientiert euch dazu an den folgenden Befehlen. (siehe Diagramm) - \item Führt die Datei \texttt{hello} aus. - \end{enumerate} -\end{praxis} - - -Zur besseren Übersichtlichkeit hier der ganze Vorgang noch mal in einem -Diagramm: - -% TODO: Buttugly, but well... - its gonna stay this way -\begin{center} - \resizebox{\textwidth}{!}{ - \begin{tikzpicture} - \node (nHelloWorldCpp) [ shape=rectangle, rounded corners = 0.1cm, draw=black, inner xsep=0.5cm, inner ysep = 0.3cm ] {\texttt{helloworld.cpp}}; - \node (nHello) [ right of = nHelloWorldCpp, node distance = 9.5cm, shape=rectangle, rounded corners = 0.1cm, draw = black, inner xsep = 0.5cm, inner ysep = 0.3cm ] {\texttt{hello}}; - \draw [->, thick, shorten >= 2pt, shorten <= 2pt ] (nHelloWorldCpp) -- (nHello) node [ midway, above, font = \small ] { \texttt{g++ -o hello helloworld.cpp}} ; - \node (nOutput) [ right of = nHello, node distance = 5cm, shape=rectangle ] {\texttt{"Hallo Welt!"}}; - \draw [->, thick, shorten <= 2pt] (nHello) -- (nOutput) node [ midway, above ] {\texttt{./hello}}; - \end{tikzpicture} - } -\end{center} - -\newpage - -\begin{spiel} - -Ihr könnt nun versuchen, den Quellcode selbst zu verändern und damit ein wenig -herumzuspielen. Öffnet dazu einen Editor und öffnet die Datei -\texttt{vorkurs/lektion01/helloworld.cpp}\footnote{am besten öffnet ihr in VSCode den gesamten Vorkurs-Ordner}. Denkt daran, nach jeder Änderung die Datei zu speichern und -im Terminal neu zu kompilieren und auszuführen. - -Dinge, die ihr ausprobieren könntet sind zum Beispiel: -\begin{enumerate} - \item Was passiert, wenn ihr „Hello world!“ in etwas anderes ändert? - \item Was passiert, wenn ihr die erste Zeile löscht (der Originalquellcode - ist in diesem pdf enthalten, ihr könnt sie also später wieder - herstellen)? - \item Was passiert, wenn ihr das „\verb|<< std::endl|“ löscht? - \item Wie könnte man mehrere Sätze ausgeben? Wie könnte man mehrere Zeilen - ausgeben? -\end{enumerate} -\end{spiel} - -\textbf{Quiz 1}\\ -\textit{Was passiert, wenn ihr \texttt{Hello world} durch etwas anderes ersetzt?} -\begin{enumerate}[label=\alph*)] - \item Das andere wird ausgegeben - \item Es gibt einen Fehler - \item Das Programm tut garnichts mehr - \item Das Programm gibt trotzdem \texttt{Hello world} aus -\end{enumerate} diff --git a/basics/input.tex b/basics/input.tex deleted file mode 100644 index 015a604..0000000 --- a/basics/input.tex +++ /dev/null @@ -1,56 +0,0 @@ -\lesson{Input und Output} - -Nachdem wir ein bisschen Vertrauen in die shell entwickelt haben und zumindest -bereits unser erstes Programm kompiliert, wollen wir nun etwas spannendere -Dinge tun. Nach wie vor müsst ihr nicht jede Zeile eures Programmes verstehen. -Sollte euch bei einer bestimmten Zeile trotzdem interessieren, was genau sie -tut, versucht doch eventuell sie zu entfernen, das Programm zu kompilieren und -schaut, was sich ändert. - -Wir wollen uns nun mit grundlegendem input und output vertraut machen, denn -erst wenn euer Programm mit einer Benutzerin interagiert, wird es wirklich -nützlich. Wir haben in der ersten Lektion bereits \texttt{cout} (für -\emph{console out}) kennengelernt, um Dinge auszugeben. Nun nutzen wir -\texttt{cin}, um Eingaben des Benutzers entgegen zu nehmen. Jedes Programm -unter Linux (und übrigens auch Mac OS oder Windows) kann auf diese Weise -Eingaben von der Nutzerin entgegen nehmen und Ausgaben liefern. Das ist auch -der Grund, warum die Konsole so wichtig ist und es viele Dinge gibt, die nur -mittels einer Konsole gelöst werden können: Während es viele Stunden dauert, -ein grafisches Interface zu programmieren, über die man mit dem Programm mit -der Maus kommunizieren kann, kann praktisch jeder ein textbasiertes -Konsoleninterface schreiben. Linux ist ein Ökosystem mit einer gewaltigen -Anzahl tools für jeden denkbaren Zweck und bei den meisten haben die Autorinnen -sich nicht die Mühe gemacht, extra eine grafische Oberfläche zu entwickeln. - -Nun aber direkt zur Praxis: - -\begin{praxis} - \begin{enumerate} - \item Öffnet die Datei \texttt{vorkurs/lektion03/helloyou.cpp} in eurem Texteditor - \item Öffnet ein Terminal und wechselt in das Verzeichnis \texttt{vorkurs/lektion03} - \item Kompiliert im Terminal die Datei (\texttt{g++ -o helloyou - helloyou.cpp}) und führt sie aus (\texttt{./helloyou}) - \item Versucht verschiedene Eingaben an das Programm und beobachtet, was passiert - \end{enumerate} - - \inputcpp{helloyou.cpp} -\end{praxis} - -\begin{spiel} -\begin{enumerate} - \item Versucht, zu verstehen, was die einzelnen Teile des Programms tun. An - welcher Stelle erfolgt die Eingabe? Was passiert dann damit? - \item Erweitert das Programm um eigene Fragen und Ausgaben. Vergesst nicht, - dass ihr das Programm nach jeder Änderung neu kompilieren und testen - müsst. -\end{enumerate} -\end{spiel} - -\textbf{Quiz 3}\\ -\textit{Was passiert, wenn \texttt{std::cin >> eingabe;} vor \texttt{std::string eingabe;} steht?} -\begin{enumerate}[label=\alph*)] - \item Das Programm funktioniert ganz normal - \item Es wird \texttt{eingabe} ausgegeben - \item Es wird \texttt{Hello} ausgegeben - \item Das Programm kann nicht kompiliert werden -\end{enumerate} diff --git a/basics/intro.tex b/basics/intro.tex deleted file mode 100644 index 664f437..0000000 --- a/basics/intro.tex +++ /dev/null @@ -1,54 +0,0 @@ -\chapter{Die Basics} -\pagestyle{empty} - -Im Ersten Kapitel werden wir die Grundlagen der Programmierung lernen. - -Wir werden rausfinden, was ein Compiler ist, wie ein Programm abläuft und wie -man es startet. Wir werden Benutzereingaben verarbeiten und Ausgaben an die -Nutzerin geben. Wir lassen den Computer Rechnungen für uns anstellen und -lernen, was der Kontrollfluß ist -- und wie man ihn beeinflusst. Zuletzt werden -wir Vektoren kennenlernen und unser erstes nützliches Progamm schreiben. - -\pagestyle{fancy} -\input{basics/hello_world} -\input{basics/konsole} -\input{basics/input} -\input{basics/fehler} -\input{basics/variablen} -\input{basics/manpages} -\input{basics/arith} -\input{basics/kontrollfluss} -\input{basics/rechte} -\input{basics/schleifen} -\input{basics/gdb} -\input{basics/style} -\input{basics/funktionen} -\input{basics/stdbib} -\input{basics/vektoren} -\input{basics/warning} -\input{basics/tictactoe1} -\input{basics/compiling.tex} -\input{basics/tictactoe2} - -\clearpage -\pagestyle{empty} - -Ihr habt hiermit das erste Kapitel unseres -Programmiervorkurses abgeschlossen. Wir hoffen, ihr hattet dabei Spaß und habt -genug gelernt, um euch gut auf eure erste Programmiervorlesung vorbereitet zu -fühlen. - -Rekapitulieren wir noch einmal unsere Eingangs formulierten „Lernziele“, was -wir uns wünschen würden, dass ihr aus diesem Vorkurs mitnehmt: -\begin{itemize} - \item Ein Computer ist keine schwarze Magie - \item Eine Konsole ist keine schwarze Magie - \item Programmieren ist keine schwarze Magie - \item Ihr wisst, wo ihr anfangt, wenn die Aufgabe ist „schreibt ein - Programm, das\dots“ - \item Ihr entwickelt Spaß daran, Programmieraufgaben zu lösen - \item Ihr wisst, was ihr tun könnt, wenn etwas nicht funktioniert -\end{itemize} - -Von wie vielen davon habt ihr das Gefühl, sie erreicht zu haben? Wir würden uns -über euer Feedback freuen! diff --git a/basics/konsole.tex b/basics/konsole.tex deleted file mode 100644 index eba2401..0000000 --- a/basics/konsole.tex +++ /dev/null @@ -1,83 +0,0 @@ -\lesson{Die Shell} - -Wenn ihr bisher nur mit Windows oder Mac gearbeitet habt, habt ihr -wahrscheinlich in der letzten Lektion nebenbei etwas neues Kennen gelernt: Die -Shell. - -Auch wenn sich unter Linux zunehmend Desktopumgebungen, wie man sie von -kommerziellen Betriebssystemen kennt verbreiten, bleibt die Shell immer noch das -Mittel der Wahl, wenn man sich mit dem System auseinander setzen, oder auch -allgemein arbeiten will. Wir erachten zumindest die Shell als wichtig genug, um -euch direkt zu Beginn damit zu konfrontieren. - -Wann immer ihr über die Anwendungen ein Terminal startet, wird dort drin -automatisch auch eine Shell gestartet. Die beiden Konzepte sind tatsächlich so -eng miteinander verknüpft, dass ihr euch um die Unterschiede erst einmal keine -Gedanken machen müsst - wann immer ihr Shell oder Terminal hört, denkt einfach -an das schwarze Fenster mit dem Text. Das ist auch das wesentliche Merkmal der -Shell, sie ist ein Textbasiertes interface zu eurem Computer. Ihr gebt Befehle -ein, sie gibt euch Text zurück und auf diese Weise könnt ihr eigentlich alles -machen, was ihr sonst gewohnterweise mit der Maus und grafischen Oberflächen -tun würdet. - -Wenn die Shell auf eure Befehle wartet, zeigt sie euch den so genannten -\emph{Prompt} an. Er enthält unter anderem euren Nutzernamen und das aktuelle -Verzeichnis ($\sim$ steht dabei für euer Nutzerverzeichnis, ein spezieller -Ordner, der eurem Account zugeordnet ist und in dem ihr alle Rechte besitzt, -dieser wird auch \emph{home} genannt). - -Wenn ihr in ein anderes Verzeichnis wechseln wollt, könnt ihr das (wie ihr -bereits in der ersten Lektion gelernt habt) mit dem Befehl \texttt{cd} tun, -gefolgt von dem Namen des Verzeichnis. Um zurück zu gehen, könnt ihr das -spezielle Verzeichnis \texttt{..} (also zwei Punkte) angeben, welches für das -nächst höher liegende Verzeichnis steht. Wenn ihr euch den Inhalt des -Verzeichnisses anschauen wollt, könnt ihr dafür den Befehl \texttt{ls} -benutzen. Um herauszufinden, in welchem Verzeichnis ihr euch befindet, könnt -ihr \texttt{pwd} nutzen, zum Kompilieren von \Cpp-Programmen habt ihr den Befehl -\texttt{g++} kennengelernt. Solltet ihr Hilfe zu irgendeinem Befehl benötigen, -könnt ihr den Befehl \texttt{man} (für „Manual“) geben, gefolgt von dem Befehl, -zu dem ihr Hilfe braucht (über \texttt{man} werden wir später noch -ausführlicher reden). - -\newpage - -\begin{praxis} - \begin{enumerate} - \item Öffnet ein Terminal und gebt die folgenden Befehle ein: - \inputshell{basics.sh} - \end{enumerate} -\end{praxis} - -\begin{spiel} - \begin{enumerate} - \item Versucht selbst durch euer Nutzerverzeichnis (\emph{home}) zu navigieren. - Wie viele Lektionen hat der Vorkurs in diesem Verzeichnis? - \item Was passiert, wenn ihr euer Homeverzeichnis verlasst (\texttt{cd ..} - während ihr darin seid)? - \item Versucht in der manpage von ls (\texttt{man ls}) zu stöbern und die - verschiedenen Parameter, mit denen ihr das Verhalten steuern könnt zu - erforschen. Findet ihr heraus, wie ihr den Verzeichnisinhalt in einem - langen Listenformat (long listing format) anzeigen lassen könnt (in dem - unter anderem auch die Dateigröße zu jeder Datei steht). - Hinweis: mit \texttt{\textbackslash Suchbegriff} kann innerhalb von \texttt{man} gesucht werden. - \item Um schnell mit der Shell zu arbeiten gibt es einige Tricks. - Damit lange Dateinamen nicht immer komplett eingegeben werden müssen, gibt es die sogenannte \texttt{tab completion}. - Um bereits eingegebene Befehle nochmals auszuführen die \texttt{history}. Finde heraus wie diese funktionieren! - \end{enumerate} - \end{spiel} - - -Falls euch das alles verwirrt, fragt entweder direkt nach oder wartet auf -Lektion 6, da geht es zu Manpages noch mal ins Detail. - -Ihr findet unter \url{http://blog.ezelo.de/basic-linux-befehle/} auch noch mal -die wichtigsten Befehle zusammengefasst. - -\textbf{Quiz 2}\\ -\textit{Was passiert, wenn ihr \texttt{cd .} ausführt?} -\begin{enumerate}[label=\alph*)] - \item Ihr geht in ein zufälliges Unterverzeichnis - \item Ihr bleibt im gleichen Verzeichnis - \item Ihr verlasst euer aktuelles Verzeichnis - \item Ihr geht direkt in euer Homeverzeichnis -\end{enumerate} \ No newline at end of file diff --git a/basics/kontrollfluss.tex b/basics/kontrollfluss.tex deleted file mode 100644 index 8a11c6d..0000000 --- a/basics/kontrollfluss.tex +++ /dev/null @@ -1,96 +0,0 @@ -\lesson{Der Kontrollfluss} - -Wer versucht hat in der vergangenen Lektion Praxisaufgabe 5 zu lösen, wird auf der Konsole eine ähnliche Ausgabe wie folgt bekommen - einen Fehler: -\begin{minted}{text} -Gebe eine Zahl ein: 5 -Gebe noch eine Zahl ein: 0 -Floating point exception -\end{minted} - -Das Programmcode hierfür kann beispielsweise wie folgt aussehen. - -\inputcpp{arith4.cpp} - -Wenn wir diesen Fehler beheben wollen, haben wir eigentlich nur zwei -Möglichkeiten: Die erste ist, die Schuld auf die Benutzerin zu schieben, warum -versucht sie auch, eine 0 einzugeben? Ich hoffe, ihr stimmt zu, dass das nicht -sehr freundlich wäre. Stellt euch vor, jedes mal, wenn ihr in einem Programm -einen Wert eingebt, auf den das Programm nicht vorbereitet ist, würde es direkt -abstürzen. Das fändet ihr vermutlich nicht so gut, es sollte doch zumindest mal -eine Fehlermeldung ausgeben und die Nutzerin informieren, dass sie was falsch -gemacht hat. - -Und das ist der zweite Weg, den wir jetzt einschlagen wollen. Unser Programm -sollte am Besten, nachdem es die Eingabe von der Benutzerin entgegen genommen -hat, einfach überprüfen, ob die Division erlaubt ist oder nicht. Sollte die -Nutzerin eine 0 eingegeben haben, sollte es auf den Fehler hinweisen und sich -beenden, sonst sollte es den Quotienten ausgeben. Diese Abhängigkeit des -Verhaltens eines Programms von den Eingaben, bezeichnen wir als -\emph{Kontrollfluss}, man kann das mit einem Diagramm verdeutlichen: - -\begin{center} - \begin{tikzpicture}[auto, node distance=3cm,>=latex'] - \tikzstyle{block} = [draw, fill=blue!20, rectangle, minimum height=3em, minimum width=6em] - - \node [block] (start) {Input}; - \node [block, right of=start] (if) { $a=0$? }; - \node [block, right of=if, node distance=4cm] (fehler) { Gib Fehler aus }; - \node [block, below of=fehler,node distance = 2cm] (quotient) { Gib Quotient aus }; - \node [block, right of=fehler, node distance = 3.5cm] (ende) { Ende }; - - \draw [->] (start) -- node {} (if); - \draw [->] (if) -- node {\texttt{ja}} (fehler); - \draw [->] (if.south) |- node [above, near end] {\texttt{nein}} (quotient); - \draw [->] (quotient) -| node {} (ende); - \draw [->] (fehler) -- node {} (ende); - \end{tikzpicture} -\end{center} - -Die einfachste Möglichkeit, den Kontrollfluss zu ändern, besteht in so -genannten „bedingten Anweisungen“: -\inputcpp{if.cpp} - -In den Zeilen 12 bis 20 sehen wir, wie eine solche Bedingte Anweisung in \Cpp -aussieht. Wir erkennen relativ direkt unser Diagramm hier wieder: In Zeile 12 -steht der „$b=0$?“ Block, in den Zeilen 13 bis 17 steht der „Gib Fehler aus“ -Block und in Zeile 19 der „Gib den Quotienten aus“ Block. Die Blöcke lassen sich auch gut anhand der geschweiften Klammern und der Einrückung erkennen. Wir empfehlen euch, solche logischen Blöcke einzurücken, um die Lesbarkeit des Codes zu verbessern. Eine ausführlichere Erklärung zum coding style gibt es in Lektion \ref{sec:codingstyle}. - -Beachtet allerding die doppelten Gleichheitszeichen in Zeile 12. \Cpp hat -getrennte Operatoren für Vergleiche und Zuweisungen - Doppelte -Gleichheitszeichen bedeuten Vergleich („sind diese beiden gleich?“), ein -einfaches Gleichheitszeichen bedeutet Zuweisung („mache diese beiden gleich!“). - -\begin{praxis} - \begin{enumerate} - \item Nutzt Google, um herauszufinden, welche anderen Vergleichsoperatoren - es in \Cpp noch gibt. Versucht, das Programm so zu verändern, dass es - auf Ungleichheit testet, statt auf Gleichheit (sich sonst aber genauso - verhält). - - \item Wie würdet ihr testen, ob zwei Zahlen durch einander teilbar sind - (Tipp: Ihr kennt bereits die Division mit Rest in \Cpp (modulo))? - Schreibt ein Programm, welches zwei Zahlen von der Nutzerin entgegen - nimmt und ausgibt, ob die zweite Zahl die erste teilt. - \end{enumerate} -\end{praxis} - -\begin{spiel} -\begin{enumerate} - \item Testet mit verschiedenen Eingaben, was passiert, wenn ihr in - \texttt{if.cpp} statt zwei Gleichheitszeichen nur eines benutzt. - - \item Schreibt ein Programm, welches die Benutzerin fragt, wie sie heißt. - Gibt sie euren eigenen Namen ein, soll das Programm begeistert über die - Namensgleichheit sein, sonst sie einfach begrüßen. -\end{enumerate} -\end{spiel} - -\textbf{Quiz 8}\\ -\textit{Welche Aussagen sind korrekt?} -\begin{enumerate}[label=\alph*)] - \item Mit \texttt{=} vergleicht man. - \item Es darf immer nur ein \texttt{if} vor einem \texttt{else} kommen. - \item Es darf nur ein else pro Fallunterscheidung geben - \item Bei falscher Einrückung funktioniert das Programm nicht -\end{enumerate} - diff --git a/basics/loesungen.tex b/basics/loesungen.tex deleted file mode 100644 index 089d070..0000000 --- a/basics/loesungen.tex +++ /dev/null @@ -1,19 +0,0 @@ -\textbf{Lösungen zu den Quizfragen:} -\begin{itemize} - \item Quiz 0: b, c, d - \item Quiz 1: a - \item Quiz 2: b - \item Quiz 3: d - \item Quiz 4: a, b, (c $\rightarrow$ frag einen Tutor) - \item Quiz 5: a, b, c - \item Quiz 6: a, b, c - \item Quiz 7: b - \item Quiz 8: c - \item Quiz 9: a, c, d - \item Quiz 10: a, b - \item Quiz 11: a, c - \item Quiz 12: a, d - \item Quiz 13: d - \item Quiz 14: a, b, d - \item Quiz 15: b, c, d -\end{itemize} \ No newline at end of file diff --git a/basics/manpages.tex b/basics/manpages.tex deleted file mode 100644 index 740a0b9..0000000 --- a/basics/manpages.tex +++ /dev/null @@ -1,112 +0,0 @@ -\lesson{Manpages} - -Wir machen eine kurze Pause vom \Cpp und schauen uns in der Zwischenzeit -\emph{man pages} an. Wie wir bereits fest gestellt haben, kann man diese -benutzen, um sich mehr Informationen über Befehle anzeigen zu lassen. Wir -wollen uns jetzt genauer anschauen, wie man all die Informationen in einer man -page am Besten konsumiert. - -Wir schauen uns das am Beispiel der Manpage \texttt{man cp} an (\texttt{cp} ist -der Befehl zum Kopieren von Dateien). - -\begin{praxis} - \begin{enumerate} - \item Öffnet eine Konsole und gebt \texttt{man cp} ein. - \end{enumerate} -\end{praxis} - - Die man page besteht aus mehreren \emph{Sections}. Welche sections genau es - gibt, hängt von der man page ab, aber meistens gibt es mindestens die folgenden - sections: - \begin{description} - \item[\texttt{NAME}] - Gibt euch den Namen des Befehls und eine Einzeilige Beschreibung an - \item[\texttt{SYNOPSIS}] - Gibt euch die generelle Benutzung des Befehls an. In diesem Fall gibt - es drei mögliche Formen. Allen gemein ist, dass man zunächst - \texttt{cp} eingibt, darauf folgen Optionen. Wie der Rest interpretiert - wird, hängt dann vom Rest ab. Werden zwei weitere Parameter angegeben, - wird der erste als Quelle, der zweite als Ziel interpretiert (erste - Form). Werden mehr Parameter angegeben, wird das letzte als - Verzeichnis, in das man alle anderen kopieren will interpretiert - (zweite Form). In der dritten Form (wenn \texttt{-t} angegeben wird) - wird hingegen der \emph{erste} Parameter als das Zielverzeichnis - interpretiert, in das alle anderen Dateien kopiert wird. - - Es gibt eine Vielzahl von Konventionen für diesen Bereich, eckige - Klammern bedeuten z.B. dass dieser Teil auch weggelassen werden darf, - drei Punkte bedeuten, dass hier mehrere solche Dinge stehen können. - - Dieser Bereich ist der, der am Interessantesten für euch ist, wenn ihr - „einfach schnell wissen wollt, wie es funktioniert“. - \item[\texttt{DESCRIPTION}] - Hier wird ausführlicher beschrieben, was der Befehl tut. Hier werden - auch alle möglichen Optionen beschrieben, die wir dem Befehl bei - \texttt{[OPTION]...} mitgeben können. Die wichtigen Informationen - stehen meistens irgendwo in diesem Bereich. - \item[\texttt{AUTHOR}, \texttt{REPORTING BUGS}, \dots] - Hier stehen weitere Hintergrundinformationen, die meistens eher für - Entwicklerinnen interessant sind. - \item[\texttt{SEE ALSO}] - Auch eine wichtige section für euch: Wenn ihr die gewünschte - Information nicht gefunden habt, oder ihr nicht den richtigen Befehl - gefunden habt, stehen hier manchmal verwandte Befehle oder Quellen - weiterer Informationen. - \end{description} - - Man pages sind häufig sehr umfangreich und enthalten viel mehr Informationen, - als ihr euch gerade wünscht. Es ist nicht immer einfach, die gerade relevanten - Informationen heraus zu filtern und es gibt nichts frustrierenderes, als einen - Befehl gerade dringend zu brauchen, aber nicht zu kennen und sich erst durch - eine lange man page lesen zu müssen. - - Dennoch ist es eine sehr hilfreiche Fähigkeit, zu wissen, wie man man pages - liest und sich einfach in einem ruhigen Moment mal durch die ein oder andere - man page durch zu lesen. Häufig lernt man dabei neue Dinge, manchmal macht es - einem das Leben irgendwann sehr viel leichter, sie zu wissen. - - Habt von daher Geduld, wenn euch eine wirsche Linux-Expertin auf die Frage, wie - ihr unter Linux euren Laptop in den Ruhemodus versetzt ein schnelles „man - pm-suspend“ antwortet. Mit ein bisschen Übung wird euch das tatsächlich - hinreichend schnell zur richtigen Lösung verhelfen. - - -Und wenn ihr mal wirklich keine Zeit habt, die ganze page zu lesen, könnt ihr mit \texttt{/} auch nach Begriffen innerhalb der page suchen: Zum Beispiel \texttt{/close} - -\begin{praxis} - \begin{enumerate}\addtocounter{enumi}{1} - \item Öffnet die man page von \texttt{ls}. Findet die Optionen fürs Lange - Listenformat (long listing format), zum Sortieren nach Dateigröße - und um auch versteckte Dateien (unter Linux sind das alle, die mit - \texttt{.} anfangen) anzuzeigen und probiert sie aus. - \item Was ist der Unterschied zwischen \texttt{ls -a} und \texttt{ls -A}? - Probiert beides aus. Das ist auf den ersten Blick nicht so leicht zu sehen - Fragt uns im einfach wenn ihr es nicht findest. - \item Nutzt \texttt{cp} um eine Datei zu kopieren. Sucht euch dafür - irgendeine \texttt{.cpp}-Datei aus dem Vorkurs-Programm und kopiert sie - in euer Homeverzeichnis (ihr könnt dafür eine Tilde (\texttt{\~}) - benutzen). - \end{enumerate} -\end{praxis} - -\begin{spiel} - \begin{enumerate} - \item Wie über so gut wie jeden Befehl gibt es auch über \texttt{man} eine - manpage. Schaut euch mal \texttt{man man} an. - \item Befehle, die für euch im späteren Leben interessant sein könnten sind - z.B. \texttt{ls}, \texttt{cp}, \texttt{mkdir}, \texttt{grep}, \texttt{cat}, - \texttt{echo}, \texttt{mv}, \dots. Ihr könnt ja schon einmal in ein - oder zwei dieser manpages hinein schauen, und ein oder zwei Befehle - ausprobieren. Aber ihr müsst das jetzt auf keinen fall alles im Kopf - behalten. - \end{enumerate} -\end{spiel} - -\textbf{Quiz 6}\\ -\textit{Was findet man alles in einer Manpage?} -\begin{enumerate}[label=\alph*)] - \item Nützliche Informationen - \item viel Text - \item wie man einen Befehl verwendet - \item warum der Befehl erfunden wurde -\end{enumerate} diff --git a/basics/rechte.tex b/basics/rechte.tex deleted file mode 100644 index afe6d97..0000000 --- a/basics/rechte.tex +++ /dev/null @@ -1,94 +0,0 @@ -\lesson{Dateirechte} - -Wir machen mal wieder eine kurze Pause von \Cpp um euch ein weiteres wichtiges -Konzept der Linux-Welt nahe zu bringen: Dateirechte. - -Unter Windows seid ihr es wahrscheinlich gewohnt, dass der Dateiname festlegt, -wie mit der Datei umgegangen wird -- eine \texttt{.doc} wird in Word geöffnet, -eine \texttt{.zip} in einem installierten Packprogramm, eine \texttt{.bmp} -vermutlich in Windows Paint und eine \texttt{.exe} wird ausgeführt. - -Das Konzept der Dateierweiterung hat es auch in die Linuxwelt geschafft, ist -hier aber deutlich weniger wichtig. Insbesondere gibt es keine Dateierweiterung -\texttt{.exe}. Stattdessen hat jede Datei einen bestimmten Modus. Eine Datei -kann ausführbar sein, oder nicht. Sie kann lesbar sein, oder nicht. Sie kann -schreibbar sein, oder nicht. Nicht nur das, jede Datei gehört auch einer -bestimmten Nutzerin und einer bestimmten Nutzerinnengruppe und Ausführbarkeit, -Lesbarkeit oder Schreibbarkeit ist getrennt eingestellt für die Besitzerin der -Datei, der Gruppe, der die Datei gehört und für alle anderen. Eine Datei kann -also z.B. lesbar sein, für alle Nutzerinnen, aber nur eine bestimmte Gruppe von -Nutzerinnen darf sie ausführen und nur eine einzige Nutzerin sie bearbeiten. All -dies wird in neun so genannten \emph{Permission bits} festgehalten (ein -\emph{Bit} ist die kleinste Einheit an Information, es kodiert genau „ja“ und -„nein“, oder „null“ und „eins“, oder „ein“ und „aus“). - -Ihr könnt euch die Besitzerin, die Gruppe, und die permission bits einer Datei -mithilfe von \texttt{ls -l} anschauen. Der output von \texttt{ls -l} ist in -mehreren Spalten angeordnet: -\begin{enumerate} - \item In der ersten Spalte stehen die Dateiberechtigungen in Form eines 10 - Zeichen langen Strings. Jedes Zeichen steht dabei für ein permission - bit kann dabei entweder ein \texttt{-}, oder ein Buchstabe sein, wobei - \texttt{-} bedeutet, dass das entsprechende Bit nicht gesetzt ist. Die - Bits bedeuten (von links nach rechts gelesen) - \begin{itemize} - \item \texttt{\underline{d}irectory} - \item \texttt{\underline{r}eadable} für die Eigentümerin - \item \texttt{\underline{w}ritable} für die Eigentümerin - \item \texttt{e\underline{x}ecutable} für die Eigentümerin - \item \texttt{\underline{r}eadable} für die Gruppe - \item \texttt{\underline{w}ritable} für die Gruppe - \item \texttt{e\underline{x}ecutable} für die Gruppe - \item \texttt{\underline{r}eadable} für alle Nutzerinnen - \item \texttt{\underline{w}ritable} für alle Nutzerinnen - \item \texttt{e\underline{x}ecutable} für alle Nutzerinnen - \end{itemize} - \item Nummer an hardlinks (das braucht euch nicht sonderlich interessieren) - \item Nutzername der Eigentümerin - \item Gruppe, der die Datei gehört - \item Dateigröße - \item Datum der letzten Änderung - \item Dateiname -\end{enumerate} - -Wenn ihr die Berechtigungen von Dateien ändern wollt, könnt ihr dazu -\texttt{chmod} benutzen (wenn ihr wissen wollt, wie man es benutzt: \texttt{man - chmod}), dazu muss sie euch aber gehören. Wenn ihr die Eigentümerin einer Datei -ändern wollt, könnt ihr dazu \texttt{chown} nutzen -- dazu müsst ihr aus -Sicherheitsgründen allerdings Administratorin sein. - -\begin{praxis} - \begin{enumerate} - \item Geht in ein Verzeichnis, in dem eine \texttt{.cpp}-Datei liegt und - kompiliert sie. Macht ein \texttt{ls -l} und vergleicht die Rechte der - \texttt{.cpp}-Datei mit der kompilierten Datei. - \item In der Datei \texttt{/etc/shadow} stehen in verschlüsselter Form - gespeichert die Kennwörter aller Benutzerinnen auf dem System. Macht ein - \texttt{ls -l /etc/shadow} und schaut euch die Dateirechte an. Welche - Bits sind gesetzt? - \end{enumerate} -\end{praxis} - -\begin{spiel} -\begin{enumerate} - \item Versucht, \texttt{/etc/shadow} in einem Editor zu öffnen. - \item Legt (z.B. mit dem Texteditor) eine Datei (Es geht nicht um - Kompilierung, also muss das keine \texttt{.cpp}-Datei sein. Gebt der - Datei am Besten die Erweiterung \texttt{.txt}) in Eurem Homeverzeichnis - an und macht sie dann mit \texttt{chmod a+w} world-writable - (\texttt{a+w} heißt „füge das Recht Schreibbarkeit für alle Nutzerinnen - hinzu“). Lasst eure Sitznachbarin die Datei an ihrem Rechner öffnen - (ihr könnt mittels \texttt{pwd} herausfinden, in welchem Ordner sie - suchen muss) und euch eine Nachricht hinein schreiben. Schaut nach - (indem ihr die Datei neu öffnet) ob ihr die Nachricht lesen könnt. -\end{enumerate} -\end{spiel} - -\textbf{Quiz 9}\\ -\textit{Welche Bits existieren?} -\begin{enumerate}[label=\alph*)] - \item readable für Gruppe - \item Rechte dürfen nicht geändert werden - \item executable für alle Nutzerinnen - \item writable für Eigentümerin -\end{enumerate} diff --git a/basics/schleifen.tex b/basics/schleifen.tex deleted file mode 100644 index db80fec..0000000 --- a/basics/schleifen.tex +++ /dev/null @@ -1,126 +0,0 @@ -\lesson{Schleifen} - -Wir können mit bedingten Anweisungen den Kontrollfluss schon hilfreich -beeinflussen. Aber nicht alle Dinge, die wir unseren Computer anweisen wollen -zu tun, können wir alleine mit bedingten Anweisungen ausdrücken. Wir können -zwar zum Beispiel testen, ob eine Zahl, eine andere teilt. Was aber, wenn wir -testen wollen, ob eine Zahl eine Primzahl ist? Wir könnten jetzt beginnen, jede -Menge bedingter Anweisungen zu machen, „ist die Zahl durch 2 teilbar, wenn ja, -dann ist es keine, sonst teste, ob sie durch 3 teilbar ist, wenn ja, dann ist -es keine, sonst teste, ob sie durch 5 teilbar ist, wenn ja, dann ist es -keine\dots“, aber es sollte offensichtlich sein, dass wir so nur endlich viele -Teilbarkeiten überprüfen können. Wir müssen zwar für jede Zahl nur endlich -viele Teiler überprüfen, aber wenn die Zahl von der Nutzerin eingegeben wird, -wissen wir im Voraus nicht, wie viele das sind! - -Für solche Aufgaben wurden Schleifen erfunden. Sie sind ein Mittel, um eine -Menge von Anweisungen häufig auszuführen, solange eine von uns fest gelegte -Bedingung erfüllt ist. Wenn wir zum Beispiel testen wollen, ob eine Zahl eine -Primzahl ist, wäre ein einfacher Algorithmus die so genannte Probedivision: -Gehe von 2 aufwärts alle Zahlen (die kleiner sind, als die Eingabe) durch, -teste, ob sie die Eingabe teilen -- wenn ja, merken wir uns, dass die Zahl -einen Teiler hat. Haben wir alle Zahlen durchprobiert handelt es sich um -eine Primzahl genau dann, wenn wir keinen Teiler gefunden haben. Dafür -benötigen wir einen neuen Datentyp nämlich \texttt{bool}, dieser hat genau -zwei Zustände \texttt{true} und \texttt{false}. Damit können wir uns also -merken, ob wir einen Teiler gefunden haben. Wir können die Probedivision wieder in einem Kontrollflussdiagramm ausdrücken ($n$ ist dabei die zu testende Zahl, $i$ -ist der Teiler, den wir gerade testen wollen und \texttt{hat\_teiler} gibt -an, ob wir schon einen Teiler gefunden haben): - -\begin{center} - \begin{tikzpicture}[auto, node distance=3cm,>=latex'] - \tikzstyle{block} = [draw, fill=blue!20, rectangle, minimum height=3em, minimum width=6em] - \tikzstyle{border} = [very thick, dashed, red] - - \node [block, align=center] (start) {$i = 2$ \\ \texttt{hat\_teiler} $=$ \texttt{false}}; - \node [block, right of=start, node distance=4cm] (cond) {$i < n$?}; - \node [block, right of=cond, node distance=3.5cm] (if) {$i\mid n$?}; - \node [block, right of=if, node distance=4cm] (teiler) {\texttt{hat\_teiler} $\leftarrow$ \texttt{true}}; - \node [block, above of=if, node distance=2cm] (incr) {$i \leftarrow i+1$}; - \node [block, below of=cond, node distance=3cm] (prim?) {\texttt{hat\_teiler}?}; - \node [block, below of=teiler, node distance=3cm] (yipp) {$n$ Primzahl}; - \node [block, below of=yipp, node distance=1.5cm] (nope) {$n$ keine Primzahl}; - - \draw [border] ($(cond) + (-1.5, 0)$) |- ($(if) + (0, -1)$) -| ($(teiler) + (2, 0)$) |- ($(incr) + (0, 1)$) -| cycle; - \node [border] at ($(cond) + (-.8, 3.3)$) {Schleife}; - - \draw [->] (start) -- node {} (cond); - \draw [->] (cond) -- node {ja} (if); - \draw [->] (cond) -- node [near end] {nein} (prim?); - \draw [->] (prim?) -- node {nein} (yipp); - \draw [->] (if) -- node {ja} (teiler); - \draw [->] (if) -- node {nein} (incr); - \draw [->] (incr) -| node {} (cond); - \draw [->] (teiler) |- (incr); - \draw [->] (prim?) |- node [near end] {ja} (nope); - \end{tikzpicture} -\end{center} -Das Besondere an Schleifen ist, dass sie geschlossene Kreise zum -Kontrollflussdiagramm hinzufügen. Das erlaubt es uns, die gleiche Anweisung -beliebig oft zu wiederholen. - -Wenn wir dieses Kontrollflussdiagramm in \Cpp gießen, sieht dies so aus: -\inputcpp{prim.cpp} - -Wie wir sehen, sind Schleifen auch nicht viel schwieriger zu handhaben, als -bedingte Anweisungen. Statt \texttt{if} schreiben wir nun \texttt{while}, sonst -ändert sich am Quellcode nicht viel. Ebenso wie bei bedingten Anweisungen sollte der Inhalt einer Schleife als logischer Block eingerückt werden, um sofort zu erkennen, dass dieser wiederholt ausgeführt wird, mehr dazu in Lektion \ref{sec:codingstyle}. - -Als kleine Nebenbemerkung sei hier gestattet, dass ihr hiermit nun alle Dinge -kennengelernt habt, um \emph{Turing-vollständig} programmieren zu können, d.h. -ihr könnt alleine mit den Mitteln, die ihr bisher kennen gelernt habt, -\emph{jede} mögliche Berechnung anstellen! - -Es gibt noch eine weitere Art von Schleifen, die \texttt{for}-Schleife. Die for-Schleife hat folgende Struktur: -\begin{center} - \texttt{for (Initialisierung; Bedingung; Inkrementierung) \{ Code-Fragment \}} -\end{center} -Die Initialisierung wird nur einmal ausgeführt, bevor die Schleife beginnt. Die Bedingung wird vor jedem Durchlauf der Schleife überprüft. Wenn die Bedingung wahr ist, wird das Code-Fragment ausgeführt. Nachdem das Code-Fragment ausgeführt wurde, wird die Inkrementierung ausgeführt. Danach wird die Bedingung erneut überprüft. Wenn die Bedingung nicht mehr wahr, also falsch ist, wird die Schleife beendet. - -Der Unterschied zwischen den beiden Schleifenarten liegt hauptsächlich in ihrer Struktur: -\begin{itemize} - \item \texttt{for}-Schleife: Ideal, wenn du im Voraus weißt, wie oft die Schleife laufen soll. Sie hat eine eingebaute Zählervariable (oft i), eine Bedingung, die überprüft, ob der Zähler einen bestimmten Wert erreicht hat, und eine Inkrementierung, die den Zähler bei jedem Durchlauf erhöht. - \item \texttt{while}-Schleife: Flexibler, da sie für verschiedene Arten von Abbruchbedingungen verwendet werden kann. Sie läuft so lange, bis die angegebene Bedingung falsch wird. -\end{itemize} - -Wie ihr später im Studium beweisen werdet, lassen sich die beiden Ausdrücke immer ineinander überführen. Sie sind also gleichmächtig, d.h. jede \texttt{for}-Schleife kann in eine \texttt{while}-Schleife umgewandelt werden und umgekehrt. Es ist also erst einmal egal, welche Schleife ihr verwendet, nutzt einfach die, die euch am meisten zusagt.\newline -Die \texttt{while}-Schleife aus dem vorherigen Beispiel mit den Primzahlen könnte also auch so aussehen: -\inputcpp{prim-for-loop.cpp} - -\begin{praxis} - \begin{enumerate} - \item Versucht, die Arbeitsweise des Programms zu simulieren. Geht selbst - den Quellcode Zeile für Zeile durch. Überlegt euch hierbei, was die Zeile tut - und welchen Inhalt die Variablen haben. Überlegt euch dann, wohin der - Computer (bei Kontrollflussstrukturen) als nächstes springen würde. - \item Warum funktioniert das Programm für den Fall $n = 2$? - \item Schreibt selbst ein Programm, welches eine Zahl von der Nutzerin - entgegennimmt und dann alle Zahlen bis zu dieser Zahl ausgibt. Nutz dafür eine \texttt{for}-Schleife. - \item Versucht nun das gleiche mit einer \texttt{while}-Schleife. - \item Modifiziert euer Programm, sodass es von dieser Zahl bis zu 0 - hinunterzählt, jeweils wieder mit einer \texttt{while}-Schleife und mit einer \texttt{for}-Schleife. - \end{enumerate} -\end{praxis} - -\begin{spiel} - \begin{enumerate} - \item Das Programm funktioniert noch nicht korrekt, wenn man 1 eingibt - (denn 1 ist keine Primzahl). Modifiziert es, sodass es auch für 1 - funktioniert. - \item Kompiliert \texttt{whiletrue.cpp} und führt es aus. Was beobachtet - ihr? Warum? (Ihr könnt das Programm abbrechen, indem ihr - \texttt{Strg+C} drückt) - \end{enumerate} - - \inputcpp{whiletrue.cpp} - -\end{spiel} - -\textbf{Quiz 10}\\ -\textit{Was kann bei der Verwendung von Schleifen passieren?} -\begin{enumerate}[label=\alph*)] - \item Die Schleife wiederholt sich endlos oft - \item Die Schleife endet - \item Die Schleife bricht nach einer gewissen Anzahl Durchläufe immer von allein ab - \item Am Ende der Schleife werden alle Variablenänderungen durch die Schleife rückgängig gemacht -\end{enumerate} diff --git a/basics/stdbib.tex b/basics/stdbib.tex deleted file mode 100644 index 227f393..0000000 --- a/basics/stdbib.tex +++ /dev/null @@ -1,81 +0,0 @@ -\lesson{Die \Cpp Standardbibliothek} - -Vielleicht habt ihr euch irgendwann gewundert, was eigentlich das -\texttt{std::} ist, was wir vor so viele Dinge schreiben. Warum müssen wir es -z.B. vor \texttt{string} schreiben, aber nicht vor \texttt{int}? - -Die Antwort auf die Frage ist die \Cpp Standardbibliothek. So wie eigentlich -jede Programmiersprache, definiert sich \Cpp nicht nur durch die \emph{Syntax} --- also die genaue Spezifikation, wie ein Quellcodeprogramm aufgebaut ist, wie -eine Anweisung aussieht und ob wir z.B. ein Semikolon am Ende jeder Anweisung -brauchen -- sondern auch über die im Sprachumfang enthaltene -Standardbibliothek, die einem nützliche Funktionen und Objekte für Ein- und -Ausgabe, komplexe Datentypen oder zur Interaktion mit dem Betriebssystem gibt. - -\Cpp nutzt das Prinzip von so genannten \emph{Namespaces}. Das ist eine -Möglichkeit, eine Gruppe von Datentypen, Funktionen und Variablen unter einem -gemeinsamen Namen zu verpacken. Stellt euch vor, ihr wollt in eurem Programm -eine Funktion \texttt{random} definieren. Ihr hättet ganz schön große Problem, -denn der Compiler wüsste dann, wenn ihr \texttt{random} schreibt nicht, ob ihr -eure eigene Funktion meint, oder ob ihr die Standard-\Cpp Funktion meint. - -Aus diesem Grund leben alle Funktionen und Objekte der \Cpp Standardbibliothek -im Namespace \texttt{std}. Um auf sie zuzugreifen, müsst ihr dem Compiler -sagen, aus welchen Namespace ihr sie haben wollt, dazu schreibt ihr eben den -Namen des Namespaces und zwei Doppelpunkte vor den Namen der Variablen (oder -Funktion), also ist \texttt{std::cout} „Die Variable \texttt{cout} aus dem -Namespace \texttt{std}“. - -\inputcpp{namespaces.cpp} - -\begin{praxis} - \begin{enumerate} - \item Was gibt dieses Programm aus, wenn man es kompiliert und ausführt? - Überlegt es euch zuerst selbst, dann probiert es aus. - \end{enumerate} - - Wenn ihr wissen wollt, was die Standardbibliothek alles so für euch bereit - stellt, könnt ihr euch in der Referenz der Standardbibliothek unter - - \url{http://www.cplusplus.com/reference/} - - umschauen. Es ist nicht ganz einfach, zu wissen, wo man dort findet, was man - sucht, in dem Fall kann Google ein im Regelfall ganz gut helfen. Wenn man - einmal weiß, \emph{was} man sucht, findet man in der Referenz vor allem, - \emph{wie} man es benutzt. - - Die Standardbibliothek ist aufgeteilt auf so genannt \emph{Headerdateien}, die - wir mittels \texttt{\#include} benutzen können. Diese Header sind, worunter ihr - zuerst wählt, wenn ihr auf obige url geht. Jeder Header definiert dann eine - Menge an Funktionen, Typen und Klassen (was genau eine Klasse ist, lernt ihr - spätestens in der Vorlesung). - - \begin{enumerate}[resume] - \item Findet in der \Cpp-Referenz eine Funktion, um die aktuelle Zeit - auszugeben. Schreibt ein Programm, welches die Aktuelle Zeit ausgibt - (es reicht, einen so genannten \emph{Unix timestamp}\footnote{Der - Unix-Timestamp ist eine einzelne Zahl, die alle Sekunden seit dem - 1.1.1970 anzeigt und die also jede Sekunde eins größer wird} auszugeben). - Ihr könnt die Ausgabe eures Programms mit der Ausgabe von \texttt{date - +\%s} vergleichen, um es zu testen. - \item Mit der Funktion \texttt{rand()} könnt ihr Zufallszahlen generieren - (ihr braucht dazu den Header \texttt{}). Schreibt ein - Programm, welches vom Benutzer eine Zahl entgegennimmt und diese Anzahl - Zufallszahlen ausgibt. Führt das Programm mehrfach aus. Was fällt auf? - \item Konsultiert die \Cpp-Referenz, um heraus zu finden, wo das Problem - liegt. Könnt ihr es beheben? - \end{enumerate} -\end{praxis} - - - -\newpage - -\textbf{Quiz 14}\\ -\textit{Welche Funktionen sind in der Standardbibliothek?} -\begin{enumerate}[label=\alph*)] - \item \texttt{cout} - \item \texttt{cin} - \item \texttt{sqrt} - \item \texttt{cerr} -\end{enumerate} diff --git a/basics/style.tex b/basics/style.tex deleted file mode 100644 index d5c7d83..0000000 --- a/basics/style.tex +++ /dev/null @@ -1,112 +0,0 @@ -\lesson{Coding style} -\label{sec:codingstyle} -Wir haben mittlerweile hinreichend viele verschiedene Verschachtelungen im -Quellcode kennen gelernt, dass es sich lohnt, ein paar Worte über coding styĺe -zu sprechen. - -Schon wenn ihr euch während dieses Kurses an einen von uns wendet und um Hilfe -bittet, ergibt sich das Problem der Lesbarkeit von Quellcode. Um euch zu -helfen, sollte man möglichst mit einem Blick erfassen können, was euer Code -tut, wie er strukturiert ist, welche Variable was bedeutet. Um dies zu -unterstützen, gibt es mehrere Dinge, auf die man achten kann. - -\begin{description} - \item[Einrückung] - Wie euch vermutlich aufgefallen ist, sind an verschiedenen Stellen im - Code einzelne Zeilen ein wenig eingerückt. Dies ist vermutlich das - wichtigste Werkzeug, welches zur Verfügung steht, um die Lesbarkeit von - Code zu unterstützen (auch, wenn es nicht nötig ist, um formal korrekte - Programme zu schreiben). Die einzelnen Einheiten des Kontrollflusss - werden dadurch visuell voneinander abgegrenzt, was es einfacher macht, - den Programmverlauf zu verfolgen. - - Wie genau eingerückt werden sollte, darüber scheiden sich die Geister. - Man kann mit mehreren Leerzeichen oder durch Tabulatoren einrücken. - Empfehlenswert ist auf jeden Fall, mehrere gleichförmige „Ebenen“ zu - haben (z.B. 4, 8, 12, \dots\ Leerzeichen zu Beginn der Zeile). Eine - Faustregel für gut lesbare Einrückung ist, immer wenn man eine - geschweifte Klammer öffnet, eine Ebene tiefer einzurücken und immer, - wenn man eine geschweifte Klammer schließt, wieder eine Ebene zurück zu - nehmen. - \item[Klammern] - Aus der Schule kennt ihr das Prinzip „Punkt- vor Strichrechnung“. Dies - ist eine Regel, die so genannte \emph{Präzedenz} ausdrückt, also die - Reihenfolge, in der Operatoren ausgewertet werden. Punkt vor Strich ist - allerdings nicht aussreichend, um vollständig zu beschreiben, wie sich - Operatoren in Gruppen verhalten. Schaut euch z.B. den Ausdruck - \texttt{3 * 2 / 3} an. Da der Computer Ganzzahldivision benutzt, kommen - hier unterschiedliche Ergebniss raus, je nachdem, ob zunächst das - \texttt{*} oder das \texttt{/} ausgewertet wird. Im ersten Fall - erhalten wir \texttt{6 / 3 == 2}, wie wir erwarten würden. Im zweiten - Fall wird aber abgerundet, sodass wir \texttt{3 * 0 == 0} erhalten. - - Um solche und ähnliche Uneindeutigkeiten zu vermeiden, bietet es sich - an, Klammerung zu verwenden. Selbst wenn wir im obigen Fall - \emph{wissen} in welcher Reihenfolge die Operatoren ausgewertet werden, - jemand der unseren Code liest, weiß das vielleicht nicht. Einfach von - vornherein die gewollte Reihenfolge der Auswertung zu klammern, - verhindert Verwirrung bei uns über das Verhalten des Computers, als - auch bei Menschen, die später wissen wollen, was wir meinten. - - Ihr könnt übrigens nicht nur einzeilige Kommentare erstellen, die mit \cppinline{//} beginnen, sondern auch mehrzeilige, und zwar so: \cppinline{/* Dies ist ein ganz langer mehrzeiliger Kommentar. */} . Alles zwischen den Slashes und Sternchen ist dann ein Kommentar und wird vom Computer ignoriert. Dies könnt ihr als kleinen Trick verwenden, um euren Code zu debuggen, ohne ständig alles neu zu schreiben. Ihr könnt stattdessen einfach den nicht benötigten Code auskommentieren und wenn ihr ihn wieder verwenden wollt, die Kommentarzeichen am Anfang und Ende wieder entfernen. - \item[Kommentare] - Wir haben schon in mehreren Quellcodedateien Kommentare verwendet, um - einzelne Dinge zu erklären. Insgesamt bietet es sich an, dies selbst - ebenfalls zu tun, um den Programmfluss der Leserin von Quellcode klar zu - machen. Das heißt nicht, dass man jede Anweisung noch einmal mit einem - Kommantar versehen sollte, der sie ausführlich erklärt, aber an - wichtigen Punkten können einem kurze Kommentare das Leben enorm - vereinfachen. Und ihr dürft nicht vergessen, dass ihr euch vielleicht - selbst in ein oder zwei Jahren noch einmal euren eigenen Quellcode - anschauen müsst und ihr werdet wirklich überrascht sein, wie wenig ihr - von dem Zeug, welches ihr selbst geschrieben habt, verstehen werdet. - \item [Benennungen] - Wenn ihr eure Variablen -- und später auch eure Funktionen und Klassen -- präzise benennt, dann vereinfacht ihr das Lesen eures Codes extrem. Durch Bezeichnungen, die für sich sprechen, könnt ihr euch außerdem Kommentare etwas ersparen, weil die Variablennamen dann schon viel erklären. Es ist zum Beispiel ungeschickt, seine Variablen wie in der Mathematik üblich einfach nur mit einzelnen Buchstaben zu benennen, statt \cppinline{int a = 42;} sollte man lieber \cppinline{int alter = 42;} verwenden, da die Leserin direkt weiß, dass in dieser Variablen das Alter gespeichert wird. Zu dieser coding style Richtlinie gibt es jedoch auch eine Ausnahme: Bei Zählervariablen, die einfach nur die Anzahl der Schleifeniterationen hochzählen, verwendet man meist einzelne Buchstaben, wie \cppinline{i} oder \cppinline{n}. Das ist schön kurz und praktisch, jedoch muss man etwas aufpassen, denn man kann schnell mit diesen Indices durcheinander kommen -- genau so wie in der Mathematik. - \item[Leerzeichen und -zeilen] - Weniger wichtig als die ersten vier Punkte können trotzdem gezielte - Leerzeichen (z.B. zwischen Operatoren und Operanden in arithmetischen - Ausdrücken) die Lesbarkeit enorm erhöhen. Gerade in arithmetischen - Ausdrücken ist es eine gute Angewohnheit. - Ebenso sind Leerzeilen zwischen logischen Abschnitten sehr hilfreich. Zu Beginn eines Abschnittes kann man dann noch einen kurzen Kommentar hinzufügen, was in dem Abschnitt passiert und schon fällt das Lesen des Codes deutlich leichter. -\end{description} - -Es gibt sicher noch viele Regeln, über die ihr im Laufe eures Lebens stolpern -werdet, wenn ihr euch entschließen solltet, regelmäßig zu programmieren. Häufig -werdet ihr euch darüber ärgern, manchmal zu recht. Aber versucht im Zweifel -einen halbwegs sauberen Stil auch als euren eigenen Verbündeten zu sehen, denn -ob es nun vergessene Klammern, Semikolons oder versteckte Fehler in der -Operatorpräzedenz sind, ein sauberer Stil kann euch bei allen enorm helfen, sie -aufzuspüren. Auch wenn es coding style Richtlinien für verschiedene Programmiersprachen gibt, die größtenteils relativ ähnlich sind, gewöhnt man sich meist einen eigenen Stil mit der Zeit an. Es ist allerdings wichtig, früh auf guten Stil zu achten, denn wenn man erst einmal damit anfängt, unübersichtlichen Code zu schreiben, gewöhnt man sich diese Unart an und das will schließlich niemand. - -\begin{praxis} - \begin{enumerate} - \item Eine weit verbreitete einfache Aufgabe, die in Bewerbungsgesprächen - auf Stellen als Programmiererin häufig gestellt wird, ist - \emph{FizzBuzz}. In \texttt{fizzbuzz.cpp} ist eine möglich Lösung für - diese Aufgabe gegeben. Könnt ihr (nur mittels des Quellcodes) sagen, - was das Programm tut? - \item Nutzt die oben gegebenen Faustregeln, um den Quellcode lesbarer zu - machen. Ihr müsst nicht alles bis aufs Wort befolgen, macht einfach so - lange weiter, bis ihr findet, man kann hinreichend schnell verstehen, - was hier passieren soll. - \end{enumerate} - - \inputcpp{fizzbuzz.cpp} -\end{praxis} - -\begin{spiel} - \begin{enumerate} - \item Entfernt in eurem veränderten Quellcode eine geschweifte Klammer - eurer Wahl. Lasst eure Sitznachbarin über den Quellcode schauen und die - fehlende Klammer finden. - \end{enumerate} -\end{spiel} - -\textbf{Quiz 12}\\ -\textit{Was gehört zu gutem Coding style?} -\begin{enumerate}[label=\alph*)] - \item Sinnvolle Kommentare - \item Möglichst keine Leerzeilen lassen - \item Variablennamen möglichst kurz wählen - \item Einrückungen vornehmen -\end{enumerate} diff --git a/basics/tictactoe1.tex b/basics/tictactoe1.tex deleted file mode 100644 index 8cd96ba..0000000 --- a/basics/tictactoe1.tex +++ /dev/null @@ -1,84 +0,0 @@ -\lesson{Tic Tac Toe - Teil 1} - -Nachdem wir jetzt lange dröge und unspannende Lektionen und Beispiele hatten, wollen wir uns als Ende von -Kapitel 1 einer ein wenig spannenderen Aufgabe widmen -- wir wollen ein -einfaches Spiel programmieren. Wir haben dazu Tic Tac Toe ausgewählt, da es -relativ überschaubare Spiellogik besitzt. Ein- und Ausgabe, werden wir über die -Konsole machen. - -In \texttt{vorkurs/lektion17} findet ihr eine Datei \texttt{tictactoe.o}. Diese -könnt ihr nicht in eurem Editor öffnen -- sie enthält von uns bereitgestellte, -bereits vorkompilierte Funktionen, die ihr nutzen könnt, um einen Anfang zu -haben. Wir werden sie später Stück für Stück ersetzen. - -Um die Funktionen zu nutzen, müsst ihr zwei Dinge tun: Ihr müsst sie einerseits -in eurem Sourcecode \emph{deklarieren}, andererseits müsst ihr sie beim -Kompilieren mit \emph{linken}. - -Die Deklaration erfolgt ganz ähnlich, wie ihr auch vorgehen würdet, wenn ihr -die Funktion selbst schreiben würdet: Ihr schreibt Rückgabetyp, Namen und -Parameter der Funktion auf. Statt des Funktionenkörpers in geschweiften -Klammern, beendet ihr die Zeile mit einem Semikolon. Da wir die Funktion aus -einer anderen Datei laden wollen, müssen wir noch ein \texttt{extern} -voranstellen. In \texttt{tictactoe.cpp} ist dies am Beispiel von -\texttt{frage\_feld\_nummer} vorgemacht. - -\texttt{tictactoe.o} definiert euch insgesamt folgende Funktionen: -\begin{description} - \item[frage\_feld\_nummer] - Nimmt einen Vektor mit 9 \texttt{int}s entgegen und gibt einen \texttt{int} zurück. - - Gibt auf der Konsole eine Frage nach der Feldnummer aus (durchnummeriert von 0 bis 8), liest eine Feldnummer von der Nutzerin ein und gibt diese zurück. - Die Funktion stellt sicher, dass die Feldnummer zwischen 0 und 8 liegt und dass das Feld noch nicht besetzt ist (sonst wird noch einmal nachgefragt). - \item[gebe\_feld\_aus] - Nimmt einen Vektor mit 9 \texttt{int}s entgegen und hat als Rückgabetyp \texttt{void} (was für „keine Rückgabe“ steht). - - Gibt das gegebene Feld auf der Konsole aus. Dabei werden die 9 Felder von oben links nach unten rechts von 0 beginnend durchnummeriert. - Der 9-elementige Vektor stellt also das Feld dar. - Eine 0 in einem Vektorelement bedeutet, dass das Feld leer ist, eine 1 bedeutet, dass sich dort ein \textbf{X} befindet und eine 2 bedeutet, dass sich ein \textbf{O} dort befindet. - Andere Werte werden mit einem \textbf{?} dargestellt. - \item[gewinnerin] - Nimmt einen Vektor mit 9 \texttt{int}s entgegen und hat als Rückgabetyp \texttt{int}. - - Prüft, ob in diesem Zustand des Feldes bereits eine der Spielerinnen gewonnen hat. - Die Funktion gibt 0 zurück, wenn noch niemand gewonnen hat, 1, wenn die Spielerin \textbf{X} gewonnen hat und 2, wenn die Spielerin \textbf{O} gewonnen hat. - Sollte das Spiel unentschieden ausgegangen sein, wird eine 3 zurück gegeben. -\end{description} - -Der zweite Teil, den ihr zur Benutzung der Funktionen braucht ist das Linken (was genau das bedeutet, wird später noch erklärt). -Dies ist fürs Erste sehr einfach: Ihr gebt einfach dem \texttt{g++} Befehl zusätzlich zu eurer \texttt{.cpp} Datei noch \texttt{tictactoe.o} als zusätzliche Inputdatei an. - -\inputcpp{tictactoe.cpp} - -\begin{praxis} - \begin{enumerate} - \item - Ergänzt \texttt{tictactoe.cpp} um Deklarationen für die anderen beschriebenen Funktionen aus \texttt{tictactoe.o}. - Einen Vektor als Parameter könnt ihr in genau der gleichen Notation angeben, wie ihr es euch in einer Funktion als Variable definieren würdet. - \item - Das Grundgerüst eines Spiels ist die \emph{input-update-display}-loop. - Dies ist eine Endlosschleife, in der zunächst der \emph{input} der Spielerin abgefragt wird. - Anschließend wird der interne Spielzustand aktualisiert (\emph{update}). - Zuletzt wird der neue Spielzustand angezeigt (\emph{display}). - Der anfängliche Spielzustand wird vor dieser loop hergestellt (\emph{setup}). - - \texttt{tictactoe.cpp} zeigt dieses Grundgerüst. - Ergänzt den input- und den display-Teil mithilfe der gegebenen Funktionen. - Ergänzt auch den setup-Teil; ihr braucht für den Spielzustand einerseits den Vektor, welcher das Spielfeld fassen soll, andererseits eine Variable für die Spielerin, die gerade am Zug ist und eine Variable, die das im aktuellen Zug eingegebene Feld speichert. - Vergesst auch nicht, dass ihr das Feld zu Beginn 9 0en enhalten muss. - \item - Nun müssen wir noch den Update-Teil ergänzen. - Hier solltet ihr in das von der aktuellen Spielerin gewählte Feld mit deren Nummer füllen, testen, ob jemand gewonnen hat und wenn ja, die Siegerin ausgeben und euer Programm beenden (denkt daran, dass das Spiel auch unentschieden ausgehen kann). - Sonst sollte die aktuelle Spielerin gewechselt werden. - \end{enumerate} -\end{praxis} - -\begin{spiel} - \begin{enumerate} - \item - Okay, das ist nun wirklich nicht schwierig zu erraten oder? - Wenn ihr dem obigen Rezept gefolgt seid, habt ihr jetzt ein funktionierendes Tic-Tac-Toe Spiel. - Und ihr habt eine Sitznachbarin. - Zählt eins und eins zusammen. - \end{enumerate} -\end{spiel} diff --git a/basics/tictactoe2.tex b/basics/tictactoe2.tex deleted file mode 100644 index 1244b89..0000000 --- a/basics/tictactoe2.tex +++ /dev/null @@ -1,50 +0,0 @@ -\lesson{Tic Tac Toe - Teil 2} - -Dies ist die letzte Lektion des ersten Kapitels. In der vorletzten Lektion -haben wir die grobe Struktur eines Tic Tac Toe Spiels implementiert, dafür -haben wir ein paar Funktionen benutzt, die uns gegeben waren. Nun wollen wir -diese Funktionen nachimplementieren („Implementieren“ heißt, dass man eine mehr -oder weniger formale Spezifikation in Programmcode umsetzt). Für eine -Beschreibung, was die Funktionen machen sollen, könnt ihr in der vorletzten -Lektion nachschauen. Damit ihr eure eigene Implementationen testen könnt, haben -wir noch einmal alle Funktionen mit beigefügt. Sie befinden sich in den Dateien -\texttt{frage\_feld\_nummer.o}, \texttt{gebe\_feld\_aus.o} und -\texttt{gewinnerin.o}. - -Um eine Funktion zu implementieren, solltet ihr die dazugehörige -\texttt{extern}-Deklaration aus eurer \texttt{tictactoe.cpp} löschen und dann -die Funktion mit dem gleichen Namen (und den gleichen Parametern und -Rückgabetypen) selbst definieren und implementieren. Ihr könnt, wenn ihr z.B. -\texttt{gewinnerin} selbst implementiert habt, euer Programm mit - -\texttt{g++ -o tictactoe tictactoe.cpp frage\_feld\_nummer.o gebe\_feld\_aus.o} - -kompilieren. Je mehr Funktionen ihr selbst nachimplementiert, desto weniger -gegebene \texttt{.o}-files müsst ihr natürlich angeben. - -Es gibt es dieses mal auch keine Nummern für die einzelnen Teile -- sucht euch -doch selbst aus, in welcher Reihenfolge ihr sie bearbeiten wollt, sie ist -ziemlich beliebig. Fangt am Besten mit dem Teil an, der euch am leichtesten -erscheint. - -\begin{praxis} - \begin{itemize} - \item Implementiert \texttt{frage\_feld\_nummer} nach. Ihr solltet darauf - achten, dass ihr in dieser Funktion auch testen müsst, ob ein gültiges - Feld eingegeben wurde und ob das angegebene Feld leer ist. - \item Implementiert \texttt{gebe\_feld\_aus} nach. Ihr könnt euch selbst - aussuchen, wie ihr die Ausgabe gestalten wollt -- es muss nicht genauso - aussehen, wie unser Vorschlag. Die - Wikipedia\footnote{\url{http://en.wikipedia.org/wiki/Box-drawing_character}} - kann euch z.B. helfen, ein schöneres Feld auszugeben. Fangt am Besten - mit einer einfachen Ausgabe an und macht sie dann immer „fancier“. - \item Implementiert \texttt{gewinnerin} nach. Bedenkt, dass ihr alle - Möglichkeiten testet, auf die ein Gewinn möglich ist -- also 3 - Möglichkeiten, eine Reihe zu bilden, 3 Möglichkeiten, eine Spalte zu - bilden und 2 Möglichkeiten für Diagonalen. Überlegt euch zunächst, wie - ihr zwischen Feldnummer (0-8) und Reihen- bzw. Spaltennummer hin- und - herrechnen könnt. Beachtet auch, dass es ein Unentschieden gibt, wenn - alle Felder belegt sind, aber keine von beiden Spielerinnen gewonnen - hat. - \end{itemize} -\end{praxis} diff --git a/basics/variablen.tex b/basics/variablen.tex deleted file mode 100644 index 03e5496..0000000 --- a/basics/variablen.tex +++ /dev/null @@ -1,48 +0,0 @@ -\lesson{Variablen} - -Das Programm \texttt{variablen.cpp} erzählt von ihrem Tag. -Compilier es und guck dir die Ausgabe an. - -\inputcpp{variablen.cpp} - -Da immer wieder das gleiche Wort \glqq{}wundervoll\grqq{} benutzt wird, wurde es in eine sogenannte \emph{Variable} ausgelagert. -Eine Variable ist ein Wert der mit einem Namen benannt wird. -Dabei findet die Zuweisung durch ein \cppinline{=} statt, dem Namen auf der linken Seite des Gleichheitszeichen wird der Wert auf der rechten Seite zugewiesen. -Im Programm selbst ist es dann so, als würde der Wert an der Stelle des Namens stehen. - -Der Wert einer Variable kann sich im Laufe des Programmes verändern. -Durch Hinzufügen der Zeile \cppinline{beschreibung = "langweilig";} wird hinter dieser Zeile anstelle von \glqq{}wundervoll\grqq{} nun \glqq{}langweilig\grqq{} ausgegeben. -Ähnlich kann wie in \texttt{helloyou.cpp} der Wert von Variablen durch \cppinline{std::cin >> beschreibung} die Benutzerin eingeben werden. - -Variablen haben immer einen bestimmten \emph{Datentypen}. -In unserem Beispiel handelt es sich um \cppinline{std::string}. -Der Datentyp wird bei dem Erstellen -- also der ersten Zuweisung -- vor dem Namen angeben. -Dieser wird benötigt, damit der Computer weiß, um was für eine Art Wert es sich handelt -- ein Text sollte anders behandelt werden als eine Zahl. -Beispielsweise kann man zwei Zahlen miteinander multiplizieren, für Texte ergibt das allerdings keinen Sinn. -In der Lektion Arithmetik lernen wir mehr über Zahlen und deren Eigenheiten. - -\begin{praxis} - \begin{enumerate} - \item Was passiert, wenn ihr \cppinline{beschreibung} in Zeile 5 ein anderes Wort zuweist? - \item Definiert eine weitere Variable und schreibt einen weiteren Satz. - \end{enumerate} -\end{praxis} - -\begin{spiel} - \begin{enumerate} - \item Was passiert, wenn ihr euch im Namen einer Variable „vertippt“? - \item Definiert euch zwei Variablen, weist ihnen - irgendwelchen Text zu, versucht, sie zu addieren und das Ergebnis auszugeben. - \item Was passiert, wenn ihr eine Variable definiert, - ihr aber nichts zuweist und dann versucht, sie auszugeben? - \end{enumerate} -\end{spiel} - -\textbf{Quiz 5}\\ -\textit{Wann wird eine Variable nicht mehr \glqq erkannt\grqq ?} -\begin{enumerate}[label=\alph*)] - \item Wenn die Groß-/Kleinschreibung nicht mehr stimmt - \item Wenn ein Buchstabe vergessen wurde - \item Wenn ein Buchstabe zu viel verwendet wurde - \item Wenn der Variable ein neuer Wert zugewiesen wird -\end{enumerate} \ No newline at end of file diff --git a/basics/vektoren.tex b/basics/vektoren.tex deleted file mode 100644 index aefb717..0000000 --- a/basics/vektoren.tex +++ /dev/null @@ -1,79 +0,0 @@ -\lesson{Vektor} - -Als nächstes wichtiges Konzept in \Cpp werden wir uns \emph{Vektoren} anschauen. -Vektoren sind eine Möglichkeit, mehrere Elemente des gleichen Typs zusammen zu fassen. -Statt also einer Stelle im Speicher, an der ein \texttt{int} liegt, habt ihr einen ganzen Speicherbereich, in dem 100 (oder eine beliebige andere Anzahl an) \texttt{int}s liegen. - -Die Elemente in einem Vektor sind durchnummeriert, man nennt die Nummer eines Vektorelements seinen \emph{Index}. -Das erste Element hat den Index 0, das zweite den Index 1 und das 100te hat den Index 99 -- Vorsicht also, der höchste Index in einem Vektor mit 100 Elementen ist 99, nicht 100! -Um einen Vektor zu definieren, schreibt ihr: -\begin{center} - \cppinline{std::vector<}\emph{Datentyp}\cppinline{> einvektor;} -\end{center} -um den Datentypen schreibt ihr also noch \cppinline{std::vector<}\dots\cppinline{>}. -Um ein Element am Ende einzufügen gibt es -\begin{center} - \cppinline{einvektor.push_back(}\emph{Element}\cppinline{);} -\end{center} -und auf ein bestimmtes Vektorelement zugreifen könnt ihr indem ihr seinen Index in eckigen Klammern hinter den Namen schreibt. -\begin{center} - \cppinline{einvektor[}\emph{Index}\cppinline{]} -\end{center} -Wenn ihr die Größe eines Vektors wissen wollt könnt ihr -\begin{center} - \cppinline{einvektor.size()} -\end{center} -verwenden. - -Folgendes Programm macht hoffentlich die Syntax klar: - -\inputcpp{vector.cpp} - -Es gibt einige Dinge, zu beachten, wenn ihr mit Vektoren arbeitet. -Das wichtigste ist oben schon genannt -- lasst euch nicht davon verwirren, dass Indizes bei 0 anfangen. -Aus Versehen über den Vektor hinaus zu schreiben oder zu lesen ist ein so häufiger Fehler, dass er seinen eigenen Namen bekommen hat: \emph{Off-by-one} error. -Wichtig ist, dass der Compiler diesen Zugriff nicht verhindern wird! -Das ist von daher eine sehr fiese Sache, als dass dieser Fehler auch beim Ausführen nicht immer Probleme machen wird -- aber manchmal lässt er auch euer Programm spontan abstürzen in einem so genannten \emph{segmentation fault}. - -\begin{praxis} - - Wir wollen die Seite \url{http://www.ich-kann-mich-nicht-entscheiden.de/} nachmachen und eine Entscheidungshilfe programmieren, die aus mehreren von der Nutzerin gegebenen Möglichkeiten eine per Zufall auswählt. - - \begin{enumerate} - \item - Schreibt zunächst ein Programm, welches einen Vektor aus 10 Strings erstellt und die Nutzerin 10 mal nach einer Antwortmöglichkeit fragt und die gegebenen Antworten nacheinander in den Vektor schreibt. - \item - Fügt nun die Möglichkeit zu, weniger Antworten anzugeben. - Dazu könnt ihr zum Beispiel zuerst fragen, wie viele Antwortmöglichkeiten es geben soll und dann so oft fragen. - \item - Ihr könnt dann (so wie in dem Programm oben) eine Zufallszahl erzeugen. - Um sicher zu gehen, dass sie nicht zu groß wird, könnt ihr den Rest bei Teilung durch Anzahl der eingegebenen Antworten nehmen (sind z.B. 7 Antworten angegeben und die Zufallszahl ist 25778, so wäre der resultierende Index \texttt{25778 \% 7 == 4}). - Gebt dann die Antwortmöglichkeit aus, die dem zufallsgeneriertem Index entspricht. - \end{enumerate} -\end{praxis} - -Sollte euer Programm einmal nicht korrekt kompilieren, denkt daran die Fehlermeldung sorgfältig zu lesen, damit sie euch Aufschluss über die Fehlerursache gibt.\\ -Sollte euer Programm zwar kompilieren, sich dann aber komisch verhalten, denkt daran, den Debugger zu benutzen und es Schritt für Schritt durchzugehen, um die Fehlerquelle zu finden. Solltet ihr trotz alledem nicht weiter kommen, oder nicht wissen, was von euch erwartet wird, fragt einen von uns. - - -\begin{spiel} -\begin{enumerate} - \item - Schreibt ein Progamm, welches einen Vektor mit einer beliebigen Anzahl an Elementen befüllt und dann auf einen Index weit über der tatsächlichen Größe schreibt. - Was beobachtet ihr?\footnote{Es wird natürlich Quark sein was dabei rauskommt, es geht hier haupsächlich darum das ihr seht was für einen Fehler das gibt} - \item - Überlegt euch wie ihr verhindern könnt, dass über den Rand des Vektors hinaus geschrieben oder gelesen wird. - \item - Implementiert das \emph{Sieb des Eratosthenes}\footnote{\url{https://de.wikipedia.org/wiki/Sieb_des_Eratosthenes}}, wenn ihr noch nicht ausgelastet seid. - Denkt daran, es initial zu befüllen und denkt euch eine clevere Möglichkeit aus, das „Streichen“ zu realisieren. -\end{enumerate} -\end{spiel} - -\textbf{Quiz 15}\\ -\textit{Welche Aussagen über Vektoren sind falsch?} -\begin{enumerate}[label=\alph*)] - \item Vektoren haben immer die Größe 3 - \item Vektoren können nur mit Elementen eines einzigen Datentyps befüllt werden - \item Der Index startet bei 0 - \item Der letzte Index ist immer die Größe - 1 -\end{enumerate} diff --git a/basics/warning.tex b/basics/warning.tex deleted file mode 100644 index 4765cb4..0000000 --- a/basics/warning.tex +++ /dev/null @@ -1,94 +0,0 @@ -\lesson{Warnings} - -Wir haben uns bereits ausführlich mit den Fehlermeldungen des Compilers -auseinander gesetzt. Wir haben auch festgestellt, dass es viele Fehler gibt, -die uns der Compiler durchgehen lässt, die aber im späteren Programmlauf zu -Problemem führen können. Und wir haben den debugger kennengelernt, um die -Ursache solcher Fehler zu finden und sie beheben zu können. Nun wollen wir uns -anschauen, wie wir den Compiler in gewisser Weise „wachsam“ machen können, -sodass er uns auch über Dinge informiert, die zwar keine Fehler sind, aber -möglicherweise zu unerwartetem Verhalten führen können. - -\begin{praxis} - \begin{enumerate} - \item Kompiliert \texttt{warnings.cpp}. Testet das Program mit - verschiedenen Eingaben. Was beobachtet ihr? - \end{enumerate} - \inputcpp{warnings.cpp} - - Fehler wie diese können nicht mehr auftreten, wenn ihr \emph{warnings} - anschaltet. Dies passiert über weitere Optionen, die wir dem Compiler mitgeben. - - \begin{enumerate}[resume] - \item Kompiliert \texttt{warnings.cpp} mittels \texttt{g++ -Wall -o - warnings warnings.cpp}. - \end{enumerate} - - Warnings sehen im Wesentlichen genauso aus, wie Fehler. Der einzige Unterschied - ist, dass statt \texttt{error} in der Zeile ein \texttt{warning} steht und dass - der Compiler zwar die Meldung ausgibt, aber trotzdem ganz normal das Programm - erzeugt. Trotzdem solltet ihr warnings ernst nehmen. Die meisten „ernsthaften“ - Programmierer aktivieren warnings, da die meisten davon gefundenen Meldungen - tatsächlich behoben werden sollten. - - Ihr könnt mit verschiedenen Parametern beeinflussen, welche warnings euch der - Compiler anzeigt und wie er damit umgeht. Wir wollen hier nur drei nennen: - - \begin{description} - \item[-Wall] - Aktiviert „alle“ warnings. Tatsächlich stimmt das so nicht, aber wenn - ihr immer daran denkt, diesen Parameter anzugeben, solltet ihr bereits - den allergrößten Teil der vom Compiler entdeckbaren Probleme, die ihr - erzeugt, abfangen können. - \item[-Wextra] - Aktiviert noch ein paar warnings (ihr seht, warum „alle“ in - Anführungszeichen stand). In einigen Fällen sind auch die hier - aktivierten warnings für euch relevant. - \item[-Werror] - Dieser Parameter führt dazu, dass jede warning als Fehler behandelt - wird, d.h. der Compiler bricht ab, wenn er eine warning produzieren - würde. Dieser Parameter ist hochumstritten und in der Praxis sollte man - ihn eigentlich nicht einsetzen. Für Beginner kann er aber hilfreich - sein, da er von vornherein antrainiert, warnings ernst zu nehmen und - sie nicht einfach zu ignorieren. - \end{description} - - Wenn ihr bei jedem Compilerlauf nun warnings anschalten wollt -- und am Besten - auch noch für den debugger, falls ihr ihn braucht -- wird der Befehl zum - Kompilieren langsam sehr lang. Für die Dauer des Vorkurses könnt ihr euch - mittels - - \begin{center} - \texttt{alias\footnote{alias ist ein shell-befehl, der euch eine Reihe von - Anweisungen und Befehlen neu benennen lässt. In diesem Fall ist danach zum - Beispiel der noch nicht existente Befehl \texttt{compile} ein neuer Name für - \texttt{g++ -Vall -Wextra -Werror -O0 -g3}. Beachtet, dass ihr hier genau das - abtippen müsst, was da steht, mit Leerzeichen und allem} compile="g++ -Wall - -Wextra -Werror -O0 -g3"} - \end{center} - - ein bisschen Arbeit ersparen. Ein einfaches \texttt{compile -o foo foo.cpp} - wird dann automatisch den Compiler mit allen angegebenen Optionen aufrufen. Den - \texttt{alias} müsst ihr allerdings jedes mal, wenn ihr in der Zwischenzeit ein - Terminal geschlossen habt, neu ausführen, denn er geht bei Schließung eines - Terminals verloren! - - \begin{enumerate}[resume] - \item Mit der warning in \texttt{warnings.cpp} möchte euch der Compiler - darauf hinweisen, dass ihr hier eine Zuweisung macht, obwohl ein - Wahrheitswert\footnote{Ein Wahrheitswert (\cppinline{bool}) ist ein - Variablentyp, der die Werte wahr (\cppinline{true}) und falsch ( - \cppinline{false}) annehmen kann.} - erwartet wird. Es gibt zwei Möglichkeiten, die warning zu - beheben: Ihr könnt Klammern um die Zuweisung machen (und dem Compiler - so sagen, dass ihr euch sicher seid, dass hier eine Zuweisung hinsoll), - oder ihr könnt aus der Zuweisung einen Vergleich machen. Welche - Möglichkeit erscheint euch angebracht? Setzt sie um und kompiliert das - Programm erneut (mit warnings). - \item In \texttt{warnprim.cpp} haben wir einen Fehler eingebaut. Kompiliert - das Programm mit warnings und korrigiert ihn. - \end{enumerate} - - \inputcpp{warnprim.cpp} - -\end{praxis} \ No newline at end of file diff --git a/classes/classes.tex b/classes/classes.tex deleted file mode 100644 index d9fded6..0000000 --- a/classes/classes.tex +++ /dev/null @@ -1,24 +0,0 @@ -\lesson{Klassen} - -Eine komplexere Art von Datentypen als Enums sind die sogenannten Klassen. Diese lassen sich als eine Art Gegenstand vorstellen, der verschiedene Eigenschaften hat. - -Wenn zum Beispiel eine Videothek ihre DVD-Sammlung verwalten möchte, wäre es eine Möglichkeit jede DVD durch eine Klasse darzustellen. Dabei ist die Klasse dann ein Bauplan für die späteren Datentypen, die erstellt werden. Diese DVD-Klasse könnte dann Attribute für den Titel, ob sie zurzeit ausgeliehen ist, eine Möglichkeit zu speichern, wann sie zurück gegeben werden muss, und einen Zähler, um zu speichern, wie oft die DVD schon ausgeliehen wird, enthalten. - -Nun wird es irgendwann passieren, dass jemand eine DVD ausleihen möchte. Dafür sollte es also eine leichte Möglichkeit geben, um den Ausleihstatus zu ändern und automatisch das Rückgabedatum auf einen sinnvollen Wert zu setzen. -Eine erfahrerne Benutzerin wird jetzt natürlich an Funktionen denken. Für die -Übersichtlichkeit des Programmes ist es sehr vorteilhaft, die Funktionen einer -Klasse zu bündeln. Dafür werden diese in der Klasse definiert und gehören so als -\emph{Memberfunktion} zur Klasse. - - -Eine Klasse kann Information haben, die für alle zugänglich sein sollten, und Informationen, die nicht oder nur eingeschränkt zugreifbar sein sollten. Zum Beispiel ist es sinnvoll, dass jede Benutzerin die Möglichkeit hat DVDs auszuleihen, deshalb wird die Methode ausleihen als \emph{public} definiert. -Da es aber auch klasseninterne Variablen und Funktionen gibt, wie hier zum -Beispiel die DVD-Sammlung selbst, ergibt es auch Sinn Teile der Klasse als -\emph{private} zu deklarieren. Wir modellieren also durch die Einteilung in public \& -private also Eigenschaften, die wir bisher nicht abbilden konnten. \\ -Per Default ist alles in einer Klasse \emph{private}. - -Jetzt gibt es auch noch weitere Attribute wie den Name der Sammlung, der nicht -so ganz in beide Kategorien passt. Da Benutzerinnen den Titel zwar auslesen müssen, aber den Titel nicht einfach verändern sollen. Dafür ist die übliche Vorgehensweise, \emph{getter}- bzw \emph{setter}-Methoden zu definieren. Eine getter-Methode sollte das entsprechende Attribut (zum Beispiel den Titel) zurückgeben. Wohingegen eine setter-Methode einen Parameter des Types des entsprechenden Attributes entgegen nimmt und dann den Wert intern ändert. - -\inputcpp{class.cpp} diff --git a/classes/content.txt b/classes/content.txt deleted file mode 100644 index e5cf8ef..0000000 --- a/classes/content.txt +++ /dev/null @@ -1,9 +0,0 @@ -Planung Kapitel 2 - -Enums, Casting + ANSI-Esc -for-Schleifen -Structs -Code-Snippets -C++11 (Funktionen), Aliase(Bash) -Klassen (Methoden, Private-Public) -STL (Vector, Array) diff --git a/classes/enum.tex b/classes/enum.tex deleted file mode 100644 index 36b0993..0000000 --- a/classes/enum.tex +++ /dev/null @@ -1,24 +0,0 @@ -\lesson{Enums \& Ansi} - -Da die Basics der \Cpp-Programmierung nun verinnerlicht sind, fangen wir an uns eigene Datentypen zu definieren. -Eine der einfachsten Kategorien von Datentypen sind \emph{Enum}s. Der Hauptzweck von Enums ist das Zuordnen von Bedeutungen zu Nummerierungen. -Sie ermöglichen z.B. das Verwenden von leicht lesbaren Begriffen an Stellen, die eigentlich ganze Zahlen erfordern. \\ -In folgendem Codebeispiel existiert eine Funktion \texttt{runden}, die abhängig der als \emph{mode} angegebenen Zahl entweder kaufmännnisch rundet, oder ab- bzw. aufrundet. - -\inputcpp{runden.cpp} - -Das ist relativ unschön und unintuitiv zu benutzen. Man weiß zum Beispiel nicht, wie viele modes es überhaupt gibt, wenn man den Code nicht genau ließt. Dies kann zu unnötigen Fehlern führen, wie man beim letzten Aufruf von \texttt{runden} sieht. Natürlich könnte man für den \emph{mode} auch den Typ String wählen, diese Verbrauchen aber sehr viel Platz und sind damit völlige Verschwendung für diese Aufgabe. Besser lässt sich das mit einem Enum lösen: - -\inputcpp{runden2.cpp} - -In den geschweiften Klammer wird angegeben, welche Zustände der Datentyp annehmen kann. -Intern werden diese von 0 beginnend durchnummeriert, was jedoch für viele Zwecke unwichtig ist. -Mit einem '='-Zeichen hinter dem Zustand kann diesem explizit eine Zahl zugewiesen werden, die dieser repräsentiert. -Dies kann in manchen Fällen sinnvoll sein, da Enums einfach in Integer verwandelt werden können (und anders herum). - -\begin{praxis} - \begin{enumerate} - \item Erweitere \texttt{runden2.cpp} so, dass auch negative Eingaben richtig gerundet werden. Bei Abrunden sollte die Eingabe -1.4 also auf 2 und bei Aufrunden auf 1 gerundet werden. - \item Füge zwei weitere modes hinzu, die jeweils zur Null und von der Null weg runden. - \end{enumerate} -\end{praxis} \ No newline at end of file diff --git a/classes/intro.tex b/classes/intro.tex deleted file mode 100644 index 254a04e..0000000 --- a/classes/intro.tex +++ /dev/null @@ -1,12 +0,0 @@ -\chapter[Objektorientierung]{Einführung in Objektorientierung \& Klassen} -\pagestyle{empty} - -Im nun folgenden Kapitel werden wir lernen einfache Datentypen zu komplexeren Typen in Klassen zusammenzufassen. - -\pagestyle{fancy} -\include{classes/enum} -\include{classes/struct} -\include{classes/operator} -\include{classes/classes} - -\pagestyle{empty} diff --git a/classes/struct.tex b/classes/struct.tex deleted file mode 100644 index 3f15510..0000000 --- a/classes/struct.tex +++ /dev/null @@ -1,53 +0,0 @@ -\lesson{Structs} - -Wir sind bisher dazu in der Lage Variablen von vielen verschiedenen Typen anzulegen. -Wir wollen uns jetzt damit beschäftigen wie wir dreidimensionale Vektoren in \Cpp implementieren können. - -Unsere bisherigen Datentypen sind dafür leider eher ungeeignet. -Wir könnten zwar einen Vektor simulieren indem wir drei \texttt{double} benutzen, allerdings haben wir bisher keine Möglichkeit, eine Funktion zu schreiben, die mehrere Zahlen auf einmal zurück gibt. - -Um Datentypen zu bündeln, gibt es die sogenannten \emph{Structs}. -Diese besitzen verschiedene \emph{Attribute}, zum Beispiel würde ein Vektor drei verschiedene Attribute vom Typ \texttt{double} besitzen. -Das könnte zum Beispiel so aussehen: - -\inputcpp{struct.cpp} - -%Jetzt ist es immer noch umständlich einen neuen Vektor zu initialisieren, da man einzeln $x$, $y$ und $z$ festlegen muss. -%An dieser Stelle wäre eine Möglichkeit, diesen Teil in eine eigene Funktion auszulagern. -%Da das Initialisieren von Attributen eine häufige Aufgabe ist, gibt es sogenannte \emph{Konstruktoren}, die vordefinierte Parameter entgegen nehmen und damit einen bestimmten Struct initialisieren können. -%Das sieht dann zum Beispiel so aus: -% -%\includecpp{konst.cpp} - -\begin{praxis} - \begin{enumerate} - \item Schreibt einen neuen Struct, der ein Datum folgender Art repräsentiert: \texttt{"1 Januar 1971"}. - Dieser Struct sollte also drei Attribute haben: - ein \texttt{int}, um das Jahr zu speichern, - ein \texttt{std::string} für den Monat - und ein weiterer \texttt{int} für den Tag. - - \item Erstellt eine Funktion, die einen \texttt{std::string} als Parameter entgegen nimmt, die Nutzerin mit der Ausgabe des Strings nach einem Datum fragt und dann das Datum mit eurem erstellten Struct zurück gibt. - - \item Fragt mit dieser Funktion die Benutzerin nach ihrem Geburtsdatum. Überprüft, ob ihr am gleichen Tag Geburtstag habt. - Außerdem solltet ihr überprüfen, ob ihr im gleichen Jahr geboren seid. - \end{enumerate} -\end{praxis} -\begin{praxis}[(Quadratsfunktion)] - - \begin{enumerate} - \item Schreibt einen Struct \texttt{Point2D}, der zweidimensionale Punkte - repräsentieren soll. ($a = (x, y) \in \mathbb{R}^2$) - \item In einem früheren Kapitel habt ihr gelernt, wie man Arrays von - Datentypen anlegen kann. Erstellt ein Array aus 100 \texttt{Point2D}s, bei dem die - x-Werte von 0 bis 99 gehen. - \item Berechnet dann für jeden \texttt{x}-Wert das entsprechende \texttt{y}, - indem ihr $y = x^2$ berechnet. - \end{enumerate} -\end{praxis} - -\begin{spiel} - \begin{enumerate} - \item ?? - \end{enumerate} -\end{spiel} \ No newline at end of file