Kurz: Eine function liefert einen Wert, eine subroutine (aufgerufen mit call) kann mehrere Ergebnisse über Argumente zurückgeben. Mit intent legst du die Richtung der Argumente fest:
Teil des Kurses Fortran
function und subroutine
Eine function liefert einen Wert, eine subroutine (aufgerufen mit call) kann mehrere Ergebnisse über Argumente zurückgeben. Mit intent legst du die Richtung der Argumente fest:
| intent | Bedeutung |
|---|---|
in | nur lesen |
out | nur zurückgeben |
inout | lesen und ändern |
program unterprogramme
implicit none
print *, quadrat(7.0)
print *, fakultaet(10)
print *, istgerade(4), istgerade(7)
block
real :: mittel, abw
call statistik([2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0], mittel, abw)
print "(a, f6.2, a, f6.2)", "Mittel ", mittel, " Abweichung ", abw
end block
block
integer :: a, b
a = 3; b = 8
call tausche(a, b)
print *, a, b
end block
contains
real function quadrat(x)
real, intent(in) :: x
quadrat = x * x
end function quadrat
recursive function fakultaet(n) result(r)
integer, intent(in) :: n
integer(kind=8) :: r
if (n <= 1) then
r = 1
else
r = n * fakultaet(n - 1)
end if
end function fakultaet
logical function istgerade(n)
integer, intent(in) :: n
istgerade = mod(n, 2) == 0
end function istgerade
subroutine statistik(v, mittel, abw)
real, intent(in) :: v(:)
real, intent(out) :: mittel, abw
mittel = sum(v) / size(v)
abw = sqrt(sum((v - mittel)**2) / size(v))
end subroutine statistik
subroutine tausche(a, b)
integer, intent(inout) :: a, b
integer :: t
t = a; a = b; b = t
end subroutine tausche
end program unterprogrammeAusgabe:
49.0000000
3628800
T F
Mittel 5.00 Abweichung 2.00
8 3Unterprogramme nach contains heißen interne Prozeduren: Sie kennen die Variablen des Hauptprogramms. Für größere Programme nutzt du Module.
Module
Ein Modul bündelt Konstanten, Datentypen und Prozeduren. Mit use bindest du es ein; private/public steuern die Sichtbarkeit.
module geometrie
implicit none
private
public :: pi, kreis_flaeche, kreis_umfang, dreieck_flaeche, form
real, parameter :: pi = 3.14159265
type :: form
character(len=10) :: name
real :: a = 0.0, b = 0.0
contains
procedure :: flaeche => form_flaeche
end type form
contains
pure function kreis_flaeche(r) result(f)
real, intent(in) :: r
real :: f
f = pi * r * r
end function kreis_flaeche
pure function kreis_umfang(r) result(u)
real, intent(in) :: r
real :: u
u = 2.0 * pi * r
end function kreis_umfang
pure function dreieck_flaeche(a, b, c) result(f)
real, intent(in) :: a, b, c
real :: f, s
s = (a + b + c) / 2.0
f = sqrt(s * (s - a) * (s - b) * (s - c))
end function dreieck_flaeche
function form_flaeche(self) result(f)
class(form), intent(in) :: self
real :: f
f = self%a * self%b
end function form_flaeche
end module geometrie
program main
use geometrie
implicit none
type(form) :: r
print "(f8.4)", kreis_flaeche(1.0)
print "(f8.4)", kreis_umfang(2.0)
print "(f8.4)", dreieck_flaeche(3.0, 4.0, 5.0)
r = form("Rechteck", 3.0, 4.5)
print "(a, f6.2)", trim(r%name) // ": ", r%flaeche()
end program mainAusgabe:
3.1416
12.5664
6.0000
Rechteck: 13.50pure: keine Nebenwirkungen (erlaubt Optimierung und Parallelität)elemental: Funktion wirkt automatisch elementweise auf ArraysoptionalArgumente mitpresent(), benannte Argumentef(x=1), Schnittstelleninterfacefür Überladung
module hilfen
implicit none
contains
elemental real function cel_zu_fahr(c)
real, intent(in) :: c
cel_zu_fahr = c * 9.0 / 5.0 + 32.0
end function
function potenz(basis, exp) result(r)
real, intent(in) :: basis
integer, intent(in), optional :: exp
real :: r
if (present(exp)) then
r = basis ** exp
else
r = basis ** 2
end if
end function
subroutine zaehle(text, anzahl)
character(len=*), intent(in) :: text
integer, intent(out) :: anzahl
anzahl = len_trim(text)
end subroutine
end module hilfen
program test
use hilfen
implicit none
integer :: n
print *, cel_zu_fahr([0.0, 37.0, 100.0]) ! wirkt auf das ganze Array
print *, potenz(3.0), potenz(2.0, 10), potenz(exp=3, basis=2.0)
call zaehle("Fortran ", n)
print *, n
end program testAusgabe:
32.0000000 98.5999985 212.000000
9.00000000 1024.00000 8.00000000
7Überladung mit interface
module ausgabe
implicit none
interface zeige
module procedure zeige_int, zeige_real, zeige_text
end interface
contains
subroutine zeige_int(x)
integer, intent(in) :: x
print "(a, i0)", "Ganzzahl: ", x
end subroutine
subroutine zeige_real(x)
real, intent(in) :: x
print "(a, f0.2)", "Kommazahl: ", x
end subroutine
subroutine zeige_text(x)
character(len=*), intent(in) :: x
print "(2a)", "Text: ", x
end subroutine
end module ausgabe
program uebung
use ausgabe
call zeige(42)
call zeige(3.14)
call zeige("Hallo")
end program uebungAusgabe:
Ganzzahl: 42
Kommazahl: 3.14
Text: HalloMerke
functionliefert einen Wert,subroutinepercall;intent(in/out/inout)dokumentiert und prüft- Module bündeln Code:
module ... contains ... end module,use modul private/public,pure,elemental,optional,recursivefür saubere Schnittstellen- Generische Namen mit
interface
Übungsaufgabe
Schreibe ein Modul statistik mit den Funktionen mittelwert, varianz und median für real-Arrays.
Quiz zur Selbstkontrolle
Wofür steht intent(out)?
- Das Argument wird nur zurückgegeben (richtig)
- Das Argument wird nur gelesen
- Das Argument ist optional
- Das Argument wird kopiert
Was tut call?
- Ruft eine Subroutine auf (richtig)
- Ruft eine Funktion auf
- Startet ein Programm
- Importiert ein Modul
Was bewirkt elemental?
- Die Funktion wirkt automatisch auf jedes Element eines Arrays (richtig)
- Die Funktion ist rekursiv
- Die Funktion ist privat
- Die Funktion ist langsam
Weiter im Kurs
Zurück: Arrays
Weiter: Eigene Datentypen, Dateien und Genauigkeit
Alle Kapitel: Fortran im Überblick