33
Programmierkurs für absolute Anfänger http://www.coli.uni-saarland.de/~cabr/ teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann Sommersemester 2005

Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Embed Size (px)

Citation preview

Page 1: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger

http://www.coli.uni-saarland.de/~cabr/teaching.php

Dateihandles, formatierte Ausgabe, Subroutinen

Caren BrinckmannSommersemester 2005

Page 2: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 2

Dateihandles Um in Perl eine bestimmte Datei zum Lesen, Schreiben oder

Anhängen zu öffnen, benötigt man so genannte Dateihandles. Ein Dateihandle ist der Name einer Eingabe-/Ausgabe-Verbindung

zwischen dem Perl-Programm und der "Außenwelt". Dateihandles sollten komplett in Großbuchstaben geschrieben

werden, damit sie nicht mit Funktionsnamen verwechselt werden können.

Sechs Dateihandle-Namen sind bereits von Perl mit einer Bedeutung belegt (und sollten daher nicht für einen anderen Zweck benutzt werden):STDIN: Standardeingabe (normalerweise: Tastatur)

STDOUT: Standardausgabe (normalerweise: Bildschirm)

STDERR: Standardfehlerausgabe (normalerweise: Bildschirm)

außerdem: ARGV, ARGVOUT, DATA

Page 3: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 3

STDIN, STDOUT und STDERR

Ein Perlprogramm liest normalerweise von STDIN und schreibt nach STDOUT (Funktion print). Fehlermeldungen (Funktion die) und Warnhinweise werden nach STDERR geschrieben.

Normalerweise stellt STDIN eine Verbindung zwischen dem Perlprogramm und der Tastatur her, STDOUT und STDERR verbinden das Programm mit dem Bildschirm.

Beim Programmaufruf kann man aber dafür sorgen, dass das Perlprogramm seine Eingabedaten aus einer Datei liest, seine Ausgabedaten in eine andere Datei schreibt, und die Fehlermeldungen an eine dritte Datei anhängt:

perl -w meins.pl < rein.txt > raus.txt 2>> fehler.txt

Page 4: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 4

Dateihandles öffnen: open Mit dem Operator open wird Perl angewiesen, eine

Verbindung zwischen dem Programm und der Außenwelt (meistens: einer Datei) herzustellen.

Dabei wird unterschieden, ob die entsprechende Datei zum Lesen, Schreiben oder Anhängen geöffnet wird:open(KIELDATEI, "<kkos025.s1h"); ## lesenopen(AUSGABE, ">label.txt"); ## schreibenopen(LOGDATEI, ">>log.txt"); ## anhängen

Anstelle des Dateinamens kann eine skalare Variable verwendet werden, z.B.:$ausgabedatei = $ARGV[0];open(AUSGABE, ">$ausgabedatei");

Page 5: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 5

Schlechte Dateihandles Wenn die Rechte der zu öffnenden Datei nicht korrekt gesetzt sind, ein

falscher Dateiname angegeben wird oder andere Gründe gegen ein Öffnen sprechen, kann das Betriebssystem den Zugriff auf die Datei verweigern.

Beim Versuch, von einem solchen schlechten Dateihandle zu lesen, wird undef bzw. die leere Liste zurückgegeben (je nach Kontext).

Beim Versuch, in ein schlechtes Dateihandle zu schreiben, werden die Daten stillschweigend verworfen!

Daher sollte immer überprüft werden, ob der Aufruf von open erfolgreich war. Ggf. wird das Programm mit einer entsprechenden Fehlermeldung abgebrochen:

open(AUSGABE, ">$ausgabedatei") or die "Konnte Ausgabedatei $ausgabedatei nicht oeffnen: $!\n";

Page 6: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 6

Spezialvariable $! Nach einem fehlgeschlagenen Aufruf des Betriebssystems (z.B. durch

den Versuch, eine Datei zu öffnen, für die der Benutzer keine Zugriffsrechte hat) enthält die Spezialvariable $! die Fehlermeldung des Betriebssystems, z.B. "Permission denied".

Wird nach $! kein Zeilentrennzeichen \n eingefügt, so wird an das Ende der Meldung automatisch der Name des Perl-Programms und die Zeilennummer angehängt. Dies hilft bei der systematischen Fehlersuche.

Beispiel:open(AUSGABE, ">$ausgabedatei") or die "Konnte Ausgabedatei $ausgabedatei nicht oeffnen: $!";

erzeugt z.B. folgende Fehlermeldung:

Konnte Ausgabedatei test.txt nicht oeffnen: Permission denied at meinprogramm.pl line 4.

Page 7: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 7

Dateihandles benutzen Wenn ein Dateihandle zum Lesen geöffnet ist, können

die Zeilen genauso gelesen werden, als kämen sie von STDIN:open(KIELDATEI, "<$datei") or die "Konnte die Datei $datei nicht oeffnen: $!";

@zeilen = <KIELDATEI>;chomp(@zeilen);

Standardverhalten von print: Ausgabe auf STDOUT. print kann aber auch mit einem Dateihandle als Argument aufgerufen werden, so dass die Ausgabe in die entsprechende Datei erfolgt:print LOGDATEI "Datei $datei bearbeitet.\n";

Page 8: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 8

Standarddateihandle für Ausgaben ändern: select

print gibt die Daten standardmäßig nach STDOUT aus.

Der Operator select setzt das Standarddateihandle für Ausgaben (mit print) auf das angegebene Dateihandle:open(AUSGABE, ">$ausgabedatei") or die "Konnte Ausgabedatei $ausgabedatei nicht oeffnen: $!";

select AUSGABE;print "Label: $label\tDauer: $dauer[$label]\n";print "Ergebnis: $ergebnis\n";

Das mit select ausgewählte Standarddateihandle gilt bis zum Ende des Programms – oder bis es auf ein anderes Dateihandle gesetzt wird.

Page 9: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 9

Dateihandles schließen: close

Der Operator close schließt das angegebene Dateihandle und gibt die entsprechenden Systemressourcen wieder frei.

Daher ist es guter Programmierstil, jedes geöffnete Dateihandle wieder zu schließen, sobald es nicht mehr gebraucht wird:open(KIELDATEI, "<$datei") or die "Konnte die Datei $datei nicht oeffnen: $!";

@zeilen = <KIELDATEI>;chomp(@zeilen);close KIELDATEI;

Page 10: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 10

Dateigröße abfragen Wenn eine Datei existiert und nicht leer ist, kann man

ihre Größe (in Bytes) mit dem Dateitest -s abfragen:

$datei = "test.txt";

$dateigroesse = -s $datei;

print "Die Datei $datei ist $dateigroesse Bytes groß.\n";

weitere Dateitests: http://perldoc.perl.org/functions/-X.html

Page 11: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 11

Verzeichnishandles Wenn mehrere Dateien aus einem Verzeichnis gelesen

werden sollen, so muss zunächst eine Liste der Dateinamen erzeugt werden. Dazu kann man ein Verzeichnishandle benutzen.

Ein Verzeichnishandle sieht aus wie ein Dateihandle und verhält sich auch so:

opendir öffnet ein Verzeichnishandle readdir liefert den nächsten Dateinamen aus dem Verzeichnis

(skalarer Kontext) bzw. die Liste aller restlichen Dateinamen (Listenkontext)Achtung: Die Dateinamen enthalten nicht den Verzeichnisnamen!

closedir schließt das Verzeichnishandle

Page 12: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 12

Beispiel: Verzeichnishandles$verzeichnis = "/proj/PhonDat/Data/Read";opendir(KIELVERZ, $verzeichnis) or die "Konnte

Verzeichnis $verzeichnis nicht oeffnen: $!";while ($dateiname = readdir KIELVERZ) { if ($dateiname =~ /\.s1h$/) { $dateiname = "$verzeichnis/$dateiname"; open(KIELDATEI, "<$dateiname") or die "Konnte

Datei $dateiname nicht oeffnen: $!"; ## ... close KIELDATEI; }}closedir(KIELVERZ);

Page 13: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 13

Formatierte Ausgabe: printf (1) Der Operator printf nimmt eine Formatierungszeichenkette, die das

Format angibt, gefolgt von der Liste der Dinge, die ausgegeben werden sollen, und gibt diese auf STDOUT (oder einem anderen Dateihandle) aus.

Die Formatierungszeichenkette enthält eine Reihe so genannter Konversionen:

Jede Konversion beginnt mit einem Prozentzeichen und endet mit einem Buchstaben.

Die Liste, die auf die Formatierungszeichenkette folgt, sollte immer genausoviele Elemente enthalten, wie es Konversionen gibt.

printf "Das Passwort von %s ist noch %d Tage gültig!\n", $name, $gueltig;

Die gebräuchlichsten Konversionen sind: %s eine Zeichenkette %d eine ganze Zahl %f eine Kommazahl (mit Punkt statt Komma)

Page 14: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 14

Formatierte Ausgabe: printf (2) printf wird häufig dafür verwendet, Daten spaltenweise

auszugeben, da für die meisten Konversionen eine Feldbreite angegeben werden kann.

Beispiel: Zahlen rechtsbündig ausgeben (Spaltenbreite: 8 Zeichen)

@zahlen = (23, 123778, -450);foreach $zahl (@zahlen) {

printf "%8d\n", $zahl;}

erzeugt folgende Ausgabe:

23 123778 -450

Ein negativer Wert für die Feldbreite führt zu einer linksbündigen Ausgabe.

Page 15: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 15

Formatierte Ausgabe: printf (3) Mit der %f-Konversion kann man Kommazahlen runden:

printf "%.3f\n", 6 * 7 + 2/3; printf "%.0f\n", 6 * 7 + 2/3;

erzeugt folgende Ausgabe:42.66743

Kombination von Feldbreite und Rundung:printf "%8.3f\n", 6 * 7 + 2/3; printf "%8.0f\n", 6 * 7 + 2/3;

erzeugt folgende Ausgabe: 42.667 43

Um ein Prozentzeichen auszugeben, muss %% verwendet werden:printf "Monatlicher Zinssatz: %.2f%%\n", 5.25/12;

Page 16: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 16

Daten formatieren: sprintf sprintf nimmt die gleichen Argumente wie printf

(abgesehen von dem optionalen Dateihandle).

Die jeweilige Zeichenkette wird jedoch nicht ausgegeben, sondern als Rückgabewert zurückgegeben, der in einer skalaren Variablen gespeichert werden kann:

$dauer = sprintf "%.0f", $dauer;

Page 17: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 17

Subroutinen Wir kennen bereits diverse in Perl eingebaute Funktionen: chomp,

reverse, die, pop, shift usw. Vom Programmierer selbst definierte Funktionen nennt man

Subroutinen. Hierdurch kann man denselben Anweisungsblock in einem Programm mehrmals verwenden.

Subroutinen können an jeder beliebigen Stelle im Programm definiert werden (Standard: entweder alle am Anfang oder alle am Ende).

Subroutinen-Definitionen sind global, d.h. sie gelten im gesamten Programm.

Achtung: Werden in einem Programm zwei Subroutinen mit dem gleichen Namen definiert, so überschreibt die später definierte die frühere!

Page 18: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 18

Subroutinen: Definition und Aufruf Um eine Subroutine zu definieren, benutzt man das Schlüsselwort

sub, gefolgt vom Namen der Subroutine und dem Anweisungsblock (in geschweiften Klammern):

sub marine { $n += 1; ## globale Variable $n print "Hallo, Taucher Nummer $n!\n";}

Um eine Subroutine innerhalb des Programms aufzurufen, verwendet man einfach ihren Namen, dem ein & vorangestellt wird:

$n = 0;&marine;&marine;&marine;&marine;

Page 19: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 19

Subroutinen: Rückgabewerte (1) Oft ist es so, dass man beim Aufruf einer Subroutine das Ergebnis

einer Berechnung in der Subroutine verwenden will, den so genannten Rückgabewert der Subroutine.

In Perl haben alle Subroutinen automatisch einen Rückgabewert, nämlich den Wert des Ausdrucks, der zuletzt ausgewertet wird:sub summe_x_y { print "Aufruf der Subroutine summe_x_y\n"; $x + $y; # Dies ist der Rückgabewert.}$x = 3;$y = 4;$z = &summe_x_y;print "\$z hat den Wert $z.\n";$k = 3 * &summe_x_y;print "\$k hat den Wert $k.\n";

Page 20: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 20

Subroutinen: Rückgabewerte (2) Achtung: Wenn die beiden Anweisungen in der Subroutine

summe_x_y vertauscht werden, ist der Rückgabewert der Rückgabewert von print (normalerweise: 1)! sub summe_x_y { $x + $y; print "Aufruf der Subroutine summe_x_y\n";}

Wichtig: Der "letzte ausgewertete Ausdruck" ist nicht unbedingt identisch mit der letzten Zeile Text in der Subroutine:sub max_x_y { if ($x > $y) { $x; } else { $y; }}

Page 21: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 21

Subroutinen: Rückgabewerte (3) Wird eine Subroutine im Listenkontext aufgerufen, so kann sie

auch eine Liste von Werten zurückgeben:sub liste_von_x_bis_y { if ($x < $y) { $x..$y; } else { reverse $y..$x; }}$x = 11;$y = 6;@z = &liste_von_x_bis_y;print "@z";

Page 22: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 22

Subroutinen: Operator return Der Operator return beendet die Subroutine sofort und

gibt das bei seinem Aufruf angegebene Argument zurück, z.B.: return $x + $y;

Wird return ohne ein Argument benutzt, so wird ein leerer Wert zurückgegeben, also

im skalaren Kontext: undef im Listenkontext: die leere Liste

Guter Programmierstil: return jedesmal benutzen, wenn es einen sinnvollen Rückgabewert gibt.

Page 23: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 23

Subroutinen: Argumente (1) In den bisherigen Beispielen wurden in den Subroutinen globale

Variablen verwendet, d.h. Variablen, die von jedem Teil des Programms aus zugänglich und veränderbar sind. Z.B. hat die Subroutine max_x_y als Rückgabewert das Maximum der beiden globalen Variablen $x und $y:sub max_x_y { if ($x > $y) { return $x; } else { return $y; }}

Viel praktischer ist es jedoch, die Subroutine bei jedem Aufruf mit neuen Werten – so genannten Argumenten – aufrufen zu können, ohne sich auf die globalen Variablen $x und $y verlassen zu müssen.

Page 24: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 24

Subroutinen: Argumente (2) Um eine Liste von Argumenten an eine Subroutine zu übergeben,

werden diese einfach in runden Klammern hin der Aufruf der Subroutine geschrieben:$n = &max(10, 15);

Für die Dauer der Subroutine enthält die spezielle Arrayvariable @_ die Liste der aufrufenden Argumente.

Im obigen Beispiel enthält beim Aufruf der Subroutine max also $_[0] den Wert 10, $_[1] enthält den Wert 15. Diese Werte kann die Subroutine max dann verwenden.

Die Variable @_ existiert in der Subroutine lokal, d.h. wenn es auch eine globale Variable @_ gibt, so wird deren Wert vor dem Aufruf der Subroutine gesichert und nach Beendung der Subroutine wieder hergestellt. Bei verschachtelten Subroutinen-Aufrufen bekommt so jede Subroutine ihr eigenes @_-Array zugeteilt.

Page 25: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 25

Private Variablen (1) Standardmäßig sind alle Variablen in einem Perl-Programm als

globale Variablen angelegt, d.h. sie sind von jedem Teil des Programms aus zugänglich und veränderbar.

Mit dem Operator my können aber private bzw. lexikalische Variablen angelegt werden:sub max { my ($x, $y) = @_; if ($x > $y) { return $x; } else { return $y; }}

Private Variablen gelten nur innerhalb des sie umschließenden Anweisungsblocks:

Andere Variablen außerhalb des Blocks, die auch $x und $y heißen, werden nicht beeinflusst.

Ebenso können die privaten Variablen nicht versehentlich von außen verändert werden.

Die obige Subroutine max kann also in ein beliebiges Perl-Programm eingebaut werden, ohne andere Variablen in dem Programm, die zufällig auch $x und $y heißen, zu verändern.

Page 26: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 26

Private Variablen (2) Private Variablen können in jedem beliebigen Anweisungsblock

verwendet werden, z.B. in einem if-Block oder in Schleifen mit for oder while:@zahlen = 2..5;for (my $i=0; $i <= $#zahlen; $i++) {

my $quadrat = $zahlen[$i] ** 2;print "$zahlen[$i] zum Quadrat ist $quadrat.\n";

}print "\$i hat den Wert $i.\n";

Mit my lassen sich auch neue private Arrays oder Hashes anlegen:my @zahlenliste;my %telefonnummer;

Neu angelegte Variablen sind zu Beginn immer leer (es sei denn, sie werden mit einem bestimmten Wert initialisiert), d.h. undef für skalare Variablen und die leere Liste für Arrays und Hashes.

Page 27: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 27

Private Variablen (3)

Achtung: Der Operator my verändert den Kontext einer Zuweisung nicht!

skalarer Kontext:my $num = @_;

$num enthält als Wert die Anzahl der Elemente in @_

Listenkontext:my ($num) = @_;

$num enthält als Wert das erste Element von @_

Page 28: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 28

Pragma "use strict" Ein Pragma ist eine Anweisung an den Compiler, wie das Programm

kompiliert werden soll. Diese Anweisung wird an den Anfang des Programms geschrieben.

Das Pragma use strict teilt dem internen Perl-Compiler mit, dass innerhalb des Programms einige gute Programmierregeln beachtet werden müssen, u.a. dass jede Variable mit my deklariert werden muss.

Ausnahme: Die in Perl eingebauten Variablen wie z.B. $_, @_, $!, @ARGV, $a und $b (bei sort) und werden niemals extra mit my deklariert.

Damit gibt es schon eine Fehlermeldung zur Compile-Zeit, wenn z.B. eine Variable aus Versehen falsch geschrieben wurde.

Regel: Bei jedem Programm, das mehr als 20 Zeilen lang ist, use strict verwenden und alle Variablen mit my deklarieren!

Page 29: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 29

Beispiel: use strictuse strict;my @woerter = <STDIN>;chomp (@woerter);## ... weitere Anweisungenif ($wort[0] eq "hend") {

## ... weitere Anweisungen}

Fehlermeldung zur Compile-Zeit, da keine Arrayvariable mit dem Namen @wort deklariert wurde. Das Programm wird nicht ausgeführt.

Global symbol "@wort" requires explicit package name at stricttest.pl line 5.

Execution of stricttest.pl aborted due to compilation errors.

Page 30: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 30

Argumentlisten mit variabler Länge Innerhalb einer Subroutine kann leicht überprüft werden, ob die

korrekte Anzahl von Argumenten übergeben wurde:sub max { my ($x, $y) = @_; if (@_ != 2) {

print "WARNUNG! &max braucht genau 2 Argumente!\n"; } if ($x > $y) { return $x; } else { return $y; }}

Allerdings ist es besser, die Subroutine max so umzuschreiben, dass sie mit einer beliebigen Anzahl von Argumenten umgehen kann:sub max { my ($max_aktuell) = shift @_; foreach (@_) { if ($_ > $max_aktuell) { $max_aktuell = $_; } } return $max_aktuell;}

Page 31: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 31

Leere Argumentlisten Angenommen, die neue Subroutine max wird im

Programm folgendermaßen aufgerufen:@zahlen = <STDIN>;chomp @zahlen;$maximum = &max(@zahlen);

Was passiert, wenn @zahlen die leere Liste enthält, weil die eingelesene Datei leer ist?

Die Subroutine max wird mit einer leeren Liste als Argument aufgerufen.

$max_aktuell erhält den Wert undef, und die foreach-Schleife wird keinmal ausgeführt.

Damit ist der Rückgabewert undef.

Page 32: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 32

Beispiel: Indexbestimmung

use strict;my @namen = ("Fred", "Otto", "Betty", "Dino", "Paul");my $index = &welchen_index_hat("Dino", @namen);print "index von Dino: $index\n";sub welchen_index_hat { my ($element, @liste) = @_; foreach my $i (0..$#liste) { if ($element eq $liste[$i]) { return $i; } } return -1;}

Page 33: Programmierkurs für absolute Anfänger cabr/teaching.php Dateihandles, formatierte Ausgabe, Subroutinen Caren Brinckmann

Programmierkurs für absolute Anfänger – Sitzung 11 33

Beispiel: Subroutine summe Die Subroutine summe erhält als Argument eine Liste von Zahlen

und gibt die Summe dieser Zahlen zurück.

my @zahlen = 1..1000;my $summe = &summe(@zahlen);print "Die Summe der Zahlen von 1 bis 1000 ist $summe.\n";sub summe {

my $summe; foreach (@_) { $summe += $_; } return $summe;

}