Kontrollstrukturen


Weitere interessante Möglichkeiten werden mit Kontrollstrukturen und Schleifen eröffnet. Perl unterstützt viele verschiedene Arten von Kontrollstrukturen, welche zum Teil C ähnlich sehen, aber auch an Pascal erinnern. Wir werden hier ein paar davon ansehen.


foreach

Um jedes Element eines Arrays oder einer andern Listenstruktur (wie zun Beispiel die Zeilen eines Files) zu durchlaufen, kann foreach verwendet werden. Das sieht folgendermassen aus:

foreach $morsel (@food) {	# Gehe der Reihe nach durch
				# @food und nenne das 
			     	# Element $morsel

	print "$morsel\n";	# Ausgabe des Elementes
	print "Yum yum\n";	# That was nice
}

Die Anweisungen, welche jedesmal durchgeführt werden sollen, müssen in geschweiften Klammern angegeben werden. Falls @food leer wäre, würde der Block in geschweiften Klammern nie durchlaufen.


Bool'sche Operatoren

Die nächsten Anweisungen testen die Gleichheit zweier Ausdrücke. In Perl wird jede Zahl ungleich Null und jeder nicht leere String als true betrachtet. Die Zahl Null, Null als String und der leere String sind false. Hier sind ein paar Tests auf Gleichheit für Zahlen und Strings:

$a == $b		# $a numerisch gleich $b?
			# Achtung: Nicht = verwenden
$a != $b		# $a numerically ungleich $b?
$a eq $b		# $a gleicher String wie $b?
$a ne $b		# $a und $b nicht der gleiche String?

Es gibt auch die logischen AND, OR und NOT:

($a && $b)		# ist $a und $b true?
($a || $b)		# ist entweder $a oder $b true?
!($a)			# ist $a false?

for

Die for-Struktur von Perl ist vergleichbar mit C:

for (init; test; inkr) {
  	 first_action;
	 second_action;
	 etc
}

Zuerst wird init ausgeführt. Falls test true ist, wird der Block von Anweisungen in geschweiften Klammern ausgeführt. Nach jedem Durchgang wird inkr ausgeführt. Mit der folgenden for-Schleife werden die Zahlen 1 bis 9 ausgegeben:

for ($i = 0; $i < 10; ++$i) {	# Starte mit $i = 1
				# falls $i < 10
				# Inkr. $i vor Block
	print "$i\n";
}

Die reservierten Wörter for und foreach können für beide Strukturen verwendet werden. Perl merkt dann schon, was gemeint ist!


while und until

Das folgende Programm liest eine Eingabe von Keyboard und wiederholt die Anfrage, bis das korrekte Passwort eingegeben wurde.

#!/usr/local/bin/perl
print "Password? ";		# Fragt nach Input
$a = <STDIN>;			# liest input
chomp $a;			# löscht \n am Ende
while ($a ne "fred") {		# Solange $a falsch ist
    print "sorry. Again? ";	# Fragt wieder
    $a = <STDIN>;		# liest
    chomp $a;			# löscht \n am Ende
}

Die while-Schleife sollte soweit klar sein. Wie immer haben wir einen Block von Anweisungen in geschweiften Klammern. Ein paar Dinge können wir hier noch erwähnen: Erstens können wir von STDIN lesen, ohne es zuerst geöffnet zu haben. Zweitens wird mit der Eingabe des Passwortes auch ein newline-character in $a abgespeichert. Drittens ist die chomp-Function dazu da, genau diesen newline-character abzuschneiden.

Um das Gegenteil zu testen, können wir die until-Schleife in genau gleicher Weise verwenden. Damit wird der Block solange ausgeführt, bis der Test true ist und nicht solange er true ist.

Eine andere Art vorzugehen, ist die Verwendung des while- oder until-Tests am Ende des Blocks anstatt am Anfang. Dazu benötigt man noch den do-Operator, welcher den Blockanfang markiert. Falls wir die Meldung sorry. Again weglassen, könnten wir das Passwortprogramm folgendermassen schreiben:

#!/usr/local/bin/perl
do {

	print "Password? ";		# Fragt nach Input
	$a = <STDIN>;		# liest Input
	chop $a;		# löscht \n
} while ($a ne "fred");		# Nochmals solange falscher Input

Uebung

Wir ändern das Programm der letzten Uebung, indem jede Zeile einzeln eingelesen werden soll und die Ausgabe am Anfang die Zeilennummer aufweist. Die folgende Struktur ist vielleicht hilfreich:

while ($line = <INFO>) {
 	...
}

Danach hätten wir noch gerne die Zeilennummern im folgenden Format: 001, 002, ..., 009, 010, 011, 012., etc. Um das zu erhalten, braucht es nur einen Zusatz von vier Buchstaben in einer Zeile. Perl ist da sehr flexibel...


Previous Start Next


last update: 17.11.2000, Roland Dietlicher , Informatikdienste ETH Zürich