Programmiersprache Pascal
Unterprogramme
Unterprogramme sind Programmeinheiten, d.h. Bausteine, mit deren Hilfe
die Konstruktion eines Programms vereinfacht werden kann.
Zu betrachten sind
-
die Deklaration (Spezifikation, Vereinbarung) von Unterprogrammen,
-
der Aufruf (Aktivierung) von Unterprogrammen
Standard Pascal erlaubt die Deklaration von Unterprogrammen nur
innerhalb des Programm-Blocks, dies erweist sich für die Konstruktion
größerer Programme als ein sehr schwerwiegendes Problem.
Extended Pascal und (wahrscheinlich) alle neueren Pascal-Realisierungen
stellen Spracherweiterungen bereit, die ein Arbeiten mit externen
Unterprogrammen möglich machen. Jedoch unterscheiden sich diese
Erweiterungen in der Syntax zum Teil erheblich.
Beim Aufruf eines Unterprogramms up gibt es - in
Abhängigkeit vom Unterprogrammtyp - folgende Varianten:
-
als Prozedur (procedure)
der Aufruf ist eine eigenständige Anweisung, z.B.
up ( parameterliste );
up ist der Prozedurname.
-
als Funktion (function)
der Aufruf erfolgt innerhalb eines Ausdrucks, z.B. auf der rechten
Seite einer Ergibtanweisung, z.B.
y := up ( parameterliste );
oder als aktueller Parameter beim Aufruf eines anderen
Unterprogramms, z.B.
Writeln( up ( parameterliste ) );
up ist der Funktionsname.
-
als Operator (operator)
der Aufruf erfolgt innerhalb eines Ausdrucks, z.B. auf der rechten
Seite einer Ergibtanweisung, z.B.
y := operand up operand
oder als aktueller Parameter beim Aufruf eines anderen
Unterprogramms, z.B.
Writeln( operand up operand );
up ist das Operatorsymbol, die Parameterliste zerfällt hier
in Operanden.
Standard und Extended Pascal sowie die Mehrheit der Pascal-Systeme erlauben
wie die meisten Programmiersprachen nur die beiden ersten Varianten.
Die Möglichkeit, neue Operatoren zu definieren bzw. vorhandene zu
überladen, gibt es z.B. in Ada und in Pascal-XSC.
Die Deklaration von Prozeduren, Funktionen und Operatoren unterscheiden
sich:
PROCEDURE up ( parameterliste );
FUNCTION up ( parameterliste ) : datentyp;
OPERATOR up ( operanden ) resultat : datentyp; { !! Pascal-XSC !! }
(Angegeben sind hier nur die Kopfanweisungen der Deklarationen.)
Achtung:
Eine Reihe anderer Sprachen benutzt PROCEDURE auch zur
Deklaration von Funktionen, z.B. Modula, Oberon, Ada.
Der Begriff "Prozedur" kann sowohl als Synonym für "Unterprogramm"
verwendet werden als auch den Spezialfall eines Unterprogramm ("eigentliche
Prozedur" gegenüber Funktionsprozedur) bezeichnen.
Andererseits sind in Sprachen wie z.B. in C, C++ oder Java Prozeduren
(im Sinne von Pascal) als Spezialfälle von Funktionen realisiert.
Prozeduren, Funktionen und Operatoren können innerhalb gewisser
Grenzen alternativ eingesetzt werden.
Beispiel: Addition zweier ganzer Zahlen
mittels Operator
VAR x, y, z : INTEGER;
z := x + y;
mittels Funktion
FUNCTION add(x, y: INTEGER) : INTEGER;
BEGIN
add := x + y;
END;
VAR x, y, z : INTEGER;
z := add(x, y);
mittels Prozedur
PROCEDURE add(x, y: INTEGER; VAR z: INTEGER);
BEGIN
z := x + y;
END;
VAR x, y, z : INTEGER;
add(x, y, z);
Es ist in Pascal nicht möglich, Funktionen wie Prozeduren
aufzurufen.
In C typische alternative Aufrufe wie
rueckkehrcode := up(x, y); { !! nicht !! }
up(x, y); { !! zulässig !! }
sind in Pascal unzulässig.
Im Vergleich zeigt sich folgendes:
-
Die Prozedur bietet das allgemeinste Konzept.
Es sind beliebig viele Ein- und Ausgangsgrößen
möglich (Parameterliste).
Eine Anweisung kann maximal einen Prozeduraufruf enthalten.
Prozedurnamen können aussagekräftig gewählt werden.
-
Die Funktion besitzt eine ausgezeichnete Ausgangsgröße
(Funktionswert).
Es sind beliebig viele Eingangsgrößen möglich
(Parameterliste). Die Parameterliste kann weitere Ausgangsgrößen
enthalten, dies ist jedoch untypisch für eine Funktion.
Der Funktionswert besitzt einen Datentyp, der meist nicht beliebig
gewählt werden kann. (Beschränkungen gibt es oft bei
nichtelementaren Datentypen.)
Eine Anweisung kann mehrere Funktionsaufrufe enthalten, Funktionen
lassen sich aus dieser Sicht flexibler einsetzen.
Funktionsnamen können aussagekräftig gewählt werden.
-
Operatoren gestatten die kompakteste Darstellung.
Bei der in imperativen Programmiersprachen üblichen
Infix-Notation sind aus Gründen der Lesbarkeit nicht mehr als ein
oder zwei Eingangsgrößen sinnvoll.
Es gibt genau eine Ausgangsgröße.
Eine Anweisung kann mehrere Operatoren enthalten.
Operatorensymbole müssen sehr kurz und prägnant sein,
da sonst die Anweisung schwer lesbar wird. Meist werden
Sonderzeichen verwendet.
Operatoren werden typischerweise in den Sprachdefinitionen festgelegt.
Funktionen und Prozeduren werden durch Sprachstandards nicht immer bzw.
oft nur für sehr elementare Aufgaben definiert. (Ausnahmen sind C
bzw. C++ und Ada). Sprachrealisierungen fügen oft weitere Funktionen
und Prozeduren hinzu, die sich aber häufig voneinander unterscheiden
(Beispiele dafür sind Pascal und Modula, nichtportable Erweiterungen
gibt es aber auch in C-Systemen).
Gestaltungsregeln
Für den Aufbau von Unterprogrammen gibt es einige Gestaltungsregeln:
-
Ein Unterprogramm sollte (genau) eine inhaltlich abgeschlossene Aufgabe
lösen.
-
Ein Unterprogramm sollte überschaubar, d.h. die zu lösende Aufgabe nicht zu komplex sein.
Andererseits sollte die Anzahl der verwendeten Unterprogramme nicht
unnötig groß sein, da dann inhaltliche Zusammenhänge
schwerer erkennbar werden und der Verwaltungsaufwand steigt.
-
Ein Unterprogramm sollte genau einen Eintrittspunkt und genau einen
Austrittspunkt besitzen.
Im Zusammenhang mit Programmausnahmen ist die Forderung hinsichtlich
des Austrittspunktes so zu sehen, daß die Behandlung der
Programmausnahmen konzentriert wird.
-
Die zwischen Eintritts- und Austrittspunkt liegenden Ablaufstrukturen
sollten linear durchlaufen werden, ohne das explizite
Rücksprünge erfolgen.
-
Der Datenaustausch der Einheit mit seiner Umgebung sollte über (genau)
eine eindeutig beschriebene Schnittstelle laufen.
-
Der Umfang der auszutauschenden Daten ist so gering wie möglich zu
halten.
P. Böhme, 09.09.1996