Zum Inhalt
wannacode

Schleifen

Kurz gesagt: Eine Schleife wiederholt ein Stück Code, solange eine Bedingung wahr ist: for zählt von einem Anfang bis zu einem Ende, while wiederholt, ohne zu wissen, wie oft, und break beendet die Schleife.

Problem

Wie viel sparst du?

Du beschließt zu sparen: Im ersten Monat legst du 10 € zur Seite, im zweiten 20 €, im dritten 30 € und so weiter, jedes Mal 10 € mehr. Wie viel hast du nach 4 Monaten?

int total = 0;
total += 1 * 10;
total += 2 * 10;
total += 3 * 10;
total += 4 * 10;
System.out.println(total);
Ausgabe
100

Das funktioniert. Aber nach 3 Jahren sind es 36 Zeilen, fast alle gleich. Und wenn die Zahl der Monate über die Tastatur eingegeben wird, weißt du gar nicht, wie viele Zeilen du schreiben sollst. Du brauchst eine Möglichkeit zu sagen: „Wiederhole das so oft.“

Die Idee

for: wiederholen, solange die Bedingung wahr ist

Ein Stück Code, das sich wiederholt, heißt Schleife. Die Schleife, die du am häufigsten brauchst, ist for. Hier sind die Zahlen von 1 bis 10:

for (int i = 1; i <= 10; i++) {
System.out.println(i);
}
Ausgabe
1
2
3
4
5
6
7
8
9
10

In den Klammern stehen drei Teile, getrennt durch ;:

  • Start: int i = 1. Er läuft einmal, vor allem anderen. Hier entsteht der Zähler.
  • Bedingung: i <= 10. Sie wird vor jedem Durchlauf geprüft. Ist sie wahr, läuft der Rumpf. Wenn nicht, endet die Schleife.
  • Schritt: i++. Er läuft nach jedem Durchlauf.

Jede Ausführung des Rumpfs heißt Iteration oder kurz Durchlauf.

Genauer, für Neugierige
  • Der Schritt kann sein, was du brauchst: i += 2 (jede zweite Zahl), i-- (rückwärts).
  • Der Zähler i existiert nur in der Schleife. Nach der schließenden } ist er weg, und wenn du ihn benutzt, lässt sich das Programm nicht kompilieren.
  • Oft siehst du, dass ab 0 gezählt wird: for (int i = 0; i < 10; i++). Das sind immer noch 10 Durchläufe. Warum man ab 0 zählt, wird in der Lektion über Arrays klar.

Sieh es dir an

Durchlauf für Durchlauf

Das sind die Ersparnisse von der ersten Karte, mit einer Schleife. Sieh zu, wie sich month und total ändern.

int total = 0;
for (int month = 1; month <= 4; month++) {
total += month * 10;
}
System.out.println(total); // 100
Schritt für Schritt, in Worten
  1. total beginnt bei 0.
  2. month = 1. Prüfung: 1 <= 4 ist wahr, also geht es in den Rumpf.
  3. Durchlauf 1: total += 1 * 10, total wird 10.
  4. month++ macht month zu 2. 2 <= 4: noch ein Durchlauf, total wird 30.
  5. month 3: total wird 60.
  6. month 4: total wird 100.
  7. month++ macht month zu 5. 5 <= 4 ist falsch: Die Schleife endet.
  8. Nach der Schleife ist total 100.

Der Rumpf ist eine Zeile und steht nur einmal da. Für 36 Monate änderst du nur 4 in 36. Du kannst dort sogar eine Variable einsetzen, die von der Tastatur gelesen wurde.

Probier es aus

Rückwärts zählen

Was gibt das Programm aus?

for (int sec = 3; sec > 0; sec--) {
System.out.println(sec);
}
System.out.println("Start!");
Antwort

Die Idee

while: bis das Ende kommt

Manchmal weißt du vorher nicht, wie viele Durchläufe es gibt. Die Kasse liest Preise, bis die Kassiererin 0 eingibt, und nennt dann die Summe. Hier passt for nicht. Es passt while: nur eine Bedingung, ohne Start und ohne Schritt.

Scanner in = new Scanner(System.in);
int total = 0;
int price = in.nextInt();
while (price != 0) {
total += price;
price = in.nextInt();
}
System.out.println("Gesamt: " + total + " €");
Eingabe
12
4
7
0
Ausgabe
Gesamt: 23 €

Der erste Preis wird vor der Schleife gelesen, damit die Bedingung etwas zu prüfen hat. Der nächste wird am Ende des Rumpfs gelesen. Ist die erste Zahl 0, läuft der Rumpf kein einziges Mal.

Wenn der Rumpf mindestens einmal laufen soll, gibt es do-while. Die Bedingung steht unten und wird nach dem Durchlauf geprüft. Das ist praktisch für eine Frage, die sich wiederholt, bis die Antwort passt:

Scanner in = new Scanner(System.in);
int count;
do {
System.out.println("Wie viele Tickets (1 bis 10)?");
count = in.nextInt();
} while (count < 1 || count > 10);
System.out.println("Reservierte Tickets: " + count);
Eingabe
0
15
3
Ausgabe
Wie viele Tickets (1 bis 10)?
Wie viele Tickets (1 bis 10)?
Wie viele Tickets (1 bis 10)?
Reservierte Tickets: 3
Genauer, für Neugierige
  • Wenn die Bedingung nie falsch wird, endet die Schleife nie. Das ist eine Endlosschleife: Das Programm „hängt“, und du musst es von Hand stoppen. Die häufigste Ursache ist eine vergessene Änderung der Variable in der Bedingung, zum Beispiel ein fehlendes price = … am Ende des Rumpfs.
  • Nach dem while (…) eines do-while steht ein ;. Ohne es lässt sich das Programm nicht kompilieren.
  • Jedes for lässt sich als while schreiben und umgekehrt. Du nimmst die Variante, die sich klarer liest: for für eine bekannte Zahl von Durchläufen, while für „bis etwas passiert“.

Probier es aus

Finde den Fehler

Das Programm soll die Zahlen von 1 bis 5 addieren: 1 + 2 + 3 + 4 + 5 = 15. Es gibt 10 aus. In welcher Zeile ist der Fehler?

Wähle die Zeile mit dem Fehler.

Die Idee

break und continue

Zwei Wörter ändern den üblichen Ablauf einer Schleife.

continue überspringt den Rest des aktuellen Durchlaufs und geht zum nächsten. Du listest Termine von 9 bis 17 Uhr auf, aber um 13 Uhr ist Mittagspause:

for (int hour = 9; hour <= 17; hour++) {
if (hour == 13) {
continue;
}
System.out.println(hour + ":00");
}
Ausgabe
9:00
10:00
11:00
12:00
14:00
15:00
16:00
17:00

break beendet die ganze Schleife sofort. Du suchst die erste Zahl, durch die 91 teilbar ist. Sobald du sie gefunden hast, hat Weitersuchen keinen Sinn:

int n = 91;
for (int d = 2; d < n; d++) {
if (n % d == 0) {
System.out.println(n + " ist durch " + d + " teilbar");
break;
}
}
Ausgabe
91 ist durch 7 teilbar
Genauer, für Neugierige
  • break beendet nur die Schleife, in der es steht. Steht es in einer verschachtelten Schleife (nächste Karte), läuft die äußere weiter.
  • Oft siehst du while (true) mit einem break darin: eine Schleife, die nicht durch ihre Bedingung endet, sondern durch ein break an der richtigen Stelle.

Die Idee

Eine Schleife in einer Schleife

Der Kinosaal hat 3 Reihen mit je 4 Plätzen. Du willst jeden Platz ausgeben. Für jede Reihe gehst du alle Plätze darin durch:

for (int row = 1; row <= 3; row++) {
for (int seat = 1; seat <= 4; seat++) {
System.out.print("[" + row + "-" + seat + "]");
}
System.out.println();
}
Ausgabe
[1-1][1-2][1-3][1-4]
[2-1][2-2][2-3][2-4]
[3-1][3-2][3-3][3-4]

Das nennt man verschachtelte Schleifen. Die innere Schleife läuft bei jedem Durchlauf der äußeren komplett durch: 3 Reihen · 4 Plätze = 12 Ausgaben. print lässt die Plätze in einer Zeile, und das leere println() nach der inneren Schleife springt in eine neue Zeile.

Probier es aus

Treppe

In der ersten Zeile soll ein Stern stehen, in der zweiten zwei, in der vierten vier. Was gehört in die Lücke?

for (int row = 1; row <= 4; row++) {
    for (int star = 1; star <= ; star++) {
        System.out.print("*");
    }
    System.out.println();
}

Die Idee

Zufallszahlen für Spiele

Ein Würfelspiel braucht eine Zahl, die das Programm vorher nicht kennt. Random liefert sie dir:

Random random = new Random();
int dice = random.nextInt(6) + 1;
System.out.println("Gewürfelt: " + dice);

Random ist ein Objekt, deshalb erzeugst du es mit new. Was ein Objekt ist, lernst du im Modul „Klassen und Objekte“. Benutze es vorerst so: Du erzeugst es einmal und holst dir dann so viele Zahlen, wie du brauchst.

Genau wie bei Scanner brauchst du ganz oben in der Datei, über der Klasse, import java.util.Random;.

random.nextInt(6) liefert eine Zahl von 0 bis 5: Die obere Grenze ist nicht dabei. Mit + 1 wird daraus 1 bis 6.

Jeder Start liefert eine andere Zahl, deshalb gibt es hier keine Ausgabe. Und hier ist eine Schleife, die würfelt, bis eine Sechs fällt:

Random random = new Random();
int rolls = 0;
int dice;
do {
dice = random.nextInt(6) + 1;
rolls++;
} while (dice != 6);
System.out.println("Sechs nach " + rolls + " Würfen");
Genauer, für Neugierige
  • Seit Java 17 gibt es auch random.nextInt(1, 7): von 1 bis 6, wie in C#.
  • Du begegnest auch Math.random(). Es liefert eine Kommazahl von 0 bis 1 (ohne 1), und eine ganze Zahl bekommst du mit (int) (Math.random() * 6) + 1.
  • Wenn du Random einen Startwert gibst (new Random(42)), liefert jeder Start dieselbe Folge. Das hilft beim Testen. Java und C# liefern aus demselben Startwert verschiedene Folgen.
  • Die Zahlen sind nicht wirklich zufällig: Sie werden mit einer Formel berechnet. Für Spiele reichen sie, für Passwörter und Sicherheit nicht.

Übung

Aufgaben zu Schleifen

Löse die Aufgaben in deinem Editor. Zu jeder gibt es eine Beispiel-Eingabe und -Ausgabe, mit der du deine vergleichen kannst. Die Zahl liest du genauso ein wie in der Lektion „Eingabe und Ausgabe“.

1. Einmaleins. Lies eine Zahl ein und gib ihre Produkte mit den Zahlen von 1 bis 10 aus.

Eingabe
7
Ausgabe
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70

2. Primzahl. Eine Zahl ist eine Primzahl, wenn sie nur durch 1 und durch sich selbst teilbar ist: 2, 3, 5, 7, 11… Lies eine Zahl ein und gib aus, ob sie eine Primzahl ist. Tipp: Probiere die Teiler ab 2 aufwärts und hör beim ersten mit break auf.

Eingabe
91
Ausgabe
91 ist keine Primzahl

Für 11 ist die Ausgabe „11 ist eine Primzahl“.

3. Die Ziffern einer Zahl. Lies eine positive ganze Zahl ein. Gib sie rückwärts aus und dazu die Summe ihrer Ziffern. Tipp: n % 10 ist die letzte Ziffer, und n / 10 entfernt die letzte Ziffer. Wiederhole das, bis die Zahl 0 wird.

Eingabe
2024
Ausgabe
Umgekehrt: 4202
Quersumme: 8

4. Zahlenraten. Der Computer „denkt sich“ eine Zahl von 1 bis 100 aus, und du suchst sie. Nach jedem Versuch sagt das Programm „Die Zahl ist kleiner.“ oder „Die Zahl ist größer.“ und am Ende, wie viele Versuche du gebraucht hast. Schreib es zuerst mit der geheimen Zahl 37, damit du es mit dem Beispiel vergleichen kannst:

Eingabe
50
25
37
Ausgabe
Die Zahl ist kleiner.
Die Zahl ist größer.
Richtig! Du hast 3 Versuche gebraucht.

Wenn es funktioniert, ersetze 37 durch eine Zufallszahl von 1 bis 100. Jetzt kennst nicht einmal du die Antwort.

Weitere Aufgaben

  • Von 1 bis N. Lies N ein und gib die Zahlen von 1 bis N in einer Zeile aus. Für 5: 1 2 3 4 5.
  • Fakultät. N! = 1 · 2 · 3 · … · N. Für 5: 120. Nimm long: int reicht nur bis 12!, long bis 20! (2432902008176640000).
  • Primzahlen bis N. Gib alle Primzahlen bis N aus. Für 20: 2 3 5 7 11 13 17 19. Die Prüfung aus Aufgabe 2 kommt in eine Schleife über die Zahlen: verschachtelte Schleifen.
  • Fibonacci. Jede Zahl ist die Summe der beiden davor: 0, 1, 1, 2, 3, 5, 8… Lies N ein und gib die ersten N Zahlen aus. Für 10: 0 1 1 2 3 5 8 13 21 34.
  • Quadrat aus Sternen. Lies N ein und gib ein Quadrat N × N aus. Für 3:
Ausgabe
* * *
* * *
* * *
  • Dreieck aus Sternen. Dasselbe, aber jede Zeile hat so viele Sterne wie ihre Nummer. Für 3:
Ausgabe
*
* *
* * *
  • Münzwurf. Lies N ein, wirf N-mal eine Münze mit einer Zufallszahl (0 ist Kopf, 1 ist Zahl) und gib aus, wie oft jede Seite gefallen ist. Je größer N ist, desto näher kommen beide Zahlen an N / 2.
  • Schere, Stein, Papier. Ein Spieler gegen den Computer. Der Spieler gibt seine Wahl ein, der Computer wählt zufällig, und das Programm sagt, wer gewinnt. Mit do-while fragt es „Noch ein Spiel? (ja/nein)“ und gibt am Ende den Spielstand aus.

Test

Teste dich

1. Wie oft läuft der Rumpf von for (int i = 0; i < 5; i++)?
2. Was ist der Unterschied zwischen while und do-while?
3. Was macht continue?
4. Die äußere Schleife läuft 3-mal, die innere 4-mal. Wie oft läuft der Rumpf der inneren Schleife?
5. Welche Zeile liefert eine Zufallszahl von 1 bis 6?

Erstellt von Ivo Gergov im Rahmen der Kampagne von Evo Tech für zugängliche Programmierausbildung ·