# Warm-ups (freiwillig)

Quelle: https://dev.inf.zone/exercises/02/warm-ups/

**Wozu das Ganze?**

Die Warm-ups führen die neuen Sprachmittel aus der Vorlesung „1. C“ in kleinen Schritten ein. Sie sind freiwillig, zählen nicht für die Bonuspunkte und sind nicht prüfungsrelevant. Nutzen Sie sie, wenn Sie bei einer Aufgabe nicht wissen, wie Sie anfangen sollen. Wenn Sie direkt loslegen können, fangen Sie mit den Aufgaben an.

Sie müssen nicht alle Warm-ups machen. Suchen Sie sich in der Tabelle das heraus, was Ihnen für eine Aufgabe fehlt:

| | Übt | Hilft bei |
|---|---|---|
| [Warm-up 1](#warm-up-1) | „Hello, world“ kompilieren und ausführen | Hello, It’s Me |
| [Warm-up 2](#warm-up-2) | Schleifen | Mario |
| [Warm-up 3](#warm-up-3) | Bedingungen mit `if` | Mario |
| [Warm-up 4](#warm-up-4) | Eigene Funktionen | Mario, Bargeld |
| [Warm-up 5](#warm-up-5) | Verschachtelte Schleifen | Mario |
| [Warm-up 6](#warm-up-6) | Funktionen mit Rückgabewert | Bargeld |

Legen Sie für die Warm-ups eine eigene Datei an, zum Beispiel `warmup_aufgaben_2.c` für Übung 2, im selben Ordner wie Ihre Übungsaufgaben. Die meisten Warm-ups bauen aufeinander auf: Sie ergänzen die Datei Schritt für Schritt. Lösungen gibt es für die Warm-ups nicht. Unter „Wo zu finden?“ steht jeweils, wo das Thema in Vorlesung und Shorts vorkommt. Mehr dazu im [FAQ zu den Warm-ups](https://dev.inf.zone/faq/uebung-warm-up/).

Mit diesem Gerüst lässt sich die Datei von Anfang an kompilieren:
```c
#include <cs50.h>
#include <stdio.h>

int main(void)
{

    return 0;
}
```

`cs50.h` stellt Funktionen wie `get_string` bereit, `stdio.h` Funktionen wie `printf`.

## Warm-up 1: „Hello, world“ kompilieren und ausführen

Dank Professor [Brian Kernighan](https://de.wikipedia.org/wiki/Brian_W._Kernighan) wurde ["hello, world" (Link führt zu YouTube, nicht kursrelevant)](https://youtu.be/ufB53UE2Cvo?t=103) in Hunderten von Sprachen implementiert. Beginnen wir also mit dieser Tradition.
Geben Sie ein einfaches `Hello World\n` auf der Konsole aus.

**Schritt für Schritt**

Öffnen Sie VS Code entsprechend Ihrem [Setup](https://dev.inf.zone/extras/setup/).

Führen Sie `cd` in Ihrem Terminalfenster aus. Die Eingabeaufforderung Ihres Terminalfensters sollte wie folgt aussehen:

```bash
$
```

Sie können nun Folgendes ausführen,

```bash
code warmup_aufgaben_2.c
```

um eine Datei namens `warmup_aufgaben_2.c` zu erstellen, in die Sie Ihren Code schreiben können. Im Endeffekt passiert hier aber nichts anderes, als wenn man eine Datei mit dem Namen `warmup_aufgaben_2.c` auf die übliche Art und Weise erstellt. Nur schneller und effizienter.

____

**Kompilieren und Ausführen**

Wenn Sie mit dem Programm fertig sind, können Sie es mit folgendem Befehl kompilieren, unter der Annahme, dass die Datei `warmup_aufgaben_2.c` heißt (ansonsten entsprechend anpassen):

```bash
make warmup_aufgaben_2
```

Wenn Sie keine Fehlermeldung sehen, wurde das Programm erfolgreich kompiliert! Sie können dies mit

```bash
ls
```

überprüfen. Es sollte nun nicht nur `warmup_aufgaben_2.c` (das ist der Quellcode), sondern auch `warmup_aufgaben_2` (darin steht der Maschinencode) aufgelistet werden.

Wenn Sie eine Fehlermeldung sehen, versuchen Sie, Ihren Code zu korrigieren und ihn erneut zu kompilieren.

Sobald Ihr Code erfolgreich kompiliert wurde, können Sie Ihr Programm mit folgendem Befehl ausführen:

```bash
./warmup_aufgaben_2
```

____

**Wo zu finden?**

Den entsprechenden Code kennen Sie bereits aus der [Vorlesung](https://dev.inf.zone/lectures/1-c/). Ansonsten sind Sie vielleicht schon in der [Setup-Anleitung](https://dev.inf.zone/extras/setup/codespace-cloud/#4-erste-schritte-in-vs-code) darüber gestolpert.

## Warm-up 2: Schleifen

Geben Sie `Hello World\n` in Abhängigkeit von einer Variablen `n` mal auf der Konsole aus. Initialisieren Sie `n` auf den Wert `5`.

Implementieren Sie diese Aufgabe in drei Varianten:

-   Verwenden Sie eine `while`-Schleife.
-   Verwenden Sie eine `for`-Schleife.
-   Verwenden Sie eine `do while`-Schleife.

Für die verschiedenen Varianten können die vorhergehenden Schleifen, wie im entsprechenden [FAQ-Eintrag](https://dev.inf.zone/faq/uebung-warm-up/) beschrieben, jeweils mit der Blockkommentar-Syntax `/* */` auskommentiert werden.

Die Ausgabe sollte folgendermaßen aussehen:
```plaintext
Hello World
Hello World
Hello World
Hello World
Hello World
```
Welcher Unterschied besteht zwischen einer `do while`-Schleife und einer `while`- oder `for`-Schleife? Mit welchem Wert für `n` funktioniert die `do while`-Schleife in diesem Kontext nicht wie gewünscht?

**Wo zu finden?**

Bei Problemen und Unklarheiten schauen Sie sich am besten noch einmal die Shorts zu [Schleifen](https://dev.inf.zone/lectures/1-c/short-1-4-schleifen/) und [Datentypen und Variablen](https://dev.inf.zone/lectures/1-c/short-1-1-datentypen/) an.

## Warm-up 3: Bedingungen mit `if`

Arbeiten Sie für die folgenden Warm-ups mit der `for`-Schleifen-Variante weiter.

Ergänzen Sie die Ausgabe von "Hello World" mit dem Index des aktuellen Schleifendurchlaufs (d.h. "Hello World 0", "Hello World 1" usw.). Verwenden Sie eine `if`-Bedingung innerhalb der Schleife, sodass die `printf`-Funktion nicht bei dem Indexwert `3` aufgerufen wird.

Mit `n = 5` sollte die Ausgabe also wie folgt aussehen:

```plaintext
Hello World 0
Hello World 1
Hello World 2
Hello World 4
```

**Wo zu finden?**

Bei Problemen und Unklarheiten schauen Sie sich am besten noch einmal die Shorts zu [Operatoren](https://dev.inf.zone/lectures/1-c/short-1-2-operatoren/) und [Bedingten Anweisungen](https://dev.inf.zone/lectures/1-c/short-1-3-bedingungen/)  an.

## Warm-up 4: Eigene Funktionen

Lagern Sie diese Funktionalität (ohne die zusätzliche `if`-Bedingung) in eine separate Funktion namens `print_n_times` aus, die einen `int` entgegennimmt und entsprechend häufig "Hello World" ausgibt. In der `main`-Funktion sollte nur diese Funktion mit einem entsprechenden Argument aufgerufen werden, um "Hello World" `n` mal auf der Konsole ausgeben zu lassen. _Vergessen Sie nicht den Funktionsprototypen oberhalb der `main`-Funktion einzufügen, wenn Sie die Funktion unterhalb der `main`-Funktion definieren._

Passen Sie anschließend in der Funktion den Schleifenkopf der `for`-Schleife so an, dass der ausgegebene Index mit dem Wert `1` beginnt und am Ende dem Wert von `n` entspricht. Bei `n = 5` sollte die Ausgabe also folgendermaßen aussehen:

```plaintext
Hello World 1
Hello World 2
Hello World 3
Hello World 4
Hello World 5
```

**Wo zu finden?**

Erinnern Sie sich an die Implementation der Funktion `meow()` aus der Vorlesung.

## Warm-up 5: Verschachtelte Schleifen

Nehmen Sie nun folgende Änderungen innerhalb der `print_n_times`-Funktion vor:
- Geben Sie statt "Hello World" nun einfach ein "+" aus (ohne Zeilenumbruch!).
- Geben Sie am Ende – nachdem die Schleife durchgelaufen ist – einen einzelnen Zeilenumbruch mit `printf` aus.

Multiplizieren Sie beim Aufruf von `print_n_times` außerdem das übergebene Argument `n` mit `4` (also `print_n_times(n * 4);`).

So sollte die Ausgabe dann aussehen:
```plaintext
++++++++++++++++++++
```

`print_n_times` gibt nun also nicht mehr mehrere Zeilen aus, sondern in Abhängigkeit von `n` das "+" nacheinander als **eine** Zeile.

Rufen Sie nun mittels einer weiteren Schleife in der `main`-Funktion die `print_n_times`-Funktion in Abhängigkeit von `n` mehrfach (im Falle von `n = 5` also 5 Mal) auf, sodass ein kleiner Gartenzaun ausgegeben wird:
```plaintext
++++++++++++++++++++
++++++++++++++++++++
++++++++++++++++++++
++++++++++++++++++++
++++++++++++++++++++
```

**Wo zu finden?**

Erinnern Sie sich an `mario.c` aus der Vorlesung.

## Warm-up 6: Funktionen mit Rückgabewert

Kommentieren Sie den bisherigen Code mittels der Blockkommentar-Syntax aus (dann haben Sie all Ihren geschriebenen Code weiterhin in einer Datei zur Verfügung):
```c
/*

// Code bis Warm-up 5

*/
```

Funktionen können auch Werte zurückgeben. Schreiben Sie eine Funktion `divide`, die zwei `int` Werte entgegennimmt, die beiden Werte dividiert (der erste Wert soll dabei der _Dividend_, der zweite der _Divisor_ sein) und den Quotienten zurückgibt. _Vergessen Sie nicht den Funktionsprototypen oberhalb der `main`-Funktion einzufügen, wenn Sie die Funktion unterhalb der `main`-Funktion definieren._

Die `main`-Funktion kann wie folgt übernommen werden:

```c
#include <cs50.h>
#include <stdio.h>

int main(void)
{
    int dividend = get_int("Input dividend: ");
    int divisor = get_int("Input divisor: ");
    int quotient = divide(dividend, divisor);
    printf("%i / %i = %i\n", dividend, divisor, quotient);
}
```

Bei korrekter Implementierung sollte bei der Programmausführung der entsprechende Quotient ausgegeben werden. Jedoch wird aufgrund der Verwendung von `int`-Typen die Berechnung jeweils trunkiert, d.h. die Nachkommastellen werden abgeschnitten (z.B. ist `7 / 5 = 1` eine korrekte Ausgabe).

Achten Sie auch darauf, zu prüfen, ob der _Divisor_ `0` ist, um einen Fehler aufgrund der Division durch `0` abzufangen. Geben Sie in diesem Fall eine kurze Fehlermeldung aus und `return`en Sie, sagen wir, den Wert `2147483647`, also z.B.:
```plaintext
Error: Division by zero is not allowed.
10 / 0 = 2147483647
```

Was würde bei einem Divisor mit dem Wert `0` ausgegeben werden, wenn Sie `2147483647 + 1` zurückgeben würden? Wie nennt man dieses Phänomen?

Übrigens, die Verwendung von `2147483647` direkt im Code ist ein Beispiel für eine sogenannte [Magische Zahl](https://dev.inf.zone/lectures/1-c/short-1-6-magic-numbers/).

**Wo zu finden?**

Erinnern Sie sich an `calculator.c` und die `add()`-Funktion aus der Vorlesung. Was müssen Sie ändern, damit dividiert statt addiert wird? Bei Problemen und Unklarheiten schauen Sie sich zusätzlich noch einmal das Short zu [Operatoren](https://dev.inf.zone/lectures/1-c/short-1-2-operatoren/) sowie die Folien und Notizen zur Vorlesung [1. C](https://dev.inf.zone/lectures/1-c/) an.

<br>
