====== 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 in Fortran 90 ist es ebenfalls möglich, die Grenzen des Feldes direkt anzugeben, dann lassen sich die Elemente auch nur innerhalb dieser Grenzen ansprechen. Es sind sogar negative Indizes möglich. ! Das Feld läuft von a(0) bis a(9) integer, dimension(0:9) :: 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) :: d integer,dimension(10) :: e integer,dimension(10) :: f integer k ! nach dem Anlegen zuweisen b = 0 ! alle Stellen überschreiben mit dem gleichen Wert d(1:10) = 0 ! jeder Stelle wird ein angegebener Wert zugeordnet. e = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/) ! Zählschleife; jeden Wert einzeln überschreiben do k=1, 10 f(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