Fortran: Fortran 2003: Zeiger
<<< zur Fortran-Startseite | |
<< Fortran 2003 | Bibliotheken >> |
< Datentypen | Ein- und Ausgabe > |
Prozedurenzeiger
BearbeitenEinführung
BearbeitenMit dem 2003er-Standard unterstützt auch Fortran Zeiger auf Prozeduren (procedure pointer, Funktionszeiger). Diese spielen auch eine wichtige interne Rolle bei der Realisierung objektorientierter Mechanismen und beim C-Binding. Schematisch wird ein Prozedurenzeiger so deklariert:
procedure( [name] ), pointer :: zeigername |
Die Angabe von name
ist optional. Wird an dieser Stelle ein Name, z.B. ein Unterprogrammbezeichner angegeben, so bedeutet dies, dass der Prozedurenzeiger mit allen Unterprogrammen, die das gleiche Interface aufweisen, kompatibel ist. Prozedurenzeiger können wie normale Zeiger gehandhabt werden.
Beispiel:
Fortran 2003 (oder neuer)-Code |
program bsp implicit none procedure(up), pointer :: pptr => null() pptr => ooops call pptr ! Ausgabe: ! ooops contains subroutine ooops() write( *, * ) "ooops" end subroutine ooops subroutine up() end subroutine up end program bsp |
Prozedurenzeiger mit implizitem Interface
BearbeitenBei der Deklaration eines Prozedurenzeigers muss keine explizite Schnittstelle angegeben werden. Im Folgenden wird dies am Beispiel eines mit pptr2
benannten Prozedurenzeigers demonstriert.
Beispiel:
Fortran 2003 (oder neuer)-Code |
program bsp implicit none procedure( up ) , pointer :: pptr1 => null() procedure( ) , pointer :: pptr2 => null() procedure( add ), pointer :: pptr3 => null() pptr1 => ooops pptr2 => ooops call pptr1 call pptr2 ! Ausgabe: ! ooops ! ooops pptr3 => add write( *, * ) pptr3( 5 , 12 ) ! Ausgabe: ! 17 ! Folgende auskommentierte Zuordnung waere nicht erlaubt: ! pptr1 => add contains subroutine up() end subroutine up subroutine ooops() write( *, * ) "ooops" end subroutine ooops function add( a, b ) integer :: add integer, intent( in ) :: a, b add = a + b end function add end program bsp |
Abstraktes Interface
BearbeitenDas bei der Deklaration eines Prozedurenzeigers als Schnittstelle genannte Unterprogramm muss nicht real implementiert sein. Es können statt dessen auch abstrakte Interfaces Verwendung finden. Diese sind gleich wie konventionelle Interface-Blöcke aufgebaut, mit dem Unterschied, dass sie als abstract interface
gekennzeichnet sind. Ein mit einem abstrakten Interface deklarierter Prozedurzeiger passt dann für jedes Unterprogramm, welches mit identer Schnittstelle ausgestattet ist.
Fortran 2003 (oder neuer)-Code |
program bsp implicit none abstract interface function afunc( x, y ) integer :: afunc integer, intent( in ) :: x, y end function afunc end interface procedure( afunc ), pointer :: pptr1 => null() procedure( add ) , pointer :: pptr2 => null() pptr1 => add write( *, * ) pptr1( 5 , 12 ) ! Ausgabe: 17 pptr1 => mult write( *, * ) pptr1( 3 , 2 ) ! Ausgabe: 6 ! Folgendes funktioniert uebrigens auch, da add() und mult() das gleiche Interface ! aufweisen: pptr2 => mult write( *, * ) pptr2( 5 , 5 ) ! Ausgabe: 25 contains function add( a, b ) integer :: add integer, intent( in ) :: a, b add = a + b end function add function mult( a, b ) integer :: mult integer, intent( in ) :: a, b mult = a * b end function mult end program bsp |
Zeiger und das intent
-Attribut
Bearbeiten
Nun ist bei der Übergabe von Zeigern an Unterprogramme auch die Angabe eines intent
-Attributs möglich. Das war mit Fortran 90/95 noch nicht erlaubt. Diese intent
-Angaben beziehen sich aber nicht auf die Variablenwerte an sich, sondern beschränken nur die Möglichkeiten zur Zeigerzuordnung im Unterprogramm selbst.
Beispiel:
Fortran 2003 (oder neuer)-Code |
program bsp implicit none integer, target :: x = 15 integer, pointer :: ptr1 => null(), ptr2 => null() ptr1 => x ptr2 => x call mult( ptr1, ptr2) write( *, *) "Zuordnungsstatus ptr1:", associated( ptr1 ) write( *, *) "Zuordnungsstatus ptr2:", associated( ptr2 ) write( *, *) "Wert ptr1:", ptr1 write( *, *) "Wert x:", x ! Ausgabe: ! Zuordnungsstatus ptr1: T ! Zuordnungsstatus ptr2: F ! Wert ptr1: 45 ! Wert x: 45 contains subroutine mult( a, b ) integer, pointer, intent( in ) :: a integer, pointer, intent( inout ) :: b integer, target :: val = 3 ! Folgendes waere nun nicht erlaubt, da a nur intent( in ) ! a => null() ! Das auch nicht: ! a => val ! Das allerdings ist erlaubt: a = a * val ! b ist mit intent( inout ) spezifiziert, also ist hier eine Zeigerzuordnung ! erlaubt: b => null() end subroutine mult end program bsp |
Zeiger und Felder
BearbeitenAuch im Zusammenspiel von Zeigern mit Feldern bringt der Fortran 2003-Standard einige Ergänzungen.
<<< zur Fortran-Startseite | |
<< Fortran 2003 | Bibliotheken >> |
< Datentypen | Ein- und Ausgabe > |