Sonntag, 10. Februar 2013

Schleifen

Hallo zusammen und herzlich willkommen bei diesem Post!

Diesmal werden wir uns mit den Schleifen in C# beschäftigen, der Name verrät ja eigentlich schon, worum es sich dabei handelt, nämlich (für die, die es noch nicht kapiert haben :-)) um eine Wiederholung einer bzw. mehrerer Anweisungen.
 
Nehmen wir uns auch hier ein einfaches Szenario und arbeiten ein Konsolenprogramm aus:

Der Benutzer muss einen Benutzernamen und ein Passwort eingeben, welches überprüft werden soll. Wenn die Eingabewerte mit einem bestimmten Wert übereinstimmen soll der Benutzer eingeben, nach wie vielen Sekunden der Computer herunterfährt. Auf der Konsole wird dann ein dementsprechender Countdown ausgegeben, danach fährt der Computer herunter.

Schreiben wir erst einmal den Code, den wir schon schreiben können:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Schleifen
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Bitte geben Sie Ihren Benutzernamen ein:");
            string benutzername = Console.ReadLine();
            Console.WriteLine("Bitte geben Sie Ihr Passwort ein:");
            string passwort = Console.ReadLine();
            if (benutzername == "XXX")
            {
                if (passwort == "1234")
                {
                    Console.WriteLine("\nSie wurden erfolgreich angemeldet!\nBitte geben Sie nun die Anzahl an Sekunden ein, nach deren Ablauf der Computer heruntergefahren werden soll:");
                    long sekunden = Convert.ToInt64(Console.ReadLine());

                    //hier muss noch Code hin
                }
                else
                {
                    Console.WriteLine("Falsches Passwort!");
                }
            }
            else
            {
                Console.WriteLine("Ungültiger Benutzername!");
            }
            Console.ReadKey();
        }
    }
}

Der Code müsste sich eigentlich mit Hilfe der letzten Posts von selbst erklären.

Wie bekommen wir es aber hin, dass ein Countdown läuft, nach dessen Ablauf wir den Computer herunterfahren können? Wir könnten natürlich 10 mal schreiben:

Console.WriteLine("10");
Thread.Sleep(1000);

Doch der Benutzer soll ja die Möglichkeit haben, einzugeben, nach wie vielen Sekunden der Computer herunterfährt. Das hieraus entstandene Problem lässt sich nur sehr begrenzt mit den bisher gelernten Anweisungen lösen. Für solche Fälle gibt es die Schleifen, und zwar gleich 4, von denen wir uns in diesem Post aber "nur" 3 anschauen möchten, da uns zu der 4. Schleifenart noch etwas Wissen fehlt.

Also los:

Die erste Schleifenform, die wohl gleichzeitig die meistgenutzte ist, ist die sog. for-Schleife.

Hier ein Beispiel:

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

Nach dem C#-Schlüsselwort for wird ein Klammernpaar geschrieben. Danach wird eine Variable, hier vom Typ int, deklariert und initialisiert. Danach folgt ein Semikolon, hinter dem ein boolescher Ausdruck steht. Solange dieser true ergibt, wird die Schleife durchlaufen. Da wir in diesem Beispiel i mit 0 initialisiert haben, ergibt der Ausdruck true, womit feststeht, dass die Schleife zumindest einmal durchlaufen wird. Doch bevor sie durchlaufen wird, wird i um 1 erhöht (dies bewirkt der Ausdruck i++, genauso könnte hier stehen i--, i + 2, i / 2,...). Danach folgen die bekannten geschweiften Klammern, zwischen denen die Anweisungen stehen, die im Schleifendurchlauf ausgeführt werden sollen. Falls hier nur eine Anweisung steht, können die geschweiften Klammern, wie bei der if-Anweisung, weggelassen werden.

Sobald die Schleife einmal durchlaufen ist, wird wieder zum for gesprungen. Die erste Anweisung wird nicht mehr ausgeführt (int i = 0), da sonst eine Endlosschleife entstehen würde und die Anweisung keinen Sinn machen würde. Doch wieder wird der boolesche Ausdruck ausgewertet. Ergibt er false, wird der Rest der Schleife übersprungen, andernfalls wird wieder i um 1 erhöht und die Schleifenanweisungen werden ausgeführt. Dies setzt sich so lange fort, bis der boolesche Ausdruck false ergibt. In diesem Beispiel wird die Schleife also 10 mal ausgeführt.

Natürlich kann auch ein anderer Datentyp genutzt werden. Auch muss dieser nicht in der for-Schleife deklariert werden, sondern kann auch schon davor existieren. Nur initialisiert werden muss er in der for-Schleife neu.

Eine Endlosschleife erreicht man beispielsweise, in dem man das < durch ein > und die 10 durch eine 0 ersetzt, denn hier ergibt der boolesche Ausdruck immer true.

Natürlich kann auch vor dem ersten Durchlauf der boolesche Ausdruck false ergeben. In diesem Fall

wird die Schleife kein einziges Mal durchlaufen/ausgeführt.

Nun bauen wir unser neues Wissen in den Programmcode ein. Dazu fügen wir hinter der Anweisung

long sekunden = Convert.ToInt64(Console.ReadLine());

folgendes ein:

for (int i = 0; sekunden != i; sekunden--)
{
       Console.WriteLine("Noch " + sekunden + " Sekunden bis zum Herunterfahren...");
       Thread.Sleep(1000);
}
System.Diagnostics.Process.Start(System.Environment.SystemDirectory + "\\shutdown.exe", "-s -t 0");

Näheres über den letzten Befehl, der den Computer herunterfährt, erfahrt ihr hier.

Was passiert hier? Wir erstellen uns wieder eine Schleife, die Zählvariable (i) ist wieder 0. Die Schleife läuft, solange die Variable "sekunden", die die vom Benutzer ausgewählte Zeit in Sekunden bis zum Herunterfahren des PCs repräsentiert, ungleich i ist (!= bedeutet ungleich).

Bei jedem Schleifendurchlauf wird nun "sekunden" um eins verringert, solange, bis sekunden = i und damit gleich 0 ist.

Bei jedem Schleifendurchlauf wird die Anzahl der Sekunden bis zum Herunterfahren ausgegeben. Dabei wird die Variable "sekunden", deren Wert ja in jedem Schleifendurchlauf um 1 verringert wird, dazu benutzt, die richtige Anzahl an Sekunden auszugeben. Danach wird der Thread 1 Sekunde lang angehalten (Achtung: using System.Threading; nicht vergessen!). Wenn die Schleife fertig durchlaufen wurde, wird der PC heruntergefahren.


Wie oben schon erwähnt, ist die for-Schleife nur eine der insgesamt 4 Schleifenarten. Eine weitere ist z. B. die sog. while-Schleife, die folgenden Aufbau hat:

while (true)
{
    //Anweisungen
}

Hier steht nach dem C#-Schlüsselwort while in Klammern ein boolescher Ausdruck. Solange dieser true ergibt (was hier der Fall ist), wird die Schleife durchlaufen. Der Ausdruck wird vor jedem Schleifendurchlauf ausgewertet. Diese Schleife wird z. B. verwendet, wenn in der Schleife der zu überprüfende boolesche Wert z. B. aufgrund einer Veränderung verändert wird. Auch Endlosschleifen lassen sich (wie oben gezeigt) sehr einfach erzeugen, was z. B. in der Spieleprogrammierung genutzt wird. Zu beachten ist hier allerdings, dass der boolesche Ausdruck nur mit Variablen funktioniert, die auch außerhalb der geschweiften Klammern der while-Schleife deklariert und initialisiert sind.

Doch was macht man nun, wenn sichergestellt sein muss, dass die while-Schleife mindestens einmal durchlaufen werden muss (was ja nicht zwangsweise der Fall sein muss)? Dazu gibt es die sog. do-while-Schleife, deren Name schon auf die große Ähnlichkeit zur while-Schleife deutet. Sie funktioniert im Prinzip auch gleich wie die while-Schleife, nur dass der boolesche Ausdruck erst nach Schleifendurchlauf ausgewertet wird:

do
{
       //Anweisungen
}
while (true);

Auch hier ist eine Endlosschleife dargestellt.

Die vierte und letzte Schleifenart sehen wir uns nächstes Mal an, nämlich, wenn es um Arrays geht.

Bis dahin,
Julian