Grundlagen in Perl - der Friedrich-List

Werbung
Perl-Grundlagen
Teile der Präsentation von A. Grupp, [email protected]
Perl - Interpreter
Aufgabe des Perl-Interpreters ist die
Umsetzung des Skripts in Maschinensprache
Und die direkte Ausführung des Programms!
Unser erstes Perl-Skript
#!/usr/bin/perl -w
# Die erste Anweisung. Alle Anweisungen sind immer mit
# einem Semikolon zu beenden
print "Hallo Hugo\n"; # Eine Ausgabe mit Newline
$name = "Hugo";
# Eine Variable
print "Hallo $name\n"; #
#
print 'Hallo $name\n'; #
#
print "\n";
#
$name = <STDIN>;
Ausgabe (interpoliert)
-> Hallo Hugo<LF>
Uups! (nicht interpoliert)
-> Hallo $name\n
Zeilenumbruch
# Eingabe über Tastatur (incl.
# der abschließend. Returntaste)
Perl-Variablen (1) - Skalare Variablen
 Perl kennt keine Datentypen wie integer, char, ...
 Skalare sind die wohl am meisten verwendete Form
von Variablen
 Einem Skalar können nach Belieben Werte
zugeordnet werden, gleichgültig ob Zahlen oder
Buchstaben oder Zeichenketten (String)
 Variablen müssen nicht definiert werden. Da wir hier
aber einen mod_perl-Server verwenden (Erklärung
folgt noch) sollten Sie davon keinen Gebrauch
machen und alle Variablen mittels "my" definieren.
 use strict # damit wir die Variablen nicht vergessen
Unser zweites Perl-Skript
#!/usr/bin/perl -w
# Damit wie die Variablendef. nicht vergessen können
use strict;
my $name;
my $alter;
my ($vorname, $groesse);
# Definition einer Variablen
# Und noch eine
# Oder etwas einfacher
$name = "Hugo";
$alter = 12;
$alter = "12";
$alter = $alter + 5;
#
#
#
#
Zuweisung Zeichenkette
Zuweisung Zahl
Zuweisung Zeichenkette
Zeichenkette + Zahl
print "$name ist $alter Jahre alt\n"; # Das geht :-)
Unser drittes Perl-Skript
#!/usr/bin/perl -w
# Dies Skript berechnet den Flächeninhalt eines Rechtecks
# nachdem Höhe und Länge über die Tastatur eingegeben worden sind
print "Bitte gib die Länge des Rechtecks ein: ";
$laenge = <STDIN>;
chomp($laenge);
print "\nBitte gib die Höhe des Rechtecks ein: ";
$hoehe = <STDIN>;
chomp($hoehe);
$ergebnis = $laenge * $hoehe;
print "Dein Rechteck hat den Flächeninhalt $ergebnis.";
# Mit dem Befehl chomp hat es folgendes auf sich: Wenn Du Deine Eingabe abgeschlossen hast,
# schließt Du mit <RETURN> ab und sagst dem Skript so, daß die Eingabe vorgenommen
# worden ist. Das Entscheidende ist, daß nun auch dieses <RETURN> Teil Deiner Eingabe ist.
# Der chomp Befehl entfernt dieses ansonsten unsichtbare sogenannte newline Zeichen.
Perl-Variablen (2) - Arrays
 Perl kennt neben Skalaren (durch ein $ gekennzeichnet wie
z.B. $name, $vorname, ...) auch eindimensionale
Felder (Array's). Deren Kennzeichen ist das @-Zeichen
 Arrays bestehen aus einer Reihe von Skalaren Variablen

@Arbeitstage = ("Montag" , "Dienstag", “Mittwoch“, “Donnerstag“, “Freitag“);
 Der Zugriff auf die einzelnen skalaren Elemente erfolgt
durch einen in eckigen Klammern geschriebenen Index.
Gestartet wird der Index mit dem Wert O, so dass mit dem
Ausdruck $Arbeitstage[3] die Rückgabe des Donnerstags
hervorgerufen wird.
Unser drittes Perl-Skript
#!/usr/bin/perl -w
use strict;
my @arbeitstage;
@arbeitstage = ("Montag" , "Dienstag", "Mittwoch",
"Donnerstag");
# Array mit 4 Feldelemente
@arbeitstage = (@arbeitstage, "Freitag");
# 5 Feldelemente in @arbeitstage
# Einzelne Feldelemente sind Skalare!!! Man spricht
# hier auch von 'skalarem Kontext'. Außerdem werden die
# Feldelemente mit '0' beginnend indexiert
print "@arbeitstage \n";
print @arbeitstage. " \n";
print "$arbeitstage[1]\n";
# Ausgabe aller arbeitstage
# Ausgabe von 5
# Ausgabe von Dienstag
Weitere Beispiele
Beispiel 1:Alle Elemtente eines Arrays durchlaufen
#!/usr/bin/perl -w
use strict;
my @arbeitstage;
my $tag;
@arbeitstage = ("Montag" , "Dienstag", "Mittwoch",
"Donnerstag");
foreach $tag (@arbeitstage)
{
print $tag;
print "\n";
}
Beispiel 2: Der Range Operator
@zahlen = (1 .. 1000)
@alphabet = ("a" .. "z")
Perl-Variablen (3) - Hash




Eine weitere Datenstruktur sind assoziative Array's oder Hash'es. Ihr Kennzeichen ist das %Zeichen
Hier erfolgt das Ansprechen der einzelnen Skalare nicht wie beim Array über einen
vorgegebene Schlüssel, sondern über einen selbst definierten Suchschlüssel.
Einzelne Werte sind wieder als Skalare zu betrachten
#!usr/bin/perl
%familie = ("22 " , "Mayer" , "24 " , "Mueller");
print "$familie{22} \n ";
print "$familie{24} \n ";
#
#
#
#
In Zeile 2 werden dem Hash %familie die Schlüssel und
Werte zugeordnet. Reihenfolge immer Schlüssel - Wert.
In Zeile 3 und 4 werden nun über den Schlüssel die
zugehörigen Familiennamen ausgegeben
Bei einer langen Liste solcher Schlüssel- und Wert-Paare kann man leicht die Orientierung
verlieren, was ein Schlüssel und was ein Wert ist. Um die Lesbarkeit solcher HashInitialisierungen zu erhöhen, bietet Perl einen speziellen Operator (=>) an.
%familie = (22=> “Mayer“, 24 => “Mueller“, 25 =>undef);
Unser viertes Perl-Skript
#!/usr/bin/perl -w
use strict;
my (%familie, @array, $schluessel, $wert, $array, $familie);
%familie = ("22" , "Mayer" , "24" , "Mueller");
print "Ein einzelner Wert:\n";
print "$familie{22} \n";
print "\n Alle Schluessel:\n";
foreach $schluessel (keys(%familie))
{print "$schluessel\n";}
#Die Funktion keys()liefert jeweils einen Schlüssel des Hashs und weist ihn der
#Variablen $schluessel zu. Der Wert dieser Variablen wird dann innerhalb der
#{} ausgeben. Die Funktion foreach () sorgt dafür, dass sich dieser Vorgang
#solange wiederholt, wie Schlüssel im Hash vorhanden sind.
print "\n Alle Werte:\n";
foreach $wert (values(%familie))
{print "$wert\n"};
#Ebenso wie alle verwendeten Schlüssel kann man auch alle verwendeten Werte
#ausgeben.
print "\n Alle
while(@array =
{
print
print
}
Wertepaare:\n";
each(%familie))
#Die Funktion ermittelt ein Wertepaar und
#übergibt Schlüssel und Wert an das @array.
"Schluessel: $array[0] -> ";
"Wert: $array[1]\n";
#$array[0] enthält den Schlüssel
#$array[1] den zugehörigen Wert
Übungsaufgabe 1
Schreiben sie ein Programm, dass nacheinander
Tag, Monat und Jahr ihres Geburtstages einliest.
Vergessen sie dabei nicht, vor jeder Eingabe
einen kurzen Text zu platzieren.
Auch das Programm selbst soll eine Überschrift
auf dem Bildschirm erhalten, damit in knappen
Worten Sinn und Zweck vom Benutzer erkannt
werden können. Die Ausgabe soll anschließend
formatiert ausgegeben werden: 1.1.1980.
Weitere Übungen
Übungsaufgabe 2:
Übungsaufgabe 3:
Übungsaufgabe 4:
Übungsaufgabe 5:
Übungsaufgabe 6:
Übungsaufgabe 7:
Lösung Übungsaufgabe 1
#!/usr/bin/perl
print "Dieses Programm gibt ihren Geburtstag aus.\n\n";
print "Tag ihres Geburtstags eingeben (1-31): ";
chomp($tag = <STDIN>);
print "Monat ihres Geburtstags eingeben(1-12): ";
chomp($monat = <STDIN>);
print "Jahr ihrer Geburt eingeben: ";
chomp($jahr = <STDIN>);
print "Sie haben am $tag.$monat.$jahr Geburtstag.";
Die Hilfetexte werden mit der Funktion print() ausgegeben. Die Eingaben werden
von STDIN, der Standard-Eingabe eingelesen. Diese Eingabe wird immer mit
einem Zeilenumbruch beendet.
Um diesen Zeilenumbruch zu entfernen, wird das letzte Zeichen der Eingabe mit
der Funktion chomp() entfernt. Nur so ist eine saubere Ausgabe des Geburtstags
möglich.
Einlesen der einzelnen Daten und Entfernen des Zeilenumbruchs hätte auch in
mehreren Schritten erfolgen können:
$tag = <STDIN>;
chomp($tag);
Wichtige Kontrollstrukturen (foreach-Schleife)
 Mit Hilfe einer foreach - Schleife
kann jedes Element eines Arrays
nacheinander abgearbeitet werden
 foreach <Schleifenvar.> ( <Array> ){
<Schleifenkörper>
};
#!/usr/bin/perl -w
use strict;
my ($name, @namen);
@namen = ("Andi", "Fritz", "Hugo");
foreach $name (@namen){
print "Hallo $name\n";
}
Wichtige Kontrollstrukturen (for-Schleife)
 Bei der for-Schleife wird die jeweilige
Anweisung sooft ausgeführt, wie als Zahlenwert
angegeben wurde.
#!/usr/bin/perl -w
use strict;
my ($i);
for ($i = 0; $i <15; $i+=1)
{
print “$i\n“;
}
Wichtige Kontrollstrukturen (while-Schleife)
 Mit einer while-Schleife wird eine Anweisung so
lange wiederholt, bis ein vorher angegebener
Wert erreicht wird.
#!/usr/bin/perl -w
use strict;
my ($passwort);
print “Passwort?“;
# Fragt nach der Eingabe einer Zahl
$passwort = <STDIN>;
# Liest den Wert ein
chomp $passwort;
# Letzte Zeichen der Eingabe wird gelöscht, also das drücken
der RETURN-Taste.
while ($passwort ne “hugo“)
#Passwort ungleich Hugo
{
print “Falsches Passwort\n“;
# Ausgabe: Falsches Passw.
print “Neues Passwort eingeben\n“;# Eingabe: Neues Passwort
$passwort = <STDIN>;
chomp $passwort;
}
Wichtige Kontrollstrukturen (until-Schleife)
 Mit einer until-Schleife erreicht man genau das
Gegenteil einer while-Schleife. So lange die
vorher festgelegte Endbedingung nicht erfüllt
ist, wird die Schleife fortgesetzt.
#!/usr/bin/perl -w
use strict;
my ($passwort);
print “Passwort?“;
$passwort = <STDIN>;
chomp $passwort;
# Fragt nach der Eingabe einer Zahl
# Liest den Wert ein
until ($passwort eq “hugo“)
{
print “Richtiges Passwort\n“;
print „Weiter geht`s.\n“;
$passwort = <STDIN>;
chomp $passwort;
}
#Passwort gleich Hugo
Wichtige Kontrollstrukturen(if-then-else)
Auch in Perl gibt es die allgemein bekannte if-then-elseAnweisung mit der Bedingungen überprüft werden.
Die if-Anweisung besteht aus 3 Teilen:
if (zwingend)
elsif (optional, mehrmalig)
else (optional, einmalig)
Der Aufbau in korrekter Perl-Syntax sieht
folgendermaßen aus:
if (Bedingung) {Anweisungsblock}
elsif (weitere Bedingung) {Anweisungsblock}
elsif (weitere Bedingung] {Anweisungsblock}
else {Anweisungsblock}
Wichtige Kontrollstrukturen(if-then-else)
#!/usr/bin/perl
my ($alter);
print "Wie alt bist du? ";
$alter = <STDIN>;
if ($alter<0){
print "Ungültiges Alter!";
}
elsif ($alter<12){
print "Du bist noch ein Kind.";
}
elsif ($alter>11 && $alter<18){
print "Du bist ein Jugendlicher.";
}
else{print "Sie sind erwachsen.";
}
Die wichtigsten Operatoren
Vergleichsoperatoren
('binär') ('lexikalisch')
<
<=
>
>=
==
!=
lt
le
gt
ge
eq
ne
Logische
Operatoren
&& UND
|| ODER
! Negation
Mathematische
Operatoren
+
*
/
+=
-=
*=
/=
%
++
-.
.=
Die Herren Skifahrer
Eine Aufgabe – 4 Lösungen
Lösungsmöglichkeit 1
#!/usr/bin/perl -w
use strict;
my($rang1, $rang2, $rang3, $rang4);
$rang1 = "Sprinzi-Stefan";
$rang2 = "Felsen-Eddy";
$rang3 = "Rau-Ralf";
$rang4 = "Preschel-Sortus";
print "1. Platz $rang1\n";
print "2. Platz $rang2\n";
print "3. Platz $rang3\n";
print "4. Platz $rang4\n";
Lösungsmöglichkeit 2
#!/usr/bin/perl -w
use strict;
my($name);
my(@rang) = ("Sprinzi-Stefan",
"Felsen-Eddy",
"Rau-Ralf",
"Preschel-Sortus",
"Horn-Günthi");
print "Platz 1 und Goldmedaille: $rang[0]\n";
print "Platz 2 und Silbermedaille: $rang[1]\n";
print "Platz 3 und Bronzedaillie: $rang[2]\n";
Lösungsmöglichkeit 3
#!/usr/bin/perl –w
use strict;
my($i);
my(@rang) = ("Sprinzi-Stefan",
"Felsen-Eddy",
"Rau-Ralf",
"Preschel-Sortus",
"Horn-Günthi");
foreach $i (0..4) {
print "Platz ", $i+1, ": $rang[$i]\n";
}
Lösungsmöglichkeit 4
#!/usr/bin/perl -w
use strict;
my($name,$i);
my(@rang) = ("Sprinzi-Stefan",
"Felsen-Eddy",
"Rau-Ralf",
"Preschel-Sortus",
"Horn-Günthi");
foreach $i (0..$#rang) {
print "Platz ", $i+1;
if ($i == 0) {
print " und Goldmedaille";
} elsif ($i == 1) {
print " und Silbermedaille";
} elsif ($i == 2) {
print " und Bronzemedaille";
}
print ": $rang[$i]\n";
}
Übungsaufgaben
Aufgabe 8: Schreiben sie ein Programm, welches zu einem beliebigen Namen einen
entsprechenden Kommentar ausgibt.
Aufgabe 9: Schreiben sie ein Programm, welches bei der Eingabe eines beliebigen
Namens einen entsprechenden Kommentar ausgibt. Das Programm aus Aufgabe 2,
soll 4 mal durchlaufen werden.
Aufgabe 10: Schreiben Sie Programm, welches das kleine Einmaleins ausgibt.
Aufgabe 11: Schreiben Sie ein Skript, das den Benutzer zur Eingabe von zwei Zahlen
auffordert und dann ein Array aus den Zahlen dazwischen erstellt (der Benutzer soll
sowohl die niedrigere als auch die höhere Zahl als erste eingeben können).
Lösung Übungsaufgabe 8
#!/usr/bin/perl -w
use strict;
my ($name, @namen);
@namen = (“Thomas“, “Peter“, “Gerd“, “Benjamin“,
“Maren“, “Kristina“, “Giuseppe“, „Frank“);
foreach $name (@namen){
if($name eq ‘Thomas'){
print "Hallo Meister!\n";
}
elsif($name eq ‘Peter' || $name eq ‘Kristina'){
print "Hallo $name, du Schwarzwaelder\n";
}
else{
print "Hallo $name\n";
}
}
Lösung Übungsaufgabe 9
#!/usr/bin/perl -w
for ($i=0; $i<4; $i+=1)
{
print "Gib dein Name ein:\n";
$namen = <STDIN>;
chomp ($namen);
if ($namen eq "Angela")
{
print "Du bist willkommen";
}
elsif ($namen eq "Sabrina")
{
print "Du bist willkommen";
}
elsif ($namen eq "Valentina")
{
print "Du bist noch ein Kind aber du bist trotzdem willkommen";
}
else
{
print "Du bist nicht die gewuenschte Person! Versuch es noch einmal:\n";
}
$namen = <STDIN>;
chomp ($namen);
}
Lösung Übungsaufgabe 10
#!/usr/bin/perl
print "\nDas Kleine Einmaleins\n\n\n";
for($i=1;$i<11;$i++)
# Beginn der äußeren der beiden Schleifen
{
# beide Schleifen beginnen mit 1 und enden mit 10
for($j=1;$j<11;$j++)
{
printf "%5u",$i*$j;
#Produkt beider Zählvariablen wird definiert und
}
# auf 5 Stellen mit prinf ausgegeben
print "\n";
}
#Im ersten Durchlauf wird also 1*1=1 ausgegeben, danach wird $j erhöht, der
Anweisungsblock wiederholt und 1*2=2 ausgegeben. Nach $j010 wird 1*10=10
ausgegeben und die innere Schleife damit vorerst beendet. Anschließend sorgt ein
Zeilenumbruch für die weitere Ausgabe in der nächsten Zeile
Nun ist der Anweisungsblock der äußeren Schleife einmal durchlaufen und $i wird auf 2
erhöht.
Lösung Übungsaufgabe 11
#!/usr/bin/perl -w
use strict;
my $eins;
my $zwei;
my $array;
print 'Geben Sie eine Bereichsgrenze ein: ';
chomp ($eins = <STDIN>);
print 'Geben Sie die andere Bereichsgrenze ein: ';
chomp ($zwei = <STDIN>);
if ($eins < $zwei) {
@array = ($eins .. $zwei);
} else {
@array = ($zwei .. $eins);
}
print "@array \n";
Die Funktion: printf
#!/usr/bin/perl
$zahl1 = 6.44;
$zahl2 = 62;
$zahl3 = -0.1564;
$zahl4 = 2.7;
$zahl5 = 3827362.746;
printf "%8.3f\n",$zahl3;
printf "%.0f\n",$zahl1;
printf "%.0f\n",$zahl5;
printf "%+-8.0fweiter\n",$zahl1;
printf "%u\n",$zahl1;
printf "%f\n",$zahl2;
printf "%.2f\n",$zahl4;
printf "%u hexadezimal: %x\n",$zahl2,$zahl2;
printf "%u oktal: %o\n",$zahl2,$zahl2;
printf "%.2e\n",$zahl5;
printf "%08u",$zahl2;
# -0.156
#6
#3827363
#+6
weiter
#6
#62.000000
#2.70
#62 hexadezimal: 3e
#62 oktal: 76
#3.83e+006
#00000062
Erläuterung von printf
•%8.3f reserviert 8 Stellen zur Ausgabe der Zahl, 6 Stellen werden genutzt, Ausgabe ist rechts
ausgerichtet, daher zu Beginn zwei Leerstellen,
• %.0f rundet auf eine Ganzzahl, bis .5 wird dabei immer abgerundet,
• %.0f rundet auf eine Ganzzahl, ab .5 wird aufgerundet,
• %+-8.0f setzt ein +- Zeichen vor die Zahl, reserviert 8 Stellen, die Ausrichtung erfolgt links, daher zu
Beginn keine Leerstellen wie in der ersten Zeile,
• %u bewirkt die Ausgabe als Ganzzahl, im Gegensatz zu %.0f wird hier aber nicht gerundet, sondern
nur die Nachkommastellen abgeschnitten.
• %f bewirkt in diesem Fall die Ausgabe als Kommazahl, daher werden nach dem Komma noch
einige 0 angefügt,
• %.2f bewirkt die Ausgabe mit 2 Nachkommastellen, da 2.7 nur eine hat wird eine 0 angefügt,
• %u ist bekannt, %x gibt dieselbe Zahl noch einmal hexadezimal aus,
• %o gibt die Zahl oktal aus,
• %e bewirkt die Ausgabe in wissenschaftlicher Form mit zwei Nachkommastellen,
• %08u ergibt die Ausgabe 00000062, da insgesamt 8 Stellen für die Zahl reserviert sind, und alle
vorderen Stellen mit einer 0 aufgefüllt sind.
Arbeiten mit Dateien
$pfad =“c:\\readme.txt";
open(DATEI, $pfad);
@inhalt=<DATEI>;
close(DATEI);
foreach $zeile (@inhalt)
{
print "$zeile\n";
}
Die erste Zeile definiert die Variable $pfad als den Pfad zu der Datei readme.txt (beachte, daß dem \ ein weiteres \ vorangestellt werden
muß, damit es auch wirklich als \ interpretiert wird). Der open Befehl in der nächsten Zeile öffnet die Datei readme.txt in C:\ zum lesen
und verknüpft die Datei mit einem sogenannten Dateihandle. Die Datei kann nun über diesen Alias angesprochen werden.
In unserem Fall lautet der Dateihandle schlicht DATEI. Der Dateihandle ist willkürlich gewählt. Wir hätten ihn auch MICKEYMAUS
oder HELMUTKOHL nennen können. Du solltest Dateihandles immer GROß schreiben. Einen speziellen Dateihandle kennst Du
eigentlich schon aus Kapitel 4 : <STDIN> ist das Dateihandle, das den Standard Input, also die Tastatur bezeichnet. Wir hatten ihn
behandelt, als wir über Benutzereingaben sprachen.
In der nächsten Zeile, @inhalt=<DATEI>, wird der Inhalt der Datei in einem Rutsch in den array @inhalt gelesen, d.h. die erste Zeile von
readme.txt ist das erste Element von @inhalt, die zweite Zeile von readme.txt ist das zweite Element von @inhalt etc. Beachte hierbei,
daß das Einlesen aus readme.txt über den Dateihandle, dem Alias, DATEI in spitzen Klammern geschieht.
In der close Anweisung wird schließlich die Datei geschlossen, da der Lesevorgang beendet ist. Auch hier wird readme.txt über den
Dateihandle DATEI angesprochen. Vergiß nicht eine Datei nach dem öffnen auch wieder zu schließen.
Die foreach Schleife ist wieder eine alte Bekannte: $zeile durchläuft elementweise den Array @inhalt und enthält die aus readme.txt
eingelesenen Zeilen, die im Schleifenkörper ausgegeben werden. Du erinnerst Dich noch sicherlich, daß \n für ein newline steht, also
einen Sprung in die nächste Zeile darstellt.
Arbeiten mit Dateien
$pfad="C:\\notizblock.txt";
open(hugo, ">>$pfad");
do {
print "Bitte geben Sie eine Notiz ein. Drücken Sie die <RETURN> Taste, wenn Sie keine
Eingaben mehr wünschen: ";
$notiz=<STDIN>;
print hugo "Eintrag: $notiz\n";
}
while ($notiz eq "\n");
close(hugo);
Der entscheidende Punkt ist hier das doppelte > in dem Ausdruck ">>$pfad", welches die Datei zum
anhängenden schreiben öffnet. Innerhalb der do while Schleife wird mittels $notiz=<STDIN>
solange nach einer Notiz gefragt bis der User die RETURN Taste drückt, um den Eingabevorgang
abzuschließen; dies wird am Fuß der Schleife durch while ($notiz eq "\n") geleistet. Jede Eingabe
$notiz wird innerhalb des Schleifenkörpers über den Dateihandle HELMUTKOHL der Datei
notizblock.txt angehängt.
Subroutinen
Sub UnterprogrammName {
Anweisung;
return Wert;
}
- Unterprogramme werden mit dem Schlüsselwort sub gekennzeichnet.
- Danach folgt der Name des Unterprogrammes. Mit diesem Namen wird das Unterprogramm
aufgerufen.
- In geschweiften Klammern wird der Anweisungsblock des Unterprogramms definiert.
- Soll das Unterprogramm einen Wert zurückliefern, muss er mit dem Schlüsselwort return
festgelegt werden. Der Rückgabewert kann eine Variable, das Ergebnis eines Ausdrucks oder ein
konstanter Wert sein.
Subroutinen
# Hauptprogramm
print "Wie ist Dein Name? \n";
# Aufruf der Unterroutine hello
&hallo();
# Unterroutinen
sub hallo {
print "Hallo, mein Name ist Henning.\n";
}
Wie wahrscheinlich jeder erraten wird, gibt dieses Skript die Texte Wie ist Dein Name? und Hallo,
mein Name ist Henning aus. Von der enormen Leistungsfähigkeit dieser Unterroutine abgesehen,
kann man hier das oben bereits erwähnte erkennen:
Die Unterroutine wird über &hallo() aufgerufen, schließlich gibt die Unterroutine nach Ihrem
Aufruf den ersten Text auf dem Bildschirm aus. Hiernach läuft das Hauptprogram weiter und gibt
den zweiten Text aus. Das Skript ist hiermit beendet.
Die Unterroutine wird am Ende nicht nocheinmal abgearbeitet bzw. alle mit mit dem Schlüsselwort
sub beginnenden Anweisungsteile am Ende des Skripts sind nur Definitionen. Eine Subroutine muß
zu Ihrer Ausführung explizit mit Namen aufgerufen werden.
Subroutinen - Beispiel
#!/usr/bin/perl
&Eingabe;
&Berechnung;
&Ausgabe;
sub Eingabe {
print "Volumen-Berechnung eines Quaders\n\n";
print "Bitte geben Sie Höhe, Breite und Tiefe in m ein. ";
print "Trennen Sie die Werte durch ein Leerzeichen.\n";
$werte=<STDIN>;
chomp($werte);
@werte=split(/ /,$werte);
#split = wandelt eine Zeichenkette in ein Array um
}
sub Berechnung {
$volumen=$werte[0]*$werte[1]*$werte[2];
}
sub Ausgabe {
print "Das Volumen beträgt $volumen m³\n\n";
}
Übungsaufgabe 12
Schreiben Sie ein Programm, welches Vorname, Name, Strasse,
PLZ, Ort, Telefon und die E-Mail Adresse von Schülern abfragt und
alle Daten in die Datei schuelerdaten.txt speichert.
Verwenden Sie wenn möglich Subroutinen!
Lösung 1
#!usr/bin/perl
@daten=($name,$vorname,$strasse,$plz,$stadt,$nummer);
$pfad = "C:\\schuelerdaten.txt";
open(datei, ">>$pfad");
do {
print "Hallo Schueler\n";
print "Bitte gebe deinen Namen ein;\n";
$name=<STDIN>;
chomp($name);
print "OK Schueler $name, nun bitte den Vornamen\n";
$vorname=<STDIN>;
chomp($vorname);
print "Bitte gebe deine Strasse ein;\n";
$strasse=<STDIN>;
chomp($strasse);
print "Ok. Schueler $name $nachname. Bitte gebe deine PLZ ein;\n";
$plz=<STDIN>;
chomp($plz);
print "Ok. Schueler $name $nachname. Bitte gebe deine Stadt ein;\n";
$stadt=<STDIN>;
chomp($stadt);
print "Ok. Schueler $name $nachname aus $stadt. Bitte gebe deine Telefonnummer ein;\n";
$nummer=<STDIN>;
chomp($nummer);
print "OK. Du bist $name $vorname und wohnst im/in der $strasse in $plz $stadt und wir erreichen die unter $nummer\n";
print datei "Eintrag:$name\n $vorname\n $strasse\n $plz\n $stadt\n $nummer\n";
}
while (@daten eq "\n");
close(datei);
Lösung 2
#!/usr/bin/perl -w
$pfad = "c:\\schuelerdaten.txt";
open(DATEI, ">>$pfad");
do{
&Eingabe;
&Ausgabe;
sub Eingabe {
print "Gib deinen Namen, Vornamen, Strasse, PLZ, Stadt, Telefon und deine E-mail adresse ein!";
print "Bitte trenne deine Eingaben durch ein Komma!\n";
$werte = <STDIN>;
chomp($werte);
@werte =split(/,/,$werte);
}
sub Ausgabe {
print DATEI "$werte";
#print "Deine Angaben:\n $werte[0] $werte[1]\n $werte[2]\n $werte[3] $werte[4]\n $werte[5] $werte[6]\n";
# Keine Ausgabe in der Konsole
}
}
while ($werte eq "\n");
close(DATEI);
Übergabe von Argumenten und Rückgabe von Werten
Argumente übergeben:
Argumente sind Parameter, die man beim Aufruf eines Unterprogramms übergeben und innerhalb des
Unterprogramms verarbeiten kann. Die Argumente werden in runde Klammern eingeschlossen und an den Namen
des Unterprogramms angeschlossen. In Perl werden die Argumente stets mithilfe des vordefinierten Arrays @_ zur
Verfügung gestellt.
Syntax des Aufrufs von Unterprogrammen mit Argumenten:
&UnterprogrammName (Argument1, ...);
Durch die besondere Art der Parameterübergabe kennt Perl keine benannten Argumente. Den ersten übergebenen
Parameter erhält man über die Variable $_[0], den zweiten über $_[1] usw.
Rückgabewert:
Wenn nötig kann man in einer Funktion einen Rückgabewert definieren. Dies kann beispielsweise das Resultat
einer Berechnung oder ein Wahrheitswert sein. Der Rückgabewert wird mit dem Schlüsselwort return festgelegt.
Sie können skalare Variablen, aber auch Arrays oder Hashes zurückgeben.
sub Summe
$a = 10;
$b = $a + 5;
return $b;
# Rückgabewert des Unterprogramms ist 15;
Übergabe von Argumenten und Rückgabe von Werten
Beispiel: Das Perl-Programm soll mithilfe einer Funktion die kleinste von einer beliebigen Anzahl Zahlen
bestimmen. Die Zahlen werden mit Leerzeichen getrennt, über die Tastatur eingegeben. Die eingegebenen Werte
werden dem Unterprogramm als Argument übergeben. Als Ergebnis liefert es die kleinste Zahl.
#!/usr/bin/perl
&Eingabe;
&Ausgabe;
sub Eingabe {
print "Geben Sie eine beliebige Anzahl Zahlen ein.\n\n";
print "Trennen Sie die Zahlen jeweils durch ein Leerzeichen.\n";
$werte=<STDIN>;
chomp($werte);
}
sub Ausgabe {
print "Die kleinste Zahl ist ".&Kleinste($werte);
}
sub Kleinste {
local $kleinste;
@werte=split(/ /,$_[0]);
foreach(@werte) {
if (!$kleinste) {
$kleinste=$_;
} elsif ($_<$kleinste) {
$kleinste=$_;
}
}
return $kleinste;
}
Referenzen verwenden
1. Array als Argumente von Unterprogrammen
Wenn man ein Array als Argument übergibt, verliert es seine Eigenständigkeit. Es wird in seine
Elemente aufgegliedert, auf die man über das vordefinierte Array @_ innerhalb des Unterprogramms
zugreifen kann.
Beispiel 1:
&Summe ($zahl1, @zahlen, $zahl2);
Innerhalb des Unterprogramms enthält das Array @_ die Werte in folgender Reihenfolge:
@_ = ($zahl1, $zahlen[0], $zahlen[1], ....., $zahlen[n], $zahl2);
Soll das Array erhalten bleiben, muss man es als Referenz, d.h. als Zeiger auf einen Speicherplatz,
übergeben.
Beispiel 2:
&Summe ($zahl1, \@zahlen, $zahl2);
In diesem Fall wird eine Referenz auf das Array @zahlen übergeben:
$zahl1 = $_[0];
$zahlen = @{$_[1]};
$zahl2 = $_[2];
Referenzen verwenden
2. Referenzen auf Variablen erstellen
Referenzen auf eine Variable erstellt man durch das Voranstellen eines Bachslashs vor den Variablennamen. Man
kann Referenzen auf skalare Variablen, Arrays, Hashes oder andere Referenzen erstellen. Die Referenz selber ist
ein skalarer Wert und kann in einer entsprechenden Variablen oder in einem Arrayelement gespeichert werden.
Beispiel:
$referenz = \$wert;
$referenz = \@werte;
$referenz = \%werte;
# Referenz auf eine skalare Variable
# Referenz auf ein Array
# Referenz auf ein Hash
3. Dereferenzierung
Eine Referenz enthält nur die Speicheradresse einer Variablen. Um wieder auf den eigentlichen Wert der Variablen
zugreifen zu können, müssen Sie eine Dereferenzierung durchführen. Dabei wird die Speicherreferenz aufgelöst.
Bei der Dereferenzierung wird der Referenzvariablen das ursprüngliche Kennzeichen des Datentyps ($, @, %)
vorangestellt.
Beispiel:
$referenz = \$wert;
print $$referenz;
# Referenz auf eine skalare Variable
# Ausgabe des ursprünglichen Wertes
$referenz = \@werte;
@array = @$referenz
Print $$referenz[0];
# Referenz auf ein Array
# Zugriff auf das ursprüngliche Array
# Ausgabe eines einzelnen Elements
Vordefinierte Perl - Funktionen
Neben den Unterprogrammen, die man selbst erstellt, enthält Perl bereits eine grosse Zahl vordefinierter
Funktionen. Die Syntax des Aufrufs von Perl internen Funktionen erfolgt über
$variable = funktionsname (Argumente);
Falls ein Ergebnis zurückgeliefert wird, kann es einer Variablen zugewiesen oder in einem Ausdruck
(print “$variable“) verwendet werden.
Funktion
Erklärung
Beispiel
Ergebnis
chomp ($str);
Löscht den Zeilenumbruch \n am Ende
der Zeichenkette
chomp (“Welt
\n“);
“Welt“
chop ($str);
Löscht das letzte Zeichen einer
Zeichenkette
chop (“Welt“);
„Wel“
lc ($str)
lcfirst ($str)
Umwandlung in Kleinbuchstaben
Nur erstes Zeichen umwandeln
lc (“Welt“);
“welt“
uc ($str)
ucfirst ($str)
Umwandlung in Großbuchstaben
Nur erstes Zeichen umwandeln
uc (“Welt“);
“WELT“
sprintf (“Format“,
$variable);
Formatierte Ausgabe von Werten
sprintf (“%.2f“,
23.5);
23.50
int ($zahl)
Liefert den ganzzahligen Teil einer
Dezimalzahl
int (24.75)
24
rand ($zahl)
Liefert eine Zufallszahl, die kleiner ist als
$zahl
rand (6)
5.4071
srand ($zahl)
Initialisiert den Zufallsgenerator
srand (time ^ $$)
split (/ /, $str);
Wandelt eine Zeichenkette anhand eines
Trennzeichens in ein Array
split (/ /, “Hallo
Welt“);
“Hallo“
“Welt“
Übungsaufgaben
Aufgabe 12:
•
•
•
•
•
•
Erstellen Sie ein Programm, das Zufallszahlen für das Lottospiel 6 aus 49 erzeugt.
Initialisieren Sie den Zufallsgenerator mit der entsprechenden Funktion.
Kapseln Sie die Erzeugung einer einzelnen Lottozahl in einem Unterprogramm
LottoZahl.
Beachten Sie, dass die Funktion zur Erzeugung einer Zufallszahl beim Wert 0
beginnt und Dezimalzahlen liefert.
Rufen Sie das Unterprogramm in einer geeigneten Schleife sechsmal auf, und geben
Sie das Ergebnis aus.
Verändern Sie das Programm so, dass es keine doppelten Zufallszahlen erzeugt. Zu
diesem Zweck können Sie die erzeugte Zahl als Schlüsselwert in einem Hash
verwenden.
Aufgabe 13:
•
•
•
•
•
•
•
•
•
•
Das Programm soll mithilfe eines Unterprogramms prüfen, ob ein über die Tastatur
eingegebener Städtenamen in einem Array vorhanden ist.
Erzeugen Sie ein Array mit verschiedenen Städtenamen.
Erstellen Sie eine Tastaturabfrage, um den Namen einer Stadt einzulesen. Denken Sie an das
Entfernen des Zeilenvorschubs am Ende der Eingabe.
Die Unterfunktion soll zwei Argumente erhalten. Das erste Argument ist die gesuchte Stadt.
Als zweites Argument soll das Array mit den Städtenamen übergeben werden. Damit das
Array erhalten bleibt, müssen Sie es als Referenz übergeben.
Erzeugen Sie im Unterprogramm zwei lokale Variablen für den Namen der Stadt und die
Städteliste.
Weisen Sie den lokalen Variablen die übergebenen Werte zu. Dereferenzieren Sie dabei den
Verweis auf das Array.
Durchlaufen Sie in einer Schleife die Elemente des Arrays, und prüfen Sie, ob der Stadtname
vorhanden ist. In diesem Fall soll der Wert 1 (true) zurückgegeben werden.
Ist die Stadt nicht gefunden worden, soll das Unterprogramm den Wert 0 (false) liefern.
Bearbeiten Sie den Vergleich so, dass die Groß- und Kleinschreibung keine Rolle spielt.
Rufen Sie das Unterprogramm auf, und geben Sie je nach zurückgeliefertem Ergebnis eine
entsprechende Meldung aus.
Lösungen zu den Übungsaufgaben
Aufgabe 12:
#!/usr/bin/perl
srand(time ^ $$);
print "Das Programm erzeugt Zahlen für das Spiel 6 aus 49:\n";
for($i=1;$i<=6;$i++) {
print &LottoZahl." ";
}
sub LottoZahl {
do {
$zahl=int(rand(48)+1);
} while (exists($zahlen{$zahl}));
$zahlen{$zahl}=1;
return $zahl;
}
Aufgabe 13:
#!/usr/bin/perl
@staedte=qw(Berlin Leipzig München Hannover Rostock Stuttgart Köln);
print "Bitte geben Sie einen Städtenamen ein: ";
$stadt=<STDIN>;
chomp($stadt);
if (PruefeStadt($stadt,\@staedte)) {
print "$stadt ist in der Liste enthalten\n";
} else {
print "$stadt ist nicht in der Liste enthalten\n";
}
sub PruefeStadt {
local ($stadt,@liste);
$stadt=$_[0];
@liste=@{$_[1]};
foreach(@liste) {
if (lc($_) eq lc($stadt)) {
return 1;
}
}
return 0;
}
Weitere Übungsaufgaben
1. Schreiben Sie ein Divisions-Skript, in dem Sie um die
Eingabe von zwei Zahlen bitten und prüfen, dass keine
der eingegebenen Zahlen negativ und die zweite Zahl
nicht Null ist. Wenn beide Zahlen diesen
Anforderungen entsprechen, teilen Sie die erste durch
die zweite Zahl, und geben Sie das Ergebnis aus.
2. Schreiben Sie ein Skript, das Sie um zwei Arrays bittet
und dann ein drittes Array erstellt, das nur die
Elemente enthält, die in beiden anderen Arrays
vorkommen (die Schnittmenge dieser Arrays).
Übungsaufgabe 1
#!/usr/bin/perl -w
print 'Geben Sie die erste Zahl ein: ';
chomp($zahl1 = <STDIN>);
print 'Geben Sie die zweite Zahl ein: ';
chomp($zahl2 = <STDIN>);
if ($zahl1 < 0 && $zahl2 < 0) {
print "Keine negativen Zahlen!\n";
}
elsif ( $zahl2 == 0)
{
print "Die zweite Zahl darf nicht 0 sein!\n";
}
else {
print "$zahl1 geteilt durch $zahl2 ist ";
$ergebnis = $zahl1 / $zahl2;
printf("%.2f\n", $ergebnis );
}
Übungsaufgabe 2
#!/usr/bin/perl -w
print 'Geben Sie das erste Array ein: ';
chomp($input = <STDIN>);
@array1 = split(/ /, $input);
print 'Geben Sie das zweite Array ein: ';
chomp($input = <STDIN>);
@array2 = split(/ /, $input);
foreach $el (@array1) {
foreach $el2 (@array2) {
if (defined $el2 && $el eq $el2) {
$final[$#final+1] = $el;
undef $el2;
last;
}
}
}
print "@final\n";
Herunterladen