Sie sind auf Seite 1von 49

ITR - Iterationen

Hinweis:
Diese Druckversion der Lerneinheit stellt aufgrund der Beschaffenheit des Mediums eine im Funktionsumfang stark eingeschränkte Variante des
Lernmaterials dar. Um alle Funktionen, insbesondere Verlinkungen, zusätzliche Dateien, Animationen und Interaktionen, nutzen zu können, benötigen
Sie die On- oder Offlineversion.
Die Inhalte sind urheberrechtlich geschützt.
©2023 Berliner Hochschule für Technik (BHT)

ITR - Iterationen

20.07.2023 1 von 49
ITR - Iterationen

Überblick und Lernziele

In dieser Lerneinheit wird die Programmierung von Schleifen an vielen Programmbeispielen


erklärt. Sie dienen dazu, bestimmte Programmteile zu wiederholen, um komplexe Algorithmen
programmieren zu können.

Lernziele
Lernziele
Sie können den Begriff Iteration erklären. Sie wissen, welche Schleifenarten es gibt. Sie
kennen deren Gemeinsamkeiten und Unterschiede.
Sie sind in der Lage, kopfgesteuerte, fußgesteuerte und Zähl-Schleifen zu programmieren
und zu erklären. Sie wissen, dass zur Realisierung dieser Schleifenarten die while-, do-
while - und for-Anweisungen verwendet werden.
Sie wissen, dass jede Schleife aus Bedingung und Rumpf besteht, und dass die Bedingung
immer einen booleschen Wert liefert.
Sie können einschätzen, welche Schleifenart wann zur Anwendung kommt.
Sie kennen die Wirkungsweise von break und continue und wissen, wann welche
Anweisung im Programm verwendet wird.

Gliederung der Lerneinheit


Gliederung
1. Schleifen
Schleifen kommen in der Programmierung zur Anwendung, um Programmabläufe mit
unbestimmter Dauer durch einen endlichen Algorithmus zu beschreiben, indem
Anweisungen wiederholt werden. In diesem Kapitel erfahren Sie, welche Schleifenarten
man prinzipiell unterscheidet.
2. Die vorprüfende Schleife
Sie lernen die vorprüfende Schleife kennen. Sie wird in Java durch die while-Anweisung
realisiert. An dieser Schleife lernen Sie den grundsätzlichen Ablauf aller Schleifen kennen
und beschäftigen sich mit der immer gegebenen Gefahr einer Endlosschleife.
3. Die nachprüfende Schleife
In diesem Kapitel stellen wir die nachprüfende Schleife vor, die in Java als do-while-
Anweisung programmiert wird. Insbesondere soll hier erläutert werden, in welchen
Situationen vor- oder nachprüfende Schleife besser geeignet ist.
4. Die Zählschleife
Zählschleifen gehören zu den vorprüfenden Schleifenarten. Sie lernen die drei Elemente
kennen, die im Kopf der Schleife enthalten sind, und was sie bewirken. Anhand von
Programmbeispielen demonstrieren wir Ihnen unter anderem, dass jede for-Anweisung in
eine while-Anweisung umgewandelt werden kann.
5. Abbrechen und Fortsetzen einer Schleife
Eine Schleife vorzeitig abzubrechen, noch bevor alle Anweisungen im Schleifenrumpf
ausgeführt worden sind, wird durch die einfachen Anweisungen break und continue
ermöglicht. Wann welche Anweisung im Programm verwendet wird und wie Syntax und
Wirkungsweise im Programm definiert sind, beschreibt dieses Kapitel.

Zeitbedarf und Umfang


Zeitbedarf
Für die Bearbeitung dieser Lerneinheit benötigen Sie etwa 150 Minuten.

Für die Bearbeitung aller Übungen sind insgesamt etwa 180 Minuten (obwohl Musterlösungen
bereitstehen, ist es für den Lernerfolg empfehlenswert, so viele Übungen wie möglich
selbstständig zu bearbeiten), für die Einsendeaufgabe zusätzlich 120 Minuten vorgesehen.

Achtung: Aufgrund von unterschiedlichen Vorkenntnissen gibt es in dieser Lerneinheit zum


Teil erhebliche Unterschiede für die benötigte Zeit.

20.07.2023 2 von 49
ITR - Iterationen

1 Schleifen
Kontrolliert wiederholen In einem Programm werden normalerweise die Anweisungen sequenziell,
also nacheinander in der Reihenfolge, wie sie im Code stehen, ausgeführt.
Mit Anweisungen wie if, if-else oder switch ist es möglich, manche
Anweisungen bei der Ausführung zu überspringen. Häufig ist es aber auch
notwendig, Teile eines Programms kontrolliert zu wiederholen.

Mit Schleifen – auch Iterationen genannt – ist es möglich, bestimmte


Anweisungen mehrmals auszuführen.

Bedingung und Rumpf


Definition
Jede Schleife besteht aus einer Bedingung und einem Schleifenrumpf oder -körper. Solange
die Bedingung wahr ist, werden die Anweisungen im Rumpf wiederholt ausgeführt. Wir
unterscheiden folgende Schleifenarten:

Wiederholung mit vorausgehender Bedingungsprüfung, man spricht von einer


kopfgesteuerten oder vorprüfenden Schleife.
Wiederholung mit nachfolgender Bedingungsprüfung, man nennt sie fußgesteuerte oder
nachprüfende Schleife.
Zählschleife mit vorausgehender Bedingungsprüfung. Sie gehört ebenfalls zu den
vorprüfenden Schleifen, verwaltet aber zusätzlich noch eine Variable, die „zählt“.
Wiederholung für jedes Mitglied einer Menge von Objekten. Diese Schleife wurde von
Oracle zuerst unter dem Namen erweiterte for-Schleife eingeführt, wird inzwischen aber
üblicherweise foreach-Schleife genannt.

Mit der foreach-Schleife beschäftigen wir uns erst in der Lerneinheit „ARR - Arrays“, ( Kap.
1.6) da sie typischerweise bei Arrays und anderen Datenstrukturen zur Verwaltung ganzer
Objektmengen eingesetzt wird.

Welche Schleifenart in einem Programm verwendet wird, hängt vor allem davon ab, ob die
Bedingung vor oder nach dem ersten Schleifendurchlauf auf ihren Wahrheitswert getestet
werden soll und ob es so etwas wie einen Zähler im zu lösenden Problem gibt. Grundsätzlich gilt
aber, dass Sie sich nicht falsch entscheiden können. Man kann prinzipiell jede der ersten drei
Schleifenart durch jede der anderen beiden ersetzen – allerdings erfordert das üblicherweise
etwas Aufwand wie das Kopieren von Code oder zusätzliche Verzweigungen. Es lohnt sich also,
sich mit allen Schleifenarten zu beschäftigen und die jeweils passende auszuwählen.

Zur Iteration gibt es eine Alternative. Das ist die Rekursion, die im Studienmodul „Grundlagen
der Programmierung II“ behandelt wird.

20.07.2023 3 von 49
ITR - Iterationen

2 Die kopfgesteuerte Schleife


Prüfung vor Ausführung Die kopfgesteuerte Schleife prüft vor der Ausführung der Anweisungen im Schleifenrumpf, ob die
Bedingung wahr ist. Wenn die zu prüfende Bedingung falsch ist, wird die Schleife verlassen.

In Java schreibt man diese sogenannte while-Schleife folgendermaßen:

while(Bedingung) {
Definition //zu wiederholende Anweisungen
}

Soll nur eine einzige Anweisung wiederholt werden, dürfen die geschweiften Klammern
wegfallen.
Wie auch schon bei der if-Anweisung kann jeder boolesche Ausdruck als Bedingung
verwendet werden, also auch verknüpfte Ausdrücke und Methodenaufrufe mit booleschem
Rückgabewert.

Schauen Sie sich die Wirkungsweise in dem folgenden Rolloverbild an. Bewegen Sie dazu die
Maus in einer kreisenden Bewegung über das Diagramm, wobei Sie den Entscheidungsknoten
berühren. So bilden Sie die Schleifendurchläufe nach.
Kopfgesteuerte Schleife
Rolloverbild

Textversion: Kopfgesteuerte Seite

1. Verbale Beschreibung:
SOLANGE die Bedingung erfüllt ist,
FÜHRE die Anweisung(en) im Schleifenrumpf AUS.
2. Bedingung
Die Abarbeitung erreicht die kopfgesteuerte Schleife. Der boolesche Ausdruck
wird ausgewertet.
3. Schleifenrumpf
Die Anweisung(en) im Schleifenrumpf werden nur ausgeführt, wenn der
boolesche Ausdruck wahr (true) ist.
4. Sprung zurück
Beim Erreichen des Endes vom Schleifenrumpf erfolgt ein Sprung an den Anfang
der while-Schleife. Die Bedingung wird erneut geprüft.
5. Ende
Hat die Bedingung den Wert falsch (false), wird die Schleife beendet. Die
Ausführung wird mit den Anweisungen hinter dem Schleifenrumpf fortgesetzt.
20.07.2023 4 von 49
ITR - Iterationen

Für die kopfgesteuerte Schleife finden Sie in der Literatur verschiedene Bezeichnungen, wie
vorprüfende oder abweisende Schleife.

Frage von Melanie:


Den Begriff kopfgesteuerte Schleife kann ich nachvollziehen, aber woher kommt der
Name abweisende Schleife?

Antwort:
Ist die Bedingung bereits beim ersten Abprüfen falsch, dann werden die
Schleifenanweisungen gar nicht ausgeführt. Wegen dieser Eigenschaft zählt man die
vorprüfende Schleife zu den abweisenden Schleifen.

Als erstes Beispiel einer while-Schleife sollen hier die Zahlen von 1 bis 10 ausgegeben werden.
Die gleiche Aufgabe wird in den folgenden Kapiteln auch mit den anderen Schleifenarten
dargestellt werden, so dass Sie den Code gegenüberstellen können.
while - Schleife
Rolloverbild 001 public class Schleifen {
002 /**
003 * schreibt die Zahlen 1 -10 auf die Konsole
004 * @param args wird nicht verwendet
005 */
006 public static void main(String[] args) {
007 int i;
008 i = 1;
009 while(i <= 10) {
010 System.out.println(i);
011 i++;
012 }
013 System.out.println("fertig");
014 }
015 }

Textversion: while - Schleife


Zeile 008:
Der Variablen i wird der Wert 1 zugewiesen.

Zeile 009:
Hier beginnt die Schleife. Die Bedingung wird überprüft. Beim ersten Erreichen dieser
Stelle ist i = 1, also ganz klar kleiner/gleich 10. Also werden die Anweisungen in
den folgenden geschweiften Klammern ausgeführt.

Zeile 010:
Der gerade aktuelle Wert von i wird ausgegeben.

Zeile 011:
Mit dieser Anweisung wird der in i gespeicherte Wert um 1 erhöht, i bekommt beim
ersten Erreichen also den Wert 2.

Zeile 012:
Mit dem Erreichen des Schleifenendes erfolgt der Sprung nach oben, zurück zum
Schlüsselwort while. Die Ausführung der Schleife beginnt also von Neuem, nur dass
i jetzt den Wert 2 hat, nicht mehr 1 wie beim ersten Durchgang.

20.07.2023 5 von 49
ITR - Iterationen

Zeile 013:
Wenn der Schleifenrumpf 10-mal ausgeführt worden ist, ist i 10-mal um 1 erhöht
worden. Damit hat i dann den Wert 11, so dass die Schleifenbedingung nicht mehr
erfüllt ist. Die Ausführung wird dann hinter dem Schleifenrumpf fortgesetzt, das Wort
„fertig“ wird auf die Konsole geschrieben.

Schleifen.java (433 Bytes)

Übung ITR-01
Multiple Choice
Der Inkrementoperator ++
Erinnern Sie sich noch einmal an den Inkrementoperator ++, der in diesem Kapitel
immer wieder auftauchen wird. Wie kann man i++ anders schreiben?
Richtig Falsch Auswertung
i = i + 1;

i + 1;

i += 1

i = 1;

gar nicht

20.07.2023 6 von 49
ITR - Iterationen

2.1 Programmbeispiel

In diesem Kapitel soll die Berechnung der Quersumme einer Zahl, also die Summe aller ihrer
Ziffern, berechnet werden. An zwei kurzen Beispielen sehen Sie das Problem, das es dabei zu
lösen gilt:

Quersumme von 34 = 4 + 3= 7
Quersumme von 65432 = 2 + 3 + 4 + 5 + 6 = 20
Je nach Größe der Zahl braucht man also mehr oder weniger viele Additionen. Mit einem
einfachen sequenziellen Programm ist das nicht zu bewerkstelligen, denn ohne Kenntnis der erst
im Programmverlauf vom Benutzer eingegebenen Zahl ist es nicht möglich, die korrekte Anzahl
von Additionen hinzuschreiben. Man braucht eine Schleife, um formulieren zu können:

„Solange noch eine weitere Ziffer übrig ist, addiere sie zum Ergebnis hinzu.“

In der folgenden Diashow sehen Sie den Ablauf einer Methode, die genau diese sprachliche
Beschreibung umsetzt. Die Eingabe durch den Benutzer ist im Bild nicht dargestellt, aber im
kompletten bereitgestellten Programm vorhanden. Sie können es also gerne selbst ausprobieren.

Diashow
Ablauf von while

20.07.2023 7 von 49
ITR - Iterationen

Textversion: Ablauf von while


Bild 01: Zugrunde liegender Quellcode

public static int quersumme(int zahl) {


if (zahl < 0) {
zahl *= -1;
}
int quer = 0;
while (zahl > 0) {
int ziffer = zahl % 10;
quer += ziffer;
zahl /= 10;
}
return quer;
}

Bild 02:
Die Methode wird aufgerufen, als Parameter wird die (willkürlich ausgewählte) Zahl 372 übergeben. Sie steht also im
Speicher, auf den die Methode Zugriff hat.

Bild 03:
Da die Zahl 372 nicht negativ ist, wird der Code im if-Zweig übersprungen. Er dient dazu, eine negative Zahl zuerst durch
Multiplikation mit -1 positiv zu machen. Im Code sehen Sie bereits einen der kombinierten Operatoren aus Lerneinheit VAR
Kap. 1.4.

Bild 04:
Die Methode deklariert die neue Variable quer, in der am Ende die zu berechnende Quersumme stehen soll. Da zum
jetzigen Zeitpunkt im Code aber noch keine Ziffer aus zahl „angeschaut“ wurde, soll quer im Moment noch 0 sein.

Bild 05:
zahl ist größer als 0, also wird der Code im Schleifenkörper ausgeführt.

Bild 06:
Die Variable ziffer wird angelegt und mit der letzten Ziffer von zahl initialisiert. Sie erinnern sich hoffentlich noch an
den Modulo-Operator, der den Rest beim ganzzahligen Teilen bestimmt. Der Rest, der übrigbleibt, wenn man eine Zahl
durch 10 teilt, ist gerade die letzte Ziffer, hier also die 2. (Probieren Sie das gerne mal mit ein paar Zahlen aus.)

Bild 07:
Mit dieser Anweisung wird die berechnete Ziffer zur Ergebnis-Variable quer addiert. Sie sehen wieder den kombinierten
Operator += in Aktion: Er berechnet nicht nur die Summe aus dem bisherigen Wert von quer und ziffer, sondern
schreibt diese Summe auch wieder in die Variable quer hinein, wie Sie im dargestellten Speicher sehen können. Man
kann alternativ auch schreiben: quer = quer + ziffer;

Bild 08:
Da die letzte Ziffer jetzt abgearbeitet ist, wird sie aus zahl entfernt, indem die Variable durch 10 geteilt wird. Auch hier
sorgt der kombinierte Operator dafür, das Ergebnis der Berechnung wieder in der Variablen zu speichern. Das ist sehr
wichtig, da sich nur dadurch der Wert in der Variablen zahl verändert und eine Chance besteht, dass die Bedingung der
while-Schleife irgendwann falsch wird.

Bild 09:
Mit dem Ende des Schleifenkörpers verschwindet die Variable ziffer aus dem Speicher, da sie nur innerhalb des Blocks
gültig war. Es erfolgt der Sprung nach oben zur erneuten Prüfung der while-Bedingung.

Bild 10:
Da zahl immer noch größer ist als 0, wird wieder der Schleifenkörper ausgeführt.

Bild 11:
Genau wie eben wird die letzte Ziffer in zahl bestimmt und in der nun wieder neu angelegten Variablen ziffer
gespeichert.

20.07.2023 8 von 49
ITR - Iterationen

Bild 12:
Wieder wird die Variable quer um die berechnete Ziffer erhöht. Sie sehen, wie sich der Wert in quer nach und nach dem
korrekten Ergebnis annähert. Sie können auch verfolgen, dass in dieser Variablen nacheinander genau die Werte stehen,
die man auch als Mensch als Zwischenergebnisse herausbekommt, wenn man die Berechnung ohne Computer anstellt.

Bild13:
Genau wie eben wird zahl durch 10 geteilt, um die letzte Ziffer zu entfernen.

Bild 14:
Mit Erreichen der schließenden Klammer erfolgt wieder der Sprung nach oben. Da zahl auch jetzt noch größer als 0 ist,
wird der Schleifenkörper wieder ausgeführt.

Bild 15:
Auch jetzt wird wieder die letzte Ziffer von zahl berechnet.

Bild 16:
Genau wie eben werden die beiden Variablen quer und zahl verändert. Sie sehen, dass inzwischen in quer das korrekte
Gesamtergebnis berechnet worden ist und zahl bei 0 angekommen ist. Trotzdem erfolgt beim Erreichen der schließenden
geschweiften Klammer zuerst einmal wieder der Sprung nach oben zur Schleifenbedingung.

Bild 17:
Jetzt ist der Punkt erreicht, dass zahl nicht mehr größer ist als 0. Der Schleifenkörper wird also nicht mehr ausgeführt,
sondern die Ausführung wird hinter dem Schleifenende fortgesetzt.

Bild 18:
Der in quer gespeicherte Wert wird mit return an die main - Methode zurückgegeben, wo er dann ausgegeben werden
kann.

Quersumme.zip (2 KB)

An diesem Beispiel sehen Sie ein sehr typisches Vorgehen in der Programmierung: Die
Gesamtlösung eines Problems wird oft nicht durch eine feste Formel, die sofort das korrekte
Ergebnis liefert, sondern nach und nach in mehreren Einzelschritten berechnet. Dabei macht
man sich zunutze, dass Variablen ihren Wert verändern können. Trifft die virtuelle Maschine
während der Ausführung auf einen Variablennamen wird immer der gerade in diesem Moment
aktuelle Wert der Variablen aus dem Speicher geholt. Auch wenn der Code
ziffer = zahl % 10; bei jeder Wiederholung gleich ist, wird hier durch die Veränderung der
Variablen zahl doch eine neue Berechnung durchgeführt.

Eine wichtige Rolle spielen in diesem Zusammenhang Zuweisungen in der Art von
quer = quer + ziffer
bzw. mit dem kombinierten Operator
zahl /= 10;

Sie berechnen den neuen Wert einer Variablen aus ihrem bisherigen und speichern ihn unter
dem gleichen Variablennamen ab wie vorher. Denken Sie in diesem Zusammenhang auch
immer daran, eine solche Variable vor dem Beginn einer Schleife mit einem Startwert zu
initialisieren.
Tipp: Um den Ablauf von Programmen zu verstehen und dadurch auch eventuelle Fehler finden
Tipp
zu können, hilft es, sich immer die aktuellen Werte der Variablen anzusehen. Ein Debugger, den
die meisten IDEs zur Verfügung stellen, macht genau das. Wenn Sie keinen haben oder er Ihnen
zu kompliziert in der Bedienung ist, bauen Sie einfach eine Ausgabe aller Variablen in den
Schleifenkörper ein.

20.07.2023 9 von 49
ITR - Iterationen

Übung ITR-02
Programmieren Inhalt einer Datei einlesen
Teil I:
Ergänzen Sie das vorgegebene Programm Dateilesen.java (1 KB). Es soll den
Inhalt der Datei beispiel.txt (112 Bytes) in der Eingabeaufforderung (Terminal)
ausgeben. Die Erzeugung des Objektes datei der Klasse BufferedReader ist
bereits vorgegeben. Es stellt die geöffnete Datei dar. In der Klasse BufferedReader
gibt es drei Methoden:
public boolean ready()
liefert true zurück, wenn es in der Datei noch eine weitere Zeile zum Lesen gibt,
sie gibt false zurück, wenn das Dateiende erreicht ist.
public String readLine()
liest die jeweils nächste Zeile aus der Datei und liefert den dort stehenden Text als
Rückgabewert zurück.
public void close()
schließt die Datei.
Setzen Sie damit dieses Diagramm um:

Hinweis: Wenn Sie sich nicht mehr genau erinnern, wie man Instanzmethoden
aufruft, lesen Sie in Lerneinheit OBJ - Kap. 2.4 noch einmal nach.
Teil II:
Wenn Sie das geschafft haben, können Sie den Code in einer eigenen Methode
unterbringen:
public static String dateilesen() throws IOException

Sie soll den Text aus der Datei beispiel.txt lesen und nicht mehr selbst in die
Eingabeaufforderung (Terminal) schreiben, sondern zu einem langen String
zusammensetzen, der zurückgegeben wird. (throws IOException kennzeichnet die
Methode als fehleranfällig, weil es sein könnte, dass die Datei nicht gefunden wird.
Genauer geht darauf die Lerneinheit EXC - Kap. 4.5 ein. Für den Moment schreiben
Sie das bitte einfach nur ans Ende des Methodenkopfes.)
Tipp: Denken Sie an die Verwendung eines kombinierten Operators, um den
Rückgabewert in einer Variablen nach und nach zu berechnen. Wichtig ist auch ein
sinnvoller Startwert zu Beginn.
Lösung Teil I (Siehe Anhang)
Lösung Teil II (Siehe Anhang)
Bearbeitungszeit: 40 Minuten

20.07.2023 10 von 49
ITR - Iterationen

2.2 Endlosschleifen und abweisende Bedingungen

Eins der großen Probleme beim Einsatz von Schleifen ist die Gefahr einer Endlosschleife.

Endlosschleife
Definition
Man spricht von einer Endlosschleife, wenn durch einen Programmierfehler die Bedingung
niemals falsch wird, so dass der Schleifenkörper wieder und wieder ausgeführt wird bis in alle
Ewigkeit.

Für den Menschen vor dem Bildschirm sieht das dann meistens so aus, als „hängt“ das
Programm, als würde es einfach gar nichts mehr tun. Sicher haben Sie das schon einmal erlebt
und mussten den Prozess dann mit Hilfe des Taskmanagers oder ähnlicher vom Betriebssystem
zur Verfügung gestellter Werkzeuge abbrechen.
Übung ITR-03
Programmieren Endlosschleife
Versuchen Sie doch einmal ganz bewusst eine Endlosschleife herbeizuführen:
Verwenden Sie das Quersumme-Programm von eben und verändern Sie eine
Kleinigkeit – etwas, was beim Tippen vielleicht einmal aus Versehen passiert.
Quersumme.zip (2 KB)
Wenn Sie das Programm in der Eingabeaufforderung (Terminal) starten und Sie
tatsächlich eine Endlosschleife programmiert haben, können Sie die Ausführung mit
der Tastenkombination Strg + c abbrechen.
Lösung (Siehe Anhang)
Bearbeitungszeit: 15 Minuten

Kontrollieren Sie immer, ob sich mindestens eine der Variablen, die in der Schleifenbedingung
Hinweis benutzt werden, innerhalb des Schleifenkörpers verändert. Dadurch können Sie viele
ungewollte Endlosschleifen verhindern.

Tatsächlich gibt es Situationen, in denen eine Endlosschleife explizit gewollt wird, z. B. bei einem
im Hintergrund laufenden Prozess, der dauerhaft auf eine eingehende Anforderung aus einer
Netzwerkverbindung horcht, oder einer Animation, die den gesamten Programmablauf begleiten
soll. Üblicherweise treten diese Situationen aber erst dann auf, wenn man nebenläufig
programmiert, also mehrere Programmteile gleichzeitig ablaufen sollen. In diesem Fall schreibt
man:
while(true) {
//endlos zu wiederholende Anweisungen
}

20.07.2023 11 von 49
ITR - Iterationen

Übung ITR-04
Multiple Choice
Die Quersumme von 0
Was geschieht eigentlich, wenn man im Quersumme-Programm 0 als zahl eingibt?
Richtig Falsch Auswertung
Der Code bricht mit einer ConditionNotTrueException
ab, weil zahl dann nicht größer ist als 0.

Die Methode quersumme() wird gar nicht erst aufgerufen, weil


es nicht sinnvoll ist, die Quersumme von 0 zu berechnen.

Der Schleifenkörper wird überhaupt nicht durchlaufen, so dass in


quer der Anfangswert 0 stehen bleibt und als Rückgabewert an
die main-Methode geliefert wird.

Der Code bricht mit einer ArithmeticException beim


Erreichen von zahl % 10 ab, weil man durch 0 nicht teilen
kann.

An der Eingabe der 0 für die Variable zahl sehen Sie das andere Extrem, das beim Erreichen
einer while-Schleife auftreten kann: Die Bedingung ist sofort bei der ersten Auswertung falsch,
so dass der Schleifenkörper komplett übersprungen wird. Im Gegensatz zur Endlosschleife ist
das üblicherweise nicht auf einen Fehler zurückzuführen, sondern ein gewollter Ausnahmefall:
Um die Quersumme der 0 zu berechnen, muss man keine einzige Addition durchführen und auch
keine Division. Dass die Berechnung sofort endet, ist das korrekte Verhalten.
Alles abweisende Bedingung Die alles abweisende Bedingung, quasi das Gegenstück zur gewollten Endlosschleife, ist:
while(false) {
//nie auszuführende Anweisungen
}

Da der Compiler erkennt, dass hier nicht erreichbare Anweisungen geschrieben worden sind,
quittiert er diesen Code mit einer Fehlermeldung.

20.07.2023 12 von 49
ITR - Iterationen

3 Die fußgesteuerte Schleife

Wollen Sie sicherstellen, dass der Block in einer Schleife wenigstens


einmal ausgeführt wird, müssen Sie die Testbedingung an das Ende der
Schleife setzen.

Für Ihr Programm bedeutet das, dass Sie die fußgesteuerte Schleife, die
auch als nichtabweisende bzw. nachprüfende Schleife bezeichnet wird,
verwenden müssen:

Die fußgesteuerte Schleife


do {
//zu wiederholende Anweisungen
} while(Bedingung);

Soll nur eine einzige Anweisung wiederholt werden, dürfen die geschweiften Klammern
wegfallen.

Hinweis: Beachten Sie das Semikolon hinter den runden Klammern mit der Bedingung. Man
Hinweis vergisst es sehr leicht…

Im folgenden Diagramm ist die Semantik der do-while-Schleife dargestellt.

Abb.: Ablauf der do-while-


Schleife
Im Gegensatz zur eben behandelten while-Schleife beginnt die Ausführung hier sofort mit dem
Schleifenkörper. Erst nach dem ersten Durchlauf wird die Bedingung ausgewertet und
entschieden, ob eine Wiederholung erfolgen soll oder nicht.

Die Anweisungen im Rumpf der do-while-Schleife werden also immer mindestens einmal
ausgeführt!

Auch mit dieser Schleife soll das Beispiel, die Zahlen von 1 bis 10 auf dem Bildschirm
auszugeben, dargestellt werden.

20.07.2023 13 von 49
ITR - Iterationen

Schleifen.java
Rolloverbild 001 public class Schleifen {
002 /**
003 * schreibt die Zahlen 1 -10 in die Eingabeaufforderung (Terminal)
004 * @param args wird nicht verwendet
005 */
006 public static void main(String[] args) {
007 int i;
008 i = 1;
009 do {
010 System.out.println(i);
011 i++;
012 } while(i <= 10);
013 System.out.println("fertig");
014 }
015 }

Textversion: Beispiel einer fußgesteuerten Schleife


Zeile 008:
Der Variablen i wird 1 zugewiesen.

Zeile 009:
Hier beginnt die Schleife. Das Schlüsselwort do dient nur als Marker, es bewirkt also
selbst keine Aktion.

Zeile 010:
Der gerade aktuelle Wert von i wird ausgegeben.

Zeile 011:
Mit dieser Anweisung wird der in i gespeicherte Wert um 1 erhöht, i bekommt beim
ersten Erreichen also den Wert 2.

Zeile 012:
Die Bedingung wird überprüft. Beim ersten Erreichen dieser Stelle ist i = 2, also
ganz klar kleiner/gleich 10. Also erfolgt der Sprung nach oben, zurück zum
Schlüsselwort do. Die Ausführung der Schleife beginnt von Neuem, nur dass i jetzt
den Wert 2 hat, nicht mehr 1 wie beim ersten Durchgang.

Zeile 013:
Wenn der Schleifenrumpf 10-mal ausgeführt worden ist, ist i 10-mal um 1 erhöht
worden. Damit hat i dann den Wert 11, so dass die Schleifenbedingung nicht mehr
erfüllt ist. Die Ausführung wird dann hinter dem Schleifenrumpf fortgesetzt, das Wort
„fertig“ wird in die Eingabeaufforderung (Terminal) geschrieben.

20.07.2023 14 von 49
ITR - Iterationen

3.1 Wann while, wann do-while

Der wichtigste Unterschied zwischen der while- und der do-while-Schleife besteht darin, dass
die Anweisungen im Schleifenrumpf der do-while-Schleife in jedem Fall mindestens einmal
ausgeführt werden, während sie bei der while-Schleife eventuell komplett wegfallen. Manchmal
ist dieser Unterschied unerheblich – wie im Beispiel, die 10 Zahlen von 1 bis 10 auszugeben –
meistens bildet er aber das Kriterium, nach dem sich der Programmierer für die ein oder andere
Schleifenart entscheidet.

In den bisherigen Programmen ist Ihnen bestimmt aufgefallen, dass bei jeder
Programmwiederholung die Applikation neu von der Eingabeaufforderung (Terminal) aus
gestartet werden musste. Das ist mit der Zeit ziemlich umständlich. Abhilfe schafft hier die
do-while-Anweisung.

Dazu wird um den zu wiederholenden Programmteil eine fußgesteuerte Schleife gelegt, die
durch eine Benutzerantwort gesteuert wird:
Programmwiederholung mittels do-while
Quellcode char antwort;
do {
//urspruengliche Programmanweisungen
antwort = EinAusgabe.eingabeZeichen("Programmwiederholung? (j/n)");
} while (antwort == 'j');

Antwortet der Benutzer mit j, dann wird das Programm wiederholt, ansonsten beendet. Hier ist
die do-while-Schleife klar sinnvoller als die while-Schleife, weil erst dann, wenn der Benutzer
gefragt worden ist, ob er das Programm wiederholen möchte, eine Überprüfung seiner Eingabe
stattfinden kann.
Übung ITR-05
Programmieren Wiederholungssteuerung mit while - Schleife
Könnten Sie diese Wiederholungssteuerung trotzdem mit der while-Schleife
formulieren?
Lösung (Siehe Anhang)
Bearbeitungszeit: 2 Minuten

Noch etwas ergonomischer wird die Steuerung, wenn man auch die Eingabe eines großen J als
Wiederholungswunsch wertet. Die Abbruchbedingung der Schleife kann dazu mehrere
boolesche Ausdrücke kombinieren:
char antwort;
do {
//urspruengliche Programmanweisungen
antwort = EinAusgabe.eingabeZeichen("Programmwiederholung? (j/J/n/N)");
} while (antwort == 'j' || antwort == 'J');

Übung ITR-06
Programmieren Programmwiederholung
Bauen Sie diese Programmwiederholung in das Quersumme-Programm ein.
Quersumme.zip (2 KB)
Lösung (Siehe Anhang)
Bearbeitungszeit: 10 Minuten

Ein häufiges Einsatzgebiet der do -while-Schleife ist auch die Wiederholung einer fehlerhaften
Eingabe. Auch hier muss der Benutzer zuerst die Möglichkeit haben, eine Eingabe zu tätigen,
bevor entschieden werden kann, ob diese fehlerhaft ist. Die Eingabe muss also wenigstens
einmal stattfinden und wird ggf. wiederholt.

20.07.2023 15 von 49
ITR - Iterationen

Erinnern Sie sich an das Blumenkauf-Programm aus der Lerneinheit VER? Hier wurde mit
Hilfe der Methoden in der mitgelieferten Klasse Ueberpruefung getestet, ob der Benutzer
überhaupt eine Zahl eingegeben hat oder fälschlicherweise Buchstaben. Die gleiche Technik
kann hier auch für das Quersummen-Programm genutzt werden:

Rolloverbild
Quersumme.java
001 public static void main(String[] args) {
002 char antwort;
003 do {
004 String eingabe;
005 do {
006 eingabe = EinAusgabe.eingabeText("Bitte Zahl eingeben: ");
007 } while(!Ueberpruefung.isEineGanzeZahl(eingabe));
008 int zahl;
009 zahl = Ueberpruefung.umwandeln(eingabe);
010 int ergebnis = quersumme(zahl);
011 System.out.println("Die Quersumme ist " + ergebnis);
012 antwort = EinAusgabe.eingabeZeichen("Programmwiederholung? (j/J/n/N)");
013 } while (antwort == 'j' || antwort == 'J');
014 }

Frage von Melanie:


Es ist also möglich, dass ich eine Schleife in einer Schleife programmiere? Auf welche
Besonderheiten muss ich dabei achten?

Antwort:
Wie Sie an dem Programm sehen, ist es prinzipiell möglich, eine Schleife in einer
Schleife zu programmieren. Wir bezeichnen diese Konstruktion als Verschachtelung
von Schleifen. Die innere Schleife befindet sich dann im Rumpf der äußeren Schleife.
Besonderheiten gibt es dabei nicht zu beachten, bis auf die Tatsache, dass jede
Schleife vollständig sein muss. Die innere Schleife liegt also komplett mit ihrem
vollständigen Rumpf innerhalb der äußeren Schleife.
Um dabei die Struktur des Programmes gut erkennen zu können, hilft es, auf eine
ordentliche Formatierung des Codes zu achten – mit jedem neuen Block etwas weiter
eingerückt.

Übung ITR-07
Programmieren Eingabe prüfen
Viel schöner wäre es natürlich, wenn auch noch geprüft wird, ob der Benutzer wirklich
j oder n eingibt und nicht vielleicht irgendeinen anderen Buchstaben.
Schreiben Sie in die Klasse EinAusgabe eine weitere Methode
public static boolean wiederholungGewuenscht()

Sie gibt die Frage „Programmwiederholung? (j/J/n/N)“ aus und liest eine Eingabe vom
Benutzer. Wenn der Benutzer sich vertippt (also die Eingabe nicht j und n und auch
nicht J und N ist), soll die Eingabe wiederholt werden. Die Methode gibt dann true
zurück, wenn die Eingabe ein j/J war, false bei n/N.
Bauen Sie diese Methode in die main-Methode von Quersumme ein, um die
Wiederholung zu steuern.
Lösung (Siehe Anhang)
Bearbeitungszeit: 30 Minuten

20.07.2023 16 von 49
ITR - Iterationen

3.2 Schleifen und Verzweigungen

Selbstverständlich kann man Schleifen auch mit Verzweigungen kombinieren. Im Rumpf einer
Schleife sind Verzweigungen erlaubt und in einem Zweig einer Verzweigung sind Schleifen
erlaubt. Genau wie bei der Verschachtelung gleichartiger Anweisungen aus dem eben
behandelten Kapitel ist es dabei nur wichtig, dass eine Kontrollstruktur wirklich komplett
innerhalb des Blocks steht, der sie umschließt. Das wird über die geschweiften Klammern
geregelt.

Tipp
Hinweis
Achten Sie wirklich immer auf die korrekte Formatierung des Codes. Die Anweisungen im
Schleifenrumpf bzw. in einem Zweig einer Verzweigung sollten etwas weiter eingerückt sein als
die Anweisungen der umgebenden Ebene. Je komplexer der Code, desto wichtiger ist das für
das Verständnis!

Das folgende Beispiel soll das verdeutlichen. Es bestimmt alle Teiler einer Zahl:
Einrückung vs. keine Einrückung
Interaktion /**
* bestimmt alle Teiler einer vom Benutzer einzugebenden Zahl
* @param args wird nicht verwendet
*/
public static void main(String[] args) {
int zahl;
zahl = EinAusgabe.eingabeGanzeZahl("Bitte Zahl eingeben: ");
if(zahl > 0){
int teiler;
teiler = 1;
do{
if(zahl % teiler == 0) {
System.out.println(teiler);
}
teiler++;
}while (teiler <= zahl);
}
else{
System.out.println("Nur positive Zahlen bitte!");
}
}

Textversion: Einrückung vs. keine Einrückung


Quellcode ohne Einrückungen:

/**
* bestimmt alle Teiler einer vom Benutzer einzugebenden Zahl
* @param args wird nicht verwendet
*/
public static void main(String[] args) {
int zahl;
zahl = EinAusgabe.eingabeGanzeZahl("Bitte Zahl eingeben: ");
if(zahl > 0){
int teiler;
teiler = 1;
do{
if(zahl % teiler == 0) {
System.out.println(teiler);
}
teiler++;
}while (teiler <= zahl);
}
else{
System.out.println("Nur positive Zahlen bitte!");
}
}

20.07.2023 17 von 49
ITR - Iterationen

Sie sehen eine äußere Verzweigung, die prüft, ob die eingegebene Zahl positiv ist. Im if-Block
befindet sich eine do-while-Schleife. Öffnende und schließende geschweifte Klammer, die zur
Schleife gehören, stehen beide innerhalb des if-Blocks. Der gesamte Code innerhalb dieses
Zweigs wurde etwas eingerückt.

Im Rumpf dieser Schleife befindet sich wiederum eine if-Anweisung, die prüft, ob der gerade
aktuelle Wert der Variablen teiler ein mathematischer Teiler der eingegebenen Zahl ist. Die
Ausgabe ist abhängig von der Prüfung der Bedingung und steht deshalb noch einmal etwas
weiter eingerückt.

Klicken Sie einmal auf den Button und schauen Sie sich an, ob Sie den Ablauf des Programms
immer noch nachvollziehen können. Schwierig, oder?

20.07.2023 18 von 49
ITR - Iterationen

4 Die Zählschleife

In vielen Algorithmen gibt es einen Zähler, also eine Variable, die sich
mit jedem Schleifendurchlauf in der gleichen Art und Weise verändert.
Erreicht er einen bestimmten Wert, wird die Schleife beendet. In den
meistens Fällen besteht die Veränderung einfach aus dem Erhöhen
um 1, so dass der Zähler eben wirklich die Anzahl der
Schleifendurchläufe zählt.

Das bereits bekannte Beispiel, die Zahlen von 1 bis 10 auszugeben, sieht mit einer for-Schleife
so aus:
Zählschleife: Ausgabe der Zahlen 1 - 10
Rolloverbild 001 public class Schleifen {
002 /**
003 * schreibt die Zahlen 1 -10 in die Eingabeaufforderung (Terminal)
004 * @param args wird nicht verwendet
005 */
006 public static void main(String[] args) {
007 for(int i=1; i<=10; i++) {
008 System.out.println(i);
009 }
010 System.out.println("fertig");
011 }
012 }

Textversion: Zählschleife
Zeile 007:

Der erste Teil der for-Anweisung wird beim Erreichen genau einmal ausgeführt. Hier
wird die Zähler-Variable i deklariert und mit 1 initialisiert. Da die Deklaration zur
Schleife gehört, existiert die Variable auch nur innerhalb der Schleife.

Die Bedingung wird überprüft. Beim ersten Erreichen dieser Stelle ist i = 1, also
ganz klar kleiner/gleich 10. Die Schleife beginnt.

Die Anweisung i++ zur Veränderung des Zählers steht zwar im Schleifenkopf, wird
aber erst nach Ende des Schleifenrumpfes ausgeführt. i bekommt also erst dann den
Wert 2, wenn die Anweisungen zwischen den geschweiften Klammern einmal
ausgeführt worden sind.

Zeile 008:
Der gerade aktuelle Wert von i wird ausgegeben. Beim ersten Erreichen ist das der
Wert 1.

Zeile 009:
Beim ersten Erreichen des Endes des Schleifenrumpfes ist i = 1. Es erfolgt der
Sprung nach oben, zur Veränderung des Zählers i mit der Anweisung i++. Erst dann
beginnt die Ausführung der Schleife von Neuem mit der Prüfung der Bedingung.

Zeile 010:
Wenn der Schleifenrumpf 10-mal ausgeführt worden ist, ist i 10-mal um 1 erhöht
worden. Damit hat i dann den Wert 11, so dass die Schleifenbedingung nicht mehr
erfüllt ist. Die Variable i wird aus dem Speicher entfernt und die Ausführung wird
hinter dem Schleifenrumpf fortgesetzt, das Wort „fertig“ wird in die
Eingabeaufforderung (Terminal) geschrieben.

20.07.2023 19 von 49
ITR - Iterationen

Übung ITR-08
Multiple Choice
Vor- oder nachprüfende Schleife?
Handelt es sich bei der for-Schleife um eine vorprüfende Schleife, bei der der
Schleifenrumpf eventuell gar nicht ausgeführt wird, oder um eine nachprüfende
Schleife, die den Schleifenrumpf mindestens einmal ausführt?
Richtig Falsch Auswertung
vorprüfend

nachprüfend

Wie man an dem obigen Beispiel gut erkennen kann, ist die Idee der for-Schleife, die
benötigten Anweisungen, um den Zähler der Schleife zu steuern, im Schleifenkopf
zusammenzufassen:

Anweisungen im Schleifenkopf
Definition
for (Initialisierungsteil; Bedingung; Aktualisierungsteil) {
//zu wiederholende Anweisung
}

Initialisierungs- und Aktualisierungsteil bestehen aus einer Zuweisung. Mehrere Anweisungen


können durch ein Komma getrennt werden. Im Initialisierungsteil ist darüber hinaus eine
gleichzeitige Deklaration von Variablen erlaubt.

Alle drei Teile - Initialisierungsteil, Bedingung, Aktualisierungsteil - können wegfallen, die


Semikola bleiben allerdings stehen.

Wie immer können die geschweiften Klammern wegfallen, wenn nur eine einzige Anweisung
im Schleifenrumpf steht.

Anmerkung
Hinweis
In Initialisierungs- und Aktualisierungsteil gibt es weitere Möglichkeiten, die die Spezifikation
der Sprache zulässt. Da sie in der Praxis extrem selten sind, sollen sie hier nicht behandelt
werden. Sie können aber gerne nachlesen:

https://docs.oracle.com/javase/.../jls-14.html#jls-BasicForStatement

Den Ablauf der for-Schleife sehen Sie im folgenden Diagramm:

20.07.2023 20 von 49
ITR - Iterationen

Abb.: Ablauf der


for-Schleife

Übung ITR-09
Multiple Choice Syntax der for-Schleife
Schauen Sie sich die Syntax der for-Schleife genau an.
Wie lautet die kürzeste for-Schleife, die man schreiben kann?
Richtig Falsch Auswertung
for(;;);

for(;;)

for(){}

for(;;){}

Eine solche Schleife ist allerdings nicht sinnvoll. Da bei fehlender Bedingung einfach true vom
Compiler eingesetzt wird, handelt es sich um eine Endlosschleife, die absolut nichts tut – bis in
alle Ewigkeit oder bis zum Abbruch mit Strg + C .

20.07.2023 21 von 49
ITR - Iterationen

4.1 Einsatzbeispiele

Eine for-Anweisung ist besonders dann gut geeignet, wenn die Anzahl der Wiederholungen
feststeht. In der folgenden mathematischen Anwendung können Sie das sehr gut erkennen.
Sehen Sie sich die Durchführung der Berechnung an:

Diashow
Ablauf einer for-Anweisung

Übung ITR-10
Programmieren
Beurteilung einer Methode?
Was würden Sie sagen: Was berechnet die Methode?
Lösung (Siehe Anhang)
Bearbeitungszeit: 5 Minuten

Ein zweites Beispiel soll Ihnen die Verschachtelung mehrerer Schleifen zeigen. In einem
Geometrieprogramm soll ein Quadrat aus n ⋅ n Sternchen in der Eingabeaufforderung (Terminal)
gezeichnet werden:

20.07.2023 22 von 49
ITR - Iterationen

Geometrie.java
Rolloverbild 001 /**
002 * zeichnet ein Quadrat mit n Zeilen auf den Bildschirm
003 * @param n Hoehe des Quadrats (Anzahl Zeilen/Spalten)
004 */
005 public static void quadrat(int n) {
006 for (int zeile = 1; zeile <= n; zeile++) {
007 for (int spalte = 1; spalte <= n; spalte++) {
008 System.out.print("*");
009 }
010 System.out.println();
011 }
012 }

Textversion: Geometrie.java

Zeile 006
Wie auch in den anderen beiden Schleifenarten, ist es auch bei der for-Schleife
möglich, dass im Schleifenrumpf eine weitere Schleife steht. Die äußere Schleife zählt
hier die Zeilen durch, deshalb heißt der verwendete Zähler auch zeile und nicht wie
in den meisten einfachen Beispielen i.

Zeile 007
Für jede Zeile muss eine feste Anzahl von Sternchen in mehreren Spalten
ausgegeben werden – deshalb die innere Schleife mit dem Zähler spalte.

Zeile 008
Beachten Sie, dass für die Ausgabe des Sternchens die Methode
System.out.print() verwendet wird. Sie schreibt nur den auszugebenden Text
hin, ohne einen abschließenden Zeilenumbruch.

Zeile 010
Die Methode System.out.println() – mit Zeilenumbruch – wird erst hinter der
inneren Schleife aufgerufen, aber immer noch innerhalb der äußeren Schleife. Man
braucht nur einmal pro Zeile einen Zeilenumbruch, nicht einmal für jede Spalte.

Bildschirmausgabe
bei n=5 *****
*****
*****
*****
*****

20.07.2023 23 von 49
ITR - Iterationen

Übung ITR-11
Programmieren Ausgabe ändern
Überlegen Sie sich, wie die Ausgabe aussieht, wenn Sie die Anweisung
System.out.println() mit der geschweiften Klammer davor vertauschen und sie
so in die innere Schleife hineinziehen. Probieren Sie es dann zur Kontrolle aus.
Lösung (Siehe Anhang)
Bearbeitungszeit: 2 Minuten

Übung ITR-12
Programmieren
Ausgabe als Dreieck
Fügen Sie in die Klasse Geometrie in Geometrie.java (581 B) eine zweite
Methode hinzu, die ein Dreieck (siehe unten) zeichnet:
public static void dreieck(int n)

*
**
***
****
*****

Sie unterscheidet sich von der quadrat-Methode tatsächlich nur in einer Kleinigkeit…
Tipp: Überlegen Sie sich, wie viele Sternchen jeweils in den einzelnen Zeilen
gezeichnet werden müssen: 1. Zeile → 1 Stern, 2. Zeile → 2 Sterne, 3. Zeile → 3
Sterne usw.
Lösung (Siehe Anhang)
Bearbeitungszeit: 15 Minuten

Um zu verdeutlichen, dass der Zähler nicht immer eine ganze Zahl sein muss, betrachten Sie
diese for-Schleife, die die Datumsangaben der kommenden Woche ausgibt:
Auszug aus Datumsangabe.java
Quellcode LocalDate inEinerWoche = LocalDate.now().plusDays(7);
for (LocalDate datum = LocalDate.now();
datum.isBefore(inEinerWoche); datum = datum.plusDays(1))
{
System.out.println(datum);
}
Datumsausgabe.java (533 B)

Selbst wenn Sie nicht Einsendeaufgabe OBJ-E1 oder E2 der Lerneinheit OBJ bearbeitet
haben und deshalb noch nicht mit der Klasse LocalDate in Berührung gekommen sind, ist der
Code sicher nicht schwer zu verstehen:

Zuerst wird mit Hilfe der statischen Methode now() der Klasse LocalDate das heutige
Datum bestimmt.
isBefore() testet, ob dieses Datum vor dem gewünschten Zieldatum liegt, hier ist das der
Tag heute in einer Woche.
Im Aktualisierungsteil sorgt die Methode plusDays() dafür, dass datum immer wieder auf
den jeweils folgenden Tag gesetzt wird.

Schauen Sie sich die Dokumentation der Klasse LocalDate an und vollziehen Sie die
Hinweis Methodenaufrufe nach.

https://docs.oracle.com/.../java.base/java/time/LocalDate.html

20.07.2023 24 von 49
ITR - Iterationen

4.2 Äquivalenz zur while-Schleife

Wie bereits erwähnt, kann man jede Schleifenart durch die anderen ersetzen. Da for- und
while-Schleife beide vorprüfend sind, ist die Äquivalenz hier besonders deutlich und kommt
ohne weitere Kontrollstrukturen aus.
Übung ITR-13
Zuordnung Code vervollständigen
Betrachten Sie den Code des Beispiels aus dem Eingangskapitel zu den jeweiligen
Schleifenarten. Ordnen Sie die einzelnen Teile der for-Schleife dem Code unten zu,
so dass eine äquivalente while-Schleife entsteht.

for( int
int i=1
i = 1; i i<=<=1010; i++ i++ )
{
System.out.println(i);
}
System.out.println("fertig");

[int i = ;
while([i <= 10] ) {
System.out.println(i);
[i++ ;
}
System.out.println("fertig");

Diese Äquivalenzbeziehung gilt immer zwischen diesen beiden Schleifenarten, auch wenn sie
deutlich komplexer sind. Tatsächlich existieren nur zwei Unterschiede:

Im Schleifenkopf der for-Schleife sind Variablendeklarationen erlaubt. Wenn diese


Möglichkeit genutzt wird, gibt es also Variablen, die ausschließlich innerhalb der kompletten
Schleife existieren, d. h. im Schleifenrumpf und in der Schleifenbedingung. Man kann die
Variablen aber auch ohne weiteres vor der Schleife deklarieren, so dass der Unterschied
wegfällt.
Beide Schleifen verhalten sich beim nur sehr selten verwendeten Schlüsselwort continue
ein wenig unterschiedlich. In Kapitel 5.2 kommen wir darauf zurück.

20.07.2023 25 von 49
ITR - Iterationen

Übung ITR-14
Multiple Choice
Fragen zum Besipielcode
Welche Aussagen sind beim obigen Code richtig?
Richtig Falsch Auswertung
i hat rechts nach der schließenden geschweiften Klammer den
Wert 11.

i hat links nach der schließenden geschweiften Klammer den


Wert 11.

i hat links nach der schließenden geschweiften Klammer den


Wert 10.

i hat rechts nach der schließenden geschweiften Klammer den


Wert 10.

Man kann i im Code nach der Schleife links noch einmal


deklarieren.

Man kann i im Code nach der Schleife rechts noch einmal


deklarieren.

Wenn beide Schleifenarten austauschbar sind, stellt sich die Frage, wann besser die eine, wann
besser die andere verwendet werden soll:

Die for-Schleife wird meist benutzt, wenn es im Algorithmus einen Zähler gibt, also einen
Hinweis Wert, der mit jeder Wiederholung auf immer die gleiche Art und Weise verändert wird und der
über das Ende der Wiederholung entscheidet. Gibt es einen solchen Zähler nicht, ist die
while-Schleife sinnvoller.

Bitte betrachten Sie diesen Satz nur als eine Art Faustregel. Gerade bei der Wahl der Schleifen
zeigt sich oft ein persönlicher Stil des Programmierers und seine spezielle Art, ein Problem zu
lösen.

20.07.2023 26 von 49
ITR - Iterationen

Übung ITR-15
Programmieren
Brute - Force - Angriff
Vorgegeben ist die Klasse Geldautomat in Geldautomat.java (624 B), die eine
zufällige PIN generiert. Ihre Aufgabe ist es, diese PIN durch einen Brute-Force-Angriff
zu knacken:

Ergänzen Sie dazu die vorgegebene main-Methode der Klasse BruteForce in


BruteForce.java (432 B) . Wählen Sie selbst, ob Sie lieber eine for- oder eine
while-Schleife verwenden.
Lösung
Bearbeitungszeit: 15 Minuten

20.07.2023 27 von 49
ITR - Iterationen

4.3 Komplexere Zählschleifen - optional

In der Beschreibung der Syntax wurde eine Möglichkeit der for-Schleife erwähnt, die in den
bisherigen Beispielen noch nicht genutzt wurde: Im Initialisierungs- und im Aktualisierungsteil
kann mehr als eine Anweisung untergebracht werden.

Betrachten Sie dazu eine Ergänzung des Eingangsbeispiels. Es sollen hier nicht nur die Zahlen
von 1 bis 10, sondern auch noch die zugehörigen Zweierpotenzen von 2 (= 21) bis 1024 ( = 210)
ausgegeben werden:
Zweierpotenzen ausgeben
/**
Quellcode
* Ein kleines Programm, das die Potenzen von 2 hoch 1 bis 2 hoch 10 ausgibt
*
*/
public class Potenzen {
/**
* schreibt die Potenzen von 2 hoch 1 bis 2 hoch 10 in die
* Eingabeaufforderung (Terminal)
*
* @param args wird nicht verwendet
*/
public static void main(String[] args) {
for (int i = 1, potenz = 2; i <= 10; i++, potenz *= 2) {
System.out.println("2 hoch " + i + " = " + potenz);
}
}
}
Potenzen.java (456 KB)

Sie erkennen sicher die Anweisungen wieder, um die Zählervariable i zu steuern, die die Zahlen
von 1 bis 10 durchläuft. Zusätzlich wurde im Initialisierungsteil der for-Schleife eine weitere
Variable namens potenz deklariert und mit 2 belegt. Im Aktualisierungsteil wird diese Variable
mit 2 multipliziert, um die nächste Potenz zu berechnen. Es ist also möglich zwei oder mehr
Zählervariablen zu haben. Die Anweisungen im Initialisierungs- und Aktualisierungsteil werden
jeweils mit Komma abgetrennt.

Technisch ganz genau betrachtet, handelt es sich in diesem Beispiel im Initialisierungsteil nicht
Hinweis um zwei durch Komma getrennte Anweisungen, sondern nur um eine einzige Deklaration
mehrerer Variablen. Wenn Sie die Zähler also innerhalb der for-Schleife deklarieren wollen,
müssen alle den gleichen Datentyp haben und so gemeinsam deklariert werden können. Wenn
Sie die Deklarationen vor die Schleife schreiben, unterliegen Sie dieser Einschränkung nicht.

Beachten Sie, dass die Regel, mehrere Teile durch Komma zusammenzusetzen, nicht für die
Bedingung gilt. Diese Schreibweise ist also falsch:

Abb.: Fehler in der Bedingung


Um mehrere Bedingungen zu verknüpfen, verwenden Sie die bekannten logischen Operatoren
&&, || .

20.07.2023 28 von 49
ITR - Iterationen

Freitext
Übung ITR-16

Bedingungen verknüpfen
Wie sollte die Bedingung hier dann also heißen?

for(int i=1, potenz = 2; i<=10 potenz <= 1024; i++, potenz *= 2)


{
System.out.println("2 hoch " + i + " = " + potenz);
}

Gerade diese Verknüpfung mehrerer Bedingungen macht man sich gerne zunutze, wenn das
Schleifenende auch noch durch etwas anderes herbeigeführt werden kann als das Erreichen des
Endwertes. Im folgenden Beispiel soll ein Passwort eingegeben werden, es gibt allerdings eine
Maximalzahl an Versuchen:

Quellcode
Zähler für Passworteingabe
/**
* Passwort eingeben
*/
public class Passwort {

/**
* lässt den Benutzer ein Passwort eingeben
*
* @param args wird nicht verwendet
*/
public static void main(String[] args) {
String korrekt = "passwort";
String eingabe = ""; // Deklaration vor der Schleife
int zaehler;
for (zaehler = 0; zaehler < 5 && !eingabe.equals(korrekt); zaehler++) {
eingabe = EinAusgabe.eingabeText("Ihr Passwort bitte: ");
}
if (zaehler == 5) {
System.out.println("Passworteingabe endgültig gesperrt");
} else {
System.out.println("Passwort gültig!");
}
}
}
Passwort.java (702 B)

Übung ITR-17
Formulieren
Anzahl der Versuche
Wie viele Versuche hat der Benutzer hier höchstens, um dein Passwort korrekt
einzugeben?
Lösung (Siehe Anhang)
Bearbeitungszeit: 2 Minuten

20.07.2023 29 von 49
ITR - Iterationen

Übung ITR-18
Multiple Choice
Deklaration vor der Schleife
Warum wurden hier die beiden Variablen zaehler und eingabe vor der Schleife
deklariert?
Richtig Falsch Auswertung
Weil zaehler im Code hinter der Schleife noch verwendet wird
und dort also noch existieren muss.

Die for-Schleife kann grundsätzlich nicht mit String-Variablen


arbeiten, deshalb muss zumindest eingabe vor der Schleife
deklariert werden.

Weil man in der for-Schleife grundsätzlich nur eine einzige


Variable deklarieren kann.

Das war sicher nur, um diese Möglichkeit auch einmal zu zeigen

20.07.2023 30 von 49
ITR - Iterationen

5 Abbrechen und Fortsetzen von Schleifen

Die Anweisungen break und continue sind einfache Anweisungen, die innerhalb von Schleifen
stehen können, also im Schleifenrumpf von while- , do-while - und for-Schleife.
break: zum vorzeitigen Verlassen einer Schleife

continue: zum vorzeitigen Verlassen eines Schleifenrumpfes


Tab.: break und continue

Das bedeutet:

break beendet die umgebende Schleife vollständig, springt also hinter das Schleifenende.
continue beendet nur den aktuellen Durchlauf der umgebenden Schleife.
Man könnte sagen, continue springt zur schließenden geschweiften Klammer und setzt
dann den normalen Ablauf fort. Je nachdem, ob die Schleifenbedingung wahr oder falsch ist,
kann es also einen weiteren Durchlauf durch den Schleifenrumpf geben.
Die Anweisungen break und continue beziehen sich
immer auf die innerste sie umgebende Schleife. Sie
stehen in der Regel in einem Block einer if -
Anweisungen, weshalb es wichtig ist, noch einmal darauf
hinzuweisen, dass es sich dabei eben nicht um eine
Schleife handelt.

Frage von Markus:


Tauchte break nicht schon einmal bei der switch-case-Anweisung auf?

Antwort:
Ja, das ist richtig. In der älteren Form der switch-case-Anweisung diente das
Schlüsselwort break genauso zum sofortigen Verlassen der umgebenden Anweisung
wie bei den Schleifen. Technisch gesehen ist es also die gleiche Anweisung.

Sowohl break als auch continue können dazu genutzt werden, um nicht nur die direkt
Achtung umgebende Schleife, sondern einen größeren umgebenden Block zu verlassen. Sie finden
diese Möglichkeit in der Spezifikation der Sprache Java beschrieben:

https://docs.oracle.com/javase/specs/jls/se17/html/jls-14.html#jls-14.15 und
https://docs.oracle.com/javase/specs/jls/se17/html/jls-14.html#jls-14.16.

Da eine solche Verwendung nie zwingend notwendig ist und praktisch immer zu sehr
unübersichtlichem Code führt, soll sie hier nicht behandelt und schon gar nicht empfohlen
werden.

20.07.2023 31 von 49
ITR - Iterationen

5.1 Abbruch von Schleifen

Die break-Anweisung beendet die umgebende for-, while- oder do-while-Schleife.


break;

Die Schleifen werden in den meisten Fällen so programmiert, dass sich innerhalb des
Beispiel
Schleifenrumpfes eine if-Anweisung befindet, die die break-Anweisung enthält. Am besten
sehen Sie das wieder an einem Beispiel zur Berechnung einer Wurfparabel:

Berechnet wird die Höhe h einer Wurfparabel in der geworfenen


Weite x nach der folgenden Formel in Abhängigkeit von der
Anfangsgeschwindigkeit v und dem Winkel α des Wurfs:

x2 ⋅ g
h = x ⋅ tan(α) −
2 ⋅ v2 ⋅ cos2 (α)
g ist dabei die Erdbeschleunigung von 9, 81 sm2 .

Um eine solche Wurfparabel zeichnen zu können, muss die x-Koordinate wiederholt um einen
bestimmten Wert vergrößert werden.

Abb.: Wurfparabel

Die mathematische Formel berechnet mit größer werdendem x auch negative Werte, in der
Realität landet der geworfene Gegenstand dann natürlich auf dem Boden und bewegt sich nicht
mehr weiter. Es gibt also eine Abbruchbedingung von h < 0.

Sehen Sie sich das Programm SchieferWurf.java (2 KB) an. Das Kernstück ist die Methode,
die die verschiedenen Höhen der Wurfparabel berechnet und als Tabelle ausgibt:

20.07.2023 32 von 49
ITR - Iterationen

Rolloverbild
Höhen der Wurfparabel berechnen
001 /**
002 * Gibt eine Tabelle mit den berechneten Höhen der
003 * Wurfparabel in der Eingabeaufforderung (Terminal) aus
004 * @param deltaX Schrittweite zwischen den berechneten Weiten
005 */
006 public void tabelleBerechnen(double deltaX) {
007 System.out.println("Höhe" + "\t" + "Weite");
008 double x;
009 for(x = 0;; x+=deltaX) {
010 double h = this.hoehe(x);
011 if(h < 0) {
012 break;
013 }
014 System.out.printf("%.3f \t %.2f%n", h, x);
015 }
016 System.out.println("Erzielte Weite zwischen " + (x-deltaX) + " und " + x);
017 }

Textversion: Höhen der Wurfparabel berechnen


Zeile 009:
Die Weite x soll bei 0 beginnen und für jede Zeile in der Tabelle um die gewünschte Schrittweite deltaX erhöht werden.
Es bietet sich also durchaus eine for-Schleife an. Allerdings sagt die Weite x nichts über das Schleifenende aus, je nach
Geschwindigkeit und Winkel wird unterschiedlich weit geworfen. Deshalb ist die Schleifenbedingung leer - der Compiler
geht von einer immer wahren Bedingung aus. Technisch betrachtet handelt es sich also um eine Endlosschleife.

Zeile 010:
Mit Hilfe der Methode hoehe wird die Höhe der Wurfparabel bei Weite x berechnet. In der Methode versteckt sich die
oben genannte Formel.

Zeile 011:
Wenn die Abbruchbedingung erreicht ist, der geworfene Gegenstand also auf dem Boden gelandet ist,…

Zeile 012:
… wird die Schleife sofort beendet. Die Gefahr der Endlosschleife ist also gebannt.

Zeile 014:
Insbesondere bedeutet dieser sofortige Abbruch auch, dass die Ausgabe von berechneter Höhe und Weite nicht mehr
erfolgt, wenn break; ausgeführt wurde. Eine negative Höhe wäre für einen Menschen auch sehr verwirrend…

Zeile 016:
Nach dem Abbruch der Schleife wird die Ausgabe der erzielten Weite erreicht. Da x nicht innerhalb der for - Schleife
deklariert wurde, steht der letzte Wert von x noch zur Verfügung. Beachten Sie, dass die Aktualisierungsanweisung beim
Abbruch nicht mehr stattfindet, x also nicht noch einmal erhöht worden ist.

Tipp
Hinweis
Halten Sie sich mit der Verwendung von break; etwas zurück. Obwohl es Situationen gibt, in
denen ein solcher Abbruch einfach und elegant ist, sind Schleifen meist verständlicher, wenn
die Bedingung für das Schleifenende dort steht, wo man diese auch erwartet. break; sollte
also wirklich eher beim Eintreten „besonderer Umstände“ verwendet werden und nicht als
„Normalfall“.

20.07.2023 33 von 49
ITR - Iterationen

Übung ITR-19
Programmieren Methoden umschreiben
Können Sie die Methode tabelleBerechnen so umschreiben, dass keine break -
Anweisung gebraucht wird?
Lösung
Bearbeitungszeit: 15 Minuten

5.2 Abbruch des aktuellen Schleifendurchlaufs


Optionales Betrachten Sie den folgenden Abschnitt als Zusatzwissen für besonders Interessierte.
Zusatzwissen
Neben der break-Anweisung steht ein weiterer Befehl zur Steuerung von Schleifen zur
Verfügung. Er heißt
continue;

Eine continue-Anweisung unterbricht die Abarbeitung des Schleifenrumpfes und springt zu


dessen Ende. D. h., sie beendet nur die Ausführung des gerade aktuellen Schleifendurchlaufs
und setzt dann die normale Abarbeitung fort:

bei for-Anweisungen wird die Aktualisierungsanweisung ausgeführt, die Zähler-Variable


wird also entsprechend verändert,
die Schleifenbedingung wird erneut geprüft,
je nach Ergebnis dieser Prüfung wird der Schleifenrumpf noch einmal ausgeführt oder die
Schleife beendet.
Üblicherweise steht auch continue innerhalb einer Verzweigung, auf jeden Fall aber innerhalb
einer Schleife (while, do-while oder for), sonst reagiert der Compiler mit einer
Fehlermeldung.

In Abschnitt 3.2 wurde bereits ein Beispiel vorgestellt, um alle Teiler einer Zahl auszugeben.
Im folgenden Beispiel soll die Anzahl dieser Teiler einer Zahl ermittelt werden - hier jetzt mit einer
for-Schleife:
Anzahl der Teiler einer Zahl mit for
Quellcode /**
* ermittelt die Anzahl der Teiler von zahl
*
* @param zahl Zahl, deren Teiler ermittelt werden sollen
* @return Anzahl der positiven Teiler von zahl; 0, wenn zahl ==0
*/
public static int anzahlTeiler(int zahl) {
if (zahl < 0) {
zahl *= -1;
}
int anzahl = 0;
for (int teiler = 1; teiler <= zahl; teiler++) {
if (zahl % teiler != 0) {
continue;
}
anzahl++;
}
return anzahl;
}
Teiler.java (1 KB)

Die for-Schleife sorgt dafür, dass in der Variablen teiler nacheinander alle Zahlen zwischen 1
und der eingegebenen Zahl stehen. In der if-Anweisung wird geprüft, ob teiler die
eingegebene Zahl teilt. Ist das nicht der Fall, wird der aktuelle Schleifendurchlauf mit Hilfe der
continue-Anweisung abgebrochen. Das bedeutet, dass für einen Nicht-Teiler die Anweisung
anzahl++; nicht ausgeführt wird, er wird also nicht mitgezählt.

20.07.2023 34 von 49
ITR - Iterationen

Übung ITR-20
Programmieren Code analysieren
Gehen Sie den Code für sich Schritt für Schritt durch und überlegen Sie sich, wann
genau was in den einzelnen Variablen steht und wann welche Anweisung ausgeführt
wird.
Bearbeitungszeit: 10 Minuten

Sie sehen bereits an diesem Beispiel, dass continue den Code nicht unbedingt übersichtlicher
und verständlicher macht. Nicht nur kürzer, sondern auch nachvollziehbarer ist sicherlich diese
Formulierung des identischen Algorithmus:
Algorithmus ohne continue
Quellcode for(int teiler = 1;teiler <= zahl; teiler++) {
if(zahl % teiler == 0) {
anzahl++;
}
}

Deshalb der folgende Tipp:

Tipp
Hinweis
continue entfaltet seine Vorteile tatsächlich erst bei sehr komplexem Code - also sehr tief
verschachtelte Verzweigungen in einer Schleife. Verzichten Sie weitgehend auf continue,
denn auch die Notwendigkeit eines solch komplexen Codes spricht nicht unbedingt für eine
gute Zerlegung des Problems in einzelne Methoden.

20.07.2023 35 von 49
ITR - Iterationen

Zusammenfassung

Man spricht in der Programmierung von einer Iteration, wenn ein Block von Anweisungen
nacheinander wiederholt ausgeführt wird.

Die folgenden Schleifenarten werden unterschieden:


kopfgesteuerte (vorprüfende, abweisende) Schleife: Wiederholung mit
vorausgehender Bedingungsprüfung. In Java sind while- und for-Anweisungen
kopfgesteuerte Schleifen.
fußgesteuerte (nachprüfende) Schleife: Wiederholung mit nachfolgender
Bedingungsprüfung. In Java ist die do-while-Anweisung eine fußgesteuerte Schleife.

Die kopfgesteuerte Schleife prüft vor der Ausführung der Anweisungen im Schleifenrumpf,
ob eine Bedingung wahr ist. Es kann also passieren, dass der Schleifenrumpf überhaupt
nicht ausgeführt wird, wenn die Bedingung sofort zu Beginn falsch ist.

Wollen Sie sicherstellen, dass der Block in einer Schleife wenigstens einmal ausgeführt wird,
müssen Sie die Testbedingung an das Ende der Schleife setzen. Realisiert wird diese Form
der Programmausführung durch die nachprüfende Schleife.

Bedingung und Schleifenrumpf bilden die Hauptbestandteile der Schleife. Die Bedingung
liefert immer einen booleschen Wert. Je nachdem ob der Wert true oder false ist, wird die
Schleife ausgeführt oder beendet.

Besondere Bedeutung in Schleifen haben die kombinierten Operatoren, die eine


Rechenoperation und eine Zuweisung zusammenfassen. Mit ihrer Hilfe kann ein Ergebnis
mit jedem Schleifendurchlauf nach und nach berechnet werden.

Die Steuerung der for-Anweisung erfolgt durch einen Zähler.


Er wird im Initialisierungsteil mit einem Startwert belegt,
In der Schleifenbedingung wird geprüft, ob er seinen Endwert erreicht hat.
Im Aktualisierungsteil wird er verändert meist durch Inkrement- oder Dekrementoperator.
Andere Veränderungen sind aber möglich.

Schleifen können ineinander verschachtelt werden.

Bei allen Schleifen müssen Sie darauf achten, dass sie terminieren, also beendet werden.
Achten Sie also darauf, dass sich in jedem Schleifendurchlauf mindestens eine der Variablen
in der Schleifenbedingung verändert.

Um Schleifen vorzeitig abbrechen zu können, verwendet man in der Programmierung die


einfachen Anweisungen break und continue. Die beiden Anweisungen dienen:
break: zum vorzeitigen Verlassen einer Schleife
continue: zum vorzeitigen Verlassen eines Schleifenrumpfes

Sie sind am Ende dieser Lerneinheit angelangt. Auf der folgenden Seite finden Sie einige
Übungen, mit denen Sie Ihr neu erworbenes Wissen testen können.

20.07.2023 36 von 49
ITR - Iterationen

Wissensüberprüfung

Übung ITR-21
Multiple Choice
Aussagen zu Schleifen
Welche Aussagen sind falsch und welche richtig?
Richtig Falsch Auswertung
Die Anweisung
while (false){
System.out.print("Das ist ein Test");
}

ist eine gültige Anweisung, die vom Compiler übersetzt wird.

In der for-Anweisung kann der Schleifenkopf leer sein (bis auf


die Semikola).

Der Schleifenzähler kann erhöht, aber nicht verringert werden.

Bedingung und Rumpf bilden die Hauptbestandteile der Schleife.

Schleifen können nicht ineinander verschachtelt werden.

Übung ITR-22
Freitext
Code analysieren I
Welche Ausgabe erwarten Sie von diesen Codestücken?

int auswahl = 7;
while(auswahl <= 3){
auswahl += 1;
}
System.out.println(auswahl);

int auswahl = 7;
do {
auswahl += 1;
} while(auswahl <= 3);
System.out.println(auswahl);

int i;
for (i=7; i == 0; i--){
//mach was Schönes
}
System.out.println(i);

20.07.2023 37 von 49
ITR - Iterationen

Übung ITR-23
Multiple Choice
Code analysieren II
Was passiert in diesem Codestück?
int i = 7;
while (i > 0)
System.out.println(i);
i = i - 1;

Richtig Falsch Auswertung


Es wird endlos die 7 ausgegeben.

Es werden die Zahlen von 7 bis 1 ausgegeben.

Es werden die Zahlen von 7 bis 0 ausgegeben.

Der Compiler meldet einen Fehler, weil die geschweiften


Klammern fehlen.

Übung ITR-24
Multiple Choice Unterschied zwischen while und do-while
Was ist der Unterschied zwischen der while - Schleife und der do-while - Schleife?
Richtig Falsch Auswertung
Die do-while-Schleife kann durch eine for-Schleife ersetzt
werden, die while-Schleife nicht.

Die while-Schleife prüft die Bedingung zuerst, so dass es sein


kann, dass der Schleifenkörper komplett übersprungen wird. Der
Schleifenkörper der do-while-Schleife wird dagegen
mindestens einmal durchlaufen.

Die do-while-Schleife prüft die Bedingung zuerst, so dass es


sein kann, dass der Schleifenkörper komplett übersprungen wird.
Der Schleifenkörper der while-Schleife wird dagegen
mindestens einmal durchlaufen.

Die while-Schleife ist zwingend nötig, um alle theoretisch


möglichen Algorithmen programmieren zu können, die do-
while-Schleife braucht man eigentlich nicht.

Es gibt nur einen Unterschied in der Schreibweise (einmal mit


dem Wörtchen do, einmal ohne), ansonsten sind sie vollkommen
identisch.

20.07.2023 38 von 49
ITR - Iterationen

Übung ITR-25
Multiple Choice Abweichungen in der for-Syntax
Die am häufigsten verwendete for-Schleife sieht so aus:
for(int i=0; i < 10; i++){
...
}

Welche der folgenden Abweichungen von dieser Syntax sind möglich?


Richtig Falsch Auswertung
Man darf die runden Klammern weglassen.

Man kann die geschweiften Klammern weglassen, dann gilt die


for-Schleife nur für die folgende
Anweisung.

Man kann für die Zählvariable einen anderen Namen wählen.

Man kann Komma statt Semikolon in den runden Klammern der


for-Schleife schreiben.

Man kann mehrere Bedingungen überprüfen lassen, indem man


sie alle durch Komma getrennt in die Mitte der for-Schleife
schreibt.

Man kann zwei oder mehr Variablen initialisieren, indem man die
beiden Zuweisungen (oder mehr) zu Beginn der for-Schleife
durch ein Komma trennt.

Man kann die Zählervariable vor der Schleife deklarieren, wenn


man ihren Wert im Code hinter der Schleife noch benötigt.

Man kann hinter der Aktualisierungsanweisung noch ein


Semikolon setzen.

Man kann die Bedingung weglassen und braucht dann break,


um die Schleife zu verlassen.

Man kann eine andere Aktualisierungsanweisung schreiben als


i++.

20.07.2023 39 von 49
ITR - Iterationen

Lückentext
Übung ITR-26

Lückentext zu Schleifen

break und ____ sind einfache Anweisungen, die in allen ____ stehen können. Üblicherweise Bedingung
werden Sie dabei in eine ____ -Anweisung eingefasst. Die Anweisungen dienen dabei zum
break
vorzeitigen ____ einer Schleife bzw. eines Schleifenrumpfes. ____ beendet die kleinste
continue
umgebende Schleife und setzt die Ausführung ____ dem Schleifenende fort. ____ beendet
do
nur den aktuellen Schleifendurchlauf. In der ____ -Anweisung wird zunächst die
Aktualisierungsanweisung ausgeführt, dann folgt in allen Schleifen die Überprüfung der for
____ , um zu entscheiden, ob ein weiterer ____ folgt. hinter
if
Schleife
Schleifendurchlauf
Verlassen
while

Übung ITR-27
Programmieren
Zahlen eingeben
Vorgegeben ist die Klasse Zahleingabe. Sorgen Sie dafür, dass die bereits
vorgegebene Eingabe von Zahlen wiederholt wird. Die Eingabe soll beendet werden,
wenn eine 0 eingegeben wird oder zum siebten Mal die 99. Am Ende wird
ausgegeben, wie oft die Zahl 99 bei der Eingabe dabei war.
Zahleingabe.java (705 B)
Lösung
Bearbeitungszeit: 10 Minuten

20.07.2023 40 von 49
ITR - Iterationen

Einsendeaufgaben

ITR-E1
Einsendeaufgabe Würfelspiel - Mensch gegen Computer
In dieser Aufgabe sollen Sie ein kleines Würfelspiel Mensch gegen Computer
programmieren. Vorgegeben ist die Klasse Wuerfelmaschine. Sie soll es
ermöglichen, mehrere Würfel zu werfen.
Wuerfelspiel.zip (3 KB)
Ergänzen Sie die Implementierungen der folgenden Methoden:
a. public int summe(boolean computer)
Die Methode soll alle Würfel werfen und die Summe ihrer Augenzahlen bilden.
b. public int wieOftBisHoechste(boolean computer)
Die Methode soll immer wieder einen Würfel werfen, bis die höchstmögliche
Augenzahl gewürfelt wurde. Die Methode gibt die Anzahl der dafür benötigten
Würfe zurück.
Die Klasse enthält bereits die private Methode werfen(boolean computer), die
Sie verwenden sollten, um zu „würfeln“. Übergibt man true, erzeugt der Computer
Zufallszahlen, übergibt man false, wird der Benutzer zur Eingabe seiner gewürfelten
Zahl aufgefordert. Damit Sie Ihre Ergebnisse kontrollieren können, schreibt die
Methode die geworfene Zahl auch auf die Eingabeaufforderung (Terminal).
Ergänzen Sie außerdem die Klasse Wuerfelspiel, die das Spiel tatsächlich
durchführt:
c. public static boolean entscheidungsspiel(Wuerfelmaschine wm)
Zuerst soll der menschliche Spieler würfeln, bis er die höchste Augenzahl erreicht
hat, dann der Computer. Wer dafür weniger Würfe benötigt, gewinnt – geben Sie
true für den Computer und false für den Menschen zurück. Sind beide
Anzahlen gleich, machen Sie eine entsprechende Ausgabe und wiederholen das
Würfeln.
Um das Spiel auszuprobieren, können Sie die main-Methode der Klasse
Wuerfelspiel starten. Viel Spaß und halten Sie die Würfel bereit!
An die Mentoren der Hochschule, an der Sie eingeschrieben sind, senden Sie bitte
folgenden Dateien:
die Quelldateien Wuerfelmaschine.java und Wuerfelspiel.java.
die übersetzten Dateien Wuerfelmaschine.class und Wuerfelspiel.class.
als .zip-Datei mit dem Namen IhrName_ITR-E1.zip.
Weitere Informationen, insbesondere den Abgabetermin, entnehmen Sie den
Ankündigungen im Lernraumsystem.
Bearbeitungszeit: 120 Minuten

20.07.2023 41 von 49
ITR - Iterationen

ITR-E2
Einsendeaufgabe
Mathematik - Quadratwurzel ziehen
Schreiben Sie eine Klasse Mathematik mit den folgenden Methoden:
a. public static double wurzel(double radikant)
Die Methode soll die Quadratwurzel aus radikant ziehen, allerdings nicht mit
Hilfe der Methoden aus der Klasse Math, sondern nach folgendem Verfahren, bei
dem die Wurzel zwischen einer unteren und einer oberen Grenze liegt, die sich
immer weiter aufeinander zubewegen:
Ist radikant größer oder gleich 1, wählen sie 1 als untere und radikant als
obere Grenze. Ist radikant kleiner als 1, vertauschen Sie obere und untere
Grenze.
Berechnen Sie die Mitte zwischen unterer und oberer Grenze.
Ist diese Mitte zu groß (weil Mitte² größer als radikant ist), nehmen Sie sie
als neue obere Grenze. Ist sie zu klein, nehmen Sie sie als neue untere
Grenze.
Wiederholen Sie diesen Vorgang, bis die gefundene Mitte genau genug ist,
also bis Mitte² nur noch um höchstens 0,001 von radikant abweicht.
Geben Sie die gefundene Mitte, die sehr genau an der echten Wurzel liegen
sollte, zurück.
b. public static void main(String[] args)
Im Hauptprogramm soll der Benutzer oder die Benutzerin eine Zahl eingeben,
deren Wurzel berechnet werden soll. Wird eine negative Zahl eingegeben, geben
Sie eine Fehlermeldung aus und wiederholen Sie die Eingabe der Zahl.
Bearbeitungszeit: 120 Minuten

ITR-E3
Einsendeaufgabe
Geschenkpapier
Lernziel:
Programmierung der verschiedenen Schleifenarten und der Mehrfachverzweigung
Während der Beschäftigung mit dem Programmierkurs haben Sie die Einladung zur
Geburtstagsparty fast vergessen und stellen fest, dass nicht mehr ausreichend
Geschenkpapier vorrätig ist!
Programmieren Sie eine Klasse Geschenkpapier, die zwei Klassenmethoden
enthält, mit denen Muster bestehend aus einfachen Zeichenfolgen auf dem Bildschirm
ausgegeben werden.
Das erste Muster soll in jeder Zeile wiederholt ausgegeben werden, beispielsweise:
** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** **

Abb.: Ergebnis ITR-01a

20.07.2023 42 von 49
ITR - Iterationen

Das zweite Muster soll sich auch wiederholen, aber in aufeinanderfolgenden Zeilen
verschieden sein, beispielsweise:
:-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-)
)-: )-: )-: )-: )-: )-: )-: )-: )-: )-: )-: )-:
:-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-)
)-: )-: )-: )-: )-: )-: )-: )-: )-: )-: )-: )-:
:-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-)
)-: )-: )-: )-: )-: )-: )-: )-: )-: )-: )-: )-:
:-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-)
)-: )-: )-: )-: )-: )-: )-: )-: )-: )-: )-: )-:
:-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-)
)-: )-: )-: )-: )-: )-: )-: )-: )-: )-: )-: )-:

Abb.: Ergebnis ITR-01b

Anforderung: Für die Ausgabe des Musters ist jeweils eine andere Schleifenart zu
benutzen. Das zu verwendende Muster z. B. „** “ und die Anzahl der
auszugebenden Zeilen und Spalten, sollen den Klassenmethoden als Parameter
übergeben werden.
Erstellen Sie ein Hauptprogramm mit dem Namen GeschenkpapierTest.java.
Testen Sie die Methoden der Klasse Geschenkpapier mit verschiedenen
Parametern in der main - Methode des Hauptprogramms GeschenkpapierTest.
Senden Sie an Ihren Betreuer die Klasse Geschenkpapier.java und die Klasse
GeschenkpapierTest.java gepackt in einer Zip-Datei mit folgendem Namen:
IhrNameLE_ITR-E3.zip
Tipp: Denken Sie auch daran, dass jede for-Anweisung durch eine while-
Anweisung ersetzbar ist.
Weitere Informationen, insbesondere den Abgabetermin, entnehmen Sie den
Ankündigungen im Lernraumsystem.
Bearbeitungszeit: 90 Minuten

20.07.2023 43 von 49
ITR - Iterationen

ITR-E4
Einsendeaufgabe
Gefüllte Raute
Lernziel:
Programmierung von Schleifen
Programmieren Sie eine Klasse Raute, die eine Klassenmethode enthält, die eine
gefüllte Raute am Bildschirm ausgibt, etwa so:
*
***
*****
*******
*********
*******
*****
***
*

Abb.: Ergebnis ITR-02

Das zu verwendende Muster – z. B. „*“ und die Größe der Raute – sollen der
Klassenmethode als Parameter übergeben werden.
Erstellen Sie ein Hauptprogramm mit dem Namen RauteTest.java. Testen Sie die
Methode der Klasse Raute mit verschiedenen Parametern in der main-Methode des
Hauptprogramms RauteTest.
Tipp: Schauen Sie sich das Programm Schleifen.java (1 KB) an.
Falls Sie Probleme mit der Lösung der Aufgabe haben, können Sie zusätzlich die
folgende Hilfestellung nutzen: Vertiefung Raute (Siehe Anhang)
Senden Sie an Ihren Betreuer die Klasse Raute.java und die Klasse
RauteTest.java gepackt in einer Zip-Datei mit folgendem Namen:
IhrNameLE_ITR-E4.zip
Weitere Informationen, insbesondere den Abgabetermin, entnehmen Sie den
Ankündigungen im Lernraumsystem.
Bearbeitungszeit: 90 Minuten

20.07.2023 44 von 49
ITR - Iterationen

Appendix

Lösung Übung ITR-02 Teil I

Dateilesen.java
001 import java.io.BufferedReader;
002 import java.io.FileReader;
003 import java.io.IOException;
004
005 /**
006 * liest die Datei beispiel.txt und gibt sie auf der Konsole aus
007 *
008 */
009 public class Dateilesen {
010
011 /**
012 * liest die Datei beispiel.txt und gibt sie auf der Konsole aus
013 *
014 * @param args wird nicht verwendet
015 * @throws IOException wenn die Datei nicht gefunden wird
016 */
017 public static void main(String[] args) throws IOException {
018 BufferedReader datei = new BufferedReader(new FileReader("beispiel.txt"));
019
020 while (datei.ready()) {
021 String zeile;
022 zeile = datei.readLine();
023 System.out.println(zeile);
024 }
025 datei.close();
026
027 }
028
029 }
Dateilesen.java

20.07.2023 45 von 49
ITR - Iterationen

Lösung Übung ITR-02 Teil II

Dateilesen.java
001 import java.io.BufferedReader;
002 import java.io.FileReader;
003 import java.io.IOException;
004
005 /**
006 * liest die Datei beispiel.txt und gibt sie auf der Konsole aus
007 *
008 */
009 public class Dateilesen {
010
011 /**
012 * liest die Datei beispiel.txt und gibt den Inhalt zurück
013 *
014 * @return Inhalt von beispiel.txt
015 * @throws IOException wenn die Datei nicht gefunden wird
016 */
017 public static String dateilesen() throws IOException {
018 BufferedReader datei = new BufferedReader(new FileReader("beispiel.txt"));
019
020 String zurueck;
021 zurueck = "";
022 while (datei.ready()) {
023 String zeile;
024 zeile = datei.readLine();
025 zurueck += zeile + System.lineSeparator();
026 }
027 datei.close();
028 return zurueck;
029 }
030
031 /**
032 * liest die Datei beispiel.txt und gibt sie auf der Konsole aus
033 *
034 * @param args wird nicht verwendet
035 * @throws IOException wenn die Datei nicht gefunden wird
036 */
037 public static void main(String[] args) throws IOException {
038 String text = dateilesen();
039 System.out.println(text);
040
041 }
042
043 }
Dateilesen.java

Lösung Übung ITR-03

Vielleicht sind Sie auf einen dieser Fehler gestoßen:

Man „vergisst“ den Teilungsoperator für zahl. Statt


zahl /= 10;
steht nur da:
zahl = 10;
Man schließt den Schleifenblock zu früh, die schließende geschweifte Klammer steht vor der
Veränderung der Variablen zahl.
Man setzt ein Semikolon direkt hinter die runden Klammern mit der Schleifenbedingung. Sie
erinnern sich: Das Semikolon steht für die leere Anweisung - solange die Bedingung wahr ist,
tue nichts!

Mit allen diesen Fehlern haben Sie dafür gesorgt, dass die Variable zahl sich im
Schleifenkörper nicht mehr verändert, sondern immer den gleichen Wert behält. Dadurch
verändert sich auch die Auswertung der Bedingung nicht mehr, sie ist und bleibt immer wahr.

20.07.2023 46 von 49
ITR - Iterationen

Lösung Übung ITR-05

Wiederholungssteuerung mit while


001 char antwort;
002 antwort = 'j';
003 while(antwort == 'j') {
004 //urspruengliche Programmanweisungen
005 antwort = EinAusgabe.eingabeZeichen("Programmwiederholung? (j/n)");
006 }

Da die Bedingungsprüfung hier sofort zu Beginn stattfindet, muss die Variable antwort zu
Beginn initialisiert werden. Dadurch „gaukelt“ man der Virtual Machine vor, der Benutzer hätte
bereits „ja“ gesagt.

Lösung Übung ITR-06

Wiederholungssteuerung mit while


001 /**
002 * Klasse zur Quersummenberechnung
003 */
004 public class Quersumme {
005
006 /**
007 * berechnet die Quersumme von zahl
008 *
009 * @param zahl
010 */
011 public static int quersumme(int zahl) {
012 if (zahl < 0) {
013 zahl *= -1;
014 }
015 int quer = 0;
016 while (zahl > 0) {
017 int ziffer = zahl % 10;
018 quer += ziffer;
019 zahl /= 10;
020 }
021 return quer;
022 }
023
024 /**
025 * nimmt eine Eingabe vom Benutzer entgegen und berechnet die Quersumme daraus
026 *
027 * @param args wird nicht verwendet
028 */
029 public static void main(String[] args) {
030 char antwort;
031 do {
032 int zahl;
033 zahl = EinAusgabe.eingabeGanzeZahl("Bitte Zahl eingeben: ");
034 int ergebnis = quersumme(zahl);
035 System.out.println("Die Quersumme ist " + ergebnis);
036 antwort = EinAusgabe.eingabeZeichen("Programmwiederholung? (j/J/n/N)");
037 } while (antwort == 'j' || antwort == 'J');
038
039 }
040
041 }
Quersumme.java (1 KB)

20.07.2023 47 von 49
ITR - Iterationen

Lösung Übung ITR-07

Auszug aus EinAusgabe.java


001 public static boolean wiederholungGewuenscht() {
002 char antwort;
003 do {
004 antwort = EinAusgabe.eingabeZeichen("Programmwiederholung? (j/J/n/N)");
005 } while (antwort != 'j' && antwort != 'n' && antwort != 'J' && antwort != 'N');
006 return antwort == 'j' || antwort == 'J';
007 }
Quersumme_Ueberpruefung.zip (3 KB)

Lösung Übung ITR-10

Die Methode berechnet xy, wenn y positiv ist.


Wenn y kleiner ist als 0, gibt die Methode einfach 1 zurück, weil die Schleifenbedingung sofort
falsch ist und keine Multiplikation durchgeführt wird. Das ist mathematisch falsch und sollte
deshalb erwähnt werden - aber da negative Zahlen für die meisten nicht zum „Wohlfühlbereich“
gehören, kann man wohl darüber hinwegsehen.

Lösung Übung ITR-11

Die Sternchen bilden kein Quadrat, sondern stehen einfach alle untereinander.

Lösung Übung ITR-12

Dreieck
/**
* zeichnet ein rechtwinkliges Dreieck mit n Zeilen auf den Bildschirm
*
* @param n Hoehe des Dreiecks (Anzahl Zeilen)
*/
public static void dreieck(int n) {
for (int zeile = 1; zeile <= n; zeile++) {
for (int spalte = 1; spalte <= zeile; spalte++) {
System.out.print("*");
}
System.out.println();
}
}
Geometrie.java (1 KB)

Lösung Übung ITR-17

Der Benutzer hat fünf Versuche.

20.07.2023 48 von 49
ITR - Iterationen

Hilfestellung ITR-E4

Aus der nachfolgenden Abbildung können Sie ersehen, wie viele Leerzeichen und Muster je
Zeile ausgegeben werden. Für dieses Beispiel wurde die Größe der Raute = 9 und als Muster ein
'*' übergeben. Aus der Abbildung können Sie ersehen, dass sich die Anzahl der Leerzeichen
zuerst jeweils um eins (4, 3, 2, ...) verringert und nach der maximalen Breite der Raute (in diesem
Beispiel=9) jeweils um eins erhöht. Umgekehrt verhält es sich bei den Sternen (*). Diese werden
zunächst erhöht (1, 3, 5...) und nach der maximalen Breite verringert.

Überlegen Sie sich, wie Sie dieses Verhalten mit Schleifen umsetzen können.

Größe der Raute=9, Muster=*


----* 1.Zeile: 4 Leerzeichen, 1 Stern
---*** 2.Zeile: 3 Leerzeichen, 3 Sterne
--***** 3.Zeile: 2 Leerzeichen, 5 Sterne
-******* 4.Zeile: 1 Leerzeichen, 7 Sterne
*********5.Zeile: 0 Leerzeichen, 9 Sterne
-******* 6.Zeile: 1 Leerzeichen, 7 Sterne
--***** 7.Zeile: 2 Leerzeichen, 5 Sterne
---*** 8.Zeile: 3 Leerzeichen, 3 Sterne
----* 9.Zeile: 4 Leerzeichen, 1 Sterne
Abb.: Eingabeaufforderung- bzw. Terminal-Ausgabe einer Raute mit Anzahl der Zeilen, Leerzeichen und Muster

20.07.2023 49 von 49

Das könnte Ihnen auch gefallen