next up previous contents
Nächste Seite: FILE oder Datei Aufwärts: Fortran 90 Vorherige Seite: Benutzerdefinierte Datentypen   Inhalt

Pointer

Wie viele andere Programmiersprachen kennt Fortran 90 auch Pointer, also Variablen, deren Werte Adressen anderer Variablen sind.
Im Gegensatz zu vielen dieser Programmiersprachen (z.B. C) wird in Fortran 90 automatisch und kontextabhängig unterschieden, ob mit dem Pointer die Adresse oder der Wert der Zieladresse gemeint ist.
Jeder Datentyp, ob vor- oder selbstdefiniert, kann das POINTER-Attribut bekommen, Pointer sind also keine eigenständigen Datentypen.
typ [parameter] [,attribute], POINTER :: name [...]
Die Ziele von Zeigern sind dann entweder Variable (mit dem TARGET-Attribut) oder aber selbst wieder Zeiger:
typ [parameter] [,attribute], TARGET :: name [...]
Pointer können z.B. verwendet werden, um Alias-Namen für Datenobjekte, vor allem für Teilobjekte, zu vergeben:
 REAL, POINTER, DIMENSION(:,:) :: oben, unten
 REAL, TARGET, DIMENSION(10,10) :: matrix
 ...
 oben => matrix(1:5,1:5)
 unten => matrix(6:10,6:10)
 ...
 DO j = 1, 5
  DO i = 1, 5
   READ (*,*) oben(i,j)
  END DO
 END DO
 ...

Die sinnvollste Verwendung von Pointern ist aber wohl der Aufbau von verketteten Listen, d.h. Datenstrukturen, die beliebig wachsen, aber auch wieder schrumpfen können, mit dem Befehl NULLIFY wird dabei eingetragen, daß der Zeiger (noch) auf kein weiteres Element der Liste zeigt, mit ASSOCIATED kann man abfragen, ob ein Zeiger auf etwas zeigt oder nicht:

PROGRAM kette

 TYPE adresse                                   ! selbstdefinierter Typ
  CHARACTER*30           :: vorname, nachname   ! aus 2 Character-Strings,
  INTEGER                :: tel_nummer          ! einer Integer-Zahl und
  TYPE(adresse), POINTER :: next                ! einem Zeiger (auf die
 END TYPE adresse                               ! selbe Datenstruktur)

 TYPE (adresse), TARGET  :: first               ! Ziel wird das erste,
 TYPE (adresse), POINTER :: jetzt, last         ! Pointer das aktuelle
                                                ! und das letzte Element

 last => first                                  ! das letzte Element zeigt
                                                ! zu Beginn auf den Anfang
 NULLIFY (last%next)                            ! der Zeiger auf das naechste
                                                ! Element zeigt vom letzten
                                                ! Element am Anfang auf nichts

 DO                                             ! Endlosschleife
  WRITE (*,'(A)') 'naechste Adresse (Beenden mit Ctrl-D): '
  ALLOCATE (jetzt)                              ! reserviere Speicher fuer
                                                ! die naechste Eingabe
  WRITE (*,'(A)', ADVANCE='NO') 'Vorname: '
  READ (*,*,IOSTAT=iostat) jetzt%vorname        ! Lies die Werte auf das
  if (iostat /= 0) EXIT                         ! aktuelle Element ein
  WRITE (*,'(A)', ADVANCE='NO') 'Nachname: '
  READ (*,*) jetzt%nachname
  WRITE (*,'(A)', ADVANCE='NO') 'Telephonnummer: '
  READ (*,*) jetzt%tel_nummer
  NULLIFY (jetzt%next)                          ! der Zeiger des aktuellen
                                                ! Elements zeigt auf nichts

  last%next => jetzt                            ! der Zeiger des bisher letzten
                                                ! Elements zeigt nun auf das
                                                ! aktuelle Element 
  last => jetzt                                 ! der Zeiger "letztes Element"
                                                ! zeigt nun auf das aktuelle
                                                ! Element
  WRITE (*,*)
 END DO

 WRITE (*,'(A)') 'Liste wuerde jetzt z.B. sortiert ...'

 WRITE (*,'(A)') 'Ausgabe der Liste: '
 jetzt => first                                 ! das aktuelle Element zeigt
                                                ! auf den Beginn der Liste
 DO
  IF (.NOT. ASSOCIATED (jetzt%next)) EXIT       ! falls das aktuelle Element
                                                ! auf nichts mehr zeigt ist 
                                                ! das Listenende erreicht

  jetzt => jetzt%next                           ! geh zum naechsten Element
                                                ! und gib die Daten aus
  WRITE (*,'(A)',ADVANCE="NO") TRIM(ADJUSTL(jetzt%vorname))//" "
  WRITE (*,'(A)',ADVANCE="NO") TRIM(ADJUSTL(jetzt%nachname))//" "
  WRITE (*,*) jetzt%tel_nummer
 END DO
END PROGRAM


Reinfried O. Peter 2001-09-07