Dies ist eine alte Version des Dokuments!


Unterprogramme und Funktionen

Unterprogramme sind oft benutze Quellcode-Stellen, die problemlos aus einem Projekt entfernt werden könnten und in anderen wieder Verwendung finden könnten.

Beachten Sie, dass bei der Parameterdeklaration im Unterprogramm die gleichen Datentypen anzugeben sind, wie Sie für die Variablen im rufenden Programm verwendet haben. Übergibt man aus dem Hauptprogramm bspw. einen Integerwert, hat im Unterprogramm für den Parameter aber Real festgelegt, wird der Compiler nicht meckern, sondern lediglich im fertigen Programm kommt es dann zu seltsamen Daten. Es obliegt einzig dem Unterprogramm festzulegen, wie die Werte zu interpretieren sind. Ziel sollte häufig es sein, die gleichen Festlegungen zu treffen, wie das in der rufenden Funktion geschehen ist. Diese Eigenschaft von Fortran kann man aber auch ausnutzen.

Die Parameterübergabe erfolgt nach Call-by-Reference, dh. es wird lediglich ein Zeiger auf die Stelle im Speicher übergeben, die den gewünschten Wert vorweist. Es wird keine Information übergeben, welcher Datentyp dieser Wert hat.

Unterprogramme

Unterprogramme sind Programmstücke, die Werte im Speicher verändern, die aber kein Ergebnis zurückliefern. Es ist dennoch möglich aus einem Unterprogramm heraus Werte zurückzugeben, indem die Eingabeparameter verändert werden (siehe unten Call-by-reference). Ein Unterprogramm hat den Vorteil, dass generischer (vielseitig einsetzbarer) Code nicht kopiert werden muss, sondern an einer Stelle stehen kann (dort können einmal Änderungen gemacht werden), nicht an vielen Stellen im Programmcode. Das erleichtert die Wartung von größeren Programmen.

Ein Unterprogramm wird in Fortran folgendermaßen definiert (im Beispiel die Funktion func mit 3 Parametern (a, b und c):

SUBROUTINE func ( a, b, c )
  ! programmcode
END SUBROUTINE

Zunächst steht also das Schlüsselwort SUBROUTINE gefolgt vom Namen des Unterprogramms und einer Liste der formalen Parameter. Beachten Sie, dass die Parameter hier noch nicht mit einem Datentypen versehen werden (anders als bspw. in C)! Sie müssen explizit im Unterprogramm dem Compiler mitteilen, welchen Datentyp die Parameter annehmen sollen. Tun Sie das nicht, wird der Compiler implizit Datentypen festlegen (mehr dazu im Kapitel Variablen). Variablendefinition sieht dann wie folgt aus:

SUBROUTINE func ( a, b, c )
  IMPLICIT NONE
  INTEGER a,b
  REAL c
  ! Programmcode
END SUBROUTINE

Das Unterprogramm wird dann mithilfe des call-Schlüsselwortes aufgerufen. Damit werden Unterprogramme gefunden - nicht aber Funktionen!

PROGRAM main
  call func (12, 42, 0.3)
END PROGRAM

Funktionen

Funktionen sind Unterprogramme, die ein Ergebnis zurückliefern (also bspw. den Wert einer Berechnung). Die Definition sieht ähnlich aus, wie bei Subroutinen, allerdings wird der Rückgabedatentyp angegeben:

INTEGER FUNCTION func ( a, b, c )
  ! programmcode
END SUBROUTINE

In der Funktion kann dann der Funktionsname als Variable benutzt werden um das Ergebnis der Funktion zu bestimmen, bspw:

REAL FUNCTION func ( a, b, c )
  INTEGER a,b
  REAL c
  func = a+b * c
  return
END FUNCTION

Der Datentyp der Ergebnisvariable steht dort bereits fest, weil das der gleiche sein muss, wie der Rückgabedatentyp, dh. eine explizit Typzuweisung ist nicht nötig. Das return-Statement nimmt in Fortran keine Parameter. Es zeigt lediglich an, dass der Programmfluss an dieser Stelle zum Hauptprogramm zurückgegeben wird, dh. nach return stehende Programmzeilen werden nicht ausgeführt.

Der Funktionsruf aus dem Hauptprogramm heraus geschieht wie folgt (hier direkte Ausgabe des Ergebnisses):

PROGRAM main
  write (*,*) func ( 12, 42, 0.3 )
END PROGRAM

Rekursive Funktionen

Eine rekursive Funktion ist eine Funktion, die sich selbst aufruft. In frühen Fortran Versionen waren Rekursionen verboten, in Fortran 90 geht das folgendermaßen:

INTEGER RECURSIVE FUNCTION fak ( a ) RESULT ( erg )
  IMPLICIT NONE
  INTEGER a
 
  IF (a < 2) THEN
    erg = 1
    return
  ENDIF
 
  erg = a * fak ( a-1 )
  return        
END FUNCTION

Hier steht das Schlüsselwort RECURSIVE bei der Funktionsdefintion, um anzudeuten, dass die Funktion rekursiv aufgerufen wird. Außerdem ist es notwendig, da der Name der Funktion als Funktion verwendet werden soll, den Ergebniswert in eine andere Variable zu schreiben. Dazu dient das Statement RESULT ( erg ). So wird festgelegt, dass erg die Ergebnisvariable sein soll.