> ## Documentation Index
> Fetch the complete documentation index at: https://homelab.amylify.de/llms.txt
> Use this file to discover all available pages before exploring further.

# 4.2.3 Kontrollfluss

> Entscheidungen mit if und switch, Schleifen mit for, while und foreach sowie Musterabgleich in C#.

Normalerweise läuft ein Programm Zeile für Zeile von oben nach unten. Der **Kontrollfluss** ändert diese Reihenfolge: Code wird nur unter einer Bedingung ausgeführt oder mehrfach wiederholt.

***

## Entscheidungen

### if, else if, else

```csharp theme={"dark"}
int punkte = 72;

if (punkte >= 90)
{
    Console.WriteLine("Sehr gut");
}
else if (punkte >= 70)
{
    Console.WriteLine("Gut");
}
else
{
    Console.WriteLine("Weiter üben");
}
```

Die Bedingung in `( )` muss ein `bool` ergeben. Bedingungen lassen sich mit `&&` (und), `||` (oder) und `!` (nicht) kombinieren:

```csharp theme={"dark"}
if (alter >= 18 && hatAusweis)
{
    Console.WriteLine("Zutritt erlaubt");
}
```

> [!WARNING]
>
> Ein einzelnes `=` **weist zu**, erst `==` **vergleicht**. In C# ist `if (x = 5)` ein Compilerfehler, in vielen anderen Sprachen ein klassischer Bug.

### Kurzform mit ?:

Für einfache Fälle gibt es den **ternären Operator**:

```csharp theme={"dark"}
string status = alter >= 18 ? "volljährig" : "minderjährig";
```

### switch

Wenn eine Variable mit vielen festen Werten verglichen wird, ist `switch` übersichtlicher als eine lange `if`-Kette:

> [tab] switch-Anweisung
>
> ```csharp theme={"dark"}
> Console.Write("Wochentag (1-7): ");
> int.TryParse(Console.ReadLine(), out int tag);
>
> switch (tag)
> {
>     case 1:
>     case 2:
>     case 3:
>     case 4:
>     case 5:
>         Console.WriteLine("Arbeitstag");
>         break;
>     case 6:
>     case 7:
>         Console.WriteLine("Wochenende");
>         break;
>     default:
>         Console.WriteLine("Ungültig");
>         break;
> }
> ```
>
> Jeder Zweig endet mit `break`. Mehrere `case`-Zeilen untereinander teilen sich einen Zweig.

> [tab] switch-Ausdruck
>
> Die kompakte Form liefert direkt einen Wert zurück:
>
> ```csharp theme={"dark"}
> string art = tag switch
> {
>     >= 1 and <= 5 => "Arbeitstag",
>     6 or 7        => "Wochenende",
>     _             => "Ungültig"
> };
> ```
>
> `_` steht für alle übrigen Fälle. Die Zweige werden von oben nach unten geprüft.

### Musterabgleich

Mit **Mustern** (Pattern Matching) prüfst du Typ und Wert in einem Schritt:

| Muster | Beispiel | Bedeutung |
| :- | :- | :- |
| Vergleich | `x is > 10` | Größer als 10 |
| Bereich | `x is >= 1 and <= 5` | Zwischen 1 und 5 |
| Auswahl | `x is 1 or 2 or 3` | Einer von mehreren Werten |
| Negation | `x is not null` | Nicht `null` |
| Typ | `obj is string text` | Ist ein `string`, direkt als `text` verfügbar |

```csharp theme={"dark"}
object wert = "Hallo";

if (wert is string text && text.Length > 3)
{
    Console.WriteLine($"Langer Text: {text}");
}
```

***

## Schleifen

Schleifen wiederholen einen Block, solange eine Bedingung erfüllt ist.

### for

Ideal, wenn die Anzahl der Durchläufe bekannt ist:

```csharp theme={"dark"}
for (int i = 1; i <= 5; i++)
{
    Console.WriteLine($"Durchlauf {i}");
}
```

```mermaid theme={"dark"}
flowchart LR
    A["Start: i = 1"] --> B{"i <= 5?"}
    B -- ja --> C["Block ausführen"]
    C --> D["i++"]
    D --> B
    B -- nein --> E["Ende"]
```

Der Kopf besteht aus drei Teilen: **Start** (`int i = 1`), **Bedingung** (`i <= 5`) und **Schritt** (`i++`).

### while und do-while

Für Wiederholungen mit unbekannter Anzahl:

> [tab] while
>
> Prüft die Bedingung **vor** jedem Durchlauf. Der Block läuft eventuell nie:
>
> ```csharp theme={"dark"}
> int zahl = 1;
> while (zahl < 100)
> {
>     zahl *= 2;
> }
> Console.WriteLine(zahl);   // 128
> ```

> [tab] do-while
>
> Prüft **nach** dem Durchlauf. Der Block läuft mindestens einmal, ideal für Eingabeprüfungen:
>
> ```csharp theme={"dark"}
> int alter;
> do
> {
>     Console.Write("Alter (1-120): ");
> }
> while (!int.TryParse(Console.ReadLine(), out alter) || alter < 1 || alter > 120);
>
> Console.WriteLine($"Alter: {alter}");
> ```

### foreach

Geht jedes Element einer Sammlung durch, ohne Zähler:

```csharp theme={"dark"}
string[] fruechte = ["Apfel", "Birne", "Kirsche"];

foreach (string frucht in fruechte)
{
    Console.WriteLine(frucht);
}
```

> [!NOTE]
>
> Innerhalb von `foreach` darfst du die Sammlung nicht verändern (kein Hinzufügen oder Entfernen), sonst gibt es einen Laufzeitfehler.

### Welche Schleife?

| Situation | Schleife |
| :- | :- |
| Anzahl der Durchläufe ist bekannt | `for` |
| Alle Elemente einer Sammlung durchgehen | `foreach` |
| Wiederholen, solange etwas gilt | `while` |
| Mindestens einmal ausführen, dann prüfen | `do-while` |

### break und continue

| Schlüsselwort | Wirkung |
| :- | :- |
| `break` | Beendet die Schleife sofort |
| `continue` | Springt zum nächsten Durchlauf |

```csharp theme={"dark"}
for (int i = 1; i <= 10; i++)
{
    if (i % 2 == 0) continue;   // gerade Zahlen überspringen
    if (i > 7) break;           // bei Zahlen über 7 abbrechen
    Console.WriteLine(i);       // 1, 3, 5, 7
}
```

### Verschachtelte Schleifen

Eine Schleife in einer Schleife, zum Beispiel für ein Einmaleins:

```csharp theme={"dark"}
for (int zeile = 1; zeile <= 3; zeile++)
{
    for (int spalte = 1; spalte <= 5; spalte++)
    {
        Console.Write($"{zeile * spalte,4}");   // rechtsbündig auf 4 Zeichen
    }
    Console.WriteLine();
}
```

> [!WARNING]
>
> **Endlosschleifen:** Ändert sich die Bedingung nie, läuft das Programm für immer. Abbrechen kannst du es im Terminal mit `Strg + C`.

***

## Weiter

> [card] [4.2.4 Methoden](https://homelab.amylify.de/documentation/code/csharp/methoden.md)
>
> Wiederkehrenden Code in benannte Bausteine auslagern.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.