Dies ist eine alte Version des Dokuments!


Felder / Arrays / Matrizen

Felder sind in Programmiersprachen nützlich um viele Daten des gleichen Typs speichern zu können. Außerdem können so Vektoren oder Matrizen dargestellt werden, sodass ein einfacher Zugriff auf die Daten möglich wird.

Anlegen von Feldern

Eindimensionale Felder

Eindimensionale Felder können auf unterschiedliche Weise angelegt werden. Einmal in Fortran 77:

integer a(10)

oder Fortran 90:

integer,dimension(10) :: a

Mehrdimensionale Felder

Fortran 77:

integer b(10,10)

Fortran 90:

integer,dimension(10,10) :: b

Startbelegung eines Feldes

Um ein Feld zum Zeitpunkt des Anlegens mit einem Wert (hier beispielhaft Nullen) zu füllen, gibt es viele mehrere Möglichkeiten, hier einige davon:

! beim Anlegen zuweisen
integer,dimension(10) :: a = 0;
integer,dimension(10) :: b
integer,dimension(10) :: c
integer,dimension(10) :: d
integer k
 
! nach dem Anlegen zuweisen
b = 0
! alle Stellen überschreiben mit dem gleichen Wert
c(1:10) = 0
 
! Zählschleife; jeden Wert einzeln überschreiben
do k=1, 10
  d(k) = 0
enddo

Je nachdem, wie gut der Compiler den Code optimiert können bei den unterschiedlichen Methoden unterschiedliche Dateigrößen und unterschiedliche Ausführungszeiten des Programms entstehen.

Zugriff auf die Datenelemente

Der Zugriff auf ein einziges Datenelement erfolgt mittels in Klammern angegebenem Index. Beachten Sie, dass in Fortran die Indizes bei 1 beginnen.

integer,dimension(10) :: a = 0
a(1) = 100
 
write (*,*) a(1), a(2) 

Auch möglich sind Zählschleifen bei der Ausgabe:

integer,dimension(10) :: a = 0
integer k
 
do k=1, 10
  a(k) = k
enddo
 
! Ausgabe aller a(i) mit i = 1 bis 10
write (*,*) (a(i), i=1, 10)
! in Kurz:
write (*,*) a(1:10)

Besonderheiten

In der Programmiersprache C kann auf Felder immer nur Elementweise zugegriffen werden, in Fortran ist es aber auch möglich mehrere Feldelemente mit einer Anweisung anzusprechen, bspw:

integer,dimension(10) :: a
a(1:5) = 1
a(6:10) = 2

Eine weitere Besonderheit ist, dass in Fortran Matrizen Spaltenweise hintereinander im Speicher liegen. Dh. legen wir eine Matrix an, und übergeben diese an ein Programm, was diese Matrix wie ein langes eindimensionales Feld interpretiert, sieht man, dass zunächst die Werte nach unten gespeichert werden, erreicht man das untere Ende der Matrix beginnen die Werte der zweiten Spalte.

Es ist ebenfalls möglich Submatrizen in Funktionen zu übergeben. Dazu werden sowohl Beginn- als auch Ende-Indizes benötigt. Der Compiler wird beim Funktionsruf genau dann ein Kopieren der Submatrix einleiten, wenn die Spaltengröße der Submatrix nicht mit der Spaltengröße der originalen Matrix übereinstimmt. Dh. wird ein Teil der Matrix übergeben, der in der originalen Matrix zusammenhängt, dann wird nicht kopiert; soll allerdings ein Teil übergeben werden, der nicht zusammenhängt (siehe Abbildung), dann muss die Submatrix kopiert werden, um einen einfachen Zugriff im Unterprogramm zu ermöglichen. Es kann effizienter sein, die Matrix in der kompletten Spaltenbreite zu übergeben (um ein Kopieren zu verhindern) und im Unterprogramm die Indizies so umzurechnen, dass nur auf das gewünschte Stück zugegriffen wird.

program main
  implicit none
  integer, dimension(10,10) :: A
  integer :: i,j
  integer summe
 
  do i=1, 10
    do j=1, 10
      A(i,j) = (i*100) + j;
    enddo
  enddo
 
  ! Ausgabe der Matrix; siehe Kapitel über Formatstrings
  write ( *, '(10I5,1X)') ((A(i,j), i=1,10), j=1,10)
 
  write (*,*) summe ( A(3:5,3:5) );
end program
 
integer function summe ( A )
  implicit none
  integer,dimension(3,3) :: A
  integer :: k, j, x
 
  do k=1, 3
    !write ( *, '(3I4,1X)') (A(k,x), x=1,3)
    do j=1, 3
      summe = summe + A(k,j)
    enddo
  enddo
end function