| <<< zur Fortran-Startseite | |
| << FORTRAN 77 | Fortran 90/95 >> |
| < Standardfunktionen | Ein- und Ausgabe > |
Natürlich können in FORTRAN 77 auch eigene Unterprogramme erstellt werden.
Funktionsanweisung
Eine Funktionsanweisung (auch Anweisungsfunktion genannt) stellt die einfachste Möglichkeit dar, ein Unterprogramm in FORTRAN 77 zu realisieren. Eine Funktionsanweisung kann nur einen Ausdruck umfassen und gilt nur in der Programmeinheit in der sie definiert wurde.
Definieren einer Funktionsanweisung:
funktionsname([formale parameter]) = ausdruck |
Aufruf der Funktion:
[variable =] funktionsname([aktuelle parameter]) |
Beispiel:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
PROGRAM BSP
FUNK() = 5
WRITE (*,*) FUNK ()
C Ausgabe: 5.000000
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Beispiel:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
PROGRAM BSP
REAL A, B, C
FUNK(A, B) = COS(A) * LOG(B)
C = FUNK(3.1415, 2.)
WRITE (*,*) C
C Ausgabe: -0.6931472
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
FUNCTION
Soll eine Funktion mehrere Anweisungen umfassen, so genügt das Konzept der Funktionsanweisung nicht mehr. FORTRAN 77 kennt zu diesem Zweck das Schlüsselwort FUNCTION.
|
[datentyp] anweisungen
|
Aufgerufen wird eine derartige Funktion gleich wie eine Funktionsanweisung.
Beispiel:
Datei bsp.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
PROGRAM BSP
C Funktionsaufruf
WRITE(*,*) FUNK()
C Ausgabe: 27.50000
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Datei funk.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
REAL FUNCTION FUNK()
REAL TMP
DO 10 I = 1,10
TMP = TMP + I*0.5
10 CONTINUE
FUNK = TMP
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Übersetzung mit gfortran:
gfortran bsp.f funk.f
Eine Funktion muss einen Wert zurückgeben. Welcher Wert das ist, wird durch eine Zuweisung an den Funktionsnamen erreicht. Wird am Anfang des Funktionskopfes kein Datentyp explizit vorgegeben, so gelten die Regeln für die implizite Datentypvergabe.
Mit Hilfe des Schlüsselwortes RETURN kann eine Funktion auch vor dem Funktionsende verlassen werden.
Beispiel:
Datei bsp.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
PROGRAM BSP
C Funktionsaufruf
WRITE(*,*) FUNK(3)
C Ausgabe: 1.500000
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Datei funk.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
FUNCTION FUNK(I1)
IF(I1 .LE. 5) THEN
FUNK = 1.5
RETURN
END IF
FUNK = SIN(I1*0.5)
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
SUBROUTINE
Eine Subroutine besitzt im Gegensatz zu einer Funktion keinen Datentyp und gibt keinen Wert zurück.
|
anweisungen
|
Aufruf der Subroutine:
CALL subroutinenname([aktuelle parameter]) |
Beispiel:
Datei test.f
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
PROGRAM BSP
CALL SUB
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Datei sub.f
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
SUBROUTINE SUB
WRITE (*,*) 'Hallo Welt!'
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Übersetzung mittels gfortran:
gfortran -c sub.f gfortran -c test.f gfortran test.o sub.o
Anzeige auf der Standardausgabe:
Hallo Welt!
Auch eine Subroutine kann mittels RETURN vorzeitig verlassen werden.
Die aktuellen und formalen Parameter müssen hinsichtlich Datentyp, Anzahl, Reihenfolge übereinstimmen.
Alle Namen und Variablen in einer Programmeinheit (Subroutine, Funktion oder Hauptprogramm) sind grundsätzlich nur lokal in der jeweiligen Programmeinheit bekannt. Über die Unterprogrammparameter können aber sehr wohl Werte in der aufrufenden Programmeinheit geändert werden.
Beispiel:
Datei bsp.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
PROGRAM BSP
REAL A = 2.0
CALL SUB(A)
WRITE(*,*) A
C Ausgabe: 10
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Datei sub.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
SUBROUTINE SUB(X)
REAL X
REAL A
C Unterprogrammparameter
X = 10
C lokale Variable
A = 500
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Felder als Parameter
Beispiel: Übergabe eines ganzen Feldes
Datei bsp.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
PROGRAM BSP
INTEGER FELD(3,3)
INTEGER CNT
CNT = 1
DO 10 I = 1, 3
DO 20 J = 1, 3
FELD(J,I) = CNT
CNT = 1 + CNT
20 CONTINUE
10 CONTINUE
C Unterprogrammaufruf
CALL SUB(FELD)
C Ausgabe: 1 2 3 4 5 6 7 8 9
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Datei sub.f
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
SUBROUTINE SUB(ARR)
INTEGER ARR(3, 3)
WRITE(*,*) ARR
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Beispiel: Übergabe einer Feld-Teilkette
Datei bsp.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
PROGRAM BSP
INTEGER FELD(3,3)
INTEGER CNT
CNT = 1
DO 10 I = 1, 3
DO 20 J = 1, 3
FELD(J,I) = CNT
CNT = 1 + CNT
20 CONTINUE
10 CONTINUE
C Unterprogrammaufruf
CALL SUB(FELD(1:2,2:3))
C Ausgabe: 4 5 7 8
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Datei sub.f
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
SUBROUTINE SUB(ARR)
INTEGER ARR(0:1, 0:1)
WRITE(*,*) ARR
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Beispiel: Übergabe eines Feld-Einzelelements
Datei bsp.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
PROGRAM BSP
INTEGER FELD(3,3)
INTEGER CNT
CNT = 1
DO 10 I = 1, 3
DO 20 J = 1, 3
FELD(J,I) = CNT
CNT = 1 + CNT
20 CONTINUE
10 CONTINUE
C Unterprogrammaufruf
CALL SUB(FELD(1,2))
C Ausgabe: 4
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Datei sub.f
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
SUBROUTINE SUB(ARR)
INTEGER ARR
WRITE(*,*) ARR
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Prozeduren als Parameter
Auch Prozeduren können als Parameter übergeben werden.
Standardfunktionen werden dazu folgendermaßen im Vereinbarungsteil gekennzeichnet:
Aufruf der Subroutine:
INTRINSIC namensliste |
Eigene Funktionen oder Subroutinen mit:
EXTERNAL namensliste |
Beispiel:
Datei bsp.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
PROGRAM BSP
REAL PI
PARAMETER(PI=3.1415927)
C intrinsic functions
INTRINSIC SIN, COS
C Unterprogrammaufrufe
CALL SUB(SIN, PI)
C Ausgabe: 0.000000
CALL SUB(COS, PI)
C Ausgabe: -1.000000
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Datei sub.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
SUBROUTINE SUB(FUNK, X)
REAL FUNK, X
WRITE(*,*) NINT(FUNK(X)*1000)/1000.0
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
COMMON
Mit COMMON läßt sich ein gemeinsamer Datenbereich für mehrere Programmeinheiten realisieren.
Unbenannter COMMON:
COMMON variablenliste |
COMMON /name/ variablenliste |
Beispiel:
Datei bsp.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
PROGRAM BSP
REAL A, B, C, D
COMMON A, B, C
COMMON /C1/ D
A = 4.0
B = 5.0
C = 6.0
CALL SUB
WRITE (*,*) A, B, C, D
C Ausgabe: 3.330000 4.440000 6.000000 5.550000
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Datei sub.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
SUBROUTINE SUB
REAL X, Y, Z
COMMON X, Y
COMMON /C1/ Z
X = 3.33
Y = 4.44
Z = 5.55
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
ENTRY
Mittels ENTRY kann gezielt in ein Unterprogamm gesprungen werden. Dieses Konstrukt widerspricht aber einer strukturierten Programmierung und sollte nicht verwendet werden.
ENTRY entryname[([formale parameter])] |
Der Aufruf entspricht dem einer Subroutine:
CALL entryname[([aktuelle parameter])] |
Beispiel:
Datei bsp.f
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
PROGRAM BSP
CALL SUB
C Ausgabe: Hallo
C Welt!
CALL E1
C Ausgabe: Welt!
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Datei sub.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
SUBROUTINE SUB
WRITE(*,*) 'Hallo'
ENTRY E1
WRITE (*,*) 'Welt!'
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
SAVE
Durch ein SAVE-Statement in Unterprogrammen behalten die lokalen Variablen ihren jeweiligen Wert auch nach Verlassen des Unterprogrammes. Dieses Konstrukt ist meist nicht notwendig, da die meisten FORTRAN-Compiler dieses Verhalten ohnehin automatisch aufweisen (siehe auch Kapitel DATA zwecks Initialisierung von Variablen).
SAVE [variablenliste] |
Beispiel:
Datei bsp.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
PROGRAM BSP
CALL SUB
C Ausgabe: 1.000000
CALL SUB
C Ausgabe: 2.000000
CALL SUB
C Ausgabe: 3.000000
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Datei sub.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
SUBROUTINE SUB
REAL A
SAVE
A = A + 1
WRITE(*,*) A
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
DATA
DATA dient zur Wertinitialisierung von Variablen vor der Programmeinheitausführung. Diese Anweisung ist also nicht gleichzusetzen mit einer Wertzuweisung.
Beispiel:
DATA [variablenliste] /variablenwerte/ |
Beispiel:
Datei bsp.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
PROGRAM BSP
CALL SUB
C Ausgabe: 1.000000
CALL SUB
C Ausgabe: 2.000000
CALL SUB
C Ausgabe: 3.000000
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Datei sub.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
SUBROUTINE SUB
REAL A
DATA A /0.0/
A = A + 1
WRITE(*,*) A
END
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Unterschied zwischen Wertinitialisierung und Wertzuweisung:
| Wertinitialisierung | Wertzuweisung | |
|---|---|---|
| Code |
PROGRAM BSP
CALL SUB
CALL SUB
CALL SUB
END
SUBROUTINE SUB
REAL A
DATA A /3.0/
A = A + 1
WRITE(*,*) A
END |
PROGRAM BSP
CALL SUB
CALL SUB
CALL SUB
END
SUBROUTINE SUB
REAL A
A = 3.0
A = A + 1
WRITE(*,*) A
END |
| Ausgabe |
4.000000 5.000000 6.000000 |
4.000000 4.000000 4.000000 |
| <<< zur Fortran-Startseite | |
| << FORTRAN 77 | Fortran 90/95 >> |
| < Standardfunktionen | Ein- und Ausgabe > |