1. Einführung
Fangen wir mal mit der Frage an: Wozu sollte man überhaupt eine Schleife in eine andere einbauen? Ganz einfach: Unsere Daten oder Aufgaben sind oft nicht nur als eine Linie organisiert, sondern zum Beispiel als Tabelle, Grid oder sogar als mehrdimensionale Struktur. Angenommen, du willst das Einmaleins ausgeben, ein zweidimensionales Array durchlaufen oder alle Schnittpunkte zwischen allen Elementpaaren berechnen. Da reicht eine Schleife nicht – du brauchst eine Schleife in der Schleife.
In der Programmierung ist eine verschachtelte Schleife wie zwei Wecker: Der äußere fängt an zu klingeln, und in ihm startet noch einer, der jedes Mal klingelt, solange der erste aktiv ist. Also: Während eine "äußere" Iteration läuft, macht die innere ihren kompletten Durchlauf (und das immer wieder für jede Iteration der äußeren).
Ein gutes Beispiel sind Stunden und Minuten. Stunden – das ist die äußere Schleife von 0 bis 23, Minuten – die innere von 0 bis 59. Bei jeder Änderung der äußeren Schleife läuft die innere einmal komplett durch.
2. Syntax von verschachtelten Schleifen
In C# unterscheidet sich die Syntax von verschachtelten Schleifen nicht von normalen Schleifen – du schreibst einfach eine Schleife ins Innere einer anderen. Schauen wir uns Beispiele mit for und while an:
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
Console.Write($"{i},{j} ");
}
Console.WriteLine();
}
Hier steuert die äußere Schleife die Variable i (von 0 bis 2), die innere die Variable j (von 0 bis 3). Für jeden Wert von i läuft die innere Schleife komplett von j=0 bis j=3. Wenn du diesen Code ausführst, bekommst du eine schöne Koordinatentabelle:
0,0 0,1 0,2 0,3
1,0 1,1 1,2 1,3
2,0 2,1 2,2 2,3
Ein ähnliches Beispiel mit while:
int i = 0;
while (i < 3)
{
int j = 0;
while (j < 4)
{
Console.Write($"{i},{j} ");
j++;
}
Console.WriteLine();
i++;
}
Achte darauf: Bei jedem Durchlauf der äußeren Schleife muss die Variable der inneren Schleife (j) neu initialisiert werden, sonst siehst du nur eine Zeile!
3. Beispiele für verschachtelte Schleifen
Beispiel 1: Schachbrett (8x8) ausgeben
Unsere erste Aufgabe: Ein klassisches Schachbrett auf dem Bildschirm ausgeben, mit schwarzen und weißen Feldern (nehmen wir # für schwarz, _ für weiß). Das machen wir mit verschachtelten for-Schleifen:
for (int row = 0; row < 8; row++)
{
for (int col = 0; col < 8; col++)
{
if ((row + col) % 2 == 0)
Console.Write("_");
else
Console.Write("#");
}
Console.WriteLine();
}
Ergebnis:
_#_#_#_#
#_#_#_#_
_#_#_#_#
#_#_#_#_
_#_#_#_#
#_#_#_#_
_#_#_#_#
#_#_#_#_
Wichtig: Die Verschachtelung sorgt dafür, dass wir für jede Zeile (row) alle Spalten (col) komplett durchlaufen. Ohne Verschachtelung gäbe es kein Brett – nur eine Zeile oder eine Spalte.
Beispiel 2: Einmaleins
Ein echter Klassiker für verschachtelte Schleifen! Lass uns das Einmaleins von 1-9 ausgeben:
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= 9; j++)
{
Console.Write($"{i * j,3} ");
}
Console.WriteLine();
}
Das Format ${i * j,3} sorgt für Abstände, damit die Tabelle ordentlich aussieht.
Ergebnis:
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
...
9 18 27 36 45 54 63 72 81
4. Verschachtelte Schleifen und ihre Steuerung – Feinheiten
Wie break und continue in verschachtelten Schleifen wirken
Hier tappen viele Anfänger rein! Wenn du break oder continue in der inneren Schleife benutzt, wirken sie nur auf diese Schleife. Die äußere läuft ganz normal weiter.
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
if (j == 3)
break; // wir springen nur aus der inneren Schleife raus!
Console.Write($"{i},{j} ");
}
Console.WriteLine();
}
Ergebnis:
0,0 0,1 0,2
1,0 1,1 1,2
2,0 2,1 2,2
Wenn du direkt aus beiden verschachtelten Schleifen raus willst (zum Beispiel, wenn du beim ersten Treffer in einer Tabelle sofort abbrechen willst), nimmt man meistens eine Flag-Variable oder einen Trick (z.B. return, falls alles in einer Funktion läuft).
5. Visualisierung von verschachtelten Schleifen
Manchmal ist es schwer, die Ausführungsreihenfolge von verschachtelten Schleifen "zu sehen". Schau dir mal dieses Flussdiagramm an:
In Tabellenform – wie viele Iterationen gibt es insgesamt, wenn i von 1 bis 3 läuft und j von 1 bis 4?
| i | j (wird für jedes i durchlaufen) | Iterationen der inneren Schleife |
|---|---|---|
| 1 | 1, 2, 3, 4 | 4 |
| 2 | 1, 2, 3, 4 | 4 |
| 3 | 1, 2, 3, 4 | 4 |
| Insgesamt: 3 × 4 = 12 |
6. Fehler und Stolperfallen bei verschachtelten Schleifen
Ein häufiger Fehler: Die Variable der inneren Schleife falsch initialisieren. Zum Beispiel sie außerhalb der äußeren Schleife deklarieren, aber nicht bei jedem Schritt zurücksetzen. Dann läuft die innere Schleife vielleicht gar nicht oder falsch.
int j = 0;
for (int i = 0; i < 3; i++)
{
while (j < 4) // Ups! j könnte nach der ersten Runde schon 4 sein.
{
Console.Write($"{i},{j} ");
j++;
}
Console.WriteLine();
}
Hier läuft die Schleife nur einmal. Vergiss nicht, die Variablen der inneren Schleifen im Inneren der äußeren zu initialisieren!
Außerdem: Wenn du aus Versehen zwei verschachtelte Schleifen mit denselben Variablennamen schreibst, meckert der Compiler – die Variable ist schon definiert.
for (int i = 0; i < 3; i++)
{
for (int i = 0; i < 3; i++)
{
Console.Write($"{i},{i} ");
}
Console.WriteLine();
}
GO TO FULL VERSION