Funktionen als Parameter

Bei einigen Anwendungen kann es notwendig sein, Funktionen als Parameter einer anderen Funktion zu übergeben. Beispielsweise, wenn Sie eine Funktion implementieren wollen, die eine mathematische Funktion integriert. Es ist zwar möglich die mathematische Funktion fest einzubauen, jedoch muss bei jeder Änderung das Programm neu übersetzt werden und eine Eingabe von Funktionen durch den Nutzer ist überhaupt nicht möglich.

Es gibt in Fortran die Möglichkeit Funktionen zu schreiben, die eine Funktion als Parameter entgegennehmen und diese dann ausführen.

Beispielcode

Für die übergebene, dann innen gerufene Funktion ändert sich nichts, dh. wir haben hier bspw folgenden Code:

funcvar1.f
      program main
        external xsquare   ! Hier steht external, nicht der Rückgabewert!
 
        call summ ( xsquare, 0, 10 )
      end program
 
      integer function xsquare ( x )
        integer x;
        xsquare = x**2;
        return;
      end function
 
      subroutine summ ( f, start, ende )
        integer f, start, ende
        integer k
 
        do k=start, ende
          write (*,*) f(k)
        enddo
      end subroutine

Die übergebene Funktion sieht genauso aus, wie eine normale Funktion, dh. daran erkennen wir nicht, dass sie im Laufe des Programms einer anderen Funktion als Parameter übergeben wird. In der Funktion sum wird f als normale Integer-Funktion definiert, die wie eine gewöhnliche, global bekannte Funktion gerufen wird. Unterschied ist hier, dass f als Parameter in der Parameterliste vorkommt.

Im Hauptprogramm erkennen wir aber einen Unterschied. Hier wird nicht integer xsquare definiert, wie wir es tun würden, wöllten wir die Funktion im Hauptprogramm rufen, sondern hier wird external xsquare definiert. Das zeigt dem Compiler an, dass es sich bei xsquare um einen Funktionsnamen handelt, nicht um eine gewöhnliche Funktion. Der Compiler könnte hier ansonsten nicht wissen, dass es sich um eine Funktion handelt, die wir übergeben wollen und nicht um eine Interger-Variable.

intrinsic / external

Bei eigens definierten Funktionen wird das Schlüsselwort external verwendet, wollen wir bspw. die Cosinus-Funktion verwenden, die in Fortran eingebaut ist, so verwenden wir das Schlüsselwort intrinsic um kenntlich zu machen, dass wir cos als Funktion übergeben wollen.

funcvar2.f
      program main
        intrinsic cos
 
        call summ ( cos, 0, 10 )
      end program
 
      subroutine summ ( f, start, ende )
        real f
        integer start, ende
        real k
 
        do k=start, ende
          write (*,*) f(k)
        enddo
      end subroutine

Wie funktioniert Funktionsübergabe intern?

Es scheint abwegig, dass komplette Funktionen - also Quellcode - zur Laufzeit übergeben werden, also umkopiert werden. Stattdessen wird beim Ruf der Funktion sum nur eine Adresse auf die erste Anweisung der Funktion xsquare übergeben. Beim Ruf der Funktion xsquare findet im Prozessor tatsächlich ein Sprungbefehl an die übergebene Adresse statt, dort wird der Code ausgeführt, bis eine Rücksprunganweisung gefunden wird, die den Prozessor wieder zurück springen lässt.