====== 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 =====
:!: [[dynaminc_memory|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