Die Webseiten der Fachschaft Informatik am ERG Saalfeld


Parameter (von Prozeduren und Funktionen)

Durch das Verwenden von Subroutinen wird es viel einfacher möglich, dass Programm in Teamarbeit erstellt werden und sich jeder Programmierer um "seine" (Unter-)Programme kümmert. Dabei tritt allerdings das Problem auf, dass man für die Übergabe der Variablen bei der Verwendung von globalen Variablen sehr eingeschränkt ist und es zusätzlicher Absprachen wegen der Benennung dieser Variablen bedarf. Zudem kann die Subroutine nicht unabhängig vom Programm erstellt oder gar weitergegeben werden.
 

formale und aktuelle Parameter (am Beispiel arithmetisches Mittel)

Wir schreiben eine Funktion  $z = &mittel($x,$y); , die für 2 Zahlen (hier $x und $y) das arithmetische Mittel (hier $z) zurück gibt. Natürlich sollen auch Aufrufe wie z.B. $a = &mittel($b,$c);  oder $zahl = &mittel(8,10);  möglich sein. Die Subroutine, die wir jetzt schreiben, muss also 2 Zahlen übernehmen, egal welchen Wert diese haben und erst recht muss es egal sein, wie diese heißen (falls es Variablen sind). Wir legen als Programmierer selbst fest, wie die Variablen benannt werden.

Subroutine für "&mittel"

sub mittel {
  my $a = shift @_;
  my $b = shift @_;

  my $c = ($a + $b) / 2;
  return $c;
}

Erläuterung: In der (Spezial-)Variablen @_ (also einer Liste) sind die übergebenen Werte enthalten. Hier wird also das erste Element der Paramterliste mit 'shift' in die lokale Variable $a gesteckt und danach die nächste Variable in $b. Welchen Namen diese Werte vorher hatten ist hier völlig uninteressant. Das arithmetische Mittel wird in die lokale Variable $c gesteckt und diese zurück gegeben. Da $c eine lokale Variable ist, interessiert diese Bezeichnung im Hauptprogramm auch nicht.

 

Programm

Die Funktion kann nun so wie in dem Beispielprogramm aufgerufen werden. Hinweis: wenn die Parameter mit der Schreibweise: my $x = shift @_; übernommen werden, dann braucht die Variable @_ nicht angegeben zu werden, das erkennt Perl auch von allein.

#!/usr/bin/perl
use warnings;
use strict;

my ($x, $y, $m);

$x = 8;
$y = 15;

$m = &mittel($x, $y);
print $m, "\n";
$m = &mittel($x, 20);
print $m, "\n";
$m = &mittel(42, 14);
print $m, "\n";
print &mittel(5,16), "\n";;

###### Ende des Hauptprogramms ######

sub mittel {
  my $a = shift;
  my $b = shift;

  my $c = ($a + $b) / 2;
  return $c;
}

__END__

Erläuterung: Wenn im Hauptprogramm die Funktion so aufgerufen wird:  $m = &mittel($x, $y); , dann sind $x und $y (bzw. die Werte 8 und 15) die aktuellen Parameter des Funktionsaufrufs. D.h. an der 1. Stelle der Parameterliste steht die 8 und an der zweiten Stelle steht die 15. Wenn jetzt der Programmcode für die Subroutine abgearbeitet wird, dann ist die Variable für die erste Stelle der Parameterliste die Variable $a und für die zweite Stelle die Variable $b.
Zusammengefasst: $x und $y sind aktuelle Parameter, $a und $b sind formale Parameter.
 

Die Ausgabe des Programms sieht so aus:

 

Verbesserung des Programms

Dadurch, dass die Parameter sowieso als Liste übergeben werden, kann man die Funktion so schreiben, dass für eine beliebige Anzahl von Zahlen das arithmetische Mittel bestimmt wird. Das Programm sieht dann z.B. so aus:

#!/usr/bin/perl
use warnings;
use strict;

my ($x, $y, $m);

$x = 8;
$y = 15;

$m = &mittel($x, $y);
print $m, "\n";
$m = &mittel($x);
print $m, "\n";
$m = &mittel(1, 2, 3, 4, 5);
print $m, "\n";
print &mittel(2,4,6,8), "\n";

###### Ende des Hauptprogramms ######

sub mittel {
  my @zahlen = @_;

  my $anzahl = scalar @zahlen;

  my $summe = 0;
  foreach my $element (@zahlen) {
    $summe = $summe + $element;
  }

  my $mittel = $summe / $anzahl;

  return $mittel;
}

__END__


Die Ausgabe des Programms sieht nun so aus:


Jahrgangsliste (Übergabe mehrerer Listen als Parameter)

Durch dieses Beispiel soll deutlich gemacht werden, dass die Liste der Parameter @_ eine ganz normale Liste ist. Soll heißen, wenn hier verschiedene Elemente an diese Liste übergeben sind, z.B. Skalarvariablen und Listen (oder auch Hashs) gemischt, so kann man z.B. diese übergebenen Listen in der Subroutine selbst nicht wieder heraus filtern. Würde für das folgende Beispiel bedeuten, dass in der Subroutine nicht herausgefunden werden könnte, welche Werte z.B. zum ersten Kurs gehören.
 

#!/usr/bin/perl
use warnings;
use strict;

my @kurs1 = (12, 8, 15, 12, 11, 6, 13, 10);   # Ergebnissse vom Kurs 1
my @kurs2 = (11, 14, 1, 10, 7, 11, 13, 10);   # Ergebnissse vom Kurs 2
my @kurs3 = (2, 11, 15, 12, 11, 4, 12, 11);   # Ergebnissse vom Kurs 3

print &mittel(@kurs1, @kurs2, @kurs3), "\n";


###### Ende des Hauptprogramms ######

sub mittel {
  my @zahlen = @_;

  my $anzahl = scalar @zahlen;

  my $summe = 0;
  foreach my $element (@zahlen) {
    $summe = $summe + $element;
  }

  my $mittel = $summe / $anzahl;

  return $mittel;
}

__END__


Die Ausgabe des Programms sieht so aus:

 

Aufgaben

Alle Aufgaben beziehen sich auf die "verbesserte Version"!

  1. Bringen Sie das Programm  mittel.pl  zum Laufen.
  2. Kommentieren Sie dieses Programm (jede Zeile bzw. jeden Block).
  3. Geben Sie für jede Variable im Programm an, ob diese eine globale oder lokale Variable ist.
  4. Welches sind die aktuellen und welches die formalen Parameter für den Aufruf  &mittel($x, $y) ?
  5. Erstellen Sie für die Subroutine mit dem Aufruf &mittel(2,14) eine Wertbelegungstabelle.
  6. Ergänzen Sie das Programm um eine Überschrift. Schreiben und verwenden Sie dazu eine Prozedur  &ueberschrift, wobei der Titel als Parameter übergeben wird.

 

zurück


© ERG Saalfeld   -   Hans-Dietrich Kirmse   26.05.2019