Woche 1

# Tag 2

#
Mit Strings und Zahlen arbeiten

Skalar ist ein besonderer Perl-Begriff für einen einzelnen Wert, ganz egal ob es sich dabei um eine Ziffer oder einen String (Zeichenfolge) handelt - solange es nur ein Wert ist, ist es ein Skalar. In diesem Kapitel lernen Sie, was es mit skalaren Daten und Variablen auf sich hat. Und ich werde Ihnen verschiedene Operatoren und Funktionen zur Arbeit mit Skalaren vorstellen. All dies gehört zu den wesentlichen Grundbausteinen eines Perl-Skripts.

Die Themen von heute sind:

- Zahlen und Strings
- Skalarvariablen: Definition, Verwendung und Wertzuweisung
- Einfache Berechnungen
- Vergleiche und Überprüfungen

## Skalare Daten und Variablen

Perls Datentypenkonzept ist ziemlich flexibel: Anders als Sprachen wie C oder Java, mit ihren getrennten Typen für Integer (ganze Zahlen), Zeichen, Fließkommazahlen und so weiter (und strengen Regeln für Verwendung und Konvertierung dieser Datentypen) unterscheidet Perl lediglich zwischen zwei generellen Sorten von Daten - dafür aber nach einem ganz anderen Kriterium: Einzahl oder Mehrzahl, Singular oder Plural. Einzelne Werte wie eine Zahl oder eine Zeichenfolge sind skalare Daten. Mehrere Werte zusammen, Sammlungen von Werten wie zum Beispiel Arrays, heißen Listen. Ob diese Listen wiederum nur aus Zahlen, nur aus Strings oder einem Mischmasch aus beidem bestehen, ist nicht so wichtig. Die Unterscheidung zwischen Skalaren und Listen hingegen spielt eine große Rolle. Einige Konstrukte in Perl verhalten sich ganz unterschiedlich, je nachdem ob Sie mit Skalaren oder Listen arbeiten. Heute allerdings bleiben wir erst einmal bei einfachen Zahlen und Strings und den Variablen dafür. Die Listendaten heben wir uns für später auf; der Unterschied ist dann auch einfacher zu verstehen.

> Während ich heute ausschließlich von Zahlen und Strings als skalaren Daten rede, gibt es noch eine dritte Form: Referenzen sind auch eine Form von skalaren Daten. Aber Sie brauchen so früh in Ihrem Perl-Studium noch nichts über Referenzen zu wissen; deswegen werde ich sie jetzt erst einmal ignorieren. Mit Referenzen befassen wir uns viel später, am Tag 19.

### Zahlen

Zahlen können Sie in Ihren Perl-Skripts eigentlich eintippen, wie Sie möchten. Beachten Sie nur, dass in Perl (wie im Englischen überhaupt) statt des Kommas ein Punkt geschrieben wird - 0,5 heißt auf Englisch 0.5. Dies alles sind gültige Zahlen in Perl:

    4
    3.2
    0.2
    .23434234
    5.
    7.0
    1_123_456
    10E2
    45e-4
    0xbeef
    012

Integer- und Fließkommazahlen werden beide so dargestellt, wie man es gewohnt ist: Integerzahlen mit ganzen Zahlen, Fließkommazahlen mit einem Integer- und einem Dezimalteil, nur wie gesagt durch einen Punkt getrennt. Kommas sind nicht erlaubt. Bei Fließkommazahlen können Nullen vor oder nach dem Punkt weggelassen werden (statt `0.23434234` kann man also auch `.23434234` schreiben bzw. `5.` statt `5.0`). Die Unterstriche in `1_123_456` sind eine optionale Schreibweise für längere Zahlen (so wie wir lange Zahlen mit Punkten in Dreiergruppen aufteilen) und dienen allein der Lesbarkeit im Skript. (Die Unterstriche werden aus der Zahl entfernt, sobald sie ausgewertet wird - aber nur, wenn die Zahl direkt im Skript steht. Wenn sie irgendwie anders ins Skript eingelesen wird, funktioniert diese Umwandlung nicht. Als Benutzer kann man also nicht `1_123_456` an der Tastatur eingeben.) Exponenten werden durch ein großes oder kleines e eingeleitet, auf das der positive oder negative Exponent folgt. Hexadezimale Zahlen beginnen mit `0x` und oktale mit einer 0 (Null).

Perl unterscheidet nicht zwischen Integer- und Fließkommazahlen, signed und unsigned oder kurzen oder langen Zahlen. Eine Zahl ist ganz einfach immer skalar, und Perl konvertiert zwischen den Zahlentypen in Ihren Skripts je nach Bedarf.

### Strings

Es scheint vielleicht etwas eigenartig, dass Strings skalare (einzelne) Daten sein sollen, wo ein String doch eine Folge von Buchstaben ist und in anderen Sprachen eigentlich in Arrays gespeichert wird. Aber Perl ist anders. In Perl sind Strings einfach eine Form von skalaren Daten.

Strings können auf zwei Arten dargestellt werden: als kein oder mehr Zeichen zwischen einfachen Anführungszeichen (`' '`) oder doppelten Anführungszeichen (`" "`), zum Beispiel:

    'das hier ist ein String'
    "das hier ist auch ein String"
    ""
    "$fahr Grad Fahrenheit sind $cel Grad Celsius"
    "Hallo, Welt!\n"

Strings können jede Art von ASCII-Daten enthalten, auch binäre Daten (hohe und niedrige ASCII-Zeichen). Allerdings enthalten Text-Strings häufig nur niedrige ASCII- Zeichen (normale Buchstaben, keine Akzente oder Sonderzeichen). Strings können beliebig lang sein. Die Länge Ihres Strings ist nur durch die Größe des Ihnen zur Verfügung stehenden Speichers begrenzt. Obwohl es eine Weile dauern und ziemlich viel Speicher fressen würde, das Gesamtwerk von Shakespeare oder einen 10- Megabyte-Unix-Kernel in einen einzigen Perl-String zu lesen, könnten Sie das sicherlich machen.

Es gibt zwei Unterschiede zwischen Strings in einfachen Anführungszeichen (auch single-quoted Strings genannt, quote ist englisch für Anführungszeichen, und was ein Single ist, brauche ich wohl nicht zu erklären) und denen in doppelten (double- quoted Strings). Zum einen führt Perl auf einem String in doppelten Anführungszeichen Variableninterpolation aus: Das heißt, jeder Variablenname innerhalb der Anführungszeichen (wie `$fahr` und `$cel` in dem obigen Beispiel) wird durch die aktuellen Werte dieser Variablen ersetzt. Ein String in einfachen Anführungszeichen wie `'`$fahr Grad Fahrenheit sind $cel Grad Celsius`'` wird genau so ausgegeben, wie Sie es hier sehen, mit den Dollarzeichen und Variablennamen an Ort und Stelle. Wenn Sie wirklich ein Dollarzeichen in einem double-quoted String haben möchten, müssen Sie einen Backslash (umgekehrten Schrägstrich) davorsetzen: `"ein Doppelzimmer kostet pro Nacht \$14 Dollar"`.

> Variableninterpolation funktioniert auch mit Strings, die Listenvariablen enthalten. Sie lernen mehr darüber an Tag 4, »Mit Listen und Arrays arbeiten«.

Der zweite Unterschied zwischen doppelten und einfachen Anführungszeichen ist, dass double-quoted Strings auch die in Tabelle 2.1 gezeigten Escape-Sequenzen interpolieren. Diese werden Ihnen vertraut vorkommen, wenn Sie C kennen; allerdings gibt es auch einige andere Escape-Sequenzen speziell für Perl. In single- quoted Strings werden Escape-Sequenzen größtenteils ausgegeben, wie sie eingetippt wurden: So wird aus `'Hallo Welt!\n'` dann `Hallo Welt!\n`, ohne Zeilenvorschub. Diese Regel hat zwei Ausnahmen: Mit `\'` und `\\` können Sie Anführungszeichen bzw. Backslashes in single-quoted Strings schreiben:

    'Dies ist Laura\'s Skript'                # Ausgabe: Dies ist Laura's Skript
    'Die Eingaben stehen in C:\\files\\input'
    # Ausgabe: Die Eingaben stehen in C:\files\input'

Zeichen | Bedeutung
--- | ---
`\n` | Zeilenvorschub (newline)
`\r` | Wagenrücklauf (carriage return)
`\t` | Tabulator
`\f` | Seitenvorschub (formfeed)
`\b` | Rückschritt (backspace)
`\a` | Alarm (bell)
`\e` | Escape-Zeichen (ESC)
`\0nn` | Oktal (`nn` sind Ziffern), (`\033` ist zum Beispiel ESC in Oktal)
`\xnn` | Hexadezimal (`nn` sind 0-9, a-f oder und A-F) (`\x7f` ist zum Beispiel DEL in Hexadezimal)
`\cX` | Steuerungszeichen (control characters), wobei X ein beliebiger Buchstabe ist (zum Beispiel ist \`cC` äquivalent mit `[Ctrl]`-`[C]` bzw. `[Strg]`-`[C]` auf deutschen Tastaturen)
`\u` | Großbuchstabe (uppercase), macht aus dem nächsten Buchstaben einen Großbuchstaben
`\l` | Kleinbuchstabe (lowercase), macht aus dem nächsten Buchstaben einen Kleinbuchstaben
`\U` | macht aus allen folgenden Buchstaben Großbuchstaben
`\L` | macht aus allen folgenden Buchstaben Kleinbuchstaben
`\Q` | Vor alle folgenden nichtalphanumerischen Zeichen wird ein Backslash gestellt (damit sie nicht mehr als Metazeichen betrachtet werden)
`\E` | Beendet `\U, \L` und `\Q`

Tabelle 2.1: Escape-Sequenzen für Strings

> Wir werden uns am Ende dieses Kapitels im Vertiefungsabschnitt mit `\u`, `\l`, `\U`, `\L` und `\E` befassen.

Leere Strings, das sind Strings ohne irgendein Zeichen, werden einfach mit zwei direkt aufeinanderfolgenden Anführungszeichen dargestellt. Beachten Sie, dass der Leerstring `"" (ohne Inhalt = leer)` nicht dasselbe ist wie ein String aus einem Leerzeichen (`" "`).

Was sollten Sie nun in einem Perl-Skript verwenden, double- oder single-quoted Strings? Das hängt ganz davon ab, was Sie mit dem String machen wollen. Wenn Sie Escape-Sequenzen und Variableninterpolation brauchen, nehmen Sie einen double- quoted String. Wenn Sie einen String mit einer Menge Dollarzeichen haben (zum Beispiel aktuelle Dollarsummen), nehmen Sie vielleicht lieber einen single-quoted String.

### Konvertieren zwischen Zahlen und Strings

Weil sowohl Zahlen als auch Strings skalar sind, müssen Sie nicht explizit zwischen beiden hin- und herkonvertieren, sie sind austauschbar. Je nach Kontext wandelt Perl einen String automatisch in eine Zahl um und umgekehrt. So könnte zum Beispiel der String `"14"` zur Zahl 5 addiert werden, und das Ergebnis wäre die Zahl 19.

Das klingt anfangs vielleicht etwas komisch, aber es macht Dinge wie Ein- und Ausgabe sehr leicht. Sie brauchen eine über Tastatur eingegebene Zahl? Lesen Sie einfach ein, was getippt wurde, und verwenden Sie es dann als String. Sie brauchen kein scanf oder eine andere Funktion um alles vor- und zurückzukonvertieren. Perl macht das für Sie.

> Es gibt eine Ausnahme von der automatischen Konvertierung in Perl: Strings, die Oktal- oder Hexadezimalzahlen zu enthalten scheinen. Die Formate `0123` und `0xabc`, die Sie im Abschnitt über Zahlen kennengelernt haben, gelten nur für Zahlen, die Sie wirklich in Ihren Code tippen (in der Computerfachsprache Literale genannt). Von der Tastatur oder anderen Strings übergebene Strings in oktaler oder hexadezimaler Notation werden nicht automatisch in Zahlen umgewandelt. Das müssen Sie mit der Funktion `oct` dann selber machen:

>     $zahl = '0x432';
>     print $zahl;      # Ausgabe: 0x432
>     $hexnum = oct $zahl;
>     print $hexnum;   # Ausgabe: 1074 (dezimales Äquivalent)
>     $zahl = '0123';
>     print (oct $zahl);  # Ausgabe: 83

> Die Funktion `oct` kann aus dem Kontext schließen, ob der String eine Oktal- oder Hex-Zahl ist. Sie können auch die Funktion `hex` verwenden, allerdings nur für Hex-Zahlen.

Perl interpretiert auch scheinbar unsinnige Anweisungen wie `"foo" + 5` oder `"23skidoo" + 5`. In der ersten Anweisung wird der String zu 0 umgewandelt, und in der zweiten Anweisung wird 23 aus dem String verwendet und zu 5 addiert. Wenn Sie Perl-Warnungen (mit der Option -w oder Skripts-->Compiler Warnings in MacPerl) aktiviert haben, wird Perl sich allerdings über derartige Vorgänge beschweren, und das soll es ja auch.

### Skalarvariablen

Skalare Daten werden in Skalarvariablen gespeichert. Skalarvariablen haben in Perl ein Dollarzeichen (`$`) am Anfang, gefolgt von einem oder mehreren alphanumerischen Zeichen oder Unterstrichen, wie zum Beispiel:

    $i
    $laenge
    $Zinsen_im_Jahr
    $max
    $a56434

Die Regeln für gültige Variablennamen (für jede Perl-Variable, nicht nur Skalarvariablen) sind folgende:

- Das erste Zeichen nach dem `Präfix $` sollte ein Buchstabe des Alphabets oder ein Unterstrich sein. Umlaute (`ä`, `ö`, `ü`) und `ß` sind Sonderzeichen und nicht erlaubt. Andere Zeichen wie Ziffern oder Sonderzeichen wie `%`, `*` und so weiter sind in der Regel für spezielle Perl-Variablen reserviert.
- Nach diesem Zeichen (also ab dem dritten Zeichen) können Variablennamen alle anderen Buchstaben des Alphabets, Zahlen und Unterstriche enthalten (auch hier dürfen keine Umlaute und kein `ß` stehen).
- Variablennamen unterscheiden Groß- und Kleinschreibung - das heißt `$var` ist eine andere Variable als `$VAR` oder `$Var`.
- Variablennamen dürfen insgesamt höchstens 256 Zeichen lang sein. Nach dem Anfangs-`$` können Sie also noch 255 Zeichen verwenden, wenn Sie lustig sind (ich persönlich bekomme Kopfschmerzen, wenn ich mir so lange Variablennamen vorstelle, aber hey, wenn Ihnen das Spaß macht, nur zu).

Sie müssen Variablen in Perl nicht deklarieren oder initialisieren. Sie können sie verwenden, wie Sie sie brauchen. Skalarvariablen ohne Anfangswert haben den undefinierten Wert, und der braucht Ihnen keine Sorgen zu machen - er wird immer entweder ein Leerstring oder ein Nullwert sein, je nachdem, wo Sie ihn benutzen (das ist wieder dieses Austauschbarkeits-Feature). Dennoch sollten Sie Ihre Variablen explizit initialisieren. Das gehört zum guten Umgangston in einer Programmiersprache. So wird Perl, wenn Sie die Warnungen eingeschaltet haben, undefinierte Variablen höflich bemäkeln.

> Ich plaudere hier einfach so über den undefinierten Wert. Im Augenblick müssen Sie darüber nicht viel wissen. Später (genauer gesagt an Tag 4), lernen Sie mehr darüber und wie man eine Variable auf Definiertheit überprüft (mit der `defined`-Funktion) oder undefiniert macht (mit der `undef`-Funktion).

Um einer Variable einen Wert zuzuweisen, verwenden Sie einen Zuweisungsoperator. Der häufigste ist das Gleichheitszeichen (`=`). Dieser Zuweisungsoperator weist ganz simpel einer Variablen einen Wert zu, mit dem Variablennamen auf der linken und dem Wert auf der rechten Seite, wie hier:

    $i = 1;

Zuweisungsausdrücke werden von rechts nach links ausgewertet. So können Sie Zuweisungen auch aneinanderreihen wie in folgendem Beispiel (dabei wird `$b` der Wert 4 zugewiesen und danach erhält `$a` den Wert dieses Ausdrucks, also 4):

    $a = $b = 4;

Perl hat viele C-ähnliche Kurzschreibweisen mit Zuweisungsoperatoren, die ich morgen näher beschreiben werde.

> Wo gelten Variablen? Eine Variable im Hauptkörper eines Perl-Skripts ist global im Gültigkeitsbereich dieses Skripts (sie steht allen Teilen des Skripts zur Verfügung). Perl erlaubt Ihnen, lokale Variablen innerhalb von Subroutinen und Schleifen einzurichten. Außerdem können Sie Variablen auch mit Packages über mehrere Skripts hinweg verwenden, Sie müssen sie aber besonders deklarieren, damit sie nicht global sind. Aber das soll heute noch nicht Thema sein. Mehr über lokale Variablen lernen Sie am Tag 11, über Gültigkeitsbereiche am Tag 13.

## Aufbau von Perl-Skripts

In der gestrigen Lektion habe ich skizziert, wie ein Perl-Skript eigentlich aussieht und wie Perl es ausführt. Verlassen wir kurz das Thema Daten und gehen etwas mehr ins Detail, zu den Grundregeln für die Anordnung von Daten, Variablen und anderen Operationen in Perl-Anweisungen und von Perl-Anweisungen in Skripts.

Perl-Skripts bestehen aus einer oder mehreren Anweisungen, die in der Regel nacheinander ausgeführt werden. Perl-Anweisungen können einfache Anweisungen sein, wie Variablenbelegung oder Ausdrücke, auf die wir etwas später am heutigen Tag noch zu sprechen kommen werden. Es können auch komplexere Anweisungen wie Bedingungen und Schleifen sein, mit denen wir uns am Tag 6 befassen. Einfache Anweisungen müssen mit einem Semikolon aufhören.

Abgesehen von dieser Semikolonregel kümmert sich Perl nicht groß um leere Stellen (Leerzeichen, Tabs, Zeilenvorschübe), solange es begreift, was Sie zu tun versuchen. Sie können ein komplettes Perl-Skript aus mehreren Anweisungen in eine einzige Zeile schreiben (und in der Tat sind Perl-Einzeiler, ausgeführt von der Kommandozeile, sogar weit verbreitet). Im allgemeinen werden Perl-Skripts aber in mehrere Zeilen geschrieben, eine Anweisung pro Zeile, mit einer gewissen Ordnung beim Zeileneinzug, um die Lesbarkeit zu verbessern. Wie Sie Ihren Quelltext einziehen, liegt ganz bei Ihnen, obwohl Perl-Programmierer beabsichtigen, sich auf einen C-ähnlichen Stil zu einigen. (Die perlstyle-Manpage enthält Vorschläge, wie Larry Wall seinen Quelltext formatiert und ist auf jeden Fall lesenswert, auch wenn Sie einen anderen Formatierungsstil vorziehen.)

Perl-Anweisungen können auch Ausdrücke enthalten, wobei ein Ausdruck ganz einfach etwas ist, das einen Wert zum Ergebnis hat. `1 + 1` ist ein Ausdruck (der als 2 ausgewertet wird). Eine Variablenzuweisung (`$a = 1` zum Beispiel) ist ein Ausdruck, der den Wert des zugewiesenen Dings ergibt (also 1 zum Beispiel). Perl-Ausdrücke können überall dort verwendet werden, wo ein Wert erwartet wird, auch innerhalb von anderen Ausdrücken.

## Arithmetische Operatoren

Operatoren sind nicht gerade eines der aufregendsten Perl-Themen, aber Sie brauchen sie zum Aufbauen von Ausdrücken. Perl stellt für Ausdrücke mit Skalaren einen recht robusten Satz von Operatoren zur Verfügung. Sie werden heute einige dieser Operatoren kennenlernen, andere erst morgen, am Tag 3.

Wir fangen mit den Rechenoperatoren an, die arithmetische Operationen auf numerischen Daten ausführen (man könnte auch sagen: die mit Zahlen rechnen). Strings werden bei Bedarf in Zahlen umgewandelt. Für Grundrechenoperationen stehen in Perl die in Tabelle 2.2 aufgeführten Operatoren zur Verfügung, bei denen die Operanden normalerweise auf beiden Seiten des Operators stehen, ganz wie man es erwarten würde.

Operator | Operation | Beispiel | Ergebnis
--- | --- | --- | ---
+ | Addition | 3 + 4 | 7
- | Subtraktion (2 Operanden) | 4 - 2 | 2
- | Negation eines Operanden | -5 | -5
* | Multiplikation | 5 * 5 | 25
/ | Division | 15 / 4 | 3.75
** | Potenzieren | 4**5 | 1024
% | Modulo (Rest) | 15 % 4 | 3

Tabelle 2.2: Rechenoperatoren

Wenig hiervon sollte Sie überraschen, obwohl der Exponentoperator neu sein könnte. Für Potenzen ist der linke Operand die Basis und der rechte der Exponent, also `10**3` ist identisch mit `10E3` oder 10 hoch 3.

Für die Rangfolge der Operatoren gilt, was Sie bereits in der Schule gelernt haben: Multiplikation, Division und Modulo haben Vorrang vor Addition und Subtraktion. Allerdings hat die Negation einen höheren Rang als die Multiplikation, und die Potenz hat einen sogar noch höheren Rang (höherer Rang bedeutet, dass diese Ausdrucke zuerst ausgewertet werden). Sie werden morgen, am Tag 3, noch mehr über die Rangfolge der Operatoren erfahren.

### Berechnungen und Nachkommapräzision

Alle Berechnungen werden in Perl mit Fließkommazahlen durchgeführt. Obwohl dies für simple Mathematik sehr bequem ist (man braucht sich nicht um das Konvertieren zwischen Integern und Fließkommazahlen zu kümmern), hat die Fließkommamathematik ein paar Haken, auf die Sie achten sollten.

Der erste ist, dass Divisionen immer Fließkommadivisionen sind. Der Ausdruck `15/4` hat das Ergebnis 3,75 und nicht 3 wie bei der Integerdivision (und was Sie erwarten würden, wenn Sie von C kommen). Wenn Sie wirklich ein ganzzahliges Ergebnis haben wollen, können Sie die Funktion int verwenden, um die Nachkommastellen zu entfernen, wie hier:

    $ergebnis_als_int = int 15 / 4;          # Ergebnis: 3

Ein anderer Nebeneffekt der Fließkommadivision ist, dass Ihr Ergebnis manchmal viel präziser ist, als Sie möchten. Nehmen Sie zum Beispiel den simplen Ausdruck:

    print 10 / 3;

Dieser Ausdruck hat die Zahl `3.33333333333333` zum Ergebnis. Das ist schön und gut, wenn Sie die Zahl `3.33333333333333` auch haben wollten, aber nicht wenn Ihnen `3.33` oder `3.3` genügt.

Perl hat keine eingebaute Funktion zum Runden, aber zwei print-Funktionen, mit denen man sich behelfen kann: `printf` und `sprintf`, entliehen aus C, werden verwendet, um einen numerischen Wert innerhalb eines Strings zu formatieren. Die Funktion `printf` gibt wie `print` den Wert auf den Bildschirm aus, während `sprintf` lediglich einen String zurückgibt, den Sie einer Variablen zuweisen oder in einem anderen Ausdruck weiterverwenden können. Weil Perl fröhlich zwischen Zahlen und Strings hin- und herkonvertiert, können Sie mit diesen beiden Funktionen auch Zahlen »runden«. Um zum Beispiel `3.33333333333` als Zahl mit nur zwei Nachkommastellen auf den Monitor auszugeben, schreiben Sie:

    printf("%.2f", 10/3);

Der `%.2f` Teil dieses Ausdrucks ist der wichtige; er sagt: »Drucke eine Fließkommazahl (`f`) mit `2` Dezimalstellen nach dem Komma (`.2`).«

Um einen Wert innerhalb Ihres Perl-Skripts zu »runden«, ohne etwas auf den Bildschirm auszugeben, verwenden Sie `sprintf` anstelle von `printf`:

    $wert = sprintf("%.2f", $wert);        # runde $wert auf 2 Nachkommastellen

Morgen lernen Sie noch ein wenig mehr über `printf` und `sprintf`.

Der letzte Haken, den man zu Fließkommaberechnungen noch erwähnen muss, ist der sogenannte Rundungsfehler. Durch die Art, wie Fließkommazahlen gespeichert werden, können manchmal sehr simple Fließkommaberechnungen Ergebnisse haben, die zwar sehr nah dran, aber doch nicht das sind, was man erwarten würde. Zum Beispiel ergibt eine simple Operation wie `4.5` `+` `5.7` womöglich die Zahl `10.199999999999999` anstatt `10.2`, wie man (guten Rechts) annehmen könnte. Meistens ist das kein Problem, da Perl die Zahlen intern im Auge behält und `print` beim Ausgeben der Zahl sehr kleine Ungenauigkeiten selbständig ausgleicht. Wirklich problematisch wird es jedoch, wenn Sie versuchen, einen derartigen Ausdruck mit einer Konstanten zu vergleichen - ein Test, ob der Ausdruck `4.5 + 5.7` gleich `10.2` ist, könnte als falsch scheitern. Behalten Sie diesen Rundungsfehler im Kopf, wenn Sie mit Perl arbeiten - und achten Sie ganz besonders darauf, wenn Sie plötzlich unerwartete Ergebnisse erhalten.

## Ein Beispiel: Fahrenheit in Celsius umrechnen

Mit Zahlen, Strings und Skalarvariablen im Repertoire können Sie nun anfangen, simple Perl-Skripts zu schreiben. Hier ist ein Skript, das Sie um einen Fahrenheit- Wert bittet und diesen dann in Celsius umrechnet. Wenn es läuft, sieht das Ganze dann so aus:

    % temperatur.pl
    Geben Sie eine Temperatur in Fahrenheit ein: 212
    212 Grad Fahrenheit entsprechen 100 Grad Celsius
    %

Listing 2.1 zeigt den Perl-Code für dieses Skript:

Listing 2.1: Das Skript temperatur.pl.

    1:  #!/usr/bin/perl -w
    2:
    3:  $fahr = 0;
    4:  $cel = 0;
    5:
    6:  print 'Geben Sie eine Temperatur in Fahrenheit ein: ';
    7:  chomp ($fahr = <STDIN>);
    8:  $cel = ($fahr - 32) * 5 / 9;
    9:  print "$fahr Grad Fahrenheit entsprechen ";
    10: printf("%d Grad Celsius\n", $cel);

Dieses Skript ist dem echo.pl- Skript von gestern sehr ähnlich, aber lassen Sie es uns Zeile für Zeile durchgehen, auf der Grundlage dessen, was Sie bisher über Skalare, Zahlen, Strings und Variablen gelernt haben.

Die Zeilen 3 und 4 initialisieren die Variablen, die wir in diesem Skript verwenden werden: `$fahr` für einen Fahrenheit-Wert und `$cel` für einen Grad-Celsius-Wert. Obwohl wir das Skript auch ohne Initialisierung der Variablen hätten schreiben können, haben wir so, wenn es fertig ist, eine nette Liste von allen Variablen in diesem Skript. Schön übersichtlich.

Zeile 6 schreibt die Eingabeaufforderung auf den Bildschirm. Hier habe ich einen single-quoted String genommen, weil es hier keine Variablen oder Escape-Sequenzen gibt, über die man sich Sorgen machen müßte, nur Buchstaben. Deswegen stehen hier nur einfache Anführungszeichen.

Zeile 7 liest eine Zeile Benutzereingaben von der Tastatur und speichert diesen String in der Skalarvariablen `$fahr`. Die Funktion `chomp` schneidet das Zeilenvorschubzeichen von diesem String ab. Diese Zeile ist vielleicht noch etwas schwierig, aber bleiben Sie dran, morgen erfahren Sie mehr über die Eingabe und die `chomp`-Funktion.

In Zeile 8 führen wir die Umrechnung des Wertes in `$fahr` durch und speichern das Ergebnis in der Skalarvariablen `$cel`. Beachten Sie, dass, obwohl die von der Tastatur eingelesenen Daten String-Form haben, Perl sich daraus nichts macht. Sie können einfach weitermachen und Berechnungen mit diesen Daten ausführen, als ob es Zahlen wären. Wenn Sie etwas Nichtnumerisches wie »philantrophisch« eingeben, werden die Perl-Warnungen natürlich mäkeln. Am Tag 6 werden Sie mehr darüber lernen, wie man Eingabefehler abfängt; für heute wollen wir einfach annehmen, dass alle Eingaben, die wir bekommen, auch die richtige, von uns erwartete Form haben.

Ohne die Klammern würden Multiplikation und Division zuerst durchgeführt. Wenn die Ausdrücke in einer anderen Reihenfolge ausgewertet werden sollen, dann setzen Sie Klammern. Hier haben wir Klammern verwendet, damit `32` vom Wert in `$fahr` subtrahiert wird, bevor man es mit `5 / 9` multipliziert.

Schließlich, in Zeile 9 und 10, geben wir das Ergebnis aus. In Zeile 6 nutzen wir die mittlerweile vertraute Funktion `print` (beachten Sie, dass die `$fahr`-Variable wegen Perls automatischer Variableninterpolation durch ihren aktuellen Wert ersetzt wird). In Zeile 10 verwenden wir zur Ausgabe die Funktion `printf`, damit wir bestimmen können, wie die Celsius-Temperatur ausgegeben wird. Mit einem normalen `print` wäre der Wert von `$cel` eine Fließkommazahl - und vielleicht eine sehr lange, je nachdem, wie die Berechnung ausgegangen ist. Durch den Einsatz von `printf` mit dem Format `%d` können wir den Celsius-Wert auf eine dezimale (ganze) Zahl begrenzen. Beachten Sie, dass, obwohl wir hier zwei Print-Anweisungen haben (zum einen `print`, zum anderen `printf`), die Ausgabe in einer einzelnen Zeile steht. Der erste ausgegebene String hat nicht mit `\n` aufgehört, also geht der zweite String in derselben Zeile weiter.

Morgen erfahren Sie mehr über `print` und `printf`.

## Operatoren für Tests und Vergleiche

Mit Perls Vergleichsoperatoren erhalten Sie eine Aussage über die Beziehung zwischen zwei Zahlen oder Strings. Gleichheitsoperatoren prüfen, ob zwei Skalare gleich sind, relationale (oder Vergleichs-)Operatoren, ob einer »größer« ist als der andere. Schließlich gibt es in Perl auch noch logische Operatoren für boolesche (wahr oder falsch) Vergleiche. Diese brauchen Sie insbesondere für Bedingungs- und Schleifenoperationen, die wir am Tag 6 behandeln.

### Was ist Wahrheit?

Nein, wir schweifen jetzt nicht in philosophische Debatten ab, doch bevor wir die Operatoren durchgehen, müssen Sie verstehen, was Perl unter wahr und falsch versteht.

Zum einem können jegliche skalare Daten auf ihre Wahrheit überprüft werden; das heißt Sie können nicht nur nachsehen, ob zwei Zahlen gleichwertig sind, sie können auch bestimmen, ob die Zahl `4` oder der String `"Thomas Jefferson"` wahr ist. Die Regel ist ganz einfach: Alle Skalare (alle Zahlen, Strings und Referenzen) sind wahr bis auf drei Ausnahmen:

- Der leere String (`""`)
- Null (`0`)
- Der undefinierte Wert (der sowieso meistens wie `""` oder `0` aussieht)

Diese drei sind falsch.

Mit diesen Regeln im Kopf können Sie sich jetzt den Operatoren zuwenden.

### Gleichheits- und Vergleichsoperatoren

Gleichheitsoperatoren überprüfen, ob zwei Daten gleich sind, relationale Operatoren ermitteln, ob ein Wert größer ist als der andere. Bei Zahlen ist das einfach: Verglichen wird in numerischer Reihenfolge. Bei Strings wird ein String für kleiner als ein anderer befunden, wenn dessen erstes Zeichen in der Reihe der ASCII-Zeichen früher auftaucht als das erste Zeichen des anderen Strings (und umgekehrt für größer als). Im ASCII-Zeichen-Schema ist die Reihenfolge der Zeichen durch den zugehörigen ASCII- Code, eine Nummer von 0-255, festgelegt, auch für Zahlen, Leerstellen und Sonderzeichen, wobei die Großbuchstaben vor den Kleinbuchstaben kommen. Strings sind dann gleich, wenn sie vom Anfang bis zum Ende aus exakt den gleichen Zeichen bestehen.

Perl hat zwei Sätze von Gleichheits- und Vergleichsperatoren, einen für Zahlen und einen für Strings, wie in Tabelle 2.3 aufgelistet. Obwohl sie unterschiedliche Namen haben, werden Sie beide gleich verwendet, mit je einem Operand auf jeder Seite. All diese Operatoren geben `1` für wahr und `""` für falsch zurück.

Vergleich | Zahlenoperator | String-Operator
--- | --- | ---
gleich | == | eq
nicht gleich | != | ne
kleiner als | < | lt
größer als | > | gt
kleiner gleich | <= | le
größer gleich | >= | ge

Tabelle 2.3: Gleichheits- und Vergleichsoperatoren

Hier ein paar Beispiele für Zahlen- und String-Vergleiche:

    4 < 5            # wahr
    4 <= 4           # wahr
    4 < 4            # falsch
    5 < 4 + 5        # wahr (Addition zuerst ausgefuehrt)
    6 < 10 > 15      # Syntaxfehler; Vergleiche sind nicht kombinierbar
    '5' < 8          # wahr; '5' wird zu 5 konvertiert
    'laut' < 'lauter'  # fuehrt unter -w zu Fehler. für Strings lt nehmen
    'laut' lt 'lauter' # wahr
    'laut' lt 'Laut'   # falsch; Gross- und Kleinschreibung
                       # wird unterschieden
    'laut' eq 'laut '  # falsch, Leerzeichen spielen eine Rolle

Beachten Sie, dass keiner der Vergleichsausdrücke mit anderen Vergleichsausdrücken kombiniert werden kann. Während Sie einen Rechenausdruck `5 + 4 - 3` haben können, der von links nach rechts ausgewertet wird, ist ein Ausdruck `6 < 10 > 15` nicht möglich; er wird einen Syntaxfehler verursachen, weil er nicht auszuwerten ist.

Seien Sie vorsichtig, und vergessen Sie nicht, dass `==` der Gleichheitstest ist, nicht zu verwechseln mit `=`, dem Zuweisungsoperator. Letzterer ist ein Ausdruck, der ebenfalls wahr oder falsch zurückgeben kann, deshalb kann es sehr schwierig sein, Fehler aufzuspüren, wo Sie aus Versehen = statt == benutzt haben.

Sie fragen sich, wofür es zwei verschiedene Sätze von Vergleichsoperatoren gibt, wo Perl doch zwischen Zahlen und Strings automatisch konvertieren kann? Genau deswegen. Gerade weil Zahlen und Strings automatisch konvertiert werden können, brauchen Sie die Möglichkeit zu sagen: »Vergleiche die hier als Zahlen und nicht als String.«

Nehmen wir zum Beispiel an, es gäbe nur einen Satz Vergleichsoperatoren in Perl, wie in anderen Sprachen. Und sagen wir, wir hätten einen Ausdruck wie `'5' < 100`. Wie wird dieser Ausdruck ausgewertet? In anderen Sprachen wäre dieser Vergleich nicht einmal möglich, es wäre ein ungültiger Ausdruck. Nicht so in Perl, denn Zahlen und Strings können ineinander umgewandelt werden. Aber es gibt zwei Möglichkeiten, es korrekt auszuwerten. Wenn man `'5'`in eine Zahl konvertiert, erhält man `5 < 100`, das ist wahr. Wandelt man `100` in einen String um, erhält man `'5' < '100'`, das ist falsch, weil in der ASCII-Reihenfolge das Zeichen `5` erst nach dem Zeichen `1` steht. Um diese Zweideutigkeit zu vermeiden, brauchen wir zwei Sätze von Operatoren.

Zu vergessen, dass es zwei Sets von Vergleichsoperatoren gibt, ist einer der häufigeren Fehler bei Perl-Programmieranfängern (und einer der einen wahnsinnig machen kann, wenn zum Beispiel `'dies' == 'das'` beide Strings zu `0` konvertiert und dann wahr zurückgibt). Aktivierte Perl-Warnungen werden Sie gegebenenfalls auf diesen Fehler aufmerksam machen (noch ein guter Grund, Warnungen in all Ihren Skripts angeschaltet zu lassen, zumindest bis Sie Ihren Programmierfähigkeiten ein bißchen mehr trauen.

### Logische Operatoren

Logische Operatoren, auch boolesche Operatoren genannt, werten ihre Operanden auf den Grundlagen der Booleschen Algebra aus, geben also nach deren Regeln wahr oder falsch zurück. Das heißt für die Werte von x und y:

- `x AND y` liefert nur dann wahr, wenn sowohl x als auch y wahr sind.
- `x OR y` liefert dann wahr, wenn mindestens einer von beiden wahr ist.
- `NOT x` liefert wahr, wenn x falsch ist und umgekehrt.

> Sie müssen `AND`, `OR` und `NOT` nicht groß schreiben. Die Großschreibung ist aber sehr gebräuchlich, um die Operatoren von den gleichnamigen Wörtern der englischen Sprache zu unterscheiden.

Typisch für Perl (die Qual der Wahl ist schließlich ein wichtiges Perl-Feature): Es gibt nicht nur einen Satz logischer Vergleiche, sondern zwei: einen aus C entliehenen und einen mit Perl-Schlüsselwörtern. Tabelle 2.4 zeigt beide Sätze dieser Operatoren:

C-Stil | Perl-Stil | Bedeutung
--- | --- | ---
&& | AND | logisches UND
|| | OR | logisches ODER
| NOT | logisches NICHT

Tabelle 2.4: Logische Vergleiche

> Es gibt auch Operatoren für logisches XOR (entweder oder), `^` und `XOR`, aber im allgemeinen werden sie außerhalb von Bitmanipulation kaum gebraucht, deswegen habe ich sie hier nicht mit hineingenommen.

Der einzige Unterschied zwischen den zwei Operatorstilen liegt in ihrer Rangfolge. Die C-Stil-Operatoren stehen höher in der Rangfolge als die Perl-Stil-Operatoren. Dieser niedrige Rang der Perl-Stil-Operatoren kann Ihnen das Eintippen von ein paar Klammern ersparen, wenn diese Sie nerven. In vorhandenem Perl-Code werden Sie wahrscheinlich häufiger C-Stil-Operatoren finden. Die Perl-Stil-Operatoren sind zum einen recht neu, und zum anderen verwenden Programmierer, die an C gewöhnt sind, lieber die C-Stil-Codierung.

Beide Arten von logischem AND und NOT sind sogenannte Kurzschlußoperatoren, das heißt, wenn nach Auswerten der linken Seite des Ausdrucks das Endergebnis schon feststeht, wird die rechte Seite des Ausdrucks komplett ignoriert.

Sagen wir zum Beispiel, Sie hätten folgenden Ausdruck:

    ($x < $y) && ($y < $z)

Wenn der Ausdruck auf der linken Seite von `&&` falsch ist (wenn `$x` größer als `$y` ist), ist der Ausgang der rechten Seite des Ausdrucks irrelevant. Ganz egal, was dort herauskommt, der gesamte Ausdruck wird falsch sein (denn, Sie erinnern sich, logisches UND besagt, dass beide Seiten des Ausdrucks wahr sein müssen, damit der Ausdruck wahr sein kann). Um etwas Zeit zu sparen, verzichtet ein Kurzschlußoperator auf die Auswertung der rechten Seite des Ausdrucks, wenn die linke Seite (und damit der gesamte Ausdruck) falsch ist.

Ganz ähnlich wird bei `||`, wenn die linke Seite des Ausdrucks als wahr ausgewertet wird, der ganze Ausdruck für wahr befunden, und die rechte Seite wird ignoriert.

Beide Formen von logischen Operatoren liefern falsch, wenn sie zum Ergebnis falsch gekommen sind. Ist das Ergebnis wahr, haben sie außerdem noch den Seiteneffekt, dass sie den zuletzt ausgewerteten Wert gleich mit zurückgeben (der, weil es keine Null oder kein Leerstring ist, noch als wahr gilt). Während dieser Nebeneffekt zuerst unsinnig erscheinen mag, wo Sie doch nur wissen wollen, ob der Wert des Ausdrucks wahr oder falsch ist, erlaubt er eine einfache Form der Auswahl zwischen verschiedenen Optionen oder Funktionsaufrufen oder ähnlichem:

    $ergebnis = $a || $b || $c || $d;

In diesem Beispiel wird Perl die Liste von Variablen durchgehen und jede auf ihre »Wahrheit« überprüfen. Die erste, die wahr ergibt, hält den Ausdruck an (Kurzschluß), und der Wert von $ergebnis wird der Wert der letzten überprüften, also der ersten »wahren« Variablen.

Viele Perl-Programmier verwenden diese logischen Tests gerne als eine Art Bedingung wie im nächsten Beispiel, das Sie häufig sehen werden, wenn Sie sich den Perl-Code anderer Leute ansehen:

    open(DATEI, 'Dateiname') || die 'kann Datei nicht oeffnen';

Auf der linken Seite des Ausdrucks wird mit `open` eine Datei geöffnet und wahr zurückgegeben, wenn die Datei erfolgreich geöffnet wurde. Auf der rechten Seite wird `die` (vom englischen to die, sterben) eingesetzt, um das Skript bei einer Fehlermeldung sofort zu verlassen. Sie möchten das Skript natürlich nur verlassen, wenn die Datei nicht geöffnet werden konnte - das heißt, wenn `open` falsch zurückgibt. Da der `||` Ausdruck kurzschließt, wird es nur dann zum `die` auf der rechten Seite kommen, wenn die Datei nicht geöffnet werden konnte.

Ich werde darauf zurückkommen, wenn wir am Tag 6 über Bedingungen sprechen (und über `open` werden Sie am Tag 15 mehr lernen).

## Vertiefung

Perl ist eine dermaßen umfangreiche Sprache - wenn ich wirklich alles erklären wollte, wäre dieses Buch so dick wie bestenfalls das Münchener, wahrscheinlicher aber wie das Berliner Telefonbuch (»Perl in 180 Tagen«?). In diesem Abschnitt reiße ich deswegen ein paar Sachen an, die Sie mit skalaren Daten noch machen können, ich in den vorigen Abschnitten aber nicht besprochen habe. Manches davon werden wir später in diesem Buch detaillierter betrachten, aber zum größten Teil sind dies Themen, die Sie selbst erforschen müssen, falls Sie mehr darüber wissen möchten.

Wie ich gestern erwähnt habe: Wenn ich auf die perlop- oder perlfunc-Manpage - oder jede andere Perl-Manpage - verweise, finden Sie diese Seiten als Teil der Dokumentation bei Ihrem Perl-Interpreter oder im Web unter `http://www.perl.com/ CPAN-local/doc/manual/html/pod/.`

### Anführungszeichen

Die Anführungszeichen `''` und `""` stellen in Perl lediglich eine Möglichkeit für das Erzeugen von Strings dar. Es gibt noch weitere Möglichkeiten, wie Sie in Perl auch ohne Anführungszeichen Strings erstellen können, von denen einige Variablen auswerten und andere nicht. Sie könnten zum Beispiel anstelle der einfachen Anführungszeichen bei `'Sein oder Nichtsein'` auch den Operater `q//` verwenden:

    q/Sein oder Nichtsein/

Sie haben einen unerklärlichen Widerwillen gegen Anführungszeichen oder Slashes? Kein Problem. Sie können den `q//`-Operator mit jedem alphanumerischen Zeichen schreiben, solange Sie nur das gleiche Zeichen für den Anfang und das Ende des Strings nehmen und das Ganze mit einem `q` beginnen. Die folgenden Beispiele sind in Perl alle gleichwertig:

    'Sein oder Nichtsein'
    q/Sein oder Nichtsein/
    q#Sein oder Nichtsein#
    q?Sein oder Nichtsein?

Wie bei einfachen Anführungszeichen interpoliert der `q//` -Operator keine Variablen. Statt doppelten Anführungszeichen (für Variableninterpolation) können Sie in der gleichen Art und Weise den `qq//` -Operator einsetzen:

    "zeige $zahl Zeilen"
    qq/zeige $zahl Zeilen/
    qq^zeige $zahl Zeilen^

Diese Formate sind recht praktisch, wenn man mit Strings arbeitet, die selbst viele Anführungszeichen enthalten. Mit `q` oder `qq` und einem beliebigen Begrenzungszeichen können Sie sich die Backslashes ersparen und die Anführungszeichen im String stehen lassen, wie sie sind. (Siehe auch die perlop- Manpage; dort finden Sie Details über die verschiedenen Operatoren, die statt Anführungszeichen verwendet werden können.)

Außerdem gibt es noch barewords (vom englischen bare, »bloß, blank«): einzelne Wörter ohne Anführungszeichen, die in Perl keine andere Bedeutung haben, werden als Strings interpretiert. Von ihnen ist prinzipiell abzuraten, weil sie Skripts sehr schwer lesbar machen, sehr fehleranfällig sind und Sie nie wissen, wann eins Ihrer barewords vielleicht doch zum reservierten Wort in einer zukünftigen Version der Sprache wird. Vermeiden Sie sie. Bei aktivierten Perl-Warnungen wird Perl sich über sie auch beklagen.

### Groß- und Kleinschreibung per Escape-Sequenz

In Tabelle 2.1 hatte ich die Sonderzeichen für interpolierte (double-quoted) Strings zusammengefaßt. Darunter waren auch Escape-Sequenzen für Groß- und Kleinschreibung (`\l, \u, \L, \U` und `\E`). Verwenden Sie diese, um die Groß- oder Kleinschreibung von Werten in Strings zu erzwingen.

Die Sonderzeichen `\l` und `\u` machen aus dem nachfolgenden Buchstaben im String einen Klein- bzw. Großbuchstaben. Sie könnten `\u` zum Beispiel verwenden, um sicherzustellen, dass ein Satzanfang groß geschrieben wird. `\L` und `\U` machen gleich eine Reihe von Zeichen innerhalb des Strings zu Groß- oder Kleinbuchstaben: Sie wandeln alle nachfolgenden Buchstaben im String entsprechend um, bis der String zu Ende ist oder ein `\E` auftaucht. Diese Sonderzeichen sind in Strings nicht unbedingt nützlich, aber sie werden es später, wenn Sie Muster für Such- und Ersetzungsprozeduren schreiben.

### Mehr zur Variableninterpolation in Strings

Variableninterpolation ist die Fähigkeit von Perl, Verweise auf Variablen in Strings durch ihre aktuellen Werte zu ersetzen. Manchmal ist es allerdings für Perl schwierig zu begreifen, wo die Variable aufhört. Nehmen Sie zum Beispiel folgenden String:

    "Dies ist ein $xes Programm...\n";

In diesem String heißt die zu interpolierende Variable eigentlich `$x` und enthält ein Adjektiv (das man vielleicht vorher aus »nett«, »langweilig« und »sinnlos« auswählen konnte). Weil aber der Ausgabestring etwas sagen soll wie `"Dies ist ein sinnloses Programm...",` stößt der Variablenname direkt an das »`es`«, und Perl sucht nach einer Variablen namens `$xes` -`` und nicht nach `$x`. Es gibt eine Menge Auswege aus dieser Art von Problem - nicht zuletzt die Verkettung von mehreren Strings. Aber Perl hat auch eine direkte Lösung:

    "Dies ist ein ${x}es Programm...\n";

Die geschweiften Klammern sind in diesem Fall einfach nur Begrenzungen, so dass Perl versteht, wo der Variablenname anfängt und endet; sie werden nicht ausgegeben. Solcher Gebrauch von geschweiften Klammern kann helfen, um Probleme bei der Variableninterpolation auszuklammern.

## Zusammenfassung

Überall Zahlen und Strings! Heute haben Sie ziemlich viel über skalare Daten gelernt. Perl verwendet die Bezeichnung skalare Daten, um sich auf einzelne Objekte zu beziehen, insbesondere Zahlen und Strings. Skalarvariablen, die mit einem `$` beginnen, speichern skalare Daten.

Mit skalaren Daten können Sie Perl-Anweisungen erstellen, Berechnungen durchführen, zwei Werte vergleichen, Variablen Werte zuweisen, die Werte ändern und zwischen Zahlen und Strings hin- und herkonvertieren.

Nachfolgend noch einmal die eingebauten Funktionen, die Sie heute kennengelernt haben:

- `print` nimmt eine Liste von kommagetrennten Werten und Strings entgegen und gibt diese Werte an das Standardausgabegerät (`STDOUT`).
- `printf` nimmt Formatierungsanweisungen und beliebig viele Werte entgegen und gibt diese Werte entsprechend den Formatierungsanweisungen aus.
- `sprintf` tut dasselbe wie `printf`, nur dass es den formatierten String zurückgibt, ohne irgend etwas auszugeben.
- `chomp` mit einem String-Argument entfernt alle Zeilenvorschübe vom übergebenen String und gibt die Zahl von Zeichen, die es gelöscht hat, zurück.
- `int` übernimmt eine Zahl und gibt den ganzzahligen Teil dieser Zahl zurück (wobei es jede Nachkommastelle abschneidet).
- `oct` nimmt einen String und interpretiert ihn als Oktal- oder Hexadezimalzahl, je nachdem, ob der String mit `0` oder `0x` anfängt.
- `hex` nimmt einen String und interpretiert diesen als eine Hexadezimalzahl.

Einige dieser Funktionen werden wir morgen noch genauer untersuchen; ansonsten können Sie in der perlfunc-Manpage (siehe Anhang A) nachschlagen, um mehr über diese Funktionen zu erfahren.

## Fragen und Antworten

Frage:
Wie definiere ich eine Variable so, dass sie nur Zahlen enthalten kann?

Antwort:
Das können Sie nicht. Perl hat keine strengen Zahlentypen wie andere Sprachen. Die beste Näherung ist eine Skalarvariable, und die kann sowohl eine Zahl als auch einen String enthalten.

> Meistens spielt das aber keine Rolle; Perl konvertiert für Sie Zahlen in Strings und umgekehrt.

Frage:
Aber was ist, wenn ich irgendwann Daten in Stringform habe, die keine Zahlen sind, und ich damit irgendwelche Berechnungen vornehmen will?

Antwort:
Das Standardverhalten sieht, wie ich es im Abschnitt »Konvertieren zwischen Zahlen und Strings« beschrieben habe, so aus, dass Strings ohne numerischen Inhalt zu 0 werden. Für Strings, die mit Zahlen beginnen und dann mit Buchstaben weitergehen, werden die Buchstaben ignoriert.

> Wenn Sie für Ihr Perl-Skript Warnungen eingeschaltet haben, dann wird Perl Sie warnen, wenn Sie versuchen, mit nichtnumerischen Daten zu rechnen, so dass Sie Ihr Skript korrigieren können, bevor das Problem überhaupt entsteht.

> Falls Sie befürchten, nichtnumerische Daten vom Anwender zu bekommen, sollten Sie die Eingaben beim Einlesen überprüfen. Wir haben dies in Ansätzen heute schon getan. An den Tagen 6 und 9 zeige ich Ihnen noch mehr Tricks zur Eingabeüberprüfung.

Frage:
Meine Berechnungen geben Fließkommazahlen mit viel zu vielen Stellen nach dem Komma zurück. Wie beschränke ich Zahlen auf zwei Dezimalstellen?

Antwort:
Sehen Sie in dem Abschnitt über die arithmetischen Operatoren nach, wo ich erkläre, wie man genau dies mit `printf` und `sprintf` erledigt.

Frage:
Aber `printf` und `sprintf` sind Stringfunktionen. Ich möchte sie auf Zahlen anwenden.

Antwort:
Sowohl Zahlen als auch Strings sind in Perl Skalare. Was Sie mit dem einen tun können, können Sie (in vielen Fällen) auch mit dem anderen tun. Nehmen Sie `printf` und `sprintf`.

## Workshop

Der Workshop enthält Quizfragen, die Ihnen helfen sollen, Ihr Wissen zu festigen, und Übungen, die Sie anregen sollen, das eben Gelernte umzusetzen und eigene Erfahrungen zu sammeln. Versuchen Sie, das Quiz und die Übungen zu beantworten und zu verstehen, bevor Sie zur Lektion des nächsten Tages übergehen.

### Quiz

1. Welche beiden Datentypen stehen Ihnen in Perl zur Verfügung?
2. Was für Daten sind skalar?
3. Was sind die Unterschiede zwischen Strings mit einfachen und Strings mit doppelten Anführungszeichen?
4. Welche der folgenden Variablen sind Skalarvariablen?

           $zaehler
         $11foo
         $_platzhalter
         $back2thefuture
         $lange_variable_zum_Speichern_von_wichtigen_Daten

5. Was ist der Unterschied zwischen den Operatoren `=` und `==`?
6. Was ist der Unterschied zwischen einer Anweisung und einem Ausdruck?
7. Zu welchem Ergebnis wir der folgende Ausdruck ausgewertet?:

           4 + 5 / 3**2 * 6

8. Wie formatiert man Zahlen in Perl?
9. Welche Werte repräsentieren in Perl den Wahrheitswert falsch?
10. Warum gibt es unterschiedliche Operatoren für Zahlen- und für Stringvergleiche?
11. Erläutern Sie, was ein kurzschließender logischer Operator macht.

### Übungen

1. Ändern Sie temperatur.pl, so dass es Celsius zurück nach Fahrenheit konvertiert.
2. Schreiben Sie ein Programm, das Sie um die Eingabe der Länge und Breite eines Raums bittet und Ihnen dann die Größe in Quadratmetern ausgibt.
3. FEHLERSUCHE: Was ist falsch an diesem Programm?

           print 'Geben Sie das Wort foo ein: ';
       chomp($input = <STDIN>);
       if ($input = 'foo') {
          print "Danke!\n";
       } else {
          print "Das ist nicht das Wort foo.\n";
       }

4. FEHLERSUCHE: Und was ist mit dieser Version?

           print 'Geben Sie das Wort foo ein: ';
       chomp($input = <STDIN>);
       if ($input == 'foo') {
          print "Danke!\n";
       } else {
          print "Das ist nicht das Wort foo.\n";
       }

## Antworten

Hier die Antworten auf die Workshop-Fragen aus dem vorigen Abschnitt.

### Antworten zum Quiz

1. Die zwei in Perl zur Verfügung stehenden Datentypen sind Skalare für individuelle, einzelne Dinge wie Zahlen oder Strings und Listen für Datensammlungen wie zum Beispiel Arrays.
2. Zahlen, Strings und Referenzen. Richtig ist Ihre Antwort aber auch, wenn Sie nur an Zahlen und Strings gedacht haben; über Referenzen haben wir noch nicht gesprochen.
3. Es gibt zwei Unterschiede zwischen single- und double-quoted Strings:
4. Double-quoted Strings können beliebig viele Sonderzeichen enthalten, single- quoted Strings nur `\'` und `\\`.
5. Double-quoted Strings werten die in ihnen enthaltene Variablen aus (das heißt, sie ersetzen die Variablen durch deren aktuellen Wert).
6. Alle Variablen in dieser Liste außer `$11foo` sind gültig. `$11foo` ist ungültig, weil es mit einer Zahl anfängt. (Perl kennt Variablen, die mit Zahlen beginnen, aber die sind alle für Perl reserviert).
7. Der `=`-Operator ist der Zuweisungsoperator, mit dem man einer Variablen einen Wert zuweist. Mit dem `==`-Operator überprüft man die Gleichheit von zwei Zahlen.
8. Eine Anweisung ist in Perl eine einzelne Operation. Ein Ausdruck ist eine Anweisung, die einen Wert zurückgibt. Sie können oft in einer einzigen Perl- Anweisung etliche Ausdrücke verschachteln.
9. `7.33333333333333`, mit ein oder zwei Dreien mehr oder weniger.
10. Zum einfachen Abrunden von Zahlen (ohne sie auszugeben) verwenden Sie `sprintf`. Mit `printf` geben Sie Zahlen weniger präzise aus.
11. In Perl entsprechen drei Werte dem Wahrheitswert falsch: `0`, der Leerstring `""` und der undefinierte Wert.
12. Perl hat unterschiedliche Operatoren für Zahlen und Strings, weil es skalare Werte automatisch konvertiert, mit beiden aber unterschiedlich umgehen muss.
13. Kurzschlußoperatoren werten die Operanden auf ihrer rechten Seite nur soweit wie nötig aus. Wenn der Wert links vom Operator schon den Wert des gesamten Ausdrucks bestimmt (zum Beispiel wenn die linke Seite von einem `&&` -Operator falsch ist), wird die Auswertung abgebrochen.

### Lösungen zu den Übungen

1. Eine mögliche Lösung ist:

           #!/usr/bin/perl -w

       $cel = 0;
       $fahr = 0;

       print 'Geben Sie eine Temperatur in Celsius ein: ';
       chomp ($cel = <STDIN>);
       $fahr = $cel * 9 / 5 + 32;
       print "$cel Grad Celsius entsprechen ";
       printf("%d Grad Fahrenheit \n", $fahr);

2. Hier eine mögliche Lösung:

           #!/usr/bin/perl -w

       $breite = 0;
       $laenge = 0;
       $qm = 0;

       print 'Geben Sie die Breite des Raums ein (Meter): ';
       chomp ($breite = <STDIN>);
       print 'Geben Sie die Laenge des Raums ein (Meter): ';
       chomp ($laenge = <STDIN>);
       $qm = $breite * $laenge;
       print "Der Raum hat $qm Quadratmeter.\n";

3. Die Überprüfung innerhalb der Klammern für die `if`-Anweisung verwendet einen Zuweisungsoperator anstatt eines Gleichheitsoperators. Dieser Test wird immer wahr sein.
4. Diesmal prüft der Test innerhalb der Klammen auf Zahlengleichheit. Da hier aber Strings verglichen werden, braucht man statt dessen eine `eq` -Prüfung.

© Markt&Technik Verlag, ein Imprint der Pearson Education Deutschland GmbH