Jetzt kommt mal wieder was entscheidend Neues. In der Folge 3 haben Sie if-else-Anweisungen kennengelernt. In dieser Folge sind die Schleifen an der Reihe; wir beginnen mit der while-Schleife

Schritt 6 - Schleifen

Schreiben Sie eine Testklasse, die ein Objekt der Klasse Auto genau 50 mal jeweils 1 km fahren lässt. Der Quelltext dieser Testklasse müsste dann ungefähr so aussehen:

public class Test
{
    Auto otto;
    
    public Test()
    {
       otto = new Auto(10000,70,7.5);
       otto.fahren(1); otto.anzeigen();
       otto.fahren(1); otto.anzeigen();
       otto.fahren(1); otto.anzeigen();
       otto.fahren(1); otto.anzeigen();
       otto.fahren(1); otto.anzeigen();
       otto.fahren(1); otto.anzeigen();
       otto.fahren(1); otto.anzeigen();

Auf die restlichen 43 gleichen Zeilen habe ich hier aus verständlichen Gründen verzichtet.

Betrachten Sie nun folgende Version der Testklasse, die das Gleiche leistet, aber sehr viel kürzer ist:

public class Test
{
   Auto otto;

   public Test()
   {
      otto = new Auto(10000, 70, 7.5);
      otto.anzeigen();
      int strecke = 0;
      while (strecke < 50)
      {
         otto.fahren(1); 
         otto.anzeigen();
         strecke++;
      } 
   }
}

Der wichtigste Teil dieser Methode ist sicherlich die while-Schleife, die im Quelltext farbig hinterlegt wurde.

Mit dem Autofahren sind wir jetzt eigentlich am Ende. Wenn Sie wollen, können Sie ja ihre Klasse Auto noch genauer modellieren und zum Fahren dann eine while-Schleife benutzen. Im folgenden Abschnitt wollen wir auf das Thema while-Schleifen noch etwas genauer eingehen; vor allem die Klausur-Leute sollten sich diesen Abschnitt eingehend anschauen.

while-Schleifen

Programmfluss

Der Ablauf der einzelnen Befehle und Überprüfungen in einer while-Schleife wird am besten in Form eines Flussdiagramms dargestellt:

In dem Flussdiagramm fällt sofort ein typisches Merkmal von while-Schleifen auf: Die entscheidende Frage, nämlich ob die Schleife durchlaufen werden soll, wird am Anfang der Schleife gestellt. Daher gehört die while-Schleife zu den sogenannten vorprüfenden Schleifen.

Betrachten wir nun den Programmfluss und das Flussdiagramm. Zunächst hat die Variable

strecke

den Wert 0. Diese lokale Variable darf nicht mit dem Attribut

kilometerStand

verwechselt werden.

strecke

speichert nur die während einer Fahrt zurückgelegte Strecke, während

kilometerStand

die gesamte Strecke speichert, die das Auto jemals zurückgelegt hat.

Die Frage strecke < 50 wird also mit true beantwortet, im Flussdiagramm folgen wir also dem Pfeil, an dem das Wort "ja" steht. Nun wird 1 km gefahren, dann werden die Werte angezeigt. Durch den Aufruf von fahren wird das Attribut kilometerStand um 1 erhöht, das sieht man im Flussdiagramm aber nicht. Wir müssen nun dafür sorgen, dass auch die lokale Variable strecke inkrementiert wird. Dies geschieht durch den Befehl strecke++.

Im Flussdiagramm führt nun ein Pfeil zurück zu der Schleifenbedingung strecke < 50. Die Variable hat nun den Wert 1, also ist die Schleifenbedingung noch erfüllt, und die Schleife wird ein zweites Mal durchlaufen. Das geht so lange, bis strecke einen Wert von 50 angenommen hat.

Nun ist die Schleifenbedingung nicht mehr erfüllt, und wir folgen dem langen Pfeil im Flussdiagramm, der mit dem Wort "nein" beschriftet ist. Dieser Pfeil mündet in einem Kasten "weiter". Das heißt, dass jetzt mit dem Java-Befehl weitergemacht wird, der auf die while-Schleife folgt.

Syntaxdiagramm

Während ein Flussdiagramm den Programmfluss zeigt (welche Befehle werden in welcher Reihenfolge ausgeführt?), zeigt ein Syntaxdiagramm den "grammatikalischen" Aufbau eines Befehls, in unserem Fall also den Aufbau einer while-Schleife.

Gehen Sie bitte nun auf den Lexikon-Eintrag "while-Schleifen" und informieren Sie sich über die Syntax derselben.

Übungen

Übung 4.2-1 (2 Punkte)

Geben Sie an, was genau durch die folgende while-Schleife berechnet wird!

int x = 1;
int y = 1;

while (x <= 10)
{
    y = y * x;
    x++;
}

Übung 4.2-2 (4 Punkte)

Betrachten Sie die folgende while-Schleife:

while (a != b)
{
   if (a > b) 
      a = a-b;
   else 
      b = b-a;
}
erg = a

Geben Sie an,

  1. welche Zahl diese while-Schleife berechnet, wenn a=35 und b = 15 ist (2 Punkte)
  2. was der Algorithmus überhaupt (allgemein) berechnet (2 Punkte)

Expertenübung

Die Konstante Pi hat den Wert 3.14159….

PiPi Langstrumpf hat nun folgende Idee:

"Wenn ich 10 durch 3 teile, erhalte ich 3.3333…, das ist schon ein guter Näherungswert für Pi - allerdings ist 10/3 größer als Pi. Ich erhöhe also den Nenner. Dummerweise ist 10/4 = 2.50 wieder kleiner als Pi. Also erhöhe ich jetzt den Zähler.
11/4 = 2.75 ist immer noch kleiner als Pi, daher erhöhe ich den Zähler noch einmal.
12/4 = 3.00 reicht auch noch nicht, versuchen wir es mit 13/4 = 3.25.
Jetzt ist der Quotient wieder zu groß, daher erhöhe ich den Zähler und erhalte 13/5 = 2.6. Dann muss ich wieder den Nenner erhöhen. 14/5 = 2,8; 15/5 = 3.0; 16/5 = 3.2 - wieder ist der Quotient größer als Pi. Also muss jetzt wieder der Nenner erhöht werden und so weiter.
Wenn ich das oft genug wiederhole, erhalte ich schließlich einen Nenner n und einen Zähler z, deren Quotient z/n den Wert 3.14159 liefert."

Schreiben Sie eine Java-Klasse BerechnePi, die ähnlich vorgeht, wie PiPi Langstrumpf das beschrieben hat. Setzen Sie dazu eine while-Schleife ein, die erst dann abbricht, wenn die Differenz zwischen z/n und 3.14159 kleiner als 0.00001 ist. Lassen Sie ihr Programm jeden Zwischenschritt ausgeben, ungefähr so:

10.0/4.0=2.5
11.0/4.0=2.75
12.0/4.0=3.0
13.0/4.0=3.25
13.0/5.0=2.6
14.0/5.0=2.8
15.0/5.0=3.0
16.0/5.0=3.2
16.0/6.0=2.6666666666666665
17.0/6.0=2.8333333333333335
18.0/6.0=3.0
19.0/6.0=3.1666666666666665
19.0/7.0=2.7142857142857144
20.0/7.0=2.857142857142857
21.0/7.0=3.0
…
352.0/112.0=3.142857142857143
352.0/113.0=3.1150442477876106
353.0/113.0=3.1238938053097347
354.0/113.0=3.1327433628318584
355.0/113.0=3.1415929203539825

Weiter mit Folge 4.3: do-while-Schleifen