| <<< zur Fortran-Startseite | |
| << Fortran 95 | Fortran 2003 >> |
| < Datentypen höherer Genauigkeit | Standardfunktionen > |
Einleitung
Datenelemente lassen sich auch zu eigenen zusammengesetzten Datentypen verbinden. Der Datenverbund ist in anderen Programmiersprachen auch als Struktur (structure, struct) bekannt. Der Fortran 95-Standard spricht vom "derived type", also einem abgeleiteten Datentyp. Zulässig als Komponenten eines Datenverbundes sind Skalare, Felder, Zeiger oder auch andere Datenverbunde. Ein Datenverbund ist durch das Schlüsselwort type gekennzeichnet und kann in folgenden Formen auftreten
|
|
Die Elemente in eckigen Klammern sind optional. Die Angabe eines Zugriffsspezifizierers (public, private) ist nur bei Verwendung von Datenverbunden in Modulen erlaubt.
Einen Datenverbund anlegen
type :: name [sequence] ! optional sequentielle Speicherplatzablage datentyp :: komponentenname_1 ! ... datentyp :: komponentenname_n end type [name] |
Beispiel (Programmausschnitt):
| Fortran 90/95-Code (free source form) |
! ...
type :: koord
integer :: id
real, dimension(3) :: x
end type koord
! ...
|
Eine Variable vom Typ "Datenverbund" anlegen
Die Variablendeklaration erfolgt in der Form
type( name ) :: var |
Beispiel (Programmausschnitt):
| Fortran 90/95-Code (free source form) |
! ...
type :: koord
integer :: id
real, dimension(3) :: x
end type koord
type( koord ) :: k
! ...
|
Zugriff auf Einzelkomponenten eines Datenverbunds
Eine Einzelkomponente in einem Datenverbund lässt sich als Kombination des Datenverbundvariablenbezeichners und des Komponentennamen ansprechen. Verknüpft werden diese beiden Bezeichner mit dem %-Zeichen.
var%komponentenname |
Beispiel (Programmausschnitt):
| Fortran 90/95-Code (free source form) |
! ...
type :: koord
integer :: id
real, dimension(3) :: x
end type koord
type( koord ) :: k
k%id = 999
k%x(1) = 0.0
k%x(2) = 20.5
k%x(3) = 10.0
write( *, * ) k%x(2)
! ...
|
Zugriff auf einen Datenverbund als Ganzes
Ein Datenverbund kann in bestimmten Situation nicht nur komponentenweise angesprochen werden, sondern auch als Einheit, z.B. bei der Ein-/Ausgabe oder beim Zuweisen der Werte einer Datenverbundvariablen an eine andere.
Beispiel (Programmausschnitt):
| Fortran 90/95-Code (free source form) |
! ...
type :: koord
integer :: id
real, dimension(3) :: x
end type koord
type( koord ) :: k1, k2
read( *, * ) k1
k2 = k1
write( *, * ) k2
! ...
|
Elemente eines Datenverbunds initialisieren
Default-Werte im Datenverbund setzen
Innerhalb eines Datenverbundes lassen sich die einzelnen Variablen mit Vorgabewerten belegen, z.B.
integer :: i = 5 character, dimension( 2, 2 ) :: c = reshape( (/ "A", "B", "C", "D" /), (/ 2, 2 /) )
Beispiel:
| Fortran 90/95-Code (free source form) |
program bsp
implicit none
type :: koord
integer :: id = -999999
real, dimension( 3 ) :: x = 0.0
end type koord
type( koord ) :: k
write( *, * ) k
! Ausgabe:
! -999999 0.0 0.0 0.0
end program bsp
|
Der "structure constructor"
Die Initialisierung der Datenverbundelemente bzw. eine spätere Wertzuweisung kann auch per "structure constructor" ("derived type value constructor") vorgenommen werden.
name( wertliste ) |
Beispiel:
| Fortran 90/95-Code (free source form) |
program bsp
implicit none
type :: koord
integer :: id
real, dimension( 3 ) :: x
end type koord
type( koord ) :: k = koord( 12, (/ 0.0, 1.5, 20.5 /) )
write( *, * ) k
k = koord( 13, (/ 5.5, 0.0, 0.5 /) )
write( *, * ) k
! Ausgabe:
! 12 0.0 1.5 20.5
! 13 5.5 0.0 0.5
end program bsp
|
Enthält ein Datenverbund bereits Variablen mit Vorgabewerten, so werden diese durch die Werte im "structure constructor" überschrieben.
Beispiel:
| Fortran 90/95-Code (free source form) |
program bsp
implicit none
type :: person
character(25) :: vorname = 'NN'
character(25) :: nachname = 'NN'
integer :: alter
end type person
type(person), dimension(5) :: p
p(1) = person('Harri', 'P.', 41)
p(5) = person('Creszenzia', 'T.', 18)
write(*, fmt=111) p
! Ausgabe:
! Harri P. 41
! NN NN 0
! NN NN 0
! NN NN 0
! Creszenzia T. 18
write(*,*) p(1)%vorname
! Ausgabe:
! Harri
p(2)%vorname = 'Holger'
write(*, '(A)') p%vorname
! Ausgabe:
! Harri
! Holger
! NN
! NN
! Creszenzia
111 format(2A, I3)
end program bsp
|
Beispiel: Verwendung eines Datenverbunds in einem anderen Datenverbund
| Fortran 90/95-Code (free source form) |
program bsp
implicit none
type :: tripel
real :: x, y, z
end type tripel
type :: koerper
integer :: id
type( tripel ) :: bezugskoordinate
type( tripel ) :: orientierung
end type koerper
type( koerper ) :: k
k = koerper( 1005, tripel( 10.5, 0.0, -6.5 ), tripel( 0.0, 0.0, -0.8 ) )
write( *, * ) k
! Ausgabe:
! 1005 10.50000 0.000000 -6.500000 0.000000
! 0.000000 -0.8000000
end program bsp
|
Das Attribut sequence
Im Datenverbund kann zu Beginn auch das Attribut sequence angegeben werden. Dieses spezifiziert, dass die Werte eines Datenverbunds sequentiell gespeichert werden. Wird dieses Attribut weggelassen, so ist nicht gewährleistet, dass die Werte von Datenverbundvariablen in der selben Reihenfolge, wie sie im Datenverbund gereiht wurden im Speicher wiederzufinden sind, oder dass sie zusammenhängend gespeichert werden. Oft wird die Speicherreihenfolge keine wesentliche Rolle spielen. Ein Spezialfall, wo die Speicherreihenfolge jedoch essenziell ist, wird anschließend dargestellt.
Die Verwendung eines Datenverbunds in separaten Programmeinheiten
Ein Datenverbund kann über ein Modul verschiedenen Programmeinheiten bekannt gemacht werden. Dazu aber später. Es ist nämlich auch so möglich in komplett getrennten Programmeinheiten auf ein und denselben Datenverbund-Datentyp zuzugreifen.
Beispiel: Ein ähnliches Beispiel findet sich auch im J3/97-007R2 Working Draft, Note 4.31
| Fortran 90/95-Code (free source form) |
program bsp
implicit none
type :: koord
sequence
integer :: id
real, dimension( 3 ) :: x
end type koord
type( koord ) :: k = koord( 555, (/ 3.0, 4.0, 5.5 /) )
call ausgabe( k )
! Ausgabe
! 555 3.0000000 4.0000000 5.5000000
end program bsp
subroutine ausgabe( coord )
type :: koord
sequence
integer :: id
real, dimension( 3 ) :: x
end type koord
type( koord ), intent( in ) :: coord
write( *, * ) coord
end subroutine ausgabe
|
In diesem speziellen Fall muss der Datenverbund lt. Standard mit dem Attribut sequence versehen werden. Des Weiteren muss der im Hauptprogramm deklarierte Datenverbund komplett identisch mit jenem im Unterprogramm sein (Datenverbundname, Variablenbezeichner, Reihenfolge, Datentypen). In der Praxis sehen das viele Compiler nicht so eng. Allerdings können bei Nichtbeachtung dieser Vorgaben spätestens beim Wechsel des Compilers oder auf andere Rechnerarchitekturen gröbere Probleme auftreten.
| <<< zur Fortran-Startseite | |
| << Fortran 95 | Fortran 2003 >> |
| < Datentypen höherer Genauigkeit | Standardfunktionen > |