Heike Zinsmeister IMS IMS Kontrollstrukturen (1) Kontrolle über die Ausführung von Programmteilen, z.B. durch die Einführung einer Bedingung Bedingungen stehen in runden Klammern Anweisungen (= auszuführender Programmblock) stehen in geschweiften Klammern Auswertung von Bedingungen über Boolsche Wahrheitswerte: wahr/falsch Bedingungen if, unless, elsif Schleifen while, until, foreach, for, Blöcke Schleifenkontrolle last, next, redo Ergänzungen zu Kontrollstrukturen Beispiele für benannte Blöcke Modifier-Schreibweise Logische Operatoren: Ternärer Operator Standardvariable $ Einführung in Perl für Linguisten Kontrollstrukturen Heike Zinsmeister Kontexte etc. IMS 1 Heike Zinsmeister Perl, 12.12.03 Perl, 12.12.03 IMS wahr) siehe auch Handout vom 17.10.03 $v = (1 < 2); print "Auswertung der Bedingung:-$v-\n"; Kontrollstrukturen dienen u.a. zur Steuerung von Schleifen Heike Zinsmeister Die Anweisung wird genau dann ausgeführt, wenn die Bedingung wahr ist. keine eigener Datentypen für Boolsche Werte in Perl Endlosschleife 2 if-Bedingung (1) Kontrollstrukturen (1) – ’falsch’ = undef, ’0’ und leerer String – ’wahr’ = restliche Stings und Zahlen ( !(undef) Kontexte etc. if ($v) { print "wahr\n"; } else { print "falsch\n"; } Abbruch mit ctrl-c (ctrl-z) Ausgabe: :> Auswertung der Bedingung:-1:> wahr Perl, 12.12.03 Kontexte etc. 3 Perl, 12.12.03 Kontexte etc. 4 Heike Zinsmeister IMS IMS if-Bedingung (2) Heike Zinsmeister unless-Bedingung (1) $v = (1 > 2); print "Auswertung der Bedingung:-$v-\n"; Umkehrung der if-Bedingung (unless (...) entspricht if (! (...)) if ($v) { print "wahr\n"; } else { print "falsch\n"; } Anweisung wird genau dann ausgeführt, wenn Bedingung falsch ist $v = (1 < 2); print "Auswertung der Bedingung:-$v-\n"; unless ($v) { print "wahr\n"; } else { print "falsch\n"; } Ausgabe: :> Auswertung der Bedingung:-:> falsch Ausgabe: :> Auswertung der Bedingung:-1:> falsch Kontexte etc. IMS 5 Heike Zinsmeister Perl, 12.12.03 Perl, 12.12.03 Heike Zinsmeister siehe auch Handout vom 17.10.03 zusammen mit if-Bedingung komplexe Kontrollstruktur folgt auf if-Bedingung erlaubt Kette von sich ausschließenden Bedingungen wenn eine Bedingung in der Kette zutrifft, wird gesamte Kontrollstruktur abgebrochen, d.h. restliche Bedingungen werden nicht mehr überprüft sinnvollerweise von else-Bedingung abgeschlossen unless ($v) { print "wahr\n"; } else { print "falsch\n"; } ggf. ineffizient, wenn bei langer Liste alle Bedingungen abgearbeitet werden müssen Ausgabe: # !!! Kontexte etc. 6 elsif-Klausel $v = (1 > 2); print "Auswertung der Bedingung:-$v-\n"; Perl, 12.12.03 Kontexte etc. IMS unless-Bedingung (2) :> Auswertung der Bedingung:-:> wahr # !!! 7 Perl, 12.12.03 Kontexte etc. 8 Heike Zinsmeister IMS IMS wenn Bedingung wahr ist, wird Anweisung ausgeführt und Bedingung erneut überprüft (d.h. while-Schleife wird erneut aufgerufen) Beispiel für Endlosschleife: Bedingung ist konstanter String und daher immer wahr Abbruch mit ctrl-c (oder ggf. ctrl-z) while ($in = "test") { print "eingelesen: $in\n"; } wenn Bedingung immmer wahr ist, entsteht eine Endlosschleife Perl, 12.12.03 # Abbruch, wenn $n = 10 # letzte Ausgabe: ’9’ # Erhöhen des Zählers Kontexte etc. IMS 9 Heike Zinsmeister Perl, 12.12.03 $n = 0; while ($n < 10) { print "$n\n"; $n++; } while überprüft, ob Bedingung wahr ist siehe auch Handout vom 24.10.03 while-Schleife (2) while-Schleife (1) Heike Zinsmeister IMS Heike Zinsmeister # Abbruch, wenn $n = 11 # letzte Ausgabe: ’10’ # Erh{\"o}hen des Z{\"a}hlers Anweisung wird solange ausgeführt bis die Bedingung wahr ist Überprüfung, ob Bedingung falsch ist geht eine Liste (ein Array) elementweise durch bei jedem Schleifendurchlauf wird Anweisung für das aktuelle Element neu ausgeführt Umkehrung von while-Schleife Perl, 12.12.03 10 foreach-Schleife (1) until-Schleife $n = 0; until ($n > 10) { print "$n\n"; $n++; } Kontexte etc. Elementinhalte können durch die Anweisung verändert werden, d.h.. Liste/Array wird nicht nur aufgerufen, sondern kann manipuliert werden @array = qw /Julian Nick Fab Nicolai Albert /; foreach $x (@array) { $x = reverse $x; } print "@array\n"; # :>nailuJ kciN baF ialociN treblA Kontexte etc. 11 Perl, 12.12.03 Kontexte etc. 12 Heike Zinsmeister IMS IMS @array = (1,2,3,4); $x = "Hoppla!"; foreach $x (@array) { print "In der Schleife \$x = ‘$x’\n"; } print "Ausserhalb der Schleife \$x =‘$x’\n"; auch bekannt; nur zur Vollsändigkeit in runder ‘Bedingungs-Klammer’ dreifache Kontrollstruktur, getrennt durch Semikolon Kontrollvariable, hier $x, wird nach Schleife auf Ausgangswert gesetzt (for (Initialisierung ; Test ; Inkrement) {...} for-Schleife erlaubt bei Iterierung mitzuzaehlen foreach-Schleife (2) ist getarnte while-Schleife (Programm unten entspricht genau dem Programm auf der Folie ‘while-Schleife (1)’) Ausgabe: :> :> :> :> :> Heike Zinsmeister In der Schleife $x = ‘1’ In der Schleife $x = ‘2’ In der Schleife $x = ‘3’ In der Schleife $x = ‘4’ Ausserhalb der Schleife $x =‘Hoppla!’ for ($i = 0 ; $i < 10 ; $i++) { print "$i\n"; } Ausgabe: Zahlen von 0 bis 9 Kontexte etc. IMS 13 Heike Zinsmeister Perl, 12.12.03 Perl, 12.12.03 Heike Zinsmeister last-Operator können mit Label (’Sprungmarke’) benannt werden und durch Schleifen-Kontrollstrukturen (next, last, redo) angesprochen werden Bsp. siehe bei last (NB: Beispiel könnte analog mit if-, elsif-, else-Struktur ausgedrückt werden 15 steht im Text einer Anweisung beschränken Geltungsbereich von lokalen Variablen entsprechen einfachster Kontrollstruktur (ohne Bedingung, mit einmaligem Programmdurchlauf) geschweifte Klammern markieren Block Kontexte etc. 14 IMS Blöcke Perl, 12.12.03 Kontexte etc. beendet Schleife sofort (‘Notausgang’ aus Schleifenblock) $in ="def"; SWITCH: { if ($in =~ /^abc/) { $v ="1"; last SWITCH; } if ($in =~ /^def/) { $v = "2"; last SWITCH; } $v = "0"; } print "$v\n"; # Label Ausgabe: :> 2 Perl, 12.12.03 Kontexte etc. 16 Heike Zinsmeister IMS IMS next- und redo-Operatoren Heike Zinsmeister Schema für last, next, redo next while () { <-- ’redo’ springt hierher – springt an das Ende des aktuellen Blocks, ohne Schleife zu beenden, d.h. springt zur nächsten Iteration ggf. Anweisungen; Kontroll-Anweisung; # last/next/redo redo ggf. Anweisungen; – wiederholt die aktuelle Iteration – Bedingung wird nicht erneut überprüft <-- ’next’ springt hierher } <-- ’last’ springt hierher ggf. weiteres Programm; Kontexte etc. 17 IMS Heike Zinsmeister Perl, 12.12.03 Perl, 12.12.03 IMS Perl, 12.12.03 vor if: a nach if: a vor if: b Ende der Schleife Kontexte etc. Heike Zinsmeister while ($in = <> ) { chomp($in); @array = split (/ /,$in); foreach $wort (@array) { $gesamt++; if ($wort =~ /\W/ ) next; # Ueberspringt Rest des lokalen Blocks } else { $gueltig++; $zaehler{$wort}++; } ## next springt an diese Stelle ## } } $types = scalar keys %zaehler; print "insgesamt: $gesamt Token. Davon gueltig: $gueltig Token ($types Types) foreach $wort (sort {$zaehler{$b} <=> $zaehler{$a}} keys %zaehler){ printf "%-12s %d\n",$wort, $zaehler{$wort};} while ($in =<>) { chomp($in); print "vor if: $in\n"; if ($in =~ /b/) { next; # last; redo; } print "nach if: $in\n"; } print"Ende der Schleife\n"; Ausgabe: :> vor if: a :> :> nach if: a :> :> vor if: b :> :> vor if: c :> :> nach if: c :> Ende der Schleife 18 Weiteres Beispiel für next Beispiel Datei: a b c Kontexte etc. :> :> :> :> :> :> :> vor if: a nach if: a vor if: b vor if: b vor if: b vor if: b ... 19 Perl, 12.12.03 Kontexte etc. 20 Heike Zinsmeister IMS IMS Heike Zinsmeister Beispiel für benannte Blöcke (1) foreach $in (@woerter) { ## redo springt hierher ## print "Tippe das Wort: ’$in’ ohne auf die Tastatur zu schauen.\n"; $versuch = <STDIN>; chomp ($versuch); if ($versuch ne $in) { print "Da hast Du Dich leider vertippt.\n"; $fehler++; redo; # an Anfang des Schleifenkoerpers zurueck } } print "Du hast $fehler Fehler gemacht.\n"; # 10-Finger-System @woerter = qw/Perl Semesterapparat Konstanz Wahrscheinlichkeit Bodensee/; $fehler = 0; Ziel: Zähle Wörter einer Datei, ignoriere Satzzeichen, breche ab, wenn Text bereits von Kollegin Tina bearbeitet wurde (Markierung ’%%Tina’) Beispiel für redo-Operator Textdatei: In diesem Kapitel lernen wir ein Merkmal von Perl kennen , durch das %%Tina Perl sich hinter keiner großen Programmiersprachen zu verstecken braucht - Hashes . erwartete Ausgabe: Zählung von 12 Wörtern Kontexte etc. IMS 21 Heike Zinsmeister Perl, 12.12.03 Perl, 12.12.03 IMS 22 Heike Zinsmeister Beispiel für benannte Blöcke (3) Programm ohne Blocklabel Ausgabe: 23 Woerter eingelesen. Beispiel für benannte Blöcke (2) Kontexte etc. Programm mit Blocklabel Ausgabe: 12 Woerter eingelesen. $wortanzahl=0; while ($in =<>) { chomp($in); @array = split (/ /,$in); foreach $x (@array) { if ($x =~ /^(%%Tina)/) { # Markierung, dass Text von hier an # von Tina bearbetet wurde last ; # beendet lokale Schleife } elsif ($x =~ /^[\.,;:-_?!]$/) { next; # Satzzeichen ignorieren, Rest des Blocks ueberspringen } $wortanzahl++; }} print "\n$wortanzahl Woerter eingelesen.\n"; $wortanzahl=0; TEXT: while ($in =<>) { chomp($in); @array = split (/ /,$in); foreach $x (@array) { if ($x =~ /^(%%Tina)/) { # Markierung, dass Text von hier an # von Tina bearbetet wurde last TEXT ; # beendet Block TEXT } elsif ($x =~ /^[\.,;:-_?!]$/) { next; # Satzzeichen ignorieren, Rest des Blocks ueberspri } $wortanzahl++; }} print "$wortanzahl Woerter eingelesen.\n"; Perl, 12.12.03 Perl, 12.12.03 Kontexte etc. 23 Kontexte etc. 24 Heike Zinsmeister IMS &&: Auswertung von linkem Konjunkt nur, wenn rechtes wahr ist ||: Auswertung von linkem Konjunkt nur, wenn rechtes falsch Klammern können weggelassen werden ist enspricht eher englischer Syntax ’Short-Circuit’-Operatoren neu: ternärer Operator ? : kompaktere Schreibweise abhänige Auswertung der Konjunkte die bekannten binäre Operatoren || und && sind teilweise auswertend Anweisung steht vor Bedingung Logische Operatoren (1) Umkehrung der Kontrollstruktur Modifier-Schreibweise Heike Zinsmeister last TEXT if $x =~ (\%\%Tina)/); &fehler( "falsche Eingabe") unless &gueltig($eingabe); $i *= 2 until $i >$j; print " ", ($n += 2) while $n < 10; Kontexte etc. IMS 25 Heike Zinsmeister Perl, 12.12.03 Perl, 12.12.03 Kontrollstruktur Kontexte etc. IMS Ternärer Operator (1) 26 Heike Zinsmeister Ternärer Operator (2) if-then-else-Test Ausdruck ? wahr Ausdruck : falsch Ausdruck IMS Beispiele $x =7; $out = ($x == 1) ? "wahr" : "falsch"; print "$out\n"; if ($breite < 10) { $groesse = $groesse = "klein"; ($breite < 10) ? "klein": } ($breite < 20) ? "mittel": elsif ($breite < 20 ) { ($breite < 50) ? "gross": $groesse = "mittel"; "sehr gross"; # Default } elsif ($breite < 50) { $groesse = "gross"; } else { $groesse = "sehr gross"; # Default } #:> falsch $out = (&alter($jahr) > 30) ? "aelter als 30" : "noch nicht aelter als 30"; print "$out\n"; Perl, 12.12.03 Kontexte etc. 27 Perl, 12.12.03 Kontexte etc. 28 Heike Zinsmeister IMS IMS Maximum eines Arrays Standardvariable $ beliebteste Standardvariable Ternärer Operator (3) Heike Zinsmeister wird von Funktionen defaultmäßig aufgerufen, wenn keine Argumentangabe, z.B. von print, foreach, while, chomp @array = qw /4 89 100 5/; $maximum = &max(@array); # Aufruf der Subroutine print "Das Maximum ist $maximum.\n"; Perl, 12.12.03 Kontexte etc. IMS 29 Heike Zinsmeister foreach (1..10) { print "Gesehen: $_.\n"; } while ($in=<>) { chomp($in); print "$in"; } while (<>) { chomp; print; } Perl, 12.12.03 sub max{ # Definition der Subroutine my $temp_max = shift; foreach $x (@_){ $temp_max = ($temp_max > $x) ? $temp_max : $x; } return ($temp_max); } foreach $x (1..10) { print "Gesehen: $x.\n"; } IMS foreach (@woerter) { ## redo springt hierher ## print "Tippe das Wort: ’$_’ ohne auf die Tastatur zu schauen.\n"; chomp ($versuch = <STDIN>); if ($versuch ne $_) { print "Da hast Du Dich leider vertippt.\n"; $fehler++; redo; # an Anfang des Schleifenkoerpers zurueck } } print "Du hast $fehler Fehler gemacht.\n"; Kontexte etc. 30 Heike Zinsmeister Zum Nachlesen redo-Beispiel – kurz # 10-Finger-System @woerter = qw/Perl Semesterapparat Konstanz Wahrscheinlichkeit Bodensee/; $fehler = 0; Perl, 12.12.03 Kontexte etc. Schwartz, Randal L. & Tom Phoenix, 2002. Einführung in Perl. Köln, O’Reilly – Kontrollstrukturen: Kapitel 10 – Standardvariable: Kapitel 3, 6 31 RRZN Perl-Skript: Kapitel 5 Perl, 12.12.03 Kontexte etc. 32