Perl 6

Die Zukunft des Programmierens

If - Bedingte Anweisungen

Alle bisherigen Programme liefen immer gleich ab, egal was eingegeben wurden. Immer wurden sie von Oben nach Unten, Zeile für Zeile, ausgeführt.

Das ändert sich jetzt, mit der if-Anweisung (Englisch für "ob" oder "wenn")

Hier ist ein kleines Programm, das eine Zahl von der Tastatur einliest, und die Wurzel berechnet und ausgibt:

use v6;

my $zahl = $*IN.get;
say sqrt $zahl;

Das einzig neue daran ist die Funktion sqrt, (Englisch square root = Quadratwurzel), die die Wurzel von $zahl berechnet.

Das Programm funktioniert auch wie erwartet, aber was passiert, wenn man eine negative Zahl eingibt? Mit ein bisschen mathematischer Vorbildung weiss man, dass man die Wurzel einer negativen Zahl nicht berechnen kann. Tatsächlich kommt als Ergebnis NaN heraus, das steht für "Not a Number", Englisch für "Keine Zahl".

Es wäre ein wenig schöner, wenn man den Benutzer darauf hinweisen könnte, dass seine Eingabe sinnlos ist. Und in der Tat geht das:

use v6;

my $zahl = $*IN.get;
if $zahl < 0 {
    say "Kann keine Wurzel aus negativen Zahlen ziehen";
} else {
    say sqrt $zahl;
}

Wenn man das Programm ausführt und eine positive Zahl eingibt, wird weiterhin die Wurzel berechnet und ausgegeben, bei einer negativen Zahl wird der Text Kann keine Wurzel aus negativen Zahlen ziehen ausgegeben.

Wie ging das? Die Antwort ist, dass das if dafür verantwortlich ist.

Die allgemeine Form sieht so aus:

if bedingung {
    anweisung1a;
    anweisung1b;
    ...
} else {
    anweisung2a;
    ...
}

Das funktioniert folgendermaßen: Wenn die Bedingung wahr ist, werden die Anweisungen im ersten Block, also anweisung1a; anweisung1b; ... ausgeführt, sonst wird der zweite Block (also anweisung2a, ...) ausgeführt.

Eine Bedingung haben Sie schon gesehen: $zahl < 0, auf Deutsch "Wenn $zahl kleiner als 0 ist".

Andere mögliche Vergleiche sind == für "ist gleich", > für "größer als", >= für "größer oder gleich", <= für "kleiner oder gleich" und != für "ungleich".

Man stelle sich das Programm eines Geldautomaten vor:

my $pin = 1234;
my $guthaben = 655.36;

say "Geben Sie ihre PIN ein:";
my $pin_eingabe = $*IN.get;

if $pin == $pin_eingabe {
    say "Geben Sie den Betrag ein, den Sie abheben wollen:";
    my $auszahlung = $*IN.get;
    if ($auszahlung <= $guthaben) {
        say "Nehmen Sie die $auszahlung Euro mit...";
        $guthaben = $guthaben - $auszahlung;
    } else {
        say "So viel haben Sie nicht auf dem Konto";
    }
} else {
    say "PIN falsch, Karte wird einbehalten";
}

Nicht zurückschrecken, das Programm ist einfacher als es aussieht, und wird im Detail erklärt.

Am Anfang wird der Benutzer nach seiner PIN gefragt, und seine Eingabe wird in der Variablen $pin_eingabe gespeichert.

Dann kommt die erste Kreuzung in dem Programm:

 if $pin == $pin_eingabe {

Hier wird überprüft, ob die gespeichert PIN in der Variablen $pin mit der eingegeben Zahl übereinstimmt. Wenn die beiden nicht übereinstimmen, wird der Text PIN falsch, Karte wird einbehalten ausgegeben. Aber was passiert, wenn die Eingabe richtig war?

Dann wird folgender Code ausgeführt:

    say "Geben Sie den Betrag ein, den Sie abheben wollen:";
    my $auszahlung = $*IN.get;
    if ($auszahlung <= $guthaben) {
        say "Nehmen Sie die $auszahlung Euro mit...";
        $guthaben = $guthaben - $auszahlung;
    } else {
        say "So viel haben Sie nicht auf dem Konto";
    }

D.h. erst wird der Benutzer aufgefordert, eine Zahl einzugeben. Dann wird überprüft, ob er genug Geld auf dem Konto hat, um den gewünschten Betrag abzuheben. Wenn das der Fall ist, wird er aufgefordert, das Geld herauszunehmen (Perl-Programme können leider kein Geld ausspucken, sonst wären wir schon alle reich...), und der Kontostand wird auf um den Betrag der Auszahlung verringert.

Falls er nicht genug Geld auf dem Konto hat, kommt die Nachricht So viel haben Sie nicht auf dem Konto.

Man kann verschiedene if-Strukturen also auch verschachteln.

Vergleich von Strings

Folgendes Programm sieht dem vorherigen relativ ähnlich, es ist sogar einfacher:

use v6;
# Vorsicht, mit Vorbehalt zu genießen!
my $passwort = "Geheim123";
my $eingabe = $*IN.get;

if $passwort == $eingabe {
    say "Passwort Korrekt, willkommen Chef";
}

Wenn man das Programm startet, und das richtige Passwort eingibt, wird man entsprechend begrüßt - so weit, so gut.

Aber wenn man ein falsches Passwort eingibt - dann leider auch.

Was geht hier vor?

Die Antwort ist, dass wir zwei Variablen mit dem Operator == vergleichen. Und == erwartet Zahlen, um sie miteinander zu vergleichen.

Das Passwort z.B. ist keine Zahl, sondern ein String. Also macht Perl automatisch aus dem String eine Zahl - und zwar 0.

Das gleiche passiert mit der Eingabe, d.h. wenn die Eingabe nicht als Zahl anfängt, wird sie auch zur 0 verwandelt, und 0 == 0 ist wahr. Deswegen funktioniert das Programm oben nicht so wie erwartet.

Doch was kann man stattdessen machen?

Die Antwort ist, das Perl eine eigene Art hat, Strings zu vergleichen:

use v6;
# so ist es richtig
my $passwort = "Geheim123";
my $eingabe = $*IN.get;

if $passwort eq $eingabe {
    say "Passwort Korrekt, willkommen Chef";
}

Anstelle von == steht jetzt ein eq, kurz für "equal", Englisch für "gleich".

Es gibt für jeden numerischen Vergleich einen entsprechenden Vergleich für Strings:

NumerischStringHerkunftBedeutung
== eq equal gleich
!= ne not equalungleich
< lt less thankleiner
> gt greater thangrößer
<= le less or equalkleiner oder gleich
>= ge greater or equalgrößer oder gleich

Niemand erwartet von einem Anfänger, diese Operatoren alle auswendig zu können, man sollte sich nur merken dass es für den Vergleich von Strings andere gibt als für den Vergleich von Zahlen, und vielleicht noch dass sie aus zwei Buchstaben bestehen.