Zeiger

Zeiger in Fortran agieren wie Zeiger in C. Sie werden durch das Attribut POINTER deklariert, und zeigen ab dann auf andere Zeiger oder mittels TARGET deklarierte Variablen. Außerdem ist es möglich Zeigern dynamisch Speicherplatz zuzuordnen.

Deklaration von Zeigern

Ein Zeiger wird bei der Deklaration der Variable als solcher bekannt gemacht, indem das Attribut POINTER angegeben wird. Ein Zeiger kann auf POINTER oder auf Variablen mit dem Attribut TARGET zeigen. Mit dem -Operator wird ein Zeiger auf ein Target gelegt.

  integer,pointer :: ptr
  integer,target :: trg
 
  ptr => trg

Es gibt drei Zustände von Zeigern:

  • dangling (unbekannt)
  • null, disassociated (nicht zugeordnet)
  • associated (zugeordnet)

Nach dem Anlegen eines Zeigers hat er den Zustand dangling, nach einem ptr⇒null() oder nullify(ptr) den Zustand disassociated und nach dem Zuweisen ist er associated. Der Zustand kann mittels der Funktion associated abgefragt werden (.TRUE. falls der Zeiger zugeordnet ist, ansonsten .FALSE.). Als zweiten Parameter kann man ein unter Verdacht stehendes Ziel angeben und erhält zurück, ob der Zeiger auf dieses Ziel zeigt.

  program main
  integer, pointer :: ptr
  integer, target :: trg=123, trg2=1
 
  ptr => trg
  write (*,*) ptr, associated (ptr)
 
  ptr => null()
  write (*,*) ptr, associated (ptr)
 
  ptr => trg2
  write (*,*) ptr, associated (ptr), associated ( ptr, trg )
end program

Ausgabe:

         123 T
           0 F
           1 T F

Speicherverwaltung

:!: dynamische Speicherverwaltung.

Mit den Funktionen ALLOCATE und DEALLOCATE kann einem Zeiger auch Speicherplatz zugewiesen werden. Sollte dem Zeiger vorher ein Wert zugewiesen werden, würde das Programm abstürzen.

program main
  integer, pointer :: ptr, ptr2
 
  allocate ( ptr )
  ptr = 1234
  write (*,*) ptr
 
  ptr2 => ptr
  write (*,*) ptr, ptr2
 
  ptr = 5678
  write (*,*) ptr, ptr2
 
  deallocate (ptr)
end program

Zeiger auf Felder

Mit Zeigern auf Felder ist es mögliche Teilfelder zu referenzieren, also bspw. Felder, die nur den Beginn, nur das Ende oder nur einen Teil in der Mitte eines Feldes anzeigen:

program main
  integer :: i
  integer, parameter :: n = 10
  integer, dimension(:),pointer :: ptr
  integer, dimension(n), target :: trg = (/1,2,3,4,5,6,7,8,9,10/)
 
  write(*,*) trg
 
  ptr => trg
  write(*,*) ptr
 
  ptr => trg(:5)
  write(*,*) ptr
 
  ptr => trg(6:8)
  write(*,*) ptr
 
  ptr => trg(6:)
  write(*,*) ptr
end program

Ausgabe:

           1           2           3           4           5           6           7           8           9          10
           1           2           3           4           5           6           7           8           9          10
           1           2           3           4           5
           6           7           8
           6           7           8           9          10