Literatur

Schleifen

Zu den weiteren Kontrollstrukturen zählen die Schleifen. Manche von Ihnen erinnern sich vielleicht noch an den guten alten Plattenspieler. Besonders nervig war es, wenn die Platte in der Endlos-Schleife festhing und immer und immer wieder dasselbe abspielte, und ohne manuellen Eingriff das Lied nicht fortgesetzt wurde. Endlos-Schleifen sollten in der Programmierung unbedingt vermieden werden, da Sie zu Programm- oder sogar PC Abstürzen führen können. In der Regel müssen Endlos-Schleifen durch den Benutzer beendet werden, indem der Prozess beendet wird. Wir wollen uns zwar hier nicht mit Endlos-Schleifen beschäftigen, sondern mit verwendbaren Schleifen, aber da es einer der häufigsten Programierfehler ist, sollten Sie vorgewarnt sein und die Bedingung noch einmal genau kontrollieren, bevor Sie das Programm ausführen.

Es gibt zwei unterschiedliche Schleifentypen: die abweisende und die annehmende Schleife. Die abweisenden Schleifen überprüfen zuerst die Abbruchbedingung, bevor sie eine Anweisung ausführen. Bei der annehmenden Schleife, wird erst, nachdem die Anweisungen einmal ausgeführt worden sind, überprüft, ob die Schleife weiterlaufen soll oder nicht.

Eine der abweisenden Schleifen ist die for-Schleife. Die for-Schleife besitzt folgenden Aufbau.

for( Initialisierungsklausel; Boolescher Ausdruck; Iteration)
{
   Anweisung;
}

Das Schlüsselwort for leitet die for-Schleife ein. Ihm folgt ein dreiteiliger Block, der vorhanden sein muss. Dieser Block besteht aus der Initialisierungsklausel bzw. der Laufzeitvariablendeklaration. Die Laufzeitvariable ist nur in der for-Schleife sichtbar, einem booleschen Ausdruck, der die Abbruchbedingung darstellt, sowie in der Iteration. In dem Iterationsteil wird in der Regel die Laufzeitvariable hoch- bzw. runtergezählt. Alle drei Bereiche werden durch ein Semikolon getrennt und wie separate Anweisungen behandelt. Nach dem Kopf der for-Schleife folgt der Anweisungsblock, der solange ausgeführt wird bis der boolesche Ausdruck false ergibt.
Kommen wir nun zu einem kleinen Beispiel für eine for-Schleife:

Beispiel 1:

// Variable i wird deklariert und initialisiert
// Abbruchbedingung wird festgelegt auf i < 5
// i wird nach jedem durchlauf um eins erhöht
for(int i=0; i<5; i++)
{
    // Die Ausgabe findet fünfmal statt (von 0 bis 4)
    System.out.println("i ist "+i);
}

Wenn der Schleifenzähler für die weitere Verarbeitung wichtig ist, so sollte er in einer anderen lokalen Variablen gespeichert werden, die außerhalb der for-Schleife deklariert wird.

Eine weitere abweisende Schleife ist die while-Schleife. Sie hat folgenden Aufbau:

while( Boolescher Ausdruck )
{
   Anweisung;
}

Das Schlüsselwort while leitet hier die Schleife ein. Hier folgt direkt die Abbruchbedingung als boolescher Ausdruck. Anschließend folgt der Anweisungsblock, der solange ausgeführt wird, bis der boolesche Ausdruck false ergibt. Bei dieser Schleife ist es wichtig, dass mindestens eine Variable, die im booleschen Ausdrucks verwendet wird, innerhalb des Anweisungsblockes manipuliert wird, ansonsten hätten wir eine ungewollte Endlos-Schleife, sobald einmal die while-Schleife betreten wurde.

Schauen wir uns dazu ein Beispiel an.

Beispiel 2:

// Deklaration und Initialisierung der Laufvariablen
int i=5;
// Kopf der while-Schleife mit der Abbruchbedingung
while(i>0)
{
    // Die Ausgabe findet fünfmal statt von 5 bis 1
    System.out.println("i ist "+i);
    // Dekrementierung der Laufvariablen
    i--;
}

 Die einzige annehmende Schleife ist die do-while-Schleife. Bei der do-while-Schleife wird der Anweisungsblock immer einmal durchgeführt, bevor die Abbruchbedingung überprüft wird. Der Aufbau der do-while-Schleife sieht wie folgt aus:

do
{
   Anweisung;
}
while( Boolescher Ausdruck )

Das Schlüsselwort do leitet hier den Anweisungsblock ein und führt alle Anweisungen einmal aus. Nach dem Anweisungsblock kommt der while-Teil mit der Abbruchbedingung. Wenn wir jetzt die beiden unterschiedlichen while-Schleifen vergleichen, fällt einem auf, dass bei der abweisenden while-Schleife die Abbruchbedingung oben steht und bei der annehmenden do-while-Schleife unten steht. Deswegen werden alle abweisenden Schleifen auch als kopfgesteuerte und die annehmenden Schleifen als rumpf- oder fußgesteuerte Schleifen bezeichnet.

Sehen wir uns zur Übung noch ein Beispiel an.

Beispiel 3:

// Deklaration und Initialisierung der Laufvariablen
int i = 0;
// Anweisungsblock, der mindestens einmal ausgeführt wird
do
{
    // Ausgabe wird dreimal ausgeführt
    System.out.println("i ist "+i);
    // Inkrementierung der Laufvariablen
    i+=10;
}
// Abbruchbedingung
while(i<=20);

Wie man am obigen Beispiel sehen kann, muss die Laufvariable nicht mit dem Inkrementierungs- bzw. Dekrementierungsoperator verändert werden.

Zu den weiteren Kontrollstrukturen zählen auch die Sprunganweisungen. Diese werden durch die Schlüsselwörter break, continue und return symbolisiert. Zu den Sprunganweisungen gibt es auch noch sogenannte Sprungmarken, die einfach durch einen Text gefolgt von einem Doppelpunkt gekennzeichnet sind. Sprungmarken werden hier nur der Vollständigkeit halber erwähnt. Wir raten Ihnen unbedingt von der Verwendung von Sprungmarken ab, da der Quellcode dadurch sehr unverständlich wird.

Beispiel 4:

// Variable i wird deklariert und initialisiert
// Abbruchbedingung wird festgelegt auf i < 5
// i wird nach jedem Durchlauf um eins erhöht
for(int i=0; i<5; i++)
{
      // Wenn i zwei wird, wird durch das break die Schleife beendet!
      if(i ==2)
      {
         break;
      }
      System.out.println("i ist "+i);
}

Durch das break in der if-Anweisung wird die Schleife beendet, sobald i==2 ist.


Beispiel 5:

// Variable i wird deklariert und initialisiert
// Abbruchbedingung wird festgelegt auf i < 5
// i wird nach jedem Durchlauf um eins erhöht
for(int i=0; i<5; i++)
{
      // Wenn i zwei wird, wird durch das continue die Ausgabe übersprungen
      // und die Schleife oben fortgesetzt!
      if(i ==2)
      {
         continue;
      }
      System.out.println("i ist "+i);
}

Durch das continue in der if-Anweisung wird die Schleife direkt mit der Erhöhung der Laufvariable fortgesetzt, wodurch die Ausgabe, wenn i==2 ist, übersprungen wird.

Beispiel 6:

// Variable i wird deklariert und initialisiert
// Abbruchbedingung wird festgelegt auf i < 5
// i wird nach jedem Durchlauf um eins erhöht
for(int i=0; i<5; i++)
{
    // Wenn i zwei wird, wird durch das return die Ausgabe übersprungen
    // und sowohl die Schleife als auch die Methode beendet!
    if(i ==2)
    {
       // Ohne Rückgabeparameter
       return;
    }
    System.out.println("i ist "+i);
}

Durch das return in der if-Anweisung werden die Schleife und die Methode direkt beendet.

Beispiel 7:

// Variable beende_schleife2 wird deklariert und initialisiert
boolean beende_schleife2 = true;
// Sprungmarke one
one:
// Endlos-Schleife1
while ( true )
{
    System.out.println( "one" );
 
    // Endlos-Schleife2
    while (beende_schleife2)
    {
         beende_schleife2 = false;
         System.out.println( "two" );
 
        // Beende die aktuelle Schleife und springe zum Ende der Sprungmarke one
        break one;
    }
    break;
 }

Die Ausgabe „one“ würde einmal erfolgen und die Ausgabe „two“ ebenso.

Abschließend zum Kapitel Kontrollstrukturen haben wir noch ein kleines Rätsel.

Warum übersetzt der Java Compiler folgenden Quell-Code:

class Rätsel
{
    static void main( String[ ] args )
   {
         http://www.java-tutorial.org
        System.out.println( "Willkommen beim Java-Tutorial." );
    }
}


Sind Sie auf die Lösung gekommen? Falls Nein, können Sie sich mit Hilfe der Schaltfläche die Lösung anschauen.