Fortran: FORTRAN 77: Unterprogramme
<<< 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
BearbeitenEine 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
BearbeitenSoll 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
BearbeitenEine 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
BearbeitenBeispiel: Ü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
BearbeitenAuch 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
BearbeitenMit 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
BearbeitenMittels 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
BearbeitenDurch 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
BearbeitenDATA
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 > |