EMZETT.
Login

Kurz: Arrays sind in Fortran eingebaut und besonders mächtig: Operationen wirken auf ganze Arrays, ohne Schleife. Indizes beginnen standardmäßig bei 1.

Teil des Kurses Fortran

Kapitel 4 von 8 im Kurs Fortran (Abschnitt „Rechnen mit Feldern“). Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

Arrays: die Stärke von Fortran

Arrays sind in Fortran eingebaut und besonders mächtig: Operationen wirken auf ganze Arrays, ohne Schleife. Indizes beginnen standardmäßig bei 1.

program arrays1
  implicit none
  integer, parameter :: n = 5
  real :: v(n), w(n)
  integer :: i, a(3) = [10, 20, 30]
 
  v = [1.0, 2.0, 3.0, 4.0, 5.0]
  w = 2.0
  print *, v
  print *, v + w                  ! elementweise
  print *, v * v
  print *, sqrt(v)
  print *, sum(v), product(v), maxval(v), minval(v)
  print *, maxloc(v), minloc(v)
  print *, size(v), shape(v)
  print *, v(2:4)                 ! Ausschnitt
  print *, v(5:1:-2)              ! mit Schrittweite
  print *, a(1), a(size(a))
  v(2:3) = 0.0
  print *, v
  print *, dot_product([1, 2, 3], [4, 5, 6])
  print *, any(v > 4), all(v >= 0), count(v > 0)
  print *, pack(v, v > 0)         ! nur positive Elemente
  where (v == 0.0) v = -1.0       ! Bedingte Zuweisung
  print *, v
  print *, [(i * i, i = 1, 6)]    ! Array-Konstruktor mit implizierter Schleife
  print *, cshift([1, 2, 3, 4], 1), eoshift([1, 2, 3, 4], 1)
end program arrays1

Ausgabe:

1.00000000       2.00000000       3.00000000       4.00000000       5.00000000
   3.00000000       4.00000000       5.00000000       6.00000000       7.00000000
   1.00000000       4.00000000       9.00000000       16.0000000       25.0000000
   1.00000000       1.41421354       1.73205078       2.00000000       2.23606801
   15.0000000       120.000000       5.00000000       1.00000000
           5           1
           5           5
   2.00000000       3.00000000       4.00000000
   5.00000000       3.00000000       1.00000000
          10          30
   1.00000000       0.00000000       0.00000000       4.00000000       5.00000000
          32
 T T           3
   1.00000000       4.00000000       5.00000000
   1.00000000      -1.00000000      -1.00000000       4.00000000       5.00000000
           1           4           9          16          25          36
           2           3           4           1           2           3           4           0

Mehrdimensionale Arrays

program matrizen
  implicit none
  integer :: A(2, 3), B(3, 2), C(2, 2), i, j
  real :: M(2, 2)
 
  A = reshape([1, 2, 3, 4, 5, 6], [2, 3])      ! spaltenweise gefüllt
  do i = 1, 2
    print "(3i4)", (A(i, j), j = 1, 3)
  end do
  print *, shape(A), size(A), rank(A)
  print *, A(2, :)                              ! zweite Zeile
  print *, A(:, 3)                              ! dritte Spalte
  B = transpose(A)
  C = matmul(A, B)
  print "(2i5)", C(1, :), C(2, :)
  print *, sum(A), sum(A, dim=1), sum(A, dim=2)
  print *, maxval(A, dim=2)
 
  M = reshape([4.0, 1.0, 2.0, 3.0], [2, 2])
  print "(2f8.3)", M(1, :), M(2, :)
  print *, "Determinante:", M(1, 1) * M(2, 2) - M(1, 2) * M(2, 1)
end program matrizen

Ausgabe:

1   3   5
   2   4   6
           2           3           6           2
           2           4           6
           5           6
   35   44
   44   56
          21           3           7          11           9          12
           5           6
   4.000   2.000
   1.000   3.000
 Determinante:   10.0000000

Hinweis

Fortran speichert Matrizen spaltenweise (column-major). Für schnelle Schleifen muss der linke Index am schnellsten laufen: do j ... do i ... a(i, j).

Dynamische Arrays

program dynamisch
  implicit none
  real, allocatable :: x(:), m(:, :)
  integer :: n, i
 
  n = 5
  allocate(x(n))
  x = [(real(i), i = 1, n)]
  print *, allocated(x), size(x), x(n)
 
  allocate(m(2, 3), source = 1.5)
  print *, shape(m), sum(m)
  deallocate(m)
  print *, allocated(m)
 
  x = [x, 6.0, 7.0]                 ! automatisch vergrößern (Fortran 2003)
  print *, size(x), x(size(x))
 
  block
    integer, allocatable :: idx(:)
    idx = pack([(i, i = 1, 10)], mod([(i, i = 1, 10)], 3) == 0)
    print *, idx
  end block
end program dynamisch

Ausgabe:

T           5   5.00000000
           2           3   9.00000000
 F
           7   7.00000000
           3           6           9

Sortieren und Suchen

program sortieren
  implicit none
  integer :: z(8) = [5, 2, 9, 1, 7, 3, 8, 4]
  integer :: i, j, tmp
 
  do i = 1, size(z) - 1                    ! Bubblesort
    do j = 1, size(z) - i
      if (z(j) > z(j + 1)) then
        tmp = z(j); z(j) = z(j + 1); z(j + 1) = tmp
      end if
    end do
  end do
  print *, z
  print *, findloc(z, 7, dim=1)             ! Index des Wertes 7
  print *, minval(z), maxval(z), sum(z) / real(size(z))
  print *, merge(z, 0, z > 4)               ! Elemente > 4 behalten, sonst 0
end program sortieren

Ausgabe:

1           2           3           4           5           7           8           9
           6
           1           9   4.87500000
           0           0           0           0           5           7           8           9

Merke

  • Arrays: real :: v(n), mehrdimensional a(2, 3), Indizes ab 1, spaltenweise gespeichert
  • Ganze-Array-Operationen (v + w, sqrt(v)) ersetzen Schleifen
  • Ausschnitte v(2:4), Funktionen sum, maxval, matmul, transpose, pack, where
  • allocatable Arrays mit allocate/deallocate

Übungsaufgabe

Berechne das Produkt zweier 3×3-Matrizen mit matmul und gib die Spur aus.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Verzweigungen und Schleifen

Weiter: Funktionen, Unterprogramme und Module

Alle Kapitel: Fortran im Überblick