Fortran: Fortran 95: Datenverbund

<<< zur Fortran-Startseite
<< Fortran 95 Fortran 2003 >>
< Datentypen höherer Genauigkeit Standardfunktionen >



Einleitung Bearbeiten

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

type name
 ...
end type [name]
type [,zugriffsspezifizierer] :: name
 ...
end type [name]

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 Bearbeiten

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 Bearbeiten

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 Bearbeiten

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 Bearbeiten

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 Bearbeiten

Default-Werte im Datenverbund setzen Bearbeiten

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" Bearbeiten

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 Bearbeiten

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 Bearbeiten

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 >