13: Schleifen und Wiederholungen

Aus Informatik-Box
Zur Navigation springen Zur Suche springen
Icon Chalk board.png
Was du in diesem Schritt lernst
  • Bedingte Schleifen
  • Zählschleifen
  • verschachtelte Schleifen


Bedingte Schleifen

Bedingte Anweisungen erlauben die Ausführung von Anweisungen unter einer bestimmten Bedingung. Oftmals sollen Anweisungen aber nicht nur einmal, sondern öfter ausgeführt werden, solange eine Bedingung wahr ist. Diese Art von Konstrukt nennt man eine Bedingte Schleife (oder auch while-Schleife).

Du hast schon Schleifen in deinen Programmen benutzt, auch wenn sie bisher in Processing versteckt waren. Die draw() Methode wird immer wieder ausgeführt solange die App läuft:

solange App läuft
    führe draw() aus

Die Syntax einer while-Schleife unterscheidet sich kaum von einer if-Anweisung:

// Gib alle Quadratzahlen kleiner 100 aus.
int x = 1;
int quadrat = 1;
while( quadrat < 100 ) {
    println(quadrat);
    x += 1;
    quadrat = x*x;
}
1
4
9
16
25
36
49
64
81

Wichtig ist hier Zeile 6: Die Schleife läuft so lange, bis x größer oder gleich 100 ist. Wenn Zeile 6 nicht wäre, würde sich x nicht verändern und immer 1 bleiben. In dem Fall würde das Programm unendlich lange laufen und niemals enden.

Icon Heft.png
Arbeitsauftrag

Kopiere das Programm nach Processing und probiere es mithilfe des Debuggers aus.

Klicke dazu den runden grauen Button oben rechts an (der etwas aussieht wie ein Käfer). Processing wechselt in den Debug-Modus. Nun kannst du das Programm schrittweise ablaufen lassen. Markiere dazu Zeile 4 als Breakpoint, indem du links auf die Zeilennummer klickst (die Nummer wird zu einem "Diamanten"). Wenn du jetzt das Programm startest, stoppt die Ausführung in Zeile 5 und zeigt dir im Debug-Fenster die Werte aller Variablen an.

Klicke nun den Weiter Button mehrmals und beobachte die Veränderung der Werte im kleinen Debug-Fenster.


Icon Heft.png
Arbeitsauftrag
  1. Gib alle geraden Zahlen von 2 bis 100 auf der Konsole aus.
  2. Zeichnen drei Quadrate nebeneinander. Das Erste liegt bei (10, 40) und ist 20x20 Pixel groß. Das nächste liegt mit 10 Pixeln Abstand rechts daneben, das dritte wieder 10 Pixel rechts davon.
    Verwende eine while-Schleife, sodass mit einer kleinen Änderung auch 5 oder 2 Quadrate gezeichnet werden können.
Lösung
int i = 0;
while( i < 3 ) {
    rect(10 + i*20, 40, 20, 20);
}


Zählschleifen

Die Aufgaben oben haben alle einen ähnlichen Aufbau: Sie zählen in einer Variable von einem Anfangswert bis zu einem Zielwert mit einer festgelegten Schrittweite. Da diese Art der Schleife beim Programmieren regelmäßig vorkommt, gibt es dafür ein eigenes Konstrukt: die Zählschleife.

Eine Zählschleife (oder auch for-Schleife) bringt alle drei Teile zusammen:

for( int i = 0; i < 100; i += 1 ) {
    println(i+1);
}
0
1
2
3
...

Das Programm gibt die Zahlen 1 bis 100 auf die Konsole aus. In der Klammer hinter for stehen die Bestandteile durch ; getrennt:

for( Zählvariable = Startwert; Zielwert; Schrittweite )
Icon Info.png
Eine Zählschleife lässt sich immer auch als while-Schleife schreiben, ist aber kompakter und dadurch besser lesbar. Das Programm zur Ausgabe der Quadratzahlen lässt sich mit einer for-Schleife zum Beispiel so programmieren:
for( int i = 1; i*i < 100; i += 1 ) {
    println(i*i);
}
Icon Heft.png
Arbeitsauftrag
  1. Probiere dieses Programm aus und erkläre seine Funktion. Was sind Startwert, Zielwert und Schrittweite?
    for (int x = 0; x < 100; x = x + 10) {
      int y = x;
      ellipse(x, y, 5, 5);
    }
    
  2. Schreibe das Programm so um, dass die Ellipsen von links unten nach rechts oben gezeichnet werden.
  3. Schreibe eine for-Schleife, die die Zeichenfläche mit vertikalen Linien mit einem Abstand von 10 Pixeln füllt.
  4. Erweitere das Programm zu einem Karo-Muster.
Lösung zu Aufgabe 2
for (int x = 0; x < 100; x = x + 10) {
  int y = 100 - x;
  ellipse(x, y, 5, 5);
}
Lösung zu Aufgabe 4
for (int y = 0; y < 100; y = y + 10) {
  line(0, y, 100, y);
}
for (int x = 0; x < 100; x = x + 10) {
  line(x, 0, x, 100);
}


Verschachtelte Schleifen

Eine Schleife kann schon eine Menge Arbeit sparen, da man Anweisungen nicht ständig wiederholen muss. Noch mächtiger werden sie aber, wenn mehrere Schleifen ineinander verwendet werden.

Stell dir vor, wir haben eine Tabelle mit Zeilen und Spalten.

0 1 2 3 4
0
1
2

Wir können alle Zeilennummern mit einer Zählschleife ausgeben:

for( int i = 0; i < 3; i += 1 ) {
    println("Zeile " + i);
}
Zeile 0
Zeile 1
Zeile 2

Ebenso die Spalten:

for( int j = 0; j < 5; j += 1 ) {
    println("Spalte " + j);
}
Spalte 0
Spalte 1
Spalte 2
Spalte 3
Spalte 4

Sollen nun für alle Zellen die Zeilen und Spaltennummer ausgegeben werden, müssen wir beide Schleifen ineinander verschachteln:

for( int i = 0; i < 3; i += 1 ) {
    for( int j = 0; j < 5; j += 1 ) {
        println("Zeile "+i+", Spalte "+j);
    }
}
Zeile 0, Spalte 0
Zeile 0, Spalte 1
Zeile 0, Spalte 2
Zeile 0, Spalte 3
Zeile 0, Spalte 4
Zeile 1, Spalte 0
Zeile 1, Spalte 1
Zeile 1, Spalte 2
Zeile 1, Spalte 3
Zeile 1, Spalte 4
Zeile 2, Spalte 0
Zeile 2, Spalte 1
Zeile 2, Spalte 2
Zeile 2, Spalte 3
Zeile 2, Spalte 4
Icon Heft.png
Arbeitsauftrag
size(200, 200);

for( int i = 0; i < 5; i += 1 ) {
    for( int j = 0; j < 5; j += 1 ) {
        if( (i+j)%2 == 0 ) {
          fill(0);
        } else {
          fill(255);
        }
        rect(i*40, j*40, 40, 40);
    }
}
  1. Analysiere das Programm oben und erkläre seine Funktion.
    Tipps:
    • Zur Erinnerung: a%2 == 0 prüft, ob die Zahl a durch zwei teilbar ist.
    • Stell dir i als Zeilen- und j als Spaltennummer vor. Welche Quadrate werden dann wie eingefärbt?
    • Du kennst das Ergebnis schon aus Schritt 10.
  2. Pass das Programm so an, dass das Muster ein Fenster der Größe 400x400 ausfüllt.
Lösung Aufgabe 1

Das Programm zeichnet dasselbe Schachbrettmuster, wie in der Aufgabe in Schritt 10.

Lösung Aufgabe 2
size(400, 400);

for( int i = 0; i < 20; i += 1 ) {
    for( int j = 0; j < 20; j += 1 ) {
        if( (i+j)%2 == 0 ) {
          fill(0);
        } else {
          fill(255);
        }
        rect(i*40, j*40, 40, 40);
    }
}
Icon Heft.png
Arbeitsauftrag
  1. Erstelle ein Programm, dass für die Zahlen Eins bis Zehn die Produkte mit den Zahlen Eins bis Zehn ausgibt (also das kleine Einmaleins).
    1*1=1, 1*2=2, 1*3=3, ..., 1*10=10, 2*1=2, 2*2=4, 2*3=6, ..., 10*10=100
    1. Fülle eine 400x400-Pixel Große Zeichenfläche reihen- und spaltenweise mit roten Kreisen.
      Processing Kreismuster.jpg
    2. Modifiziere das Programm so, dass jede zweite Spalte grüne Kreise enthält.
      Processing Kreismuster 2.jpg
Lösung Aufgabe 1
for( int i = 1; i <= 10; i += 1 ) {
  for( int j = 1; j <= 10; j += 1 ) {
    int produkt = i*j;
    println(i+"*"+j+"="+produkt);
  }  
}
Lösung Aufgabe 2
void setup() {
  size(400, 400);
}

void draw() {
  fill(236, 48, 0);
  for ( int i = 0; i < 10; i += 1 ) {
    for ( int j = 0; j < 10; j += 1 ) {
      ellipse(20 + i*40, 20 + j*40, 30, 30);
    }
  }
}
Lösung Aufgabe 3
void setup() {
  size(400, 400);
}

void draw() {
  for ( int i = 0; i < 10; i += 1 ) {
    for ( int j = 0; j < 10; j += 1 ) {
      if ( i%2 == 1 ) {
        fill(0, 198, 48);
      } else {
        fill(236, 48, 0);
      }
      ellipse(20 + i*40, 20 + j*40, 30, 30);
    }
  }
}


Icon Heft.png
Zusatzaufgabe

Erstelle ein radiales Muster dieser Art:

Processing Kreise radial.jpg

Verwende auch hier verschachtelte Schleifen. Die erste bestimmt den Abstand zum Mittelpunkt, die zweite den Winkel. Nutze dann sin() zur Berechnung der x- und cos() für die y-Koordinate.

Tipp zur Zusatzaufgabe

Für den nullten Kreis und den Winkel 135 Grad könntest du die Koordinaten berechnen durch:

  • x: i*60*sin(radians(135))
  • y: i*60*cos(radians(135))

60 ist der Abstand zwischen zwei Ringen. Der Winkel beginnt bei 0 und zählt bis 360 hoch. Die Schrittweite wird anhand der Anzahl Kreise pro Ring bestimmt. Bei Acht Kreisen: 360 / 8 = 45.

Lösung Zusatzaufgabe
void setup() {
  size(400, 400);
}

void draw() {
  for ( int i = 0; i <= 3; i += 1 ) {
    for ( int j = 0; j < 360; j += 45 ) {
      ellipse(200+i*60*sin(radians(j)), 200+i*60*cos(radians(j)), 30, 30);
    }
  }
}