Zu den benutzereigenen Unterprogrammen mit Funktionscharakter gehören die in diesem Abschnitt zu besprechenden Formelfunktionen, die internen und die externen Funktionen.
Eine Formelfunktion (statement function) wird definiert durch eine einzige, vom Programmierer in der aufrufenden Programmeinheit anzugebende nichtausführbare Anweisung. Sie ähnelt einer Zuweisung. Die Definition einer Formelfunktion muß vor der ersten ausführbaren Anweisung und hinter den Vereinbarungsanweisungen vorgenommen werden. Die allgemeine Definitionsanweisung lautet:
Stfun (
...) = expr
Der Name der Funktion ist Stfun
und sind Formalparameter
(Variablennamen). Der Wert des Ausdrucks
ist der Wert der Formelfunktion
nach deren Ausführung. Die
Formelfunktion wird über ihren Namen
aufgerufen:
Stfun (
, ...)
Die Aktualparameter sind
Ausdrücke. Wird der Name
der Formelfunktion in einem
Ausdruck angetroffen, wird die
Formelfunktion ausgewertet. Dazu werden
die Werte der Aktualparameter berechnet
und anstelle der Formalparameter bei der
Auswertung des Ausdrucks
verwendet.
Eine Formelfunktion kann nur in der
sie definierenden Programmeinheit
aufgerufen werden. Ihr Name ist lokal, d.h.
dieser Programmeinheit zugeordnet und
darf nicht mit irgendeinem anderen Namen
dieser Programmeinheit übereinstimmen.
Beispiel für Definition und Verwendung einer Formelfunktion:
PROGRAM demo ! --- Polynomauswertung nach HORNER-Schema IMPLICIT NONE REAL :: XAnf, XEnd, XI, DX, FXI, A0, A1, A2, A3 REAL :: A, B, C, D, X ! --- Die Formelfunktion HORNY muss selbst auch deklariert werden REAL :: HORNY INTEGER :: I, NX ! --- Definition des Hornerschemas als Statementfunction HORNY (A, B, C, D, X) = D + X*(C + X*(B + A*X)) ! --- Eingabe PolynomKoeffizienten und Wertebereich READ*, A0, A1, A2, A3 READ*, XAnf, XEnd, NX ! --- Berechnung und Ausgabe Funktionstabelle DX = (XEnd - XAnf) / (NX - 1) PRINT 100, 'WerteTabelle' PRINT 100, 'X','F(X)' DO I = 1, NX XI = Xanf + (I - 1)*DX FXI = HORNY (A0, A1, A2, A3, XI) PRINT 110, XI, FXI ENDDO 100 FORMAT(2A15) 110 FORMAT(2F15.5) END
Die Verwendung von Formelfunktionen ist allerdings nicht sehr zukunftsweisend, da sie in nachfolgenden FORTRAN-Versionen nicht mehr unterstützt werden wird. Da die Formelfunktion ohnehin nur lokal, d.h. in einem Unterprogramm, Gültigkeit besitzt, ist sie durch die interne Funktion abgelöst worden.
Die interne ist wie die externe Funktion ein benutzereigenes Unterprogramm, das eine Reihe von Anweisungen ausführt und einen Wert über seinen Namen zurückliefert. Sie werden über die FUNCTION-Anweisung
typ FUNCTION fun (, ...)
definiert. ist der Typ der Funktion, welcher nicht nur jeder beliebige
skalare Datentyp sein kann, sondern auch ein Feld beliebigen Typs, und
ist ihr
Funktionsname. (Die Zuweisung eines Typs zum Funktionnamen darf sogar auch erst innerhalb der
Funktion selbst erfolgen.)
Die Formalparameter
können Variablennamen, Feldnamen oder Namen
anderer Unterprogramme sein. Der Name der Funktion ist innerhalb der Funktion
selbst ein Variablenname, der nur auf der linken Seite einer Zuweisung stehen
darf. Diese Variable muß während der Ausführung der Funktion
definiert d.h. mit einem Wert versehen werden. Der Wert der Funktion beim
Rücksprung (Antreffen von END FUNCTION) ins rufende Programm ist dann der
Wert dieser Variablen.
Prinzipielle Struktur einer Funktion:
FUNCTION
(
, ...)
:
:
END FUNCTION
Der Aufruf einer internen oder externen Funktion geschieht über ihren Funktionsnamen. Die Funktion wird ausgeführt, wenn ihr Name als Operand innerhalb eines Ausdrucks erscheint. Die Funktion übernimmt Werte von der aufrufenden Programmeinheit über eine Parameterliste oder über gemeinsame Speicherbereiche; sie liefert einen Wert über ihren Namen zurück (oder auch mehrere Werte über die Parameterliste oder gemeinsame Speicherbereiche).
Der Typ des Ergebnisses ist indirekt durch die Deklaration des Funktionsnamen festgelegt. Die Aktualparameter müssen hinsichtlich Anzahl, Typ und Reihenfolge mit den Formalparametern übereinstimmen, ihre Namen können unterschiedlich sein.
Zwischen internen oder externen Funktion gibt es nun folgende Unterschiede:
Die interne Funktion
Die interne Funktion wird innerhalb einer Programmeinheit definiert, welche das Hauptprogramm, eine Unterroutine, aber auch eine andere Funktion sein kann. Die Definition der Funktion findet zwischen der CONTAINS- Anweisung und der END-Anweisung der umgebenen Programmeinheit statt:
PROGRAM main
:
CONTAINS
FUNCTION
(
, ...)
:
:
END FUNCTION
END
Die interne Funktion ist nur lokal in der umgebenen Programmeinheit bekannt, muß aber bei expliziter Deklaration noch mittels Deklaration des Funktionsnamens innerhalb der Einheit bekannt gemacht werden. Außerdem kann eine interne Funktion, ebenso wie Formelfunktionen, auf alle Variablen des umgebenen Unterprogramms zurückgreifen, und das auch ohne Kommunikation über die Parameterliste.
Die externe Funktion
Externe Funktionen sind gegenüber den internen global verfügbar. Ihr Name ist überall im Programm bekannt und darf daher im gesamten Programm nur ein einziges Mal auftauchen. Ihre Definition findet äuquivalent zum Hauptprogramm als eigenständiger Programmteil (also außerhalb jedes anderen Unterprogramms) statt und sieht wie folgt aus:
FUNCTION
(
, ...)
:
:
END FUNCTION
Da die externe Funktion eigenständig definiert wird, sind in ihr nur die Werte bekannt, die ihr mittels Parameterliste, COMMON-Block, o.ä. zugänglich gemacht werden. Der Vorteil einer externen Funktion liegt offensichtlich in ihrer globalen Natur, da sie innerhalb des gesamten Programms aufgerufen werden kann. Im Prinzip hängt die Entscheidung für einen der Funktionsarten natürlich immer vom jeweiligen Verwendungszweck ab.
Beispiel:
PROGRAM vektor IMPLICIT NONE INTEGER :: i REAL :: a(3), b(3), sp, SKALP READ*, (a(i), b(i), i = 1,3) sp = SKALP (a, b, 3) PRINT*, 'Das Skalarprodukt ist:', sp PRINT*, 'Aus der Vektoraddition ergibt sich: ',VEKTADD(3) CONTAINS ! --- Funktion zur Addition zweier Vektoren FUNCTION VEKTADD (dimen) IMPLICIT NONE INTEGER :: k, dimen REAL, DIMENSION(dimen) :: VEKTADD DO k=1, dimen ! --- a() und b() sind aus dem umgebenen Programm bekannt VEKTADD (k) = a(k) + b(k) ENDDO END FUNCTION END ! --- Funktion zur Berechnung des Skalarprodukts zweier Vektoren REAL FUNCTION SKALP (v1, v2, n) IMPLICIT NONE INTEGER :: n, ik REAL :: v1(n), v2(n) SKALP = 0.0 DO ik = 1, n SKALP = SKALP + v1(ik)*v2(ik) ENDDO END FUNCTION
Im Zusammenhang mit Funktionen soll noch kurz auf den Unterschied zwischen lokalen und globalen Größen eingegangen werden. Alle in Programmeinheiten auftretenden Namen und Anweisungsnummern haben lokale Bedeutung, d.h. sie sind nur in der jeweiligen Programmeinheit bekannt und dürfen außerhalb, gegebenenfalls mit anderer Bedeutung, wieder verwendet werden. Der Name einer externen Funktion ist dagegen eine globale Größe; er darf weder mit anderen globalen Namen (z.B. Name der rufenden Programmeinheit) noch mit lokalen Namen der betreffenden Programmeinheit identisch sein (Ausnahme: gleichnamige Variable in der FUNCTION selbst). Globale Größen sind für das gesamte Programm von Wichtigkeit. Weitere globale Größen sind z.B. die Namen gemeinsamer Speicherbereiche (benannte COMMON-Blöcke) oder benutzerdefinierte Typen (TYPE).