Programmieren lernen Kapitel 5 Schleifen

Tutorials zu verschiedenen Softwarenutzungen

Moderator: Moderatoren

Benutzeravatar
Jaegerfeld
Tribunus Angusticlavius
Tribunus Angusticlavius
Beiträge: 3571
Registriert: 10. November 2010 21:15
Wohnort: AudiCity
:
Pfeiler der Community Gewinner Userwahl

Programmieren lernen Kapitel 5 Schleifen

Beitragvon Jaegerfeld » 11. Dezember 2010 15:51


Kapitel 5
Schleifen

In diesem Kapitel wollen wir das Grundlagentraining abschließen indem wir uns mit Schleifen beschäftigen.

Bisher haben wir ja das Problem, dass sich unser Programm nach einem Durchlauf selbst beendet (terminiert).

Das ist für ein Spiel(und darum geht es uns ja) natürlich selten dämlich. Ein Frame hat ja nur ca. 17 Millisekunden, und das wäre dann schon ein SEHR kurzes Spiel.
Wir benötigen also einen Mechanismus, der uns in die Lage versetzt bestimmte Codestücke immer wieder zu durchlaufen.

Zum Glück gibt es deren gleich vier:


While

While ist mal wieder Englisch und bedeutet soviel wie " Während" oder auch "so lange".

Das beschreibt die Funktionsweise schon recht schön. Wenn wir

Code: Alles auswählen

bool bedingung;

while( bedingung )

{

// mache ganz viel;

}

schreiben, bedeutet dies:

mache das was in den geschweiften Klammern steht so lange das was in den runden Klammern steht wahr ist.

Sobald bedingung also false wird, hört die Schleife auf.
Als Bedingung können wir alles nehmen, was in irgendeiner Form vergleichbar ist.
also auch while(1+1 == 3) zum Beispiel. Das ist natürlich Unsinn, denn diese Aussage ist IMMER false.
Beliebt sind Scheifen, die zum Beispiel definiert 10 mal durchlaufen werden.
Dazu nutzt man einen schönen Mechanismus, der sich Inkrement/Dekrement nennt.

Der Ausdruck :

Code: Alles auswählen

int a = 0;
a++:

bedeutet:

  • Wir haben eine Variable vom Typ int, die nennt sich a und hat den Wert 0.
  • Erhöhe a um eins.

a++ ist also nichts anderes als a = a+1;
Nette Abkürzung, Programmierer sind faule Hunde.

Dasselbe geht auch mit Minus.
a-- bedeutet also nichts anderes als a= a-1;

Dabei macht es einen Unterschied, ob man a++ oder ++a schreibt.

BEIDES erhöht a um eins. Bei a++ wird allerdings zuerst der Wert von a ausgelesene und dann um eins erhöht, ++a funktioniert genau anders herum.

int a = 0;

int b = a++ + 1; ergibt a == 1 und b == 1

int b = ++a +1; ergibt a == 1 und b == 2

Prinzip verstanden?

Diesen Mechanismus können wir uns zunutze machen.

Code: Alles auswählen

int i = 10;
while ( i > 0)
{
  // was wir machen wollen und zum Schluss
  i--;
}


Diese Schleife wird also 10 mal durchlaufen, danach ist i>0 falsch und die Schleife endet.
Wenn wir mehrere Bedingungen kombinieren wollen, können wir auch mehrere Abfragen machen.
Dafür nutzen wir boolsche Logik. Das sind so tolle Sachen wie

UND(&&), ODER(||), NICHT(!).

Wenn wir in eine Schleife wollen, wenn i > 2 UND j == 2 ist, können wir das wie folgt abfragen:


Code: Alles auswählen

while ( i > 2 && j == 2)


Wer jetzt nichts mit den drei boolschen Verknüpfungen anfangen kann, hier eine schnelle Erklärung:

&& bedeutet nichts anderes als das umgangssprachliche UND. Es muss also jede einzelne Bedingung wahr sein, damit das Gesamtergebnis wahr ist. 1==1 && 2 ==3 ist also FALSCH

|| ist da schon schwieriger zu fassen, es bedeutet ODER, aber nicht das umgansprachliche ENTWEDER ODER, sondern das logische Oder.
Es ist wahr, wenn EINE der Bedingungen wahr wird oder BEIDE.

1==1 || 2==3 ist also WAHR
1==1 || 2==2 ist auch WAHR
1==3 || 2==4 ist FALSCH

! ist die Negation,die wir schon kennengelernt haben. Sie dreht die Bedeutung einer Aussage um.

!(2 == 3) ist also WAHR.

Die Pipes | sind übrigens über Alt GR und < zu erreichen (links neben y) :-)

DO WHILE

Manchmal will man etwas auf jeden Fall einmal machen und wenn dann eine bestimmte Bedingung erfüllt ist, öfter.
dafür gibt es die do while schleife. Sie funktioniert ganz ähnlich der while.

Code: Alles auswählen

do
{
  //das was wir machen wollen
}
while( bedingung);


Der Code in der geschweiften Klammer nach dem do wird einmal ausgeführt und wenn bedingung true ist, öfter.

Sehr logisch, oder?
FOR

Oben haben wir gesehen, wie man eine zählende Schleife machen kann, es gibt hierfür aber sogar ein eigenes Konstrukt, die FOR Schleife.
Sie sieht z.B. so aus:

Code: Alles auswählen

for( int i = 0; i < 10; i++)
{
  // mache was
}

Die Schreibweise ist also völlig anders, aber trotzdem sehr einfach.
Die Klammer nach dem Schlüsselwort for hat drei Bestandteile, jeweils durch ein ; getrennt.

  • Initialisierung der Zählvariable
  • Bedingung
  • Was geschieht nach einem Durchlauf.
Im obigen Beispiel bedeutet dies folgendes:
  • Unser Zähler ist eine int und nennt sich i (i ist der absolute Lieblingsnahme für Zählvariablen, hat sich so eingebürgert), sie hat den Anfangswert 0;
  • Wir wollen die Schleife so lange durchlaufen bis i größer 10 ist.
  • Wenn wir einen Durchlauf geschafft haben, setzten wir den Wert von i um eins hoch.

while und for Schleifen sind übrigens austauschbar, alles was man mit for machen kann geht auch mit while und umgekehrt.
Jeder darf die Variante nehmen die einem besser gefällt. Der Compiler macht im Hintergrund sowieso sein eigenes Ding daraus.

Seit relativ kurzer Zeit (paar Jahre) gibt es auch noch eine vierte Schleife:

FOREACH

Das ist ein zusammengesetztes Wort und bedeutet soviel wie "für jedes".

Hiermit kann man sehr elegant Sammlungen (Collections) von Daten durchlaufen, vom ersten Datum (Einzahl von Daten, NICHT der Tag ;-) ) bis zum letzten.

Sowas benötigt man öfter als man denkt und bisher war das sehr mühsam. Collections haben wir zwar noch nicht besprochen, aber für jetzt reicht es wenn ihr wisst dass es mehrere Möglichkeiten gibt Daten zu "speichern".
Man kann sich das wie einen großen Aktenordnervorstellen, in dem jede Seite ein bestimmter Eintrag ist.
Typischer Vertreter der Collections ist die Liste. Das ist nichts anderes als eine Aneinanderreihung von Daten. Ein Datum nach dem anderen.

Wir stellen uns mal ein einfaches Namensverzeichnis vor. Das könnte einfach eine Liste aus Namen sein.
Wenn man jetzt wissen will, ob ein bestimmter Name in der Liste vorhanden ist, muss man sich jeden Eintrag ansehen und überprüfen ob er mit dem gesuchten übereinstimmt.

Das geht ganz einfach:

Code: Alles auswählen

foreach( string eintrag in Liste)
{
  //vergleiche
}


Wir sagen in der Klammer einfach nach was (string eintrag) und wo (in Liste) wir suchen.
Die Schleife wird dann so lange durchlaufen, bis der Rechner am Ende der Liste angekommen ist. SEHR nützlich.
Einziger Wermutstropfen: Ihr dürft KEINEN Eintrag löschen während die Liste durchlaufen wird. Der Iterator (Das Ding welches intern durch die Liste läuft) würde durcheinander kommen, was zu einem Absturz führt. Dafür gibts dann aber auch andere Tricks.



Das wars auch schon, was man über die Schleifenwissen muss. Natürlich ist da noch mehr aber für euch reicht 's erst mal.

Dann wollen wir das mal auf unseren Rechner anwenden:
Um immer wieder zum Menü zurückzukehren, umschließen wir den ganzen Code in der main Methode einfach mit einer while Schleife.
In der Bedingung fragen wir einfach einen Wahrheitswert ab, un sobald der false wird endet das Programm.
Um das Programm zu beenden fügen wir abschließend noch einen fünften Menüpunkt "Beenden" ein.

Sieht bei mir so aus:

Code: Alles auswählen

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Taschenrechner
{

 class Program
 {
   static bool running = true;
   static void Main(string[] args)
 {

   while (running)
 {
   Console.WriteLine("1 - Addition \n2 - Subtraktion \n3 - Multiplikation \n4 - Division \n5 - Beenden");
   string inputString = Console.ReadLine();
   string a, b;
   double c;
   switch(inputString)
 {
 case "1":
   Console.WriteLine("Addition");
   Console.WriteLine("Bitte ersten Operand eingeben: ");
   a = Console.ReadLine();
   Console.WriteLine("Bitte zweiten Operand eingeben: ");
   b = Console.ReadLine();
   c = addition(Convert.ToDouble(a), Convert.ToDouble(b));
   Console.WriteLine(a + "+" + b + " = " + c);
   break;

 case "2":
   Console.WriteLine("Substraktion");
   Console.WriteLine("Bitte ersten Operand eingeben: ");
   a = Console.ReadLine();
   Console.WriteLine("Bitte zweiten Operand eingeben: ");
   b = Console.ReadLine();
   c = substraktion(Convert.ToDouble(a), Convert.ToDouble(b));
   Console.WriteLine(a + "-" + b + " = " + c);
   break;

 case "3":
   Console.WriteLine("Multiplikation");
   Console.WriteLine("Bitte ersten Operand eingeben: ");
   a = Console.ReadLine();
   Console.WriteLine("Bitte zweiten Operand eingeben: ");
   b = Console.ReadLine();
   c = multiplikation(Convert.ToDouble(a), Convert.ToDouble(b));
   Console.WriteLine(a + "*" + b + " = " + c);
   break;

 case "4":
   Console.WriteLine("Division");
   Console.WriteLine("Bitte ersten Operand eingeben: ");
   a = Console.ReadLine();
   Console.WriteLine("Bitte zweiten Operand eingeben: ");
   b = Console.ReadLine();
   c = division(Convert.ToDouble(a), Convert.ToDouble(b));
   Console.WriteLine(a + "/" + b + " = " + c);
   break;

 case "5":
   running = false;
   break;

 default:
   Console.WriteLine("ungültige Menüauswahl - erneut wählen!");
   break; 
 }
 }



 }

 static double addition(double a, double b)
 {
   return a + b;
 }
static double substraktion(double a, double b)
 {
   return a - b;
 }
static double multiplikation(double a, double b)
 {
   return a * b;
 }
 static double division(double a, double b)
 {
   return a / b;
 }

 }
}


Die Bedingung bool running habe ich außerhalb der main definiert, sie muss static sein. Einfach hinnehmen, ich erkläre das mit dem static bald. Versprochen!

Hiermit endet unser kleiner Ausflug in die Konsolenwelt. Im nächsten Kapitel werden wir eine hübsche GUI (grafische Benutzeroberfläche) erstellen. Wenn das dann sitzt gehts an das Spiel. Übt also fleissig, alles was wir bisher gemacht haben werden wir ständig brauchen.
„Ich schätze mal, das kann jeder Online-Community passieren. Irgendwann stellen die höflichen und vernünftigen Leute fest, dass sie sich in dieser Gruppe nicht mehr aufhalten wollen. Also verschwinden die. Und diejenigen die übrig bleiben, erfahren nur noch die Leute die genau so wie sie drauf sind.“

=== David Gaider, Bioware ===