Übungen zum Perlkurs, Teil Operatoren Musterlösung A: Operatoren A1: Schreibe ein Programm, das nach einer Zahl fragt und dann ausgibt, ob die Zahl gerade oder ungerade ist. • Tipp: Verwende short circuiting oder den conditional-Operator. 1 2 3 4 5 6 7 8 use strict; use warnings; print 'Bitte Zahl eingeben: '; my $num = <STDIN>; ($num % 2) ? print 'ungerade' : print 'gerade'; print "\n"; A2: Erweitere dass Programm so, dass die Eingabe nicht ganzzahliger Zahlen erkannt wird und eine adäquate Ausgabe erfolgt. • Tipps: o o 1 2 3 4 5 6 7 8 int() gibt den ganzzahligen Anteil einer Zahl zurück der conditional-Operator kann verschachtelt werden: (COND)? EXPR1 : (COND2) ? EXPR2 : (COND3) ? EXPR3 : EXPR4. Dieser Operator ist rechtsassoziativ. use strict; use warnings; print 'Bitte Zahl eingeben: '; my $num = <STDIN>; ($num != int($num)) ? print 'nicht ganzzahlig' : ($num % 2) ? print 'ungerade' : print 'gerade'; print "\n"; B: Subroutinen B1: Schreibe ein Programm mit einer Subroutine, die drei Zahlen als Argument nimmt und den Median zurückgibt (return und nicht print). Der Median soll dann im Hauptprogramm ausgegeben werden. 1 2 3 4 5 6 use strict; use warnings; my $med = median(2,6,10); print $med, "\n"; sub median { my ($x, $y, $z) = sort {$a <=> $b} @_; return $y; 10 } 7 8 9 B2: Erweitere das Programm: Wenn weniger als drei Argumente übergeben werden, soll die Subroutine eine Warnmeldung ausgeben. Die Ausgabe des Medians soll in diesem Falle nicht erfolgen. • Tipp: die Subroutine kann als return value undef zurückgeben (das wird genau so eingegeben; nicht quoten!). Mit defined() kann man testen, ob eine Variable definiert oder undefiniert ist. 1 2 3 4 5 6 7 8 use strict; use warnings; my $med = median(2,6,10); (defined($med)) or die "Mindestens 3 Argumente angeben"; print $med, "\n"; sub median { @_ >= 3 or return undef; my ($x, $y, $z) = sort {$a <=> $b} @_; 11 return $y; 12 } 9 10 B3: Verallgemeinere die Subroutine aus B1 so, dass der Median einer beliebig langen Liste von Zahlen zurückgegeben wird. • Tipp: verwende den conditional-Operator. 1 2 3 4 5 6 7 8 use strict; use warnings; my $med = median(2,6,11,13); print $med, "\n"; sub median { my @numbers = sort {$a <=> $b} @_; 9 my $median = (@numbers % 2) ? $numbers[(@numbers - 1)/2] : ($numbers[@numbers/2] + $numbers[@numbers/2-1])/2; 10 return $median; # koennte man weglassen 11 } C: Kommandozeilenargumente C1: Schreibe ein Programm, das beim Programmaufruf eine Liste von Zahlen als Argumente annimmt und dann die kleinste und die größte Zahl ausgibt. 1 2 3 4 5 6 use strict; use warnings; my @numbers = sort {$a <=> $b} @ARGV; print "Die kleinste Zahl ist $numbers[0] und die groesste $numbers[-1]\n"; C2: Erweitere das Programm so, dass auch die Anzahl der übergebenen Zahlen ausgegeben wird. 1 2 3 4 5 6 7 use strict; use warnings; my @numbers = sort {$a <=> $b} @ARGV; print "Die kleinste Zahl ist $numbers[0] und die groesste $numbers[-1]\n"; print "Es wurden ", scalar @numbers, " Zahlen einngegeben.\n"; C3: Schreibe ein Programm, das beim Programmaufruf einen String als Argument nimmt und die Anzahl der Zeichen des String ausgibt. 1 2 3 4 use strict; use warnings; my $string = join(' ', @ARGV); 5 6 7 8 my @characters = split(//, 9 10 print "Der string $string # wenn man nur $ARGV[0] einliest # werden Strings mit Leerzeichen nicht # komplett gezaehlt $string); hat ", scalar @characters, " Zeichen\n"; C4: Modifiziere dieses Programm so, dass die vorkommenden Zeichen in alphabetischer Reihenfolge ausgegeben werden. Jedes Zeichen soll nur einmal ausgegeben werden (-> Duplikate entfernen) 1 2 3 4 5 6 7 8 9 use strict; use warnings; my $string = join(' ', @ARGV); # wenn man nur $ARGV[0] einliest # werden Strings mit Leerzeichen nicht # komplett gezaehlt my @characters = split(//, $string); my %h; 10 @h{@characters} = ""; 11 12 print join(' ', sort keys %h), "\n";