In den ersten drei Folgen des Kurses wurden die Grundlagen der Programmiersprache Pascal vermittelt. Dieser fünfte Teil setzt die Unterprogramme mit der Funktion fort, nachdem der vierte Teil die Prozedur behandelt hat.
Die Funktionen behandeln einen Sonderfall der Prozeduren. Nach dem Aufruf einer Funktion wird ein Wert berechnet, der anschließend zurückgegeben wird, weiterbearbeitet oder in einer Variablen abgelegt werden muss. Die vorhandenen Standardfunktionen verhalten sich genauso. Für die zurückgegeben Werte sind die Datentypen INTEGER, REAL, CHAR, BOOLEAN zugelassen.
Im Grundaufbau sieht eine Funktion wie eine Prozedur aus. Der Unterschied liegt lediglich in dem Schlüsselwort function, das das Schlüsselwort procedure ersetzt und darin, dass in der Deklarationszeile der Funktion ein Datentyp zugeordnet wird. Zusätzlich darf man den Funktionsnamen als Variable benutzen, die nicht zusätzlich deklariert werden muss und der man somit auch einen Wert übergeben kann.
Für den Einsatz einer Funktion sind nötig (siehe Listing 1)
Wert := Funktionsname
(Liste der aktuellen Parameter);
Der Rückgabewert übergibt den Wert, der dem zuvor für die Funktion deklarierten Datentyp entsprechen muss, an die Funktion. Mit dem Aufruf der Funktion wird dieser Wert an die Variable Wert übergeben.
In dem folgenden Beispielprogramm wird in der Funktion RUNDEN die übergebene reale Zahl auf- bzw. abgerundet. Mit dem Aufruf im Hauptprogramm wird der berechnete Wert dann an die Variable Rabatt zurückgegeben (siehe Listing 2).
Im Vergleich zu der aus dem letzten Teil des Kurses verwendeten Prozedur EINGABE muss bei der Funktion RUNDEN nicht extra eine Variable zur Rückgabe deklariert werden.
Kann eine Funktion oder Prozedur in ihrem Block wieder aufgerufen werden, spricht man von rekursiven Unterprogrammaufrufen.
Beispiel zur Fakultätsberechnung (siehe Listing 3):
Beide Beispielfunktionen berechnen die Fakultät der übergebenen Zahl. Während die Funktion facul_ i die Berechnung durch eine for-Schleife durchführt, wird in der Funktion facul r die Berechnung bei Zahlen größer oder gleich 1 durch rekursiven Aufruf mit Übergabe des um 1 verringerten Wertes der Variablen i durchgeführt. Wie zu sehen ist, ist die Variante mit der Rekursion durch weniger Programmtext und ohne zusätzliche Variablen einfacher. Bei großen übergebenen Werten gibt es zwischen den Varianten allerdings Laufzeitunterschiede, wobei die erste, abhängig vom Rechner, schneller sein wird, da sie keine Verzweigungen durchführen muss.
Listing 1:
1. Vereinbarung:
function Funktionsname (Liste der
formalen Parameter): Datentyp; var ... (Vereinbarung von Variablen}
begin
Funktionsname := Rueckgabewert
...
end;
Listing 3;
function facul_ i(n: integer): real;
var j: integer;
x: real;
begin
x := 1;
for j := 1 to n do
x := x * j,
facul_i := x;
end;
function facul_r(i: integer): real;
begin
if i < 1 then
facul_r := 1.0
else
facul_r := i * facul_r(i - 1)
end;
Damit sich zwei Unterprogramme gegenseitig aufrufen können, muss im Vereinbarungsteil eine Prozedur oder Funktion vor der anderen deklariert werden. Da immer ein Unterprogramm vor dem anderen deklariert wird, hilft hierbei die Forward-Deklaration. Vor der Beschreibung der Prozedur oder Funktion wird diese in Kurzform bekanntgegeben.
procedure P2(...); FORWARD; (FORWARD-Deklaration von P2 mit Parametern)
Zu beachten ist hierbei, dass die Kurzform die Parameterliste enthalten muss, während das eigentliche Unterprogramm diese dann nicht mehr enthalten darf.
Aufgabe:
Um überprüfen zu können, ob Sie die bereits behandelten Teile erfolgreich gelernt und verstanden haben, folgt nun eine kleine Aufgabe, deren Lösung im nächsten Teil dieses Kurses veröffentlicht wird:
Die FIBONACCI-Zahlen beschreiben Abläufe und Wachstum in der Natur. Die Zahlenfolge wird nach folgender Vorgabe berechnet:
f(0) = 0, f(1) = 1, f(2) = 1, ... f(n) = f(n-1) + f(n-2)
n f(n)
0 0 4 3
1 1 5 5
2 1 6 8
3 2
Entwickeln Sie eine rekursive Funktion FIB, die nach Eingabe der Zahl n die Fibonacci-Zahl zurück liefert. Testen Sie die Funktion in einem kleinen Pascal-Programm. Als kleiner Tip am Rande sei gesagt, dass die Funktion mit einer einzigen if-then-else-Bedingung auskommt.
Im nächsten Teil dieses Kurses folgen dann verschiedene Datentypen wie z.B. Zeichenketten und Felder sowie die Lösung der Aufgabe.
Torsten Runge
Listing 2:
program RABBATTE;
uses crt;
var Rabatt, Rabattsatz, Listenpreis : real;
procedure EINGABE(var Wert: real; HINWEIS: string20);
begin
write(HINWEIS)
readln(WERT)
end;
function RUNDEN (Wert: real): real;
var Zwischenwert: real;
begin
Zwischenwert := int(Wert * 100 + 0.500001);
RUNDEN := Zwischenwert / 100;
end;
begin
Clrscr;
writeln('Bestimmung des Rabattes');
EINGABE (Listenpreis, 'Listenpreis: ');
Rabattsatz := 0.10;
Rabatt := RUNDEN (Listenpreis * Rabattsatz / 100);
writeln('Der Rabatt beträgt: ', Rabatt);
end.
Listing 4:
procedure P1(...);
{Deklaration von Prozedur P1 mit Parametern}
var ...
begin
...
P2( ); (Aufruf von Prozedur P2}
...
end;
procedure P2;
(Deklaration von Prozedur P2 ohne Parameter}
var
begin
...
P1(...); {Aufruf von Prozedur P1}
...
end;