Fortran - Wikimedia Commons

Fortran - Wikimedia Commons

Fortran Wikibooks Bibliografische Information Detaillierte Daten zu dieser Publikation sind bei Wikibooks zu erhalten: H T T P :// D E . W I K I B ...

4MB Sizes 0 Downloads 0 Views

Recommend Documents

Personal Computer - Wikimedia Commons
The PS/2's Model M keyboard from which modern PC ... two-handed alternatives more akin to a game controller, such as the

Cables v1.3 - Wikimedia Commons
Some computers and monitors. Some laptop computers. Some laptop computers. Aluminum Unibody MacBook (late 2008 - mid 200

WikiReader Internet - Wikimedia Commons
13.05.2004 - Viele dieser Browser (wie Mozilla, Internet Explorer) werden heu- ... Camino (früher: Chimera, für Mac OS

Inhaltsverzeichnis - Wikimedia Commons
Staaten, Hauptstädte und Landessprachen zuzuordnen. Flagge. Land. Hauptstadt. Landessprachen. (Minderheiten siehe. Fuß

Cloud Computing - Wikimedia Commons
Mar 10, 2015 - works: A revolution in the earth system science? ...... Grow to 26 Billion Units By 2020”. ... the Inte

Quizspiel - Wikimedia Commons
Absurdistan. Allwissende Müllhalde. Partymeile. Pommesgabel. Wikimedia logo family of Wikimedia Foundation. Wikipedia lo

Arduino - Wikimedia Commons
Jul 28, 2017 - Massimo Banzi (http://twit.tv/show/triangulation/110/) interviewed on the TV show Triangulation on the. T

Scientific mtti - Wikimedia Commons
with each other to co-operate i.n producing I others after It. The. oupling ... I pletely across a broad and deep river

nagarjunasagar dam - Wikimedia Commons
G. V. Gopalarao. Abstract. This article deals with the design and construction aspects of Nagarjunasagar. Dam situated i

Fortran

Wikibooks

Bibliografische Information Detaillierte Daten zu dieser Publikation sind bei Wikibooks zu erhalten: H T T P :// D E . W I K I B O O K S . O R G /

Namen von Programmen und Produkten sowie sonstige Angaben sind häufig geschützt. Da es auch freie Bezeichnungen gibt, wird das Symbol ® nicht verwendet. Erstellt am 10. März 2011.

Diese Publikation ist entstanden bei Wikibooks, einem Projekt für Lehr-, Sach- und Fachbücher unter den Lizenzen Creative Commons Attribution/Share-Alike (CC-BY-SA) und GFDL. PDF- und Druckversion sind entstanden mit dem Programm wb2pdf unter GPL. Dabei wurde das Textsatzprogramm LATEX verwendet, das unter der LPPL steht. Einzelheiten und Quellen dazu stehen im Anhang.

Inhaltsverzeichnis 1.

. . . .

1 1 4 5 6

I.

C OMPILER 1.5. WAS IST EIN C OMPILER ? . . . . . . . . . . . . . . . 1.6. AUFBAU EINES C OMPILERS . . . . . . . . . . . . . 1.7. G ESCHICHTE . . . . . . . . . . . . . . . . . . . . .

7 9 10 13

2.

G FORTRAN 2.1. WAS IST GFORTRAN ? . . . . . . . . . . . . . . . . . 2.2. I NSTALLATION . . . . . . . . . . . . . . . . . . . . . 2.3. S TARTEN DES GFORTRAN -C OMPILERS . . . . . . . 2.4. D ATEIENDUNGEN FÜR QUELLDATEIEN . . . . . . 2.5. A NWENDUNG . . . . . . . . . . . . . . . . . . . . . 2.6. P RÜFUNG DES QUELLCODES AUF S TANDARD KONFORMITÄT . . . . . . . . . . . . . . . . . . . . . 2.7. GFORTRAN -W EBLINKS . . . . . . . . . . . . . . . .

15 15 15 15 18 19

F ORTRAN : G95 3.1. Ü BER G 95 . . . . . . . . . . . . 3.2. I NSTALLATION . . . . . . . . . . 3.3. B EDIENUNG . . . . . . . . . . . 3.4. T ECHNISCHER H INTERGRUND

23 23 23 24 25

3.

E INLEITUNG 1.1. G ESCHICHTE . . 1.2. E IGENSCHAFTEN 1.3. C OMPILER . . . . 1.4. R EFERENZEN . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

20 21

III

Inhaltsverzeichnis

3.5. 4.

II.

III. 5.

6.

W EBLINK . . . . . . . . . . . . . . . . . . . . . . .

25

F ORTRAN : I FORT 4.1. A LLGEMEINES . . . . . . . . . . . . . . . . . . . . . 4.2. I NSTALLATION . . . . . . . . . . . . . . . . . . . . . 4.3. D ATEIENDUNGEN FÜR QUELLDATEIEN . . . . . . 4.4. A NWENDUNG . . . . . . . . . . . . . . . . . . . . . 4.5. W EBLINK FÜR DEN I NTEL F ORTRAN C OMPILER FOR L INUX . . . . . . . . . . . . . . . . . . . . . . .

27 27 27 28 28

D IE P ROGRAMMIERSPRACHE 4.6. WAS IST EINE P ROGRAMMIERSPRACHE ? . . . 4.7. E INORDNUNG VON F ORTRAN . . . . . . . . . 4.8. E IN Ü BERBLICK ÜBER DIE HISTORISCHE TWICKLUNG VON F ORTRAN . . . . . . . . . .

31 33 34

. . . . . . EN. . .

FORTRAN 77

36

39

P ROGRAMMAUFBAU 5.1. B EISPIEL : H ALLO W ELT . . . . . . . 5.2. D AS Z EILENFORMAT . . . . . . . . . 5.3. D IE P ROGRAMMSTRUKTUR FÜR DAS GRAMM . . . . . . . . . . . . . . . . . 5.4. D ER FORTRAN-Z EICHENVORRAT . 5.5. S YMBOLISCHE N AMEN . . . . . . . .

. . . . . . . . . . . . . . . . H AUPTPRO . . . . . . . . . . . . . . . . . . . . . . . .

41 41 42 45 45 46

D ATENTYPEN , VARIABLEN , W ERTZUWEISUNGEN , KON STANTEN

6.1. 6.2. 6.3. 6.4.

IV

29

D ATENTYPEN . . . . . . . VARIABLEN . . . . . . . . B ENANNTE KONSTANTEN W ERTZUWEISUNG . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

49 49 51 55 56

Inhaltsverzeichnis

7.

F ELDER 7.1. E INDIMENSIONALE F ELDER . . . . . . . . . . . . . 7.2. M EHRDIMENSIONALE F ELDER . . . . . . . . . . .

57 57 59

8.

A RITHMETISCHE AUSDRÜCKE 8.1. A RITHMETISCHE O PERATOREN . . . . . . . . . . . 8.2. E RGEBNISDATENTYP . . . . . . . . . . . . . . . . .

63 63 64

9.

L OGISCHE AUSDRÜCKE 9.1. L OGISCHE O PERATOREN . . . . . . . . . . . . . . . 9.2. WAHRHEITSTAFEL . . . . . . . . . . . . . . . . . .

67 67 67

10.

V ERGLEICHSAUSDRÜCKE 10.1. V ERGLEICHSOPERATOREN FÜR ARITHMETISCHE T YPEN . . . . . . . . . . . . . . . . . . . . . . . . . 10.2. Z EICHENKETTENVERGLEICHE . . . . . . . . . . . . 10.3. O PERATORENPRIORITÄT . . . . . . . . . . . . . . .

71

11.

S TRINGOPERATIONEN 11.1. V ERKNÜPFUNGSOPERATOR . . . . . . . . . . . . . 11.2. T EILKETTEN . . . . . . . . . . . . . . . . . . . . . .

77 77 78

12.

V ERZWEIGUNGEN UND S CHLEIFEN 12.1. GOTO . . . . . . . . . . . . . 12.2. CONTINUE . . . . . . . . . 12.3. B EDINGTES GOTO . . . . . . 12.4. IF-V ERZWEIGUNGEN . . . . . 12.5. DO-S CHLEIFEN . . . . . . . . 12.6. W EITERE S CHLEIFEN . . . . . 12.7. I MPLIZITE S CHLEIFE . . . . . 12.8. STOP . . . . . . . . . . . . .

. . . . . . . .

81 81 81 82 83 86 86 88 88

S TANDARDFUNKTIONEN 13.1. D ATENTYPUMWANDLUNG . . . . . . . . . . . . . . 13.2. M ATHEMATISCHE F UNKTIONEN . . . . . . . . . .

91 91 93

13.

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

71 73 74

V

Inhaltsverzeichnis

13.3. 14.

15.

16.

IV. 17.

VI

Z EICHENKETTEN -F UNKTIONEN . . . . . . . . . .

98

U NTERPROGRAMME 14.1. F UNKTIONSANWEISUNG . . . . 14.2. FUNCTION . . . . . . . . . . 14.3. SUBROUTINE . . . . . . . . . 14.4. F ELDER ALS PARAMETER . . . . 14.5. P ROZEDUREN ALS PARAMETER 14.6. COMMON . . . . . . . . . . . 14.7. ENTRY . . . . . . . . . . . . . 14.8. SAVE . . . . . . . . . . . . . . . 14.9. DATA . . . . . . . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

101 101 102 105 107 111 112 114 115 116

E IN - UND AUSGABE 15.1. READ . . . . . . 15.2. WRITE . . . . . 15.3. F ORMATIERUNG 15.4. D ATEIEN . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

119 119 122 124 128

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

A NHANG 16.1. L ISTE ALLER FORTRAN 77 S CHLÜSSELWÖRTER . 16.2. PAUSE . . . . . . . . . . . . . . . . . . . . . . . . . 16.3. INCLUDE . . . . . . . . . . . . . . . . . . . . . . 16.4. H OLLERITH -KONSTANTEN . . . . . . . . . . . . . 16.5. A RITHMETISCHES IF . . . . . . . . . . . . . . . . . 16.6. ASSIGN UND A SSIGNED GOTO . . . . . . . . . . 16.7. M IL S TD 1753, D O D S UPPLEMENT T O A MERICAN N ATIONAL S TANDARD X3.9-1978 . . . . . . . . .

F ORTRAN 95

145 145 145 146 147 148 149 151

153

P ROGRAMMAUFBAU 155 17.1. B EISPIEL : H ALLO W ELT . . . . . . . . . . . . . . . 155 17.2. D AS Z EILENFORMAT . . . . . . . . . . . . . . . . . 156

Inhaltsverzeichnis

17.3. 17.4. 17.5. 17.6. 17.7.

18.

D IE P ROGRAMMSTRUKTUR FÜR DAS H AUPTPRO GRAMM . . . . . . . . . . . . . . . . . . . . . . . . . D ER F ORTRAN -Z EICHENVORRAT . . . . . . . . . . S YMBOLISCHE N AMEN . . . . . . . . . . . . . . . . R ESERVIERTE S CHLÜSSELWÖRTER ? . . . . . . . . . D ETAILS ZUR A NORDNUNGSREIHENFOLGE VON A NWEISUNGEN . . . . . . . . . . . . . . . . . . . .

160

D ATENTYPEN , VARIABLEN , W ERTZUWEISUNGEN , KON . . . .

163 163 166 168 169

. . . . .

171 171 172 174 177 178

STANTEN

18.1. 18.2. 18.3. 18.4. 19.

158 158 159 159

D ATENTYPEN . . . . . . . VARIABLEN . . . . . . . . B ENANNTE KONSTANTEN W ERTZUWEISUNG . . . .

. . . .

. . . .

. . . .

F ELDER 19.1. B EISPIEL . . . . . . . . . . . . . 19.2. E INDIMENSIONALE F ELDER . . 19.3. M EHRDIMENSIONALE F ELDER 19.4. F ELDINITIALISIERUNG . . . . . 19.5. T EILFELDER . . . . . . . . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

. . . .

. . . . .

20.

A RITHMETISCHE AUSDRÜCKE 181 20.1. A RITHMETISCHE O PERATOREN . . . . . . . . . . . 181 20.2. E RGEBNISDATENTYP . . . . . . . . . . . . . . . . . 182

21.

L OGISCHE AUSDRÜCKE 21.1. L OGISCHE O PERATOREN . . . . . . . . . . . . . . . 21.2. WAHRHEITSTAFEL . . . . . . . . . . . . . . . . . . 21.3. O PERATORENPRIORITÄT . . . . . . . . . . . . . . .

22.

V ERGLEICHSAUSDRÜCKE 187 22.1. V ERGLEICHSOPERATOREN . . . . . . . . . . . . . . 187 22.2. O PERATORENPRIORITÄT . . . . . . . . . . . . . . . 188

185 185 185 186

VII

Inhaltsverzeichnis

23.

S TRINGOPERATIONEN 189 23.1. V ERKNÜPFUNGSOPERATOR . . . . . . . . . . . . . 189 23.2. T EILKETTEN . . . . . . . . . . . . . . . . . . . . . . 189

24.

V ERZWEIGUNGEN UND S CHLEIFEN 24.1. E INLEITUNG . . . . . . . . . . . . . 24.2. IF -V ERZWEIGUNGEN . . . . . . . . 24.3. D IE SELECT CASE -V ERZWEIGUNG 24.4. DO -S CHLEIFEN . . . . . . . . . . . 24.5. S PEZIALKONSTRUKTE FÜR F ELDER 24.6. T ERMINIERUNG . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

191 191 193 199 202 206 212

25.

D ATENTYPEN HÖHERER G ENAUIGKEIT 217 25.1. E INFACHE VARIANTE . . . . . . . . . . . . . . . . . 217 25.2. S YSTEM - UND COMPILERUNABHÄNGIGE VARIANTE 218

26.

D ATENVERBUND 223 26.1. E INLEITUNG . . . . . . . . . . . . . . . . . . . . . . 223 26.2. E INEN D ATENVERBUND ANLEGEN . . . . . . . . . 223 26.3. E INE VARIABLE VOM T YP "D ATENVERBUND " ANLEGEN . . . . . . . . . . . . . . . . . . . 224 26.4. Z UGRIFF AUF E INZELKOMPONENTEN EINES D ATENVERBUNDS . . . . . . . . . . . . . . . . . . . 225 26.5. Z UGRIFF AUF EINEN D ATENVERBUND ALS G ANZES 225 26.6. E LEMENTE EINES D ATENVERBUNDS INITIALISIEREN226 26.7. D AS ATTRIBUT sequence . . . . . . . . . . . . . . 229 26.8. D IE V ERWENDUNG EINES D ATENVERBUNDS IN SEPARATEN P ROGRAMMEINHEITEN . . . . . . . . . 229

27.

S TANDARDFUNKTIONEN 231 27.1. TABELLENLEGENDE . . . . . . . . . . . . . . . . . 231

VIII

Inhaltsverzeichnis

27.2. 27.3. 27.4. 27.5. 27.6. 27.7. 27.8. 27.9. 28.

1

2

3

4 5

6 7

8

D ATENTYPFUNKTIONEN 1 . . . . . M ATHEMATISCHE F UNKTIONEN 2 S TRINGFUNKTIONEN 3 . . . . . . . F ELDFUNKTIONEN 4 . . . . . . . . Z EIGERFUNKTIONEN 5 . . . . . . . B ITFUNKTIONEN 6 . . . . . . . . . W EITERE F UNKTIONEN 7 . . . . . I NTRINSISCHE S UBROUTINEN 8 . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

232 232 233 233 234 234 234 234

U NTERPROGRAMME 28.1. D AS function U NTERPROGRAMM . . . . . . . . . 28.2. D AS subroutine U NTERPROGRAMM . . . . . . . 28.3. W EITERE A NWEISUNGEN FÜR DIE U NTERPRO GRAMMTECHNIK . . . . . . . . . . . . . . . . . . . 28.4. F ELDER ALS PARAMETER . . . . . . . . . . . . . . .

235 235 238 239 243

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A% 20F O R T R A N %2095%3A%20S T A N D A R D F U N K T I O N E N %3A% 20D A T E N T Y P F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20S T A N D A R D F U N K T I O N E N %3A%20M A T H E M A T I S C H E % 20F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20S T A N D A R D F U N K T I O N E N %3A%20S T R I N G F U N K T I O N E N % 20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20S T A N D A R D F U N K T I O N E N %3A%20F E L D F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20S T A N D A R D F U N K T I O N E N %3A%20Z E I G E R F U N K T I O N E N % 20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20S T A N D A R D F U N K T I O N E N %3A%20B I T F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20S T A N D A R D F U N K T I O N E N %3A%20W E I T E R E % 20F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20S T A N D A R D F U N K T I O N E N %3A%20I N T R I N S I S C H E % 20S U B R O U T I N E N %20

IX

Inhaltsverzeichnis

28.5. 28.6. 28.7. 28.8.

P ROZEDUREN ALS PARAMETER . . . . . . O PTIONALE PARAMETER . . . . . . . . . . M ODULE . . . . . . . . . . . . . . . . . . . R EKURSIVER U NTERPROGRAMMAUFRUF

. . . .

. . . .

. . . .

. . . .

. . . .

245 246 247 249

29.

E IN - UND AUSGABE 251 29.1. READ . . . . . . . . . . . . . . . . . . . . . . . . . . 251 29.2. WRITE . . . . . . . . . . . . . . . . . . . . . . . . . 253 29.3. K ÜRZER : print, read, write UND N AMENSLISTEN 255 29.4. F ORMATIERUNG . . . . . . . . . . . . . . . . . . . 257 29.5. D ATEIEN . . . . . . . . . . . . . . . . . . . . . . . . 262

30.

Z EIGER 30.1. WAS SIND Z EIGER ? . . . . . . 30.2. Z EIGER IN F ORTRAN 95 . . . 30.3. A SSOZIATIONSSTATUS . . . . 30.4. S PEICHERPLATZ DYNAMISCH FREIGEBEN . . . . . . . . . . 30.5. Z EIGER UND F ELDER . . . . . 30.6. V ERKETTETE L ISTEN . . . . .

31.

281 . . . . . . . . . . . . 281 . . . . . . . . . . . . 281 . . . . . . . . . . . . 282 RESERVIEREN UND

. . . . . . . . . . . . 284 . . . . . . . . . . . . 285 . . . . . . . . . . . . 287

V EKTOREN - UND M ATRIZENRECHNUNG

291

32.

S YSTEMROUTINEN 295 32.1. D ATUM UND Z EIT . . . . . . . . . . . . . . . . . . 295 32.2. Z UFALLSZAHLEN . . . . . . . . . . . . . . . . . . . 295 32.3. KOMMANDOZEILENARGUMENTE . . . . . . . . . . 296

33.

V ON DER MODULAREN ZUR OBJEKTORIENTIERTEN P ROGRAMMIERUNG 33.1. M ODULE IM D ETAIL . . . . . . . . . . . . . . . . . 33.2. O BJEKTORIENTIERTE P ROGRAMMIERUNG . . . . . 33.3. AUSBLICK . . . . . . . . . . . . . . . . . . . . . . . 33.4. L ITERATUR . . . . . . . . . . . . . . . . . . . . . .

X

297 297 316 324 324

Inhaltsverzeichnis

34.

V. 35.

O FFIZIELLE F ORTRAN 95-E RWEITERUNGEN 34.1. Z EICHENKETTEN VARIABLER L ÄNGE . 34.2. B EDINGTE C OMPILIERUNG . . . . . . 34.3. F LOATING - POINT E XCEPTIONS . . . . 34.4. A LLOCATABLE C OMPONENTS . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

F ORTRAN 2003

327 327 329 331 332

337

P ROGRAMMAUFBAU 35.1. P ROGRAMMAUFBAU UND Z EILENFORMAT . . . . . 35.2. Z EICHENVORRAT . . . . . . . . . . . . . . . . . . . 35.3. A NWENDUNGSGEBIET DER NEU HINZUGEKOMMENEN Z EICHEN . . . . . . . . . . .

340

36.

D ATENTYPEN 36.1. I NTRINSISCHE D ATENTYPEN . . . . . . . . . . . . 36.2. E NUMERATION . . . . . . . . . . . . . . . . . . . . 36.3. D ERIVED T YPE . . . . . . . . . . . . . . . . . . . .

341 341 342 343

37.

Z EIGER 347 37.1. P ROZEDURENZEIGER . . . . . . . . . . . . . . . . . 347 37.2. Z EIGER UND DAS intent-ATTRIBUT . . . . . . . . 350 37.3. Z EIGER UND F ELDER . . . . . . . . . . . . . . . . . 351

38.

E IN - UND AUSGABE 38.1. S TREAMS . . . . . . 38.2. A SYNCHRONE I/O 38.3. R EKURSIVE I/O . . 38.4. S ONSTIGES . . . . 38.5. W EBLINKS . . . . .

39.

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

339 339 339

353 353 356 356 356 356

I NTRINSISCHE F UNKTIONEN UND S UBROUTINEN 357 39.1. N EU . . . . . . . . . . . . . . . . . . . . . . . . . . 357 39.2. E RWEITERT . . . . . . . . . . . . . . . . . . . . . . 362

XI

Inhaltsverzeichnis

40.

VI.

41.

42. 43.

44.

XII

I NTRINSISCHE M ODULE 40.1. G RUNDLEGENDES . . . . . . . . . . . . . . . . . 40.2. D AS INTRINSISCHE M ODUL iso_fortran_env 40.3. D AS INTRINSISCHE M ODUL iso_c_binding . . 40.4. D IE INTRINSISCHEN IEEE-M ODULE . . . . . . .

. . . .

B IBLIOTHEKEN 40.5. QUELLTEXTBIBLIOTHEKEN . . . . . . . . . . . . . 40.6. S TATISCHE B IBLIOTHEKEN . . . . . . . . . . . . . 40.7. DYNAMISCHE B IBLIOTHEKEN . . . . . . . . . . . . 40.8. B IBLIOTHEKEN IN VERSCHIEDENEN P ROGRAM MIERSPRACHEN . . . . . . . . . . . . . . . . . . . . 40.9. B IBLIOTHEKEN BEI VERSCHIEDENEN B ETRIEB SSYSTEMEN . . . . . . . . . . . . . . . . . . . . . .

363 363 363 365 365

377 379 380 380 381 382

G RAFIK UND GUI 385 41.1. DISLIN . . . . . . . . . . . . . . . . . . . . . . . . 385 A LLGEMEINES

387

B EISPIELE 43.1. B EISPIEL 1: S TRINGS UND Z AHLEN . . . . . . . . 43.2. B EISPIEL 2: Z EICHNEN VON K URVEN UND F UNK TIONEN . . . . . . . . . . . . . . . . . . . . . . . . 43.3. B EISPIEL 3: E IN P IE -C HART . . . . . . . . . . . . . 43.4. B EISPIEL 4: E IN M ELDUNGSFENSTER . . . . . . .

390 392 394

W EBLINKS 44.1. F 03 GL . . . . . . . 44.2. A LLGEMEINES . . . 44.3. B EISPIEL . . . . . . 44.4. B ESONDERHEITEN 44.5. W EBLINKS . . . . . 44.6. J API . . . . . . . . .

397 397 397 397 401 402 402

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

389 389

Inhaltsverzeichnis

45.

A LLGEMEINES

403

46.

JAPI -I NSTALLATION

405

47.

B EISPIEL

407

48.

W EBLINKS 411 48.1. P ILIB . . . . . . . . . . . . . . . . . . . . . . . . . . 411

49.

A LLGEMEINES

413

50.

PILIB -I NSTALLATION

415

51.

B EISPIEL

417

52.

W EBLINKS

421

53.

M ATHEMATIK 423 53.1. BLAS UND ATLAS . . . . . . . . . . . . . . . . . . 423

54.

A LLGEMEINES

425

55.

I NSTALLATION VON BLAS

427

56.

B EISPIELE 429 56.1. B EISPIEL : D IE L EVEL 1-F UNKTIONEN sdot UND dnrm2 . . . . . . . . . . . . . . . . . . . . . . . . . 429 56.2. B EISPIEL : D IE L EVEL 2-S UBROUTINE sger . . . . . 430

57.

W EBLINKS 57.1. FGSL . . . . . 57.2. A LLGEMEINES 57.3. B EISPIELE . . 57.4. W EBLINKS . . 57.5. LAPACK . . . 57.6. A LLGEMEINES

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

431 431 431 432 439 440 440

XIII

Inhaltsverzeichnis

57.7.

B EISPIEL :

L ÖSEN

EINES EINFACHEN G LE . . . . . . . . . . . . . . . . . . 441 B EISPIEL : I NVERSE M ATRIX . . . . . . . . . . . . . 443 W EBLINKS . . . . . . . . . . . . . . . . . . . . . . . 444 ICHUNGSSYSTEMS

57.8. 57.9. 58.

VII.

PARALLELE P ROGRAMMIERUNG 58.1. O PEN MP . . . . . . . . . . . . . . . . . . . . . . . 58.2. WAS IST O PEN MP . . . . . . . . . . . . . . . . . . 58.3. E IN EINFACHES B EISPIEL . . . . . . . . . . . . . . 58.4. T HREAD -E RZEUGUNG : D IE parallel-D IREKTIVE 58.5. T HREAD -A NZAHL BESTIMMEN . . . . . . . . . . . 58.6. S ICHTBARKEIT /G ÜLTIGKEIT VON D ATEN . . . . . 58.7. D IE do-D IREKTIVE . . . . . . . . . . . . . . . . . . 58.8. D IE sections-D IREKTIVE . . . . . . . . . . . . . 58.9. W EITERE D IREKTIVEN . . . . . . . . . . . . . . . . 58.10. KOMBINIERTE D IREKTIVEN . . . . . . . . . . . . . 58.11. S YNCHRONISATION . . . . . . . . . . . . . . . . . . 58.12. D AS M ODUL omp_lib . . . . . . . . . . . . . . . . 58.13. L ITERATUR . . . . . . . . . . . . . . . . . . . . . . 58.14. W EBLINKS . . . . . . . . . . . . . . . . . . . . . . .

F ORTRAN

IN

KOMBINATION

MIERSPRACHEN

59.

60. 61.

XIV

MIT ANDEREN

445 445 445 446 447 448 448 450 453 454 454 455 459 461 462

P ROGRAM 463

F ORTRAN UND T CL 465 59.1. B EISPIEL . . . . . . . . . . . . . . . . . . . . . . . . 465 59.2. A LTERNATIVEN . . . . . . . . . . . . . . . . . . . . 468 W EBLINKS

469

F ORTRAN UND C 471 61.1. I NTERFACE . . . . . . . . . . . . . . . . . . . . . . . 471 61.2. F ORTRAN 90/95 . . . . . . . . . . . . . . . . . . . 471 61.3. G 95 ( GFORTRAN ) UND GCC . . . . . . . . . . . . . 472

Inhaltsverzeichnis

61.4. 61.5. 61.6. 61.7. 61.8. 61.9. 61.10. 61.11. 61.12. 61.13. 61.14. 61.15. 61.16. 62.

IFORT UND GCC . . . . . . . . . . . . . . . . . . . . F ORTRAN 2003 . . . . . . . . . . . . . . . . . . . . E IN EINFACHES B EISPIEL . . . . . . . . . . . . . . D ATENTYP-Z UORDNUNG . . . . . . . . . . . . . . „ CALL BY VALUE “ VS . „ CALL BY REFERENCE “ . . . G LOBALE C-VARIABLEN . . . . . . . . . . . . . . . F ELDER . . . . . . . . . . . . . . . . . . . . . . . . Ü BERGABE VON Z EICHENKETTEN . . . . . . . . . E NUMERATIONEN . . . . . . . . . . . . . . . . . . Z EIGER . . . . . . . . . . . . . . . . . . . . . . . . . D ATENVERBUND . . . . . . . . . . . . . . . . . . . P ROBLEMATISCHE K AMELHÖCKERSCHREIBWEISE ? S ONSTIGES . . . . . . . . . . . . . . . . . . . . . .

475 478 478 480 483 485 485 486 490 492 494 503 504

F ORTRAN UND P YTHON 505 62.1. V ORAUSSETZUNGEN . . . . . . . . . . . . . . . . . 505 62.2. B EISPIEL . . . . . . . . . . . . . . . . . . . . . . . . 506 62.3. W EBLINKS . . . . . . . . . . . . . . . . . . . . . . . 507

VIII. F ORTRAN -„D IALEKTE “ 63.

F 63.1. 63.2. 63.3.

64.

R ATFOR 64.1. A LLGEMEINES 64.2. R ATFOR 77 . . 64.3. R ATFOR 90 . . 64.4. W EBLINKS . .

509

511 WAS IST F? . . . . . . . . . . . . . . . . . . . . . . . 511 E INIGE U NTERSCHIEDE ZU F ORTRAN 90/95 . . . 512 W EBLINKS . . . . . . . . . . . . . . . . . . . . . . . 515

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

517 517 518 518 519

XV

Inhaltsverzeichnis

IX. 65.

S ONSTIGES C RAY P OINTER 65.1. E INLEITUNG . 65.2. G RUNDLAGEN 65.3. B EISPIEL . . . 65.4. W EBLINKS . .

521

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

523 523 523 525 526

X.

A NHANG

66.

E INE G EGENÜBERSTELLUNG VON GRUNDLEGENDEN F ORTRAN - UND C-S PRACHELEMENTEN 529

67.

P ROGRAMMGRUNDSTRUKTUR 67.1. G ROSS -, K LEINSCHREIBUNG . 67.2. KOMMENTARE . . . . . . . . . . 67.3. D AS E NDE EINER A NWEISUNG 67.4. H AUPTPROGRAMM . . . . . . . 67.5. U NTERPROGRAMME . . . . . .

527

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

531 531 531 531 532 533

68.

E INFACHE D ATENTYPEN

535

69.

VARIABLENDEKLARATION

537

70.

KONSTANTEN

539

71.

B ENANNTE KONSTANTEN

541

72.

XVI

O PERATOREN 72.1. A RITHMETISCHE O PERATOREN 72.2. V ERGLEICHSOPERATOREN . . . 72.3. L OGISCHE O PERATOREN . . . . 72.4. S TRINGVERKNÜPFUNG . . . . . 72.5. B ITOPERATOREN . . . . . . . . 72.6. W EITERE O PERATOREN . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

543 543 543 543 544 544 544

Inhaltsverzeichnis

73.

Z USAMMENGESETZTE D ATENTYPEN

545

74.

F ELDER

547

75.

Z EICHENKETTEN

549

76.

B LÖCKE , V ERZWEIGUNGEN , S CHLEIFEN 76.1. B LOCK . . . . . . . . . . . . . . . . 76.2. V ERZWEIGUNGEN . . . . . . . . . . 76.3. S CHLEIFEN . . . . . . . . . . . . . 76.4. S ONSTIGES . . . . . . . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

551 551 551 551 552

77.

E IN -, AUSGABE

553

78.

D ATEIEN

555

79.

Z EIGER

557

80.

81. 82.

83. 84.

A NWENDUNGSBEISPIELE 559 80.1. D REIECKSBERECHNUNG . . . . . . . . . . . . . . . 559 AUFGABE G RUNDLAGEN 82.1. KOORDINATENWERTE ---> R ICHTUNGSVEKTOREN 82.2. S EITENLÄNGEN UND U MFANG . . . . . . . . . . . 82.3. W INKEL . . . . . . . . . . . . . . . . . . . . . . . . 82.4. F LÄCHE . . . . . . . . . . . . . . . . . . . . . . . . 82.5. U MKREIS . . . . . . . . . . . . . . . . . . . . . . . . 82.6. I NKREIS . . . . . . . . . . . . . . . . . . . . . . . . 82.7. S CHWERPUNKT . . . . . . . . . . . . . . . . . . . . C ODE

561 563 564 564 565 566 567 569 570 573

S CREENSHOTS 575 84.1. K ETTENLINIE . . . . . . . . . . . . . . . . . . . . . 576

XVII

Inhaltsverzeichnis

85.

AUFGABE

577

86.

G RUNDLAGEN

579

87.

C ODE

581

88.

S CREENSHOTS 583 88.1. I NVERSE M ATRIX . . . . . . . . . . . . . . . . . . . 584

89.

AUFGABE

585

90.

G RUNDLAGEN

587

91.

C ODE

589

92.

S CREENSHOTS

591

93.

D EBUGGER

593

94.

D ER GNU D EBUGGER 595 94.1. GDB UND GFORTRAN . . . . . . . . . . . . . . . . . 595 94.2. GDB UND G 95 . . . . . . . . . . . . . . . . . . . . . 596

95. 96.

D ER I NTEL D EBUGGER Q UELLCODEDOKUMENTATION 96.1. ROBOD OC . . . . . . . . 96.2. E IN EINFACHES B EISPIEL 96.3. W EBLINKS . . . . . . . . . 96.4. N ATURAL D OCS . . . . . . 96.5. E IN EINFACHES B EISPIEL 96.6. K URZE E RLÄUTERUNG . . 96.7. W EBLINKS . . . . . . . . . 96.8. D OXYGEN . . . . . . . . . 96.9. E IN EINFACHES B EISPIEL 96.10. W EBLINKS . . . . . . . . .

XVIII

597

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

599 599 599 604 604 605 606 607 607 608 609

Inhaltsverzeichnis

97.

M AKE & C O. 97.1. E INLEITUNG . . . . . . . . . . . . . . . . . . . . . 97.2. E XPLIZITE B EKANNTGABE VON M ODULPFADEN 97.3. GNU M AKE . . . . . . . . . . . . . . . . . . . . . 97.4. CM AKE . . . . . . . . . . . . . . . . . . . . . . . . 97.5. SC ONS . . . . . . . . . . . . . . . . . . . . . . . .

. . . . .

611 612 612 614 621 623

98.

P HOTRAN - E INE IDE FÜR F ORTRAN BASIEREND AUF E CLIPSE 625 98.1. W EBLINKS . . . . . . . . . . . . . . . . . . . . . . . 627

XI.

W EBLINKS 98.2. W IKIS . . . . . . . . . . . . . . . 98.3. S TANDARDS . . . . . . . . . . . . 98.4. S KRIPTEN , T UTORIALS , B ÜCHER 98.5. C OMPILER . . . . . . . . . . . . . 98.6. D EBUGGER . . . . . . . . . . . . 98.7. IDE S . . . . . . . . . . . . . . . . 98.8. A MÜSANTES . . . . . . . . . . . .

XII. S TICHWORTVERZEICHNIS 98.9. A . . . . . . . . . . . 98.10. B . . . . . . . . . . . 98.11. C . . . . . . . . . . . 98.12. D . . . . . . . . . . . 98.13. E . . . . . . . . . . . 98.14. F . . . . . . . . . . . 98.15. G . . . . . . . . . . . 98.16. H . . . . . . . . . . . 98.17. I . . . . . . . . . . . . 98.18. J . . . . . . . . . . . . 98.19. K . . . . . . . . . . . 98.20. L . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

629 631 631 632 633 634 634 634

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

635 637 641 642 645 650 652 655 656 656 660 661 661

XIX

Inhaltsverzeichnis

98.21. 98.22. 98.23. 98.24. 98.25. 98.26. 98.27. 98.28. 98.29. 98.30. 98.31. 98.32. 98.33. 98.34. 99.

M N O P Q R S T U V W X Y Z

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

663 665 666 667 668 668 669 672 673 674 675 676 676 676

AUTOREN

677

100. B ILDNACHWEIS

679

XX

1. Einleitung F ORTRAN1 Fortran ist eine Programmiersprache, die insbesondere für numerische Berechnungen eingesetzt wird. Der Name entstand aus FORmula TRANslation und wurde bis zur Version FORTRAN 77 mit Großbuchstaben geschrieben.

1.1. Geschichte

Abb. 1: Eine FORTRAN-Lochkarte aus den Anfangstagen des Computerzeitalters 1

H T T P :// D E . W I K I P E D I A . O R G / W I K I /%20F O R T R A N

1

Einleitung

Fortran gilt als die erste jemals tatsächlich realisierte höhere Programmiersprache. Sie geht zurück auf einen Vorschlag, den John W. Backus, Programmierer bei IBM, 1953 seinen Vorgesetzten unterbreitete.

Dem Entwurf der Sprache folgte die Entwicklung eines Compilers durch ein IBM-Team unter Leitung von John W. Backus. Das Projekt begann 1954 und war ursprünglich auf sechs Monate ausgelegt. Tatsächlich konnte Harlan Herrick, der Erfinder der später heftig kritisierten Goto-Anweisung, am 20. September 1954 das erste Fortran-Programm ausführen. Doch erst 1957 wurde der Compiler für marktreif befunden und mit jedem IBM 704System ausgeliefert. Backus hatte darauf bestanden, den Compiler von Anfang an mit der Fähigkeit zu Optimierungen auszustatten: er sah voraus, dass sich Fortran nur dann durchsetzen würde, wenn ähnliche Ausführungsgeschwindigkeiten wie mit bisherigen Assembler-Programmen erzielt würden.

2

Geschichte

1.1.1. Versionen

Abb. 2: Genealogie

Fortran wurde mehrmals erweitert. Viele neue Sprachelemente wurden zunächst von einem einzelnen Hersteller eingeführt und später in den internationalen Standard übernommen. Als Versionen folgten aufeinander FORTRAN I, FORTRAN II, FORTRAN IV, FORTRAN 66, FORTRAN 77, Fortran 90, Fortran 95 und zuletzt Fortran 2003. Ab FORTRAN 66 ist Fortran von einer internationalen Organisation standardisiert. Die Fortschreibung der Standards ist ein komplizierter Prozess, der oft wesentlich länger dauert als zunächst angestrebt: Der Nachfolger des 1978 erschienenen Standards FORTRAN-77, der als Fortran 8x bezeichnet wurde, war ursprünglich für das Jahr 1982 geplant, später dann für das Jahr 1985, und wurde schließlich unter der Bezeichnung Fortran90 erst am

3

Einleitung

11. April 1991 als neuer Standard und Nachfolger von FORTRAN77 angenommen.2 Im Laufe dieser Erweiterungen wurden zahlreiche Sprachelemente aus neueren Programmiersprachen übernommen. Beruhte früher Fortran-Stil noch ganz auf Goto-Anweisungen, kann man seit FORTRAN 77 uneingeschränkt strukturiert programmieren. Mit Fortran 90 wurde das aus der Lochkartenzeit stammende Zeilenformat freigegeben. Ab Fortran 90 wurden interessante Elemente eingeführt, die auch z.B. in Ada vorhanden sind, beispielsweise optionale Parameter und die Möglichkeit, Prozedurparameter nicht nur über die Position in der Parameterliste zu identifizieren, sondern über ihren Namen.

1.1.2. Varianten Einige von Fortran abgeleitete Programmiersprachen bzw. Dialekte von Fortran sind beispielsweise Ratfor, F und HPF (High Performance Fortran). Auf Fortran aufgesetzt ist das Finite-ElementeProgrammpaket Nastran.

1.2. Eigenschaften Fortran war und ist für numerische Berechnungen vorgesehen und optimiert. Von Anfang an hatte Fortran den Potenz-Operator **. Dieser ist in vielen anderen Hochsprachen nicht vorhanden. Weiters kennt Fortran einen Datentyp für komplexe Zahlen. 2

4

Vorwort von Michael Metcalf in: W. H. Press, S. A. Teukolsky, W. T. Vetterling, B. P. Flannery: Numerical Recipes in Fortran 90. Cambridge University Press, 1999, ISBN 0-521-57439-0.

Compiler

Mit Fortran 90 wurden Vektor- und Matrix-Operationen standardisiert. Insbesondere für wissenschaftliche und numerische Berechnungen gibt es in FORTRAN umfangreiche Bibliotheken, die immer noch weit verbreitet sind, auch wenn eine zunehmende Menge an Routinen inzwischen nach C und C++ portiert wurde.

1.3. Compiler Bis zum heutigen Zeitpunkt (Mai 2007) gibt es keinen Compiler der den aktuellen Fortran-Standard von 2003 vollständig unterstützt. Viele Compiler unterstützen jedoch schon Teile dieses Standards.

1.3.1. Kommerzielle Software

F95-Compiler gibt es für praktisch alle Computer, von Arbeitsplatzrechnern bis zu Supercomputern. Hersteller hierfür sind entweder die Computerhersteller wie z.B. IBM, Sun, HP, Intel oder aber spezialisierte Softwarehersteller wie z.B. Absoft, PGI, NAG, Lahey, Silverfrost/Salford. Reine F77-Compiler werden heute zumeist nicht mehr hergestellt, da Fortran 77 fast vollständig im Sprachstandard Fortran 95 enthalten ist. Manche der oben genannten Compiler sind für Privatanwender bzw. nichtkommerzielle Nutzung kostenlos, zum Beispiel die Linux-Variante des Intel-Fortran-Compilers, Sun Studio Express oder für Microsoft-Windows der Compiler von Silverfrost/Salford.

5

Einleitung

1.3.2. Freie Software Seit Version 4.0 der GNU Compiler Collection (GCC), die praktisch für alle Plattformen vorhanden ist, enthält diese ein Fortran 95Frontend (gfortran). Außerdem existiert mit G95 ein weiterer freier Fortran 95-Compiler.

1.3.3. Übersetzer Es gibt Programme, wie z.B. f2c, zur automatischen Übersetzung von Fortran in (allerdings kaum lesbares) C.

1.4. Referenzen

6

Teil I.

Compiler

7

Was ist ein Compiler?

1.5. Was ist ein Compiler?

Abb. 3: Compilerschema

Ein Compiler (auch Kompilierer oder Übersetzer) ist ein Computerprogramm, das ein in einer Quellsprache geschriebenes Pro-

9

Einleitung

gramm - genannt Quellprogramm - in ein semantisch äquivalentes Programm einer Zielsprache (Zielprogramm) umwandelt. Üblicherweise handelt es sich dabei um die Übersetzung eines von einem Programmierer in einer Programmiersprache geschriebenen Quelltextes in Assemblersprache, Bytecode oder Maschinensprache. Das Übersetzen eines Quellprogramms in ein Zielprogramm durch einen Compiler wird als Kompilierung oder auch als Übersetzung bezeichnet. Die Bezeichnung Compiler (engl. to compile: zusammenstellen) ist eigentlich irreführend. Ursprünglich bezeichnete das Wort Compiler Programme, die Unterprogramme zusammenfügen (etwa mit heutigen Linkern vergleichbar). Dies geht an der heutigen Kernaufgabe eines Compilers vorbei. Verwandt mit einem Compiler ist ein Interpreter, der ein Programm nicht in die Zielsprache übersetzt, sondern Schritt für Schritt direkt ausführt.

1.6. Aufbau eines Compilers Compiler werden in verschiedene Phasen gegliedert, die jeweils verschiedene Teilaufgaben des Compilers übernehmen. Sie werden sequentiell ausgeführt. Im Wesentlichen lassen sich zwei Phasen unterscheiden: das Frontend (auch Analysephase), das den Quelltext analysiert und daraus einen attributierten Syntaxbaum erzeugt, sowie das Backend (auch Synthesephase), das daraus das Zielprogramm erzeugt.

1.6.1. Frontend (auch „Analysephase“) Im Frontend wird der Code analysiert, strukturiert und auf Fehler geprüft. Es ist auch selbst wieder in Phasen gegliedert:

10

Aufbau eines Compilers

Lexikalische Analyse Die lexikalische Analyse zerteilt den eingelesenen Quelltext in zusammengehörende Token verschiedener Klassen, z. B. Schlüsselwörter, Bezeichner, Zahlen und Operatoren. Dieser Teil des Compilers heißt Scanner oder Lexer. Ein Scanner benutzt gelegentlich einen separaten Screener, um Whitespace (also Leerzeichen, Tabulatorzeichen, Zeilenenden) und Kommentare zu überspringen.

Syntaktische Analyse Die syntaktische Analyse überprüft, ob der eingelesene Quellcode ein korrektes Programm der zu übersetzenden Quellsprache ist, d. h. der Syntax (Grammatik) der Quellsprache entspricht. Dabei wird die Eingabe in einen Syntaxbaum umgewandelt. Dieser Teil wird auch als Parser bezeichnet.

Semantische Analyse Die semantische Analyse überprüft die statische Semantik, also über die syntaktische Analyse hinausgehende Bedingungen an das Programm. Zum Beispiel muss eine Variable in der Regel deklariert worden sein, bevor sie verwendet wird, und Zuweisungen müssen mit kompatiblen (verträglichen) Datentypen erfolgen. Dies kann mit Hilfe von Attributgrammatiken realisiert werden. Dabei werden die Knoten des vom Parser generierten Syntaxbaums mit Attributen versehen, die Informationen enthalten. So kann zum Beispiel eine Liste aller deklarierten Variablen erstellt werden. Die Ausgabe der semantischen Analyse nennt man dann dekorierter oder attributierter Syntaxbaum.

11

Einleitung

1.6.2. Backend (auch „Synthesephase“) Das Backend erzeugt aus dem vom Frontend erstellten attributierten Syntaxbaum den Programmcode der Zielsprache.

Zwischencodeerzeugung Viele moderne Compiler erzeugen aus dem Syntaxbaum einen Zwischencode, der schon relativ maschinennah sein kann und führen auf diesem Zwischencode z. B. Programmoptimierungen durch. Das bietet sich besonders bei Compilern an, die mehrere Quellsprachen oder verschiedene Zielplattformen unterstützen. Hier kann der Zwischencode auch ein Austauschformat sein.

Programmoptimierung Der Zwischencode ist Basis vieler Programmoptimierungen.

Codegenerierung Bei der Codegenerierung wird der Programmcode der Zielsprache entweder direkt aus dem Syntaxbaum oder aus dem Zwischencode erzeugt. Falls die Zielsprache eine Maschinensprache ist, kann das Ergebnis direkt ein ausführbares Programm sein oder eine so genannte Objektdatei, die durch das Linken mit der Laufzeitbibliothek und evtl. weiteren Objektdateien zu einer Bibliothek oder einem ausführbaren Programm führt.

12

Geschichte

1.7. Geschichte Die Geschichte des Compilerbaus wurde von den jeweils aktuellen Programmiersprachen und Hardwarearchitekturen geprägt. Der erste Compiler (A-0) wurde 1952 von der Mathematikerin Grace Hopper entwickelt. Weitere frühe Meilensteine sind 1954 der erste FORTRAN-Compiler und 1960 der erste COBOL-Compiler. Viele Architekturmerkmale heutiger Compiler wurden aber erst in den 1960er Jahren entwickelt.

13

2. Gfortran 2.1. Was ist gfortran? gfortran (oder GNU Fortran) ist ein Fortran-Compiler-Frontend für die GNU Compiler Collection (GCC).

2.2. Installation Vorcompilierte Pakete und Anleitungen zur Installation von gfortran finden sich gegliedert nach Betriebssystem und Prozessortyp auf: HTTP :// GCC . GNU . ORG / WIKI /GF ORTRAN B INARIES1

2.3. Starten des gfortran-Compilers 2.3.1. MS Windows XP Nach erfolgter Installation befinde sich das gfortran-Softwarepaket beispielsweise im Verzeichnis C:\Programme\gfortran. Zwecks Funktionstest wird die Eingabeaufforderung von MS Windows gestartet und der gfortranCompiler aufgerufen: 1

H T T P :// G C C . G N U . O R G / W I K I /GF O R T R A N B I N A R I E S

15

Gfortran

Abb. 4

Das Fortran-Programm für einen ersten konkreten Compilertest könnte so aussehen program test write (*,*) ’Hallo Welt!’ end program test

Dieses Quellprogramm werde via Texteditor für dieses Beispiel unter dem Dateinamen test.f90 im Verzeichnis c:\tmp gespeichert. Nun wird das Programm compiliert und gebunden

Abb. 5

und liegt dann unter dem Programmnamen a.exe als ausführbares Programm vor. Die Startanweisung für das Programm a.exe inklusive unmittelbar danach folgender Programmausgabe sieht so aus.

16

Starten des gfortran-Compilers

Abb. 6

Alternativ kann a.exe natürlich auch konventionell mittels Windows-Explorer gestartet werden. In diesem speziellen Fall wäre aber bis auf ein kurzes Aufblinken des Eingabeaufforderungs-Fensters nicht viel zu sehen, da das Programm nach der Textausgabe beendet wird.

2.3.2. Linux Für die Linux-Variante des gfortran-Compilers gilt prinzipiell die selbe Vorgehensweise wie für die Windows-Variante. Compilieren des Beispielprogrammes:

Abb. 7

Starten des ausführbaren Programms a.out und Anzeige der Programmausgabe:

17

Gfortran

Abb. 8

Abb. 9

Durch entsprechende Nutzung des Linux-PATH-Mechanismus (z.B. symbolischer Link in ein PATH-Verzeichnis oder Aufnahme des ./gfortran/bin/-Verzeichnisses in den PATH) kann die Angabe des gesamten Compilerpfades bei jedem gfortranCompileraufruf entfallen.

Abb. 10

2.4. Dateiendungen für Quelldateien Mit gfortran lassen sich Programme verschiedener FortranSprachstandardversionen kompilieren. Der Fortran-Typ wird üblicherweise durch die Dateiendung der Quelldatei festgelegt.

18

Anwendung Dateiendung .f .f90 .f95 .f03 .F

.F90

.F95

.F03

Fortran-Version FORTRAN 77 (fixes Zeilenformat) Fortran 90 (freies Zeilenformat) Fortran 95 (freies Zeilenformat) Fortran 2003 (freies Zeilenformat) FORTRAN 77 (fixes Zeilenformat) mit Preprocessing durch cpp Fortran 90 (freies Zeilenformat) mit Preprocessing durch cpp Fortran 95 (freies Zeilenformat) mit Preprocessing durch cpp Fortran 2003 (freies Zeilenformat) mit Preprocessing durch cpp

2.5. Anwendung In der Anwendung gleicht gfortran anderen GCC-Frontends (z. B. gcc, g++ oder g77). • Übersetzung einer Quelldatei in die ausführbare Datei a.out (bzw. a.exe auf MS Windows-Systemen):

gfortran bsp.f90 • Übersetzung einer Quelldatei in eine Objektdatei bsp.o:

19

Gfortran

gfortran -c bsp.f90 • Übersetzung einer Quelldatei in die ausführbare Datei bsp:

gfortran -o bsp bsp.f90 • Statisches Linken:

gfortran -static -o bsp bsp.f90 • Mehrere Quelldateien kompilieren und zu einer ausführbaren Datei linken:

gfortran -c bsp1.f90 gfortran -c bsp2.f90 gfortran -o bsp bsp1.o bsp2.o • Mehrere Quelldateien in einer Anweisung kompilieren und zu einer ausführbaren Datei linken:

gfortran -o bsp bsp1.f90 bsp2.f90

2.6. Prüfung des Quellcodes auf Standardkonformität Zur Sicherstellung einer strikten Standardkonformität kann die Option std mit folgenden Parametern verwendet werden: Parameter f95 f2003

20

Kommentar Fortran 95 Fortran 2003 (noch nicht vollständig implementiert [Stand: Dez. 2005])

gfortran-Weblinks Parameter gnu

Kommentar Fortran mit GNUErweiterungen

legacy • Beispiele:

gfortran -std=f95 bsp.f gfortran -std=f95 -W -Wall -pedantic bsp.f

2.7. gfortran-Weblinks • GNU F ORTRAN 952 • GNU F ORTRAN 95-W IKI3

2 3

H T T P :// G C C . G N U . O R G / F O R T R A N / H T T P :// G C C . G N U . O R G / W I K I /GF O R T R A N

21

3. Fortran: G95 3.1. Über g95 Mit g95 steht dem Fortran-Programmierer ein freier (im Sinne von Freier Software) Kommandozeilen-Compiler zur Verfügung, der für eine Vielzahl von Plattformen erhältlich ist.

3.2. Installation 3.2.1. Windows Für die native Windows-Version existiert ein Self-Installer, g95MinGW.exe, dessen Anweisungen man einfach folgen sollte. Da es sich um einen Kommandozeilen-Compiler handelt, sollte man entweder mit dem Windows-internen CMD.EXE umgehen können, oder man installiert sich eine komfortablere Kommandozeilen-Entwicklungsumgebung, z.B. MSYS1 (dann aber am besten vor der g95-Installation) oder GNU UTILS FOR W IN 322 . Alternativ erlaubt u.U. der zur Programmierung verwendete Editor bzw. die IDE eine komfortable Konfiguration, so dass g95 von dort aus aufgerufen werden kann. 1 2

H T T P :// W W W . M I N G W . O R G / M S Y S . S H T M L H T T P :// U N X U T I L S . S O U R C E F O R G E . N E T /

23

Fortran: G95

3.2.2. Unix-artige inkl. Cygwin und MacOSX Für alle anderen Systeme steht ein komprimiertes tar-Archiv zur Verfügung. Dies kann an einem beliebigen Ort im Dateisystem entpackt werden, je nach Rechten z.B. in /usr/local oder im $HOME Verzeichnis. Für Linux z.B.:

tar -xzv -f g95-x86-linux.tgz -C /usr/local oder

tar -xzv -f g95-x86-linux.tgz -C $HOME Anschließend steht der Kompiler im Unterverzeichnis g95install/bin/ mit einem eher unhandlichen Namen zur Verfügung. Daher sollte man sich einen symbolischen link anlegen, z.B. (je nachdem ob systemweit installiert werden soll oder nur für den Gebrauch als User):

ln -s /usr/local/g95-install/bin/*g95* /usr/local/bin/g95 oder

ln -s $HOME/g95-install/bin/*g95* $HOME/bin/g95

3.3. Bedienung Die im Kapitel D AS C OMPILER-F RONTEND gfortran3 getroffenen Aussagen zu den Dateiendungen gelten auch für g95. Die Compil3

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20G F O R T R A N %

20

24

Technischer Hintergrund

eraufrufoptionen sind ebenfalls in wesentlichen Teilen identisch zu jenen von gfortran. So wird z.B. ein Programm, das nur aus einer Datei besteht, mit:

g95 -o bsp bsp.f kompiliert.

3.4. Technischer Hintergrund Wie GFORTRAN4 baut g95 auf der GNU Compiler Collection (GCC) auf. Streng genommen sind beide nur Frontends zu dem GCCBackend. Allerdings präsentiert sich der installierte g95 wie ein eigenständiger Compiler. Insbesondere bedarf es weder einer weiteren Installation einer bestimmten GCC-Version, noch treten Konflikte mit installierten GCC-Versionen auf. Dies spiegelt sich insbesondere in den flexiblen Installationsmöglichkeiten wieder. g95 und gfortran basieren auf dem selben Programmcode. Im Jahr 2003 gabelten sich die Entwicklungszweige. gfortran ist nun Teil der GCC. Die Entwicklung von g95 wird vom ursprünglichen Programmautor Andrew Vaught unabhängig davon weitergeführt.

3.5. Weblink D AS G 95-P ROJEKT5

4 5

Kapitel 2 auf Seite 15 H T T P :// W W W . G 95. O R G

25

4. Fortran: Ifort 4.1. Allgemeines Der Intel Fortran Compiler for Linux ist ein Fortran-Compiler, der für nicht-kommerzielle Zwecke auch in einer kostenfreien Variante verfügbar ist. Beeindruckend ist auch die diesem Softwarepaket beigegebene ausführliche Dokumentation, vor allem die knapp 900-seitige "Intel Fortran Language Reference". Im Intel Fortran Compiler sind neben den üblichen FortranStandardfunktionen auch eine Unmenge eigener Subroutinen und Funktionen implementiert.

4.2. Installation 1. Eine Downloadadresse und der Lizenzschlüssel für den Intel Fortran Compilers for Linux werden nach einer Registrierungsprozedur auf der Intel-Website per E-Mail übermittelt. 2. Download der Compiler-Software. 3. Entpacken der gepackten Datei (gunzip, tar). 4. Die eigentliche Installation des Intel Fortran Compilers erfolgt mittels install-Skript.

27

Fortran: Ifort

4.3. Dateiendungen für Quelldateien Mit dem Intel Fortran Compiler lassen sich Programme verschiedener Fortran-Sprachstandardversionen kompilieren. Der Fortran-Typ wird üblicherweise durch die Dateiendung der Quelldatei festgelegt. Dateiendung .f, .for, .fnt, .i .f90, .i90 .F, .FOR, .FTN, .FPP, .fpp .F90

Fortran-Version FORTRAN 77 (fixes Zeilenformat) Fortran 90/95 (freies Zeilenformat) FORTRAN 77 (fixes Zeilenformat) mit Preprocessing Fortran 90/95 (freies Zeilenformat) mit Preprocessing

4.4. Anwendung In der Anwendung gleicht der Intel Fortran Compiler dem GNU Fortran Compiler. Die offensichtlichsten Unterschiede sind: • Die Intel Fortran Compiler-Software wird mittels ifort gestartet • Die Intel Fortran Compiler-Software kennt die Dateiendungen .f95 und .F95 nicht • Die Intel Fortran Compiler-Software enthält einen eigenen Kommandozeilendebugger idb. idb bietet auch ein GUI . Die Benutzung von anderen debugern wie gdb ist auch möglich.

• Übersetzung einer Quelldatei in die ausführbare Datei a.out:

28

Weblink für den Intel Fortran Compiler for Linux

ifort bsp.f90 Übersetzung einer Quelldatei in eine Objektdatei bsp.o: ifort -c bsp.f90 • Übersetzung einer Quelldatei in die ausführbare Datei bsp: ifort -o bsp bsp.f90 • Mehrere Quelldateien kompilieren und zu einer ausführbaren Datei linken: ifort -c bsp1.f90 ifort -c bsp2.f90 ifort -o bsp bsp1.o bsp2.o • Mehrere Quelldateien in einer Anweisung kompilieren und zu einer ausführbaren Datei linken: ifort -o bsp bsp1.f90 bsp2.f90

4.5. Weblink für den Intel Fortran Compiler for Linux http://www.intel.com/cd/software/products/asmona/eng/compilers/flin/index.htm

29

Teil II.

Die Programmiersprache

31

Was ist eine Programmiersprache?

4.6. Was ist eine Programmiersprache?

Abb. 11: Früher wurden Computer "debugged", heutzutage Computerprogramme

P ROGRAMMIERSPRACHE1 In Kurzform: Eine Programmiersprache ist eine Sprache zwecks Abfassung von Computerprogrammen.

1

H T T P :// D E . W I K I P E D I A . O R G / W I K I /P R O G R A M M I E R S P R A C H E

33

Fortran: Ifort

4.7. Einordnung von Fortran 4.7.1. Generell • Fortran ist eine höhere Programmiersprache (Higher Level Language, HLL, Programmiersprache der 3. Generation) • Fortran ist eine prozedurale Programmiersprache (P ROZEDURALE P ROGRAMMIERUNG2 ) • Fortran ist eine imperative Programmiersprache (I MPERATIVE _P ROGRAMMIERUNG3 ) • Fortran ist eine objektorientierte Programmiersprache (ab Fortran 2003, O BJEKTORIENTIERTE P ROGRAMMIERUNG4 ). • Fortran verwendet das Konzept der starken Typisierung. Fortran kennt explizite und implizite Typisierung (T YPISIERUNG (I NFORMATIK )5 ) • Fortran ist eine sehr alte Programmiersprache, die aber laufend weiterentwickelt und somit den modernen Trends immer wieder angepasst wurde und wird.

4.7.2. Popularität Die Popularität einer Programmiersprache einigermaßen fundiert zu bestimmen ist nicht einfach. Dennoch gibt es Institutionen, die das versuchen, sei es über die Anzahl von Einträgen in Suchmaschinen, Zugriffstatistiken für Internetseiten, Nutzerbefragun2 3 4 5

34

H T T P :// D E . W I K I P E D I A . O R G / W I K I /P R O Z E D U R A L E % 20P R O G R A M M I E R U N G H T T P :// D E . W I K I P E D I A . O R G / W I K I /I M P E R A T I V E _ PR O G R A M M I E R U N G H T T P :// D E . W I K I P E D I A . O R G / W I K I /O B J E K T O R I E N T I E R T E % 20P R O G R A M M I E R U N G H T T P :// D E . W I K I P E D I A . O R G / W I K I /T Y P I S I E R U N G %20% 28I N F O R M A T I K %29

Einordnung von Fortran

gen oder auch zeitliche Veränderungen bei Buchverkäufen. Hier werden stellvertretend zwei dieser Statistiken angeführt: Lt. TIOBE lag Fortran im September 2007 hinsichtlich Popularität (TPCI) an 20. Stelle von insgesamt 100 gelisteten Programmiersprachen. Das ist zwar weit hinter dem führenden Java oder dem zweitplatzierten C. Dennoch rangiert Fortran in dieser Statistik vor anderen bekannten Programmiersprachen, wie z.B. Pascal, Prolog, Haskell oder Smalltalk. GULP liefert mit Stand 22.09.2007 eine Statistik "Wie viele ITFreiberufler verfügen über fachliche Kenntnisse auf welchem Gebiet?". Für Fortran wurden 5860 Treffer gelistet. Führend sind auch hier Java, Basic und C mit über 20.000 Treffern. Solche Statistiken sind natürlich mit Vorsicht zu geniessen, aber in Form eines groben Richtwerts "Daumen mal Pi" können sie schon einen ersten Eindruck von Verbreitung und Popularität einer Programmiersprache geben. Im Bereich der numerische Datenverarbeitung, insbesondere auf Hochleistungsrechnern, ist Fortran gemeinsam mit C/C++ nach wie vor führend. Siehe auch: • TPCI - TIOBE P ROGRAMMING C OMMUNITY I NDEX6 • GULP - S TATISTIK - P ROGRAMMIERSPRACHEN7

6 7

H T T P :// W W W . T I O B E . C O M / T P C I . H T M H T T P :// W W W . G U L P . D E / S T A T I S T I K / S T A T A B P S . H T M L

35

Fortran: Ifort

4.8. Ein Überblick über die historische Entwicklung von Fortran

Abb. 12: Simulation von Galaxien mittels Fortran-Programm

36

Ein Überblick über die historische Entwicklung von Fortran Jahr

8

1954 bis 1957

Version FORTRAN, FORTRAN I

1957/58

FORTRAN II

1958

FORTRAN III

1961/62

FORTRAN IV

1966

FORTRAN 66

1978

FORTRAN 77

Anmerkungen entwickelt von einem IBM-Team unter Leitung von J OHN W. B ACKUS8 , war dies die erste wirklich erfolgreiche höhere Programmiersprache Inline-Assembler, Kommentare, u.a. einige kleinere Änderungen, wurde aber nie offiziell freigegeben eine verbesserte und erweiterte Version die erste standardisierte FortranVersion und gleichzeitig überhaupt die erste standardisierte höhere Programmiersprache DO-Schleife, IF THEN-ELSE IFELSE-END IF, CHARACTERDatentyp, u.a.

H T T P :// D E . W I K I P E D I A . O R G / W I K I /J O H N %20W A R N E R %20B A C K U S

37

Fortran: Ifort Jahr 1991

Version Fortran 90

1997

Fortran 95

2003

Fortran 2003

(2009)

(Fortran 2008)

Anmerkungen free form style, Module, Zeiger, Datenverbund, u.v.m. kleinere Änderungen OOP, C-Binding, u.a. geplant (Co-Arrays und kleinere Änderungen)

Siehe auch: • • • •

9 10

T HE HISTORICAL DEVELOPMENT OF F ORTRAN9 A B RIEF H ISTORY OF FORTRAN/F ORTRAN10 FORTRAN I11 H ISTORY OF FORTRAN AND FORTRAN II12

H T T P :// W W W . N S C . L I U . S E /~{} B O E I N / F 77 T O 90/ A 7. H T M L H T T P :// W W W . I B I B L I O . O R G / P U B / L A N G U A G E S / F O R T R A N / C H 1-{}1. H T M L

11 12

H T T P :// W W W . P A U L G R A H A M . C O M / H I S T O R Y . H T M L H T T P :// C O M M U N I T Y . C O M P U T E R H I S T O R Y . O R G / S C C / P R O J E C T S /

FORTRAN/

38

Teil III.

FORTRAN 77

39

5. Programmaufbau 5.1. Beispiel: Hallo Welt 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM HALLO C C C

Das typische Hallo Welt-Programm WRITE (*,*) ’Hallo Welt!’ END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

Wie Sie an diesem Beispiel ersehen, weist FORTRAN-77-Code eine charakteristische Struktur auf. Etwas seltsam mutet an, dass die Programmanweisungen nicht am Zeilenanfang stehen, sondern mehrere Leerzeichen eingerückt sind. Das ist obligatorisch, ansonsten würde sich das Programm nicht kompilieren lassen. Die Nummerierungen oberhalb und unterhalb der Programmanweisungen (12345678901...) gehören übrigens nicht zum FORTRAN-Code, sondern sollen nur die Spaltenstruktur von FORTRAN-77-Programmen verdeutlichen und die Orientierung etwas erleichtern. Weiter ist zu erkennen, dass das Beispiel sehr kurz und aussagekräftig ausfällt. Die Anweisung in der ersten Zeile kennze-

41

.

8

Programmaufbau

ichnet die Programmeinheit als Hauptprogramm und gibt ihr die Bezeichnung HALLO. Die nächsten drei Zeilen sind Kommentarzeilen, erkennbar am Buchstaben in der ersten Spalte der Zeile. Dann folgt die Anweisung, einen String auf die Standardausgabe zu schreiben. Und schließlich signalisiert die END-Anweisung das Programmende.

5.2. Das Zeilenformat Normalerweise gilt, dass jede FORTRAN-Anweisung in einer eigenen Zeile steht. Eine Spezialität von FORTRAN 77 ist die Spaltenorganisation eines Programmes: das fixe Zeilenformat. Es gibt fixe Spalten (Zeichenpositionen) in denen bestimmte Inhalte stehen müssen bzw. dürfen. Diese Art der Codeanordnung rührt von den Anforderungen der Lochkarte her. Bei den damaligen Großrechenanlagen war die der Eingabe von Programmen häufig nur in Form von Lochkartenstapeln möglich. FORTRAN 77 nimmt auf diese Beschränkung Rücksicht.

Abb. 13: Lochkarte mit Fortran-Statements

42

Das Zeilenformat

Der generelle Aufbau des fixen Zeilenformates von FORTRAN 77 ist wie folgt:

Abb. 14

In der nachstehenden Tabelle wird die Bedeutung der einzelnen Spalten detaillierter dargestellt. Spalte 1

Inhalt C oder *

1 bis 5

Eine Zahl 1 bis 99999 Leerzeichen oder 0 (Null)

6

Bedeutung Kennzeichnet eine Kommentarzeile Anweisungsnummer (Marke) Beginn einer Anweisung (das ist der Normalfall)

43

Programmaufbau Spalte 6

Inhalt sonstiges Zeichen

Bedeutung Fortsetzungszeile (standardmäßig sind bis zu 19 Fortsetzungszeilen erlaubt) FORTRAN-Befehl (Anweisung) Kommentar (ursprünglich für LochkartenSequenznummern)

7 bis 72 73 bis 80

beliebige Zeichen

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP * Leerzeilen werden übrigens wie Kommentarzeilen behandelt * Eine 0 (Null) an der sechsten Position entspricht einem Leerzeichen, * foerdert aber nicht gerade die Uebersichtlichkeit 0A = 5 B = 7 C = A + * Und jetzt kommt eine Fortsetzungszeile $B WRITE (*,*) C END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

Besondere Vorsicht ist bei langen Anweisungen geboten. Alles nach der 72 Zeichenposition wird nicht mehr als Teil der Anweisung aufgefasst. Im günstigsten Fall wirft der Compiler in einem solchen Fall bei der Übersetzung einen Syntaxfehler aus.

44

.

8

Die Programmstruktur für das Hauptprogramm

5.3. Die Programmstruktur für das Hauptprogramm Ein Hauptprogramm weist immer folgende Struktur auf 1. 2. 3. 4.

PROGRAM prname Vereinbarungsteil Aktionsteil

END

prname ist ein symbolischer Name für das Hauptprogramm und kann mehr oder minder willkürlich festgelegt werden. Das erste Zeichen muss immer ein Buchstabe sein. Im Vereinbarungsteil werden z. B. die Variablen deklariert. Im Aktionsteil wird dann der eigentliche Programmablauf festgelegt. END kennzeichnet das Programmende. Theoretisch könnte im Hauptprogramm die erste Zeile (PROGRAM prname) auch komplett entfallen. In älteren Programmcodes wurde das durchaus auch so gehandhabt. Allerdings leidet darunter die Übersichtlichkeit des Programmes. Die ENDAnweisung muss auf jeden Fall angegeben werden.

5.4. Der FORTRAN-Zeichenvorrat FORTRAN-77-Programme bestehen standardmäßig nur aus folgenden Zeichen • Großbuchstaben: A bis Z • Ziffern: 0 bis 9 • 13 Sonderzeichen: + - * / = ( ) : , . ’ $ und dem Leerzeichen Viele FORTRAN-77-Compiler akzeptieren auch Kleinbuchstaben. Zeichenkettenliterale können natürlich alle ASCII-Zeichen beinhalten.

45

Programmaufbau

5.5. Symbolische Namen Standardmäßig dürfen symbolische Namen maximal sechs Zeichen lang sein. Als erstes Zeichen muss immer ein Buchstabe (AZ) stehen, der Rest muss alphanumerisch sein (Buchstabe oder Ziffer). „Lustigerweise“ dürfen bei FORTRAN 77 Leerzeichen auch innerhalb eines symbolischen Namens auftreten. Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PR O GRA M BSP * * gfortran, g95, ifort etc. kompilieren diesen Code und * bei der Programmausfuehrung wird auch das richtige * Ergebnis angezeigt. * ALPHA = 5 BETA = 7 GAMm a = A L PH A + B E TA WRI TE (*,*) G A MM A EN D

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

Besonders unangenehm kann dieses Verhalten werden, wenn in einer Zählschleife anstelle eines Kommas irrtümlicherweise ein Punkt gesetzt wird, wenn also z. B. anstelle DO 10 I = 1, 3

fälschlicherweise

46

.

8

Symbolische Namen

DO 10 I = 1. 3

steht. Letzteres entspricht nämlich der Zuweisung der Zahl 1.3 an die Variable DO10I. Gleiches gilt, wenn ähnlich wie in den Programmiersprachen C, C++ oder Java versucht wird, einer Variablen gleich in einer Deklarationszeile einen Wert zuzuweisen, z. B. REAL A = 10.5 WRITE(*,*) A

Hier wird irgendein Wert ausgegeben, aber mit an Sicherheit grenzender Wahrscheinlichkeit nicht 10.500000, denn die Wertzuweisung erfolgte an die Variable REALA und nicht an A.

47

6. Datentypen, Variablen, Wertzuweisungen, Konstanten Dieses Kapitel handelt von Datentypen, Variablen, Konstanten und der Wertzuweisung.

6.1. Datentypen 6.1.1. Arithmetische Datentypen FORTRAN 77 unterscheidet standardmäßig zwischen vier arithmetischen Datentypen: Datentyp

Kommentar

INTEGER

Ganzzahlen

REAL

Reelle Zahlen einfacher Genauigkeit Reelle Zahlen doppelter Genauigkeit Komplexe Zahlen (zwei REALZahlen)

DOUBLE PRECISION COMPLEX

Literale (Beispiele) 15, -6500, 200

000 000 3.1415, -5.5, .7E3, 12.5E-5 3.1415D0, -5.5D0, .7D3, 12.5D-5 (3.1415, -5.5), (1.4, 7.1E4)

49

Datentypen, Variablen, Wertzuweisungen, Konstanten

6.1.2. Logischer Datentyp Datentyp

LOGICAL

Kommentar Logischer Datentyp (wahr oder falsch)

Literale (alle)

.TRUE., .FALSE.

Manchmal sind in alten FORTRAN-Programmen auch folgende Schreibweisen zu finden, welche jedoch nicht standardkonform sind: • • • • •

INTEGER*4, REAL*4, LOGICAL*4 (Standardgrößen) INTEGER*1, LOGICAL*1 INTEGER*2, LOGICAL*2 REAL*8 (entspricht DOUBLE PRECISION) COMPLEX*16 (komplexe Zahlen mit zwei DOUBLE-PRECISIONElementen)

Die Zahlen geben den Speicherplatzbedarf in Byte an.

6.1.3. Zeichenketten Datentyp

Kommentar

CHARACTER*n

Zeichenkette (String) mit einer Länge von n Zeichen Zeichenkette mit einer Länge von einem Zeichen (entspricht CHARACTER*1)

CHARACTER

50

Beispiel (Konstante) ’Hallo, Welt!’

’A’

Variablen

Beachte: Im Gegensatz zu vielen anderen Programmiersprachen werden Zeichenketten in FORTRAN 77 nicht in Anführungszeichen eingeschlossen, sondern in Apostrophe. Tritt in einem String ein Apostroph auf, so muss dieses verdoppelt werden, z. B. ’Wie geht”s?’

Beispiel: CHARACTER*5 STR STR = ’Hallo’

Alternative Schreibweise: CHARACTER STR*5 STR = ’Hallo’

6.2. Variablen Eine Variable ist charakterisiert durch einen • • • •

symbolischen Namen Datentyp Wert Speicherplatz

Beim Programmstart hat eine Variable keinen definierten Wert. Eine Variable kann ihren Datentyp auf zwei Arten erhalten, durch implizite oder explizite Typanweisung.

51

Datentypen, Variablen, Wertzuweisungen, Konstanten

6.2.1. Implizite Typanweisung Bei der impliziten Typanweisung bestimmt der Anfangsbuchstabe des Variablenbezeichners den Datentyp. Anfangsbuchstabe der Variablen I, J, K, L, M oder N alle restliche Buchstaben

Impliziter Datentyp INTEGER REAL

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP B1 = 8.9 C1 = 3. I1 = B1/C1

C

WRITE (*,*) I1 Das Ergebnis ist 2, da I1 implizit als INTEGER definiert ist END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

Die Standardzuordnung der Anfangsbuchstaben kann durch das Schlüsselwort IMPLICIT auch geändert werden. Es gibt noch ein weiteres Problem dieser impliziten Datentypzuordnung. Durch Tippfehler können unbeabsichtigt neue Variablen entstehen. Entschärft werden kann diese Tatsache durch folgende Festlegung im Vereinbarungsteil des Programms:

52

.

8

Variablen

IMPLICIT LOGICAL (A-Z)

Dadurch werden alle Variablen mit implizit festgelegtem Datentyp automatisch zu Variablen mit logischem Datentyp. In vielen Fällen konnten so Tippfehler bei Variablennamen schnell eingegrenzt werden. Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP IMPLICIT LOGICAL (A-Z) REAL REE

C

REE = 5.8 Tippfehler: REA anstatt REE WRITE (*,*) REA + 2.1 END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

Der Compilierungsversuch mit g77, gfortran und g95 endet mit einer Fehlermeldung. Bei gfortran sieht das so aus In file test.f:9 WRITE (*,*) REA + 2.1 1 Error: Operands of binary numeric operator ’+’ at (1) are LOGICAL(4)/REAL(4)

Doch der Intel Fortran Compiler 9.0 zeigt die Grenzen der Sinnhaftigkeit der IMPLICIT-Anweisung in der dargestellten Art und Weise beim heutigen Einsatz von FORTRAN-77-Code auf.

53

.

8

Datentypen, Variablen, Wertzuweisungen, Konstanten

Dieser Compiler akzeptiert den Beispielscode warnhinweislos und liefert bei Programmausführung den Wert 2.1. Wirklich Abhilfe schafft also erst die IMPLICIT NONE-Anweisung. Diese legt eindeutig fest, dass ausschließlich die explizite Datentypfestlegung Verwendung finden soll. Allerdings ist IMPLICIT NONE erst ab Fortran-90/95-Standard. In einigen noch erhältlichen FORTRAN-77-Compilern, wie dem g77, ist diese Anweisung im Vorgriff auf den genannten neueren Standard bereits implementiert.

6.2.2. Explizite Typanweisung Durch die Vorgabe von datentyp variablenbezeichner

im Vereinbarungsteil des Programms wird der Datentyp einer Variablen explizit festgelegt. Die explizite Typanweisung hat gegenüber der impliziten Typanweisung Vorrang. Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP IMPLICIT LOGICAL (A-Z) REAL B REAL C REAL I B = 8.9 C = 3. I = B/C

C

54

WRITE (*,*) I Das Ergebnis ist 2.966666 END

Benannte Konstanten

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

6.3. Benannte Konstanten Benannte Konstanten können Schlüsselwort festgelegt werden.

durch

das

PARAMETER-

CHARACTER*5 STR PARAMETER (PI=3.1415, PIFAK=PI/2., STR=’Hallo’)

Der zugewiesene Wert kann eine Konstante (Literal) oder eine schon definierte benannte Konstante sein. Der Datentyp muss vorher vereinbart werden oder ist implizit bekannt. Für Zeichenketten ist im Zusammenwirken mit PARAMETER auch eine *-Schreibweise möglich. Dies erspart die explizite Angabe der Stringlänge. Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP CHARACTER*(*) A PARAMETER (A = ’Jetzt wird auch die Stringlaenge festgelegt’)

C

WRITE (*,*) A Ausgabe: Jetzt wird auch die Stringlaenge festgelegt END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

55

.

8

Datentypen, Variablen, Wertzuweisungen, Konstanten

6.4. Wertzuweisung Wertzuweisungen haben wir schon kennengelernt: variable = ausdruck Beispiel: K = 1 K = K + 2

Die Wertzuweisung an eine Variable ist, wie am vorigen Beispiel und auch nachfolgend zu ersehen, nicht zu verwechseln mit einer mathematischen Gleichung. Der Ausdruck K + 2 = 5

wäre zwar mathematisch korrekt. Als Wertzuweisung in einem FORTRAN-Programm ist dies aber keine gültige Formulierung. K + 2 ist kein zulässiger Ausdruck auf der linken Seite des Zuweisungsoperators (L-Wert). Beachte: In FORTRAN 77 ist auch keine Kette von Wertzuweisungen möglich. Der folgende Ausdruck ist in FORTRAN 77 nicht erlaubt und liefert eine Fehlermeldung. I = J = K = 1.5 C Fehler!

56

7. Felder Bei allem, was mehr oder weniger wie ein Vektor, eine Matrix oder eine sonstige Aneinanderreihung von gleichartigen Elementen aussieht, kann der Einsatz von Feldern (Arrays) sinnvoll sein.

7.1. Eindimensionale Felder Für die Deklaration von eindimensionalen Feldern gibt es mehrere Möglichkeiten. Die Feldgrenzen müssen konstante Werte sein. Die Varianten werden nun anhand von Beispielen gezeigt.

7.1.1. Variante 1: Einfach REAL ARR(10)

Beachte: Der Feldindex läuft hier von 1 bis 10 und nicht von 0 bis 9, wie es bei vielen modernen Hochsprachen der Fall ist.

7.1.2. Variante 2: Das DIMENSION-Schlüsselwort REAL ARR DIMENSION ARR(10)

57

Felder

7.1.3. Variante 3: Verwendung von benannten Konstanten INTEGER MAXIND PARAMETER (MAXIND=10) REAL ARR(MAXIND)

Hier erfolgt die Festlegung der Feldgröße über eine benannte Konstante.

7.1.4. Variante 4: Explizite Angabe der Indexgrenzen REAL ARR(0:9)

Hier wird Unter- und Obergrenze explizit angegeben. Der Index läuft nun von 0 bis 9. Auch negative Werte für die Indizes sind möglich, z. B. REAL ARR(-4:5)

7.1.5. Beispiel 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INTEGER MAXIND PARAMETER (MAXIND=10) REAL ARR(MAXIND) C ACHTUNG! Array startet mit dem Index 1 C ARR(0) waere ein Fehler! ARR(1) = 1.5 ARR(2) = 2.5 ARR(10) = 10.5 WRITE (*,*) ARR(1)

58

Mehrdimensionale Felder

C

1.5 wird ausgegeben

C

WRITE (*,*) ARR(10) 10.5 wird ausgegeben END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

Ein WRITE (*,*) ARR

listet den gesamten Feldinhalt. 1.500000 2.500000 0.000000 3.9902670E-34 -2.7682916E-05 -2.7269103E-05 -2.9040850E-05 10.50000

3.9876625E-34

0.000000

Im Beispielsfall wurden die Feldelemente ARR(3) bis ARR(9) nicht explizit vorbelegt. Sie sind deshalb undefinierten Inhalts und können bei jedem Programmaufruf andere Werte annehmen.

7.2. Mehrdimensionale Felder Für mehrdimensionale Felder gelten die gleichen Varianten wie für eindimensionale Felder. Standardmäßig kann ein Feld bis zu sieben Dimensionen besitzen. Die Speicherreihenfolge ist spaltenorientiert. Das bedeutet, der erste Index variiert am schnellsten: a 11 , a 21 , . . . , a (n−1)m , a nm

59

.

8

Felder

Abb. 15

7.2.1. Beispiel: Ein 2-dimensionales Feld 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP CHARACTER*10 ARR(0:9, 2:5)

C

ARR(0, 2) = ARR(1, 2) = ... ARR(9, 5) = WRITE (*,*) Hallo

C

WRITE (*,*) ARR(9, 5) Universum

C

END

60

’Hallo’ ’Welt’ ’Universum’ ARR(0, 2)

Mehrdimensionale Felder

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

7.2.2. Beispiel: Spaltenorientierte Speicherreihenfolge  1 −5 0 Die 3×3-Matrix A =  40 3 −2 soll in ein Fortran-Programm −1 9 65 eingelesen und wieder komplett ausgegeben werden. Zusätzlich soll auch der Wert des Feldelementes a23 (2. Zeile, 3.Spalte, Wert = -2) separat ausgegeben werden. 

0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INTEGER ARR(3,3) C Feldelemente einlesen WRITE (*,*) ’Werte (spaltenorientierte Eingabe):’ READ (*,*) ARR C Komplettes Feld ausgeben WRITE (*,*) ’Gesamtfeld = ’ , ARR C a23 ausgeben WRITE (*,*) ’a23 = ’, ARR(2,3) END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

Ein-/Ausgabe: Werte (spaltenorientierte Eingabe): 1 40 -1

61

.

8

Felder

-5 3 9 0 -2 65 Gesamtfeld = 3 -2 a23 =

62

1 9

40 0

65 -2

-1

-5

8. Arithmetische Ausdrücke 8.1. Arithmetische Operatoren FORTRAN 77 kennt folgende arithmetische Operatoren Operator

Kommentar

A+B A-B A*B A/B A ** B

Addition Subtraktion Multiplikation Division Exponentiation

Mathematische Entsprechung A +B A −B AB A B

AB

Mit dem Exponentiationsoperator (Potenzierung) war und ist FORTRAN 77 anderen Programmiersprachen einen Schritt voraus. Andererseits kennt FORTRAN 77 den aus vielen anderen Programmiersprachen bekannten Modulo-Operator nicht. Als Überkompensation gibt es für diesen Zweck die MOD()1 -Funktion sowohl für Ganzzahlen, wie auch für Fließkommazahlen.

1

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77% 3A_S T A N D A R D F U N K T I O N E N %23M O D U L O

63

Arithmetische Ausdrücke

8.1.1. Operatorenpriorität Die Prioriät der arithmetischen Operatoren entspricht den mathematischen Gesetzmäßigkeiten. • Klammerung vor allem anderen, z. B. (A+B)*C ⇔ A*C+B*C • Exponentiation vor Punktrechnung, z. B. A*B**C ⇔ A*(B**C) • Punktrechnung vor Strichrechnung, z. B. A+B*C ⇔ A+(B*C)

8.1.2. Berechnungsfolge bei gleicher Priorität • Klammerung, Punktrechnung und Strichrechnung: → Beispiel: A*B/C*D⇔((A*B)/C)*D • Exponentiation: ← Beispiel: A**B**C⇔ A**(B**C) Außerdem ist zu beachten, dass niemals zwei Operatoren direkt aufeinander folgen dürfen. Beispiel: Der Ausdruck 1.5**-1 ist in FORTRAN 77 falsch und führt zu einer Fehlermeldung. Richtig ist 1.5**(-1)

8.2. Ergebnisdatentyp 8.2.1. Operanden gleichen Datentyps Bei Operanden gleichen Datentyps erhält das Ergebnis den Datentyp der Operanden. Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP REAL A

64

Ergebnisdatentyp

C C C C

A = 3/2 3 ist ein INTEGER und 2 ist auch ein INTEGER, daher muss das Ergebnis auch ein INTEGER sein, also 1. Die Zuweisung an die REAL-Variable A stellt das Ergebnis nicht mehr richtig.

C

WRITE (*,*) A Ausgabe: 1.00000 END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

8.2.2. Implizite Typumwandlung bei Operanden gemischten Datentyps Weisen die Operanden unterschiedliche Datentypen auf, so wird bei jeder Operation, falls nötig, das Ergebnis dem höherwertigen Datentyp angepasst. INTEGER→ REAL→ DOUBLE PRECISION → COMPLEX

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP REAL A

C

A = 3/2. 2. ist ein REAL. Jetzt stimmt das Ergebnis.

C

WRITE (*,*) A Ausgabe: 1.500000

65

Arithmetische Ausdrücke

END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

8.2.3. Explizite Typumwandlung FORTRAN 77 besitzt auch Funktionen zur expliziten Umwandlung des Datentyps. Diese werden im Kapitel S TANDARDFUNKTIONEN2 näher beschrieben. Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP REAL R COMPLEX C R = 2 C = CMPLX(R) WRITE (*,*) C C Ausgabe: ( 2.000000 , 0.000000 ) END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

2

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77% 3A_S T A N D A R D F U N K T I O N E N %23D A T E N T Y P U M W A N D L U N G %20

66

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

9. Logische Ausdrücke Logische Ausdrücke können zwei Zustände annehmen, wahr oder falsch. Diese werden in FORTRAN 77 durch die Literale .TRUE. oder .FALSE. dargestellt.

9.1. Logische Operatoren Folgende Tabelle enthält alle in FORTRAN 77 bekannte logische Operatoren. Sie sind in der Reihenfolge ihrer Prioritäten absteigend geordnet. Operator

Kommentar

.NOT. A A .AND. B A .OR. B A .EQV. B

logisches NICHT logisches UND logisches ODER logische Äquivalenz (XNOR) logische Antivalenz (XOR)

A .NEQV. B

Mathematische Entsprechung ¬A AB A ∨B A ⊕B A ⊕B

9.2. Wahrheitstafel

67

Logische Ausdrücke A

B

.NOT. A

A .AND. B .FALSE. .TRUE.

A .OR. B

A .EQV. B .TRUE.

A .NEQV. B .FALSE.

.TRUE. .TRUE. .TRUE. .TRUE. .FALSE. .FALSE. .FALSE. .TRUE. .FALSE. .TRUE. .FALSE. .TRUE. .TRUE. .FALSE. .TRUE. .FALSE. .TRUE. .FALSE. .FALSE. .TRUE. .FALSE. .FALSE. .TRUE. .FALSE. Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP LOGICAL L L = .TRUE.

C

WRITE (*,*) .NOT. L Ausgabe: F END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP LOGICAL A, B A = .TRUE. B = .FALSE.

C

68

WRITE (*,*) A .NEQV. B Ausgabe: T

Wahrheitstafel

END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

69

.

8

10. Vergleichsausdrücke Zum Vergleichen zweier arithmetischer Ausdrücke oder von Strings gibt es in FORTRAN 77 Vergleichsoperatoren. Das Ergebnis eines Vergleichs ist immer logischer Wert (.TRUE. oder .FALSE.).

10.1. Vergleichsoperatoren für arithmetische Typen Operator

Kommentar

A .LT. B

less than (kleiner als) less equal (kleiner gleich) greater than (größer als) greater equal (größer gleich) equal (gleich) not equal (ungleich)

A .LE. B A .GT. B A .GE. B A .EQ. B A .NE. B

Mathematische Entsprechung AB A≥B A=B A 6= B

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890

71

Vergleichsausdrücke

PROGRAM BSP INTEGER A, B A = 5 B = 6

C

WRITE (*,*) A .LT. B Ausgabe: T END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP CHARACTER*5 A, B A = ’Halli’ B = ’Hallo’

C

WRITE (*,*) A .LT. B Ausgabe: T END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

Beim Rechnen mit Fließkommazahlen (Datentypen: REAL, DOUBLE PRECISION, COMPLEX) sind die systemimmanenten Rechenungenauigkeiten zu beachten. Aus diesem Grund sollten Fließkommazahlen nicht auf strikte (Un)Gleichheit geprüft werden, son-

72

.

8

Zeichenkettenvergleiche

dern Vergleiche sollten einen kleinen Toleranzbereich aufweisen: x ± ² = y. Beispiel (hier mit ² = 0,00001 und y = 2: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890

C C

X = LOG(A) Statt... IF (X .EQ. 2) besser IF (ABS(X - 2) .LT. .00001)

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

10.2. Zeichenkettenvergleiche Das Ergebnis eines Vergleichs von Zeichenketten mittels Vergleichsoperatoren ist teilweise systemabhängig. Ausnahmen sind .EQ. und .NE.. Systemunabhängige Resultate sind durch Verwendung der entsprechenden LEXIKALISCHEN S TANDARDFUNK TIONEN 1 erhältlich. Dort wird immer die Reihenfolge im ASCIIZeichensatz verwendet. Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP IMPLICIT LOGICAL(A-Z) CHARACTER*15 A, B A = ’Hallö’

1

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77% 3A_S T A N D A R D F U N K T I O N E N %23L E X I K A L I S C H E _F U N K T I O N E N %20

73

Vergleichsausdrücke

B = ’hallo’

C C C C

WRITE (*,*) ’A gleich B? ’, A .EQ. B WRITE (*,*) ’A kleiner als B (Operator)? ’, A .LT. B WRITE (*,*) ’A kleiner als B (Funktion)? ’, LLT (A, B) Ausgabe: A gleich B? F A kleiner als B (Operator)? T A kleiner als B (Funktion)? T END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

10.3. Operatorenpriorität 1. 2. 3. 4. 5.

Klammerung Arithmetische Operatoren Vergleichsoperatoren Logische Operatoren Zuweisungsoperator

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP IMPLICIT LOGICAL(A-Z) REAL A, B, C LOGICAL X, RES A = 5.5 B = -1.2 C = 8.6 X = .FALSE. RES = X .AND. A - B .GT. C .OR. A .LE. C C entspricht infolge Op.priorität: C RES = ((X .AND. ((A-B) .GT. C)) .OR. (A .LE. C))

74

Operatorenpriorität

WRITE (*,*) RES C Ausgabe: T END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

Vergleichsoperatoren und logische Operatoren finden in erster Linie bei V ERZWEIGUNGEN UND S CHLEIFENBEDINGUNGEN2 Verwendung.

2

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20FORTRAN% 2077%3A%20V E R Z W E I G U N G E N %20 U N D %20S C H L E I F E N %20

75

.

8

11. Stringoperationen FORTRAN 77 bietet vergleichsweise komfortable Operatoren zur Behandlung von Zeichenketten.

11.1. Verknüpfungsoperator Operator A // B

Kommentar Operator zum Verknüpfen von Zeichenketten

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP CHARACTER*4 A, B*10 A=’How ’ B=’do you do.’

C

WRITE (*,*) A // B Ausgabe: How do you do. END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

77

.

8

Stringoperationen

11.2. Teilketten Ein String ist ein CHARACTER-Feld. Auch Teilketten einer solchen Zeichenkette können adressiert werden. Prinzip stringname (anfang:ende) stringname (:ende) stringname (anfang:) stringname (index:index)

Beschreibung von anfang bis ende vom ersten Zeichen bis ende von anfang bis zum letzten Zeichen genau ein Zeichen an der Position index

Dabei muss anfang stets größer oder gleich Eins sein. ende darf nicht größer als die Länge der Zeichenkette sein. index muss sich stets zwischen Eins und der Länge der Zeichenkette befinden. Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP CHARACTER*10 A A=’Hallo Welt’

C

WRITE (*,*) A(2:4) Ausgabe: all

C

WRITE (*,*) A(5:) Ausgabe: o Welt

C

WRITE (*,*) A(:3) Ausgabe: Hal END

78

Teilketten

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP CHARACTER*10 A A=’Hallo Welt’ A(7:) = ’XYZ’

C

WRITE (*,*) A Ausgabe: Hallo XYZ END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

Neben diesen Möglichkeiten sind in FORTRAN 77 auch einige Standardfunktionen für das Hantieren mit Zeichenketten vorgesehen. Diese sind im Kapitel S TANDARDFUNKTIONEN1 beschrieben.

1

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77% 3A_S T A N D A R D F U N K T I O N E N %23S T R I N G F U N K T I O N E N

79

.

8

12. Verzweigungen und Schleifen 12.1. GOTO GOTO bewirkt einen weisungsnummer.

Sprung

zu

einer

bestimmten

An-

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP GOTO 100 WRITE (*,*) ’Hallo’ 100 WRITE (*,*) ’Welt’ C Ausgabe: Welt END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

.

8

12.2. CONTINUE CONTINUE ermöglicht bei Anweisungsnummern eine „leere“ Anweisung. Beispiel: 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

81

Verzweigungen und Schleifen

12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP GOTO 100 WRITE (*,*) ’Hallo’ 100 CONTINUE C keine Ausgabe END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

12.3. Bedingtes GOTO Beim bedingten GOTO ist in Abhängigkeit von einer IntegerVariablen der Sprung zu einer bestimmten Anweisungsnummer möglich. Beispiel: Eine „Switch“-Verzweigung 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INTEGER I I=2 GOTO (100, 200, 300), I 100 WRITE (*,*) ’Hallo 1’ GOTO 1000 200 WRITE (*,*) ’Hallo 2’ GOTO 1000 300 WRITE (*,*) ’Hallo 3’ 1000 CONTINUE C Ausgabe: Hallo 2 END

82

IF-Verzweigungen

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

12.4. IF-Verzweigungen 12.4.1. Der IF-Einzeiler IF (logischer ausdruck) anweisung Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INTEGER I

C

I=2 IF (I .EQ. 2) WRITE (*,*) ’Hallo’ Ausgabe: Hallo END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

12.4.2. IF-THEN IF (logischer ausdruck) THEN anweisungsblock END IF Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890

83

Verzweigungen und Schleifen

PROGRAM BSP INTEGER I I=2 IF (I .EQ. 2) THEN WRITE (*,*) ’Hallo’ END IF Ausgabe: Hallo

C

END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

12.4.3. IF-THEN-ELSE IF (logischer ausdruck) THEN if-anweisungsblock ELSE elseanweisungsblock END IF

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INTEGER I

C

I=333 IF (I .GE. 444) THEN WRITE (*,*) ’Hallo’ ELSE WRITE (*,*) ’Hola’ END IF Ausgabe: Hola END

84

IF-Verzweigungen

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

12.4.4. ELSE-IF IF (logischer ausdruck 1) THEN if-anweisungsblock 1 ELSE IF (logischerAusdruck 2) THEN if-anweisungsblock 2 ELSE IF (logischerAusdruck n) THEN if-anweisungsblock n ELSE elseanweisungsblock END IF

0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INTEGER I I = 2 IF (I .EQ. 1) THEN WRITE (*,*) ’I ist eins’ ELSE IF (I .EQ. 2) THEN WRITE (*,*) ’I ist zwei’ ELSE WRITE (*,*) ’Ich weiß nicht was I ist’ END IF C Ausgabe: I ist zwei END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

85

.

8

Verzweigungen und Schleifen

12.5. DO-Schleifen Die DO-Schleife (Zählschleife) ist die einzige Schleife die FORTRAN 77 standardmäßig kennt. DO nr zählvariable = startwert, endwert [, schrittweite] anweisungsblock nr CONTINUE

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INTEGER I DO 100 I = 1, 10 WRITE (*,*) I 100 CONTINUE C Zeilenweise Ausgabe der Zahlen 1 bis 10 END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

12.6. Weitere Schleifen Da FORTRAN 77 keine weiteren Schleifen kennt, müssen diese mit Hilfe einer IF-Verzweigung und einem GOTO-Befehl nachgebildet werden. Prominente Beispiele sind die While-Schleife und die Repeat-Until-Schleife.

86

.

8

Weitere Schleifen

12.6.1. While-Schleife Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INTEGER I I=0 10

C

IF(I .LT. 5) THEN WRITE (*,*) I I = I + 1 GOTO 10 END IF Die Zahlen 0 bis 4 werden ausgegeben END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

12.6.2. Repeat-Until-Schleife Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INTEGER I I=6 10

C

CONTINUE WRITE (*,*) I I = I + 1 IF (I .LT. 5) GOTO 10 Die Zahl 6 wird ausgegeben

87

Verzweigungen und Schleifen

END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

12.7. Implizite Schleife Bei Eingabe oder Ausgabe ist die Angabe einer impliziten Schleife möglich. Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INTEGER I

C

WRITE (*,*) (’Hallo’, I = 1, 10) Ausgabe: HalloHalloHalloHalloHalloHalloHalloHalloHalloHallo END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

12.8. STOP Die STOP-Anweisung beendet das Programm. Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890

88

STOP

PROGRAM BSP

C

WRITE (*,*) ’Vor Stop-Statement’ STOP WRITE (*,*) ’Nach Stop-Statement’ Ausgabe: Vor Stop-Statement END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

89

.

8

13. Standardfunktionen In diesem Kapitel werden für die Funktionsargumente und Rückgabewerte nachfolgende Kürzel verwendetet, die Aufschluss über die möglichen Datentypen geben. Kürzel i r d x c l

Datentypen

INTEGER REAL DOUBLE PRECISION COMPLEX CHARACTER*n LOGICAL

13.1. Datentypumwandlung 13.1.1. Umwandlung in INTEGER • i = INT(i) Abschneiden des Nachkommaanteils: • i = INT(r) • i = IFIX(r) • i = IDINT(d) • i = INT(x)

91

Standardfunktionen

ASCII-Wert des Zeichens c: • i = ICHAR(c)

13.1.2. Umwandlung in REAL • • • • •

r = REAL(i) r = FLOAT(i) r = REAL(r) r = SNGL(d) r = REAL(x)

13.1.3. Umwandlung in DOUBLE • • • •

d = DBLE(i) d = DBLE(r) d = DBLE(d) d = DBLE(x)

13.1.4. Umwandlung in COMPLEX • • • •

x = CMPLX(i) x = CMPLX(r) x = CMPLX(d) x = CMPLX(x)

13.1.5. Umwandlung in CHARACTER Gibt das Zeichen zum ASCII-Wert i zurück. • c = CHAR(i)

92

Mathematische Funktionen

13.2. Mathematische Funktionen 13.2.1. Abschneiden des Nachkommaanteils Ist das Argument größer Null, wird die nächstkleinere ganze Zahl zurückgegeben. Ist das Argument kleiner Null, wird die nächstgrößere ganze Zahl zurückgegeben. • r = AINT(r) • d = DINT(d)

13.2.2. Runden Ist das Argument größer oder gleich Null, ist der Rückgabewert INT(X+0.5). Ist das Argument kleiner Null, ist der Rückgabewert INT(X-0.5) • • • •

r = ANINT(r) d = DNINT(d) i = NINT(r) i = IDNINT(d)

13.2.3. Absolutwert • • • •

i = IABS(i) r = ABS(r) d = DABS(d) r = CABS(x)

13.2.4. Double Precision-Produkt Rückgabewert ist r1 × r2 mit Datentyp DOUBLE PRECISION

93

Standardfunktionen

• d = DPROD(r1, r2)

13.2.5. Modulo Rückgabewert ist zahl1 - INT(zahl1 /zahl2)*zahl2 • i = MOD(i1, i2) • r = AMOD(r1, r2) • d = DMOD(d1, d2)

13.2.6. Vorzeichentransfer Wenn die zahl2 >= 0 ist, dann wird |zahl1| zurückgegeben. Wenn die zahl2 < 0 ist, dann wird -|zahl1| zurückgegeben. • i = ISIGN(i1, i2) • r = SIGN(r1, r2) • d = DSIGN(d1, d2)

13.2.7. Positive Differenz Für zahl1 > zahl2 ist der Rückgabewert zahl1 - zahl2. Für zahl1 <= zahl2 wird Null zurückgegeben. • i = IDIM(i1, i2) • r = DIM(r1, r2) • d = DDIM(d1, d2)

13.2.8. Maximum Gibt den größten Argumentwert zurück. • i = MAX0(i1, i2, ...)

94

Mathematische Funktionen

• • • •

r = AMAX1(r1, r2, ...) d = DMAX1(d1, d2, ...) r = AMAX0(i1, i2, ...) i = MAX1(r1, r2, ...)

13.2.9. Minimum Gibt den kleinsten Argumentwert zurück. • • • • •

i = MIN0(i1, i2, ...) r = AMIN1(r1, r2, ...) d = DMIN1(d1, d2, ...) r = AMIN0(i1, i2, ...) i = MIN1(r1, r2, ...)

13.2.10. Komplexe Zahlen Gibt den Imaginärteil zurück: • r = AIMAG(x) Gibt die konjugiert komplexe Zahl zurück: • x = CONJG(x)

13.2.11. Quadratwurzel Gibt die Quadratwurzel zurück: • r = SQRT(r) • d = DSQRT(d) • x = CSQRT(x)

95

Standardfunktionen

13.2.12. Exponentialfunktion Gibt natürliche Exponentialfunktion zurück: • r = EXP(r) • d = DEXP(d) • x = CEXP(x)

13.2.13. Logarithmus naturalis Gibt den natürlichen Logarithmus zurück: • r = ALOG(r) • d = DLOG(d) • x = CLOG(x)

13.2.14. Dekadischer Logarithmus Gibt den dekadischen Logarithmus zurück: • r = ALOG10(r) • d = DLOG10(d)

13.2.15. Winkelfunktionen • r = SIN(r) • d = DSIN(d) • x = CSIN(x) • r = COS(r) • d = DCOS(d) • x = CCOS(x) • r = TAN(r)

96

Mathematische Funktionen

• d = DTAN(d)

13.2.16. Arkusfunktionen • r = ASIN(r) • d = DASIN(d) • r = ACOS(r) • d = DACOS(d) • r = ATAN(r) • d = DATAN(d) Gibt arctan( rr 12 ) zurück: • r = ATAN2(r1, r2) • d = DATAN2(d1, d2) Diese Funktionen sind für ähnliche Werte der beiden Argumente erheblich genauer.

13.2.17. Hyperbelfunktionen • r = SINH(r) • d = DSINH(d) • r = COSH(r) • d = DCOSH(d) • r = TANH(r) • d = DTANH(d)

97

Standardfunktionen

13.3. Zeichenketten-Funktionen 13.3.1. Länge • i = LEN(c)

13.3.2. Index eines Teilstrings Gibt die erste Position des Auftretens eines Teilstrings c2 in c1 zurück. c2 muss eine (benannte) Konstante sein. • i = INDEX(c1, c2)

13.3.3. Lexikalische Funktionen Hier wird unabhängig von der Plattform immer der ASCIIZeichensatz als Grundlage verwendet. Lexikalisch größer oder gleich (Rückgabewert ist .TRUE. wenn c1 >= c2): • l = LGE(c1, c2) Lexikalisch größer als (Rückgabewert ist .TRUE. wenn c1 > c2): • l = LGT(c1, c2) Lexikalisch kleiner oder gleich (Rückgabewert ist .TRUE. wenn c1 <= c2): • l = LLE(c1, c2) Lexikalisch kleiner als (Rückgabewert ist .TRUE. wenn c1 < c2): • l = LLT(c1, c2)

98

Zeichenketten-Funktionen

Obige Funktionenauflistung basiert auf dem Fortran 77 Sprachstandard X3J3/90.4, Kap.15: Functions and Subroutines HTTP :// WWW. FORTRAN . COM /F77_ STD / RJCNF -15. HTMLSH 15.101 . Bei Unklarheiten sollte diese Originalqelle zu Rate gezogen werden, wenngleich die tabellarische Darstellung der "intrinsic functions" dort ziemlich gewöhnungsbedürftig ist.

1

H T T P :// W W W . F O R T R A N . C O M /F77_ S T D / R J C N F -{}15. H T M L # S H -{}15.10

99

14. Unterprogramme Natürlich können in FORTRAN 77 auch eigene Unterprogramme erstellt werden.

14.1. 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

101

Unterprogramme

C

WRITE (*,*) FUNK () 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.)

C

WRITE (*,*) C Ausgabe: -0.6931472 END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

14.2. 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] FUNCTION funktionsname([formale parameter]) anweisungen END

102

.

8

FUNCTION

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 C

Funktionsaufruf WRITE(*,*) FUNK() 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

10

DO 10 I = 1,10 TMP = TMP + I*0.5 CONTINUE FUNK = TMP END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

Übersetzung mit gfortran:

103

.

8

Unterprogramme

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 C

Funktionsaufruf WRITE(*,*) FUNK(3) 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)

104

SUBROUTINE

END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

14.3. SUBROUTINE Eine Subroutine besitzt im Gegensatz zu einer Funktion keinen Datentyp und gibt keinen Wert zurück.

SUBROUTINE subroutinenname([formale parameter]) anweisungen END 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

105

Unterprogramme

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

106

Felder als Parameter

REAL A = 2.0 CALL SUB(A)

C

WRITE(*,*) A 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

.

5

.

6

.

7 |

.

8

14.4. Felder als Parameter Beispiel: Übergabe eines ganzen Feldes Datei bsp.f: 0

. |

1

.

2

.

3

.

4

107

Unterprogramme

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 CONTINUE CONTINUE

20 10 C C

Unterprogrammaufruf CALL SUB(FELD) 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

Beispiel: Übergabe einer Feld-Teilkette

108

.

5

.

6

.

7 |

.

8

Felder als Parameter

Datei bsp.f: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INTEGER FELD(3,3) INTEGER CNT CNT = 1

20 10 C C

DO 10 I = 1, 3 DO 20 J = 1, 3 FELD(J,I) = CNT CNT = 1 + CNT CONTINUE CONTINUE

Unterprogrammaufruf CALL SUB(FELD(1:2,2:3)) 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 |

109

.

8

Unterprogramme

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 CONTINUE CONTINUE

20 10 C C

Unterprogrammaufruf CALL SUB(FELD(1,2)) 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

110

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

Prozeduren als Parameter

14.5. 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) Ausgabe: 0.000000 CALL SUB(COS, PI) Ausgabe: -1.000000

C C

END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

111

.

8

Unterprogramme

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

14.6. 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

112

COMMON

A = 4.0 B = 5.0 C = 6.0 CALL SUB

C

WRITE (*,*) A, B, C, D 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 |

113

.

8

Unterprogramme

14.7. 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

C C

CALL SUB Ausgabe: Hallo Welt!

C

CALL E1 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’

114

SAVE

ENTRY E1 WRITE (*,*) ’Welt!’ END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

14.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 DATA1 zwecks Initialisierung von Variablen).

SAVE [variablenliste] Beispiel: Datei bsp.f: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP

C

CALL SUB Ausgabe: 1.000000

C

CALL SUB Ausgabe: 2.000000

1

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77% 3A%20U N T E R P R O G R A M M E %23DATA

115

Unterprogramme

C

CALL SUB 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 |

14.9. DATA DATA dient zur Wertinitialisierung von Variablen vor der Programmeinheitausführung. Diese Anweisung ist also nicht gleichzusetzen mit einer Wertzuweisung. Beispiel:

DATA [variablenliste] /variablenwerte/

116

.

8

DATA

Beispiel: Datei bsp.f: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP

C

CALL SUB Ausgabe: 1.000000

C

CALL SUB Ausgabe: 2.000000

C

CALL SUB 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 |

Unterschied zwischen Wertinitialisierung und Wertzuweisung:

117

.

8

Unterprogramme

Code

Ausgabe

118

Wertinitialisierung PROGRAM BSP CALL SUB CALL SUB CALL SUB END SUBROUTINE SUB REAL A DATA A /3.0/ A = A + 1 WRITE(*,*) A END 4.000000 5.000000 6.000000

Wertzuweisung PROGRAM BSP CALL SUB CALL SUB CALL SUB END SUBROUTINE SUB REAL A A = 3.0 A = A + 1 WRITE(*,*) A END 4.000000 4.000000 4.000000

15. Ein- und Ausgabe 15.1. READ

Abb. 16

Die READ-Anweisung dient dem Einlesen von Daten. Typisches Beispiel ist die Dateneingabe mittels Tastatur. Formal sieht eine READ-Anweisung so aus: READ([UNIT=]unit, [FMT=]fmt [, ERR=err] [, END=end] [, IOSTAT=iostat]) [eingabeliste] • unit ... Nummer der Eingabeeinheit (ist systemabhängig), Sternoperator oder auch die einer Datei mittels OPEN-Anweisung zugeordnete Nummer. • fmt ... Anweisungsnummer zu einer FORMAT-Anweisung oder Sternoperator • err ... Tritt während der Eingabe ein Fehler auf, so wird zu dieser Anweisungsnummer gesprungen

119

Ein- und Ausgabe

• end ... Nach dem Einlesen des letzten Datensatzes wird zu diese Anweisungsnummer gesprungen • iostat ... READ-Status Listengesteuerte Eingabe auf der Standardeingabe (normalerweise die Tastatur): READ (*,*) A, B, C

Alternativ kann das auch so geschrieben werden: READ (UNIT=*, FMT=*) A, B, C

Beim Intel Fortran Compiler, gfortran und g95 ist auch UNIT = 5 als stdin (Tastatur) vorbelegt. Das Einlesen aus Dateien und die Einstellung des Formates werden später erläutert. Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INTEGER I(5) C Einlesen in ein Feld (UNIT ... Standardeingabe, FMT ... listengesteuert) READ (*,*) I C ... END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

Kurze Erläuterung zu IOSTAT:

120

.

4

.

5

.

6

.

7 |

.

8

READ Wert

Erläuterung

Wert 0 positiver Wert (systemabhängig) negativer Wert (systemabhängig)

Erläuterung kein Fehler Fehler End Of File und kein Fehler

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890

C

C

PROGRAM BSP INTEGER I INTEGER ST Einlesen eines Wertes READ (*, *, IOSTAT=ST) I Ausgabe des IO-Status WRITE (*,*) ’IO-Status:’, ST END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

Ausgabe: Für Eingabe: 5 → 0 Für Eingabe: 5.3 → Positiver Wert = Fehler

121

.

8

Ein- und Ausgabe

15.2. WRITE

Abb. 17

Die WRITE-Anweisung dient der Datenausgabe. Typisches Beispiel ist die Anzeige von Daten auf dem Bildschirm. Formal sieht eine WRITE-Anweisung so aus: WRITE([UNIT=]unit, [FMT=]fmt [, ERR=err] [, IOSTAT=iostat]) [ausgabeliste]

• unit ... Nummer der Ausgabeeinheit (ist systemabhängig), Sternoperator oder auch die einer Datei mittels OPENAnweisung zugeordnete Nummer. • fmt ... Anweisungsnummer zu einer FORMAT-Anweisung oder Sternoperator • err ... Tritt während der Ausgabe ein Fehler auf, so wird zu dieser Anweisungsnummer gesprungen • iostat ... WRITE-Status Listengesteuerte Ausgabe auf der Standardausgabe (normalerweise der Bildschirm): WRITE (*,*) A, B, C

122

WRITE

Alternativ kann das auch so geschrieben werden: WRITE (UNIT=*, FMT=*) A, B, C

Beim Intel Fortran Compiler, gfortran und g95 sind auch

• unit=0 als stderr (Bildschirm) und • unit=6 als stdout (Bildschirm)

vorbelegt. Bezüglich IOSTAT gilt auch hier der im vorigen Abschnitt kurz geschilderte Sachverhalt. Die Ausgabe in Dateien und die Einstellung des Formates werden nachfolgend erläutert.

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INTEGER I(5) C I(1) = ... C ... C Ausgabe der Feldwerte (UNIT ... Standardausgabe, FMT ... listengesteuert) WRITE (*,*) I C ... END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

123

.

8

Ein- und Ausgabe

15.3. Formatierung

Abb. 18

Die Ein- und Ausgabeformatierung kann beeinflusst werden. Zu diesem Zweck gibt es die FORMAT-Anweisung. ... (..., FMT = marke, ...) ... marke FORMAT (formatliste) Alternativ dazu kann auch direkt bei der FMT-Option die Formatliste bekanntgemacht werden. ... (..., FMT = ’(formatliste)’, ...) ...

15.3.1. Formatlistenelemente Formatspezifizierer Ix[.z]

124

Kommentar Ganzzahl mit einer Feldlänge von x Zeichen. z gibt die Mindestanzahl der auszugebenden Zeichen an (Feld wird, wenn nötig, mit führenden Nullen aufgefüllt).

Formatierung Formatspezifizierer Fx.y

Ex.y

Dx.y A Ax Lx xX

Kommentar Fixkommazahl mit einer Gesamtfeldlänge von x Zeichen. y ist die Anzahl der Nachkommastellen (Vorzeichen und Dezimalpunkt müssen in der Gesamtfeldlänge berücksichtigt werden). Gleitkommazahl mit einer Gesamtfeldlänge von x Zeichen. y ist die Anzahl der Nachkommastellen. (Vorzeichen, Dezimalpunkt und die Zeichen für den Exponenten müssen in der Gesamtfeldlänge berücksichtigt werden). -"Ein Zeichenkette. Eine Zeichenkette mit x Zeichen. Ein logischer Wert, T bzw. F x Leerzeichen.

Obige Tabelle der Formatlistenelemente ist nicht vollständig. Fortran kennt noch weitere Formatierungsmöglichkeiten. Die Ausgabe erfolgt normalerweise rechtsbündig. Reicht die Gesamtfeldlänge bei numerischen Werten nicht aus, so werden anstelle einer Zahl Sternchen angezeigt. Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890

125

Ein- und Ausgabe

PROGRAM BSP INTEGER A

C

A = 999 WRITE (*, 3333) A Ausgabe: 999

C

A = -999 WRITE (*, 3333) A Ausgabe: ***

3333 FORMAT (I3) END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

Weitere Formatierungsbeispiele: Code WRITE(*, 999) 1234 WRITE(*, 999) 1234567 WRITE(*, 999) 1234567890 999 FORMAT(I9.6) WRITE(*, 999) 555.6666 WRITE(*, 999) +5.6 WRITE(*, 999) -55.666E7 WRITE(*, 999) -55555.666 999 FORMAT(F9.3)

126

Ausgabe 001234 1234567 *********

555.667 5.600 ********* *********

7 |

.

8

Formatierung Code WRITE(*, 999) 555.6666 WRITE(*, 999) +5.6 WRITE(*, 999) -55.666E7 WRITE(*, 999) -55555.666 999 FORMAT(E9.3) WRITE(*, 999) ’Hallo’ WRITE(*, 999) ’ABCDEFGHIJKL’ WRITE(*, 888) ’ABCDEFGHIJKL’ 888 FORMAT(A) 999 FORMAT(A10) WRITE(*, *) ’FORTRAN’, ’77’ WRITE(*, 999) ’FORTRAN’, ’77’ 999 FORMAT(A, 1X, A) WRITE(*, 888) ’FORTRAN’, ’77’ WRITE(*, 999) ’FORTRAN’, ’77’ 888 FORMAT(A, T3, A) 999 FORMAT(A, T20, A) WRITE(*, 999) ’FORTRAN’, ’77’ 999 FORMAT(A, /, A) WRITE(*, 999) 34.56 WRITE(*, *) 34.56 C SP ... Sign Plus (+) 999 FORMAT(SP, F12.3)

Ausgabe 0.556E+03 0.560E+01 .557E+09 -.556E+05

Hallo ABCDEFGHIJ ABCDEFGHIJKL

FORTRAN77 FORTRAN 77

FO77RAN FORTRAN 77

FORTRAN 77

+34.560 34.56



127

Ein- und Ausgabe

15.3.2. Wiederholung von Formatteilen Beispiel:

100

WRITE (*, 100) ’abc’, 10.3, ’xxx’, 23.4 FORMAT (2(A3, F6.1))

15.3.3. WRITE etwas anders Beispiel:

100

WRITE (*, 100) FORMAT (’Hallo’, 1X, ’Welt!’)

15.4. Dateien

Abb. 19

128

Dateien

15.4.1. Datensatz Datensätze können in folgender Form auftreten: • Formatierter Datensatz: Textdatensatz • Unformatierter Datensatz: Datensatz in einer maschineninternen Form. • Dateiendesatz

15.4.2. Datei Für FORTRAN 77 ist alles eine Datei, das durch READ oder WRITE bearbeitbar ist. Zugriffsmethoden: • Sequentieller Zugriff: Lesen ab Beginn der Datei (file) und dann immer den nächsten Datensatz einlesen. Geschrieben wird jeweils ans Dateiende. Auf interne Dateien kann nur sequentiell zugegriffen werden. • Direkter Zugriff: Bearbeiten in beliebiger Reihenfolge durch Angabe der Satznummer. Dateitypen: • Externe Datei: Eine konventionelle Datei • Interne Datei: CHARACTER-Variable oder -Feld. Dateien haben im Betriebssystem einen Dateinamen. In FORTRAN wird eine Datei über eine Dateinummer (unit) angesprochen. Die Zuordnung erfolgt mit dem Befehl OPEN.

15.4.3. OPEN Zum Öffnen einer externen Datei dient die OPEN -Anweisung.

129

Ein- und Ausgabe

OPEN (liste) mit folgender liste Element [UNIT =] x FILE = x IOSTAT = x

ERR = x STATUS = x

ACCESS = x

FORM = x

RECL = x

130

Kommentar x ist eine Dateinummer (0 bis 99) x ist der externe Dateiname x ist 0 wenn OPEN fehlerfrei ausgeführt wurde, ansonsten eine systemabhängige Fehlernummer Bei Fehler Sprung zur Anweisungsnummer x Dateistatus: ’OLD’ ... Datei existiert bereits ’NEW’ ... Datei wird neu erzeugt ’SCRATCH’ ... namenlose temporäre Datei ’UNKNOWN’ ... System bestimmt Dateistatus selbst Zugriffsmethode: ’SEQUENTIAL’ ... Sequentielle Datei ’DIRECT’ ... direkter Zugriff Format: ’FORMATTED’ oder ’UNFORMATTED’ Datensatzlänge (positive Zahl, ACCESS=’DIRECT’, in Bytes bzw. bei formatierten Dateien in Characters)

Dateien Element BLANK = x

Kommentar ’NULL’ (ignorieren von Leerzeichen bei numerischen Werten) oder ’ZERO’ (Leerzeichen bei numerischen Werten als 0 interpretieren)

Eingestellte Vorgabewerte sind: • • • •

STATUS = ’UNKNOWN’ ACCESS = ’SEQUENTIAL’ FORM = ’FORMATTED’ BLANK = ’NULL’

Wird ACCESS=’DIRECT’ gesetzt, so gilt FORM=’UNFORMATTED’ als Vorgabewert. Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP OPEN (20, FILE=’/tmp/testdatei.txt’, STATUS=’OLD’, ERR=222) WRITE (*,*) ’Voller Erfolg’ CLOSE(20) GOTO 333 222 333

WRITE(*,*) ’Fehler beim Öffnen der Datei’ END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

131

.

8

Ein- und Ausgabe

15.4.4. CLOSE Geschlossen wird die Verbindung zur externen Datei mit dem CLOSE-Befehl. CLOSE (liste)

liste: Element [UNIT =] x IOSTAT = x ERR = x STATUS = x

Kommentar wie bei OPEN wie bei OPEN wie bei OPEN KEEP ... Datei erhalten DELETE ... Datei löschen

15.4.5. Lesen und Schreiben Aus Dateien gelesen oder in Dateien geschrieben wird mit den bereits bekannten READ- und WRITE-Anweisungen. Element [UNIT =] x

[FMT =] x

1

132

Kommentar Unit 0 bis 99 bzw. CHARACTER-Variable oder Feld (interne Datei) siehe F ORMATIERUNG1

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20FORTRAN% 2077%3A%20E I N -{}%20 U N D %20A U S G A B E %23F O R M A T I E R U N G

Dateien Element REC = x

IOSTAT = x ERR = x END = x

Kommentar Datensatznummer bei Direktzugriff (siehe Abschnitt D IREKTZUGRIFF2 ) wie bei READ3 Bei Fehler Sprung zur Anweisungsnummer x Bei Dateiende Sprung zur Anweisungsnummer x (nicht erlaubt bei Direktzugriff)

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP CHARACTER*80 A OPEN (20, FILE=’/tmp/testdatei.txt’, STATUS=’OLD’, ERR=222) 10 CONTINUE Aus Datei lesen READ (20, 888, END=20) A C Auf Standardausgabe schreiben WRITE (*,*) A GOTO 10 C

20

CLOSE(20) GOTO 333

222 888 333

WRITE(*,*) ’Fehler beim Öffnen der Datei’ FORMAT(A) END

2 3

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20FORTRAN% 2077%3A%20E I N -{}%20 U N D %20A U S G A B E %23D I R E K T Z U G R I F F H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20FORTRAN% 2077%3A%20E I N -{}%20 U N D %20A U S G A B E %23READ

133

Ein- und Ausgabe

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

Direktzugriff OPEN: Element ACCESS = x RECL = x

Kommentar x ... ’DIRECT’ x ... Datensatzlänge (positive Zahl, ACCESS=’DIRECT’, in Bytes bzw. bei formatierten Dateien in Characters)

READ/WRITE: Element REC = x

Kommentar x ... Satznummer bei Direktzugriff

Beispiel: Gegeben ist die Textdatei /tmp/testdatei.txt mit dem Inhalt Die WRITE-Anweisung dient der Datenausgabe aus einem FORTRAN-Programm auf ein externes Gerät. Typisches Beispiel ist die Anzeige von Daten auf dem Bildschirm. Formal sieht eine WRITE-Anweisung so aus:

0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP

134

Dateien

CHARACTER*10 C

& & & &

OPEN (20, FILE=’/tmp/testdatei.txt’, STATUS=’OLD’, ACCESS=’DIRECT’, RECL=10, ERR=222) READ (20, REC=4, ERR=333) C WRITE (*,*) C READ (20, REC=25, ERR=333) C WRITE (*,*) C CLOSE (20) GOTO 444

222 333 444

WRITE (*,*) ’Fehler beim Öffnen der Datei’ WRITE (*,*) ’Fehler beim Lesen des Datensatzes’ CONTINUE END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

Ausgabe: Datenausga Fehler beim Lesen des Datensatzes

Positionieren bei sequentiellen Dateien Datensatzzeiger um einen Datensatz zurücksetzen: BACKSPACE ([UNIT=]x [,IOSTAT=y] [,ERR=z]) Positionieren an den Dateibeginn:

135

.

8

Ein- und Ausgabe

REWIND ([UNIT=]x [,IOSTAT=y] [,ERR=z]) Schreiben eines Dateiendsatzes: ENDFILE ([UNIT=]x [,IOSTAT=y] [,ERR=z]) Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP CHARACTER*100 C(3)

& &

OPEN (20, FILE=’/tmp/testx.txt’, STATUS=’NEW’, ERR=222) WRITE (20,*) ’Das ist eine Testdatei’ WRITE (20,*) ’Dies ist Zeile 2 der Testdatei’ WRITE (20,*) ’Jenes die Zeile 3 der Testdatei’ WRITE (20,*) ’Jetzt ist”s aber genug’ ENDFILE (20, ERR=444) REWIND (20, ERR=444) READ (20, FMT=555, ERR=333) C WRITE (*, FMT=555) C BACKSPACE (20, ERR=444) READ (20, FMT=555, ERR=333) C(1) WRITE (*, FMT=555) C(1) GOTO 999

222

WRITE (*,*) ’Fehler beim Öffnen der Datei’ GOTO 999

333

WRITE (*,*) ’Fehler beim Lesen des Datensatzes’ GOTO 999 WRITE (*,*) ’Sonstiger Fehler’ GOTO 999 FORMAT (A) CLOSE (20)

444 555 999 C C

Ausgabe: Das ist eine Testdatei

136

Dateien

C C C

Dies ist Zeile 2 der Testdatei Jenes die Zeile 3 der Testdatei Jenes die Zeile 3 der Testdatei END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

15.4.6. INQUIRE Die Anweisung INQUIRE dient der Abfrage einiger Eigenschaften von Dateien oder I/O-Units. INQUIRE (FILE = x, liste)

mit x ... Dateiname (inkl. Pfad) INQUIRE ([UNIT =] x, liste)

mit x ... Nummer der I/O-Unit. liste: Element ACCESS = x

Kommentar x: • ’SEQ’ ... sequentieller Dateizugriff • ’DIRECT’ ... Direktzugriff

137

.

8

Ein- und Ausgabe Element BLANK = x

Kommentar x: • ’NULL’ • ’ZERO’

DIRECT = x

x: • ’YES’ ... Direktzugriff • ’NO’ ... kein Direktzugriff für diese Datei erlaubt • ’UNKNOWN’ ... unbekannt

ERR = x EXIST = x

Bei Fehler Sprung zur Anweisungsnummer x x: • .TRUE. ... Datei existiert • .FALSE. ... Datei existiert nicht

FORM = x

x: • ’FORMATTED’ ... Datei geöffnet für formatierte Datensätze • ’UNFORMATED’ ... Datei geöffnet für unformatierte Datensätze

138

Dateien Element FORMATTED = x

Kommentar

• ’YES’ ... formatierte Datensätze sind erlaubt • ’NO’ ... formatierte Datensätze sind nicht erlaubt • ’UNKNOWN’ ... unbekannt IOSTAT = x

NAME = x

NAMED = x

x ist 0 wenn INQUIRE fehlerfrei ausgeführt wurde, ansonsten eine systemabhängige positive Fehlernummer Der Dateiname wird der Zeichenketten-Variablen x zugewiesen. Hat die Datei keinen Namen, dann ist ist das Ergebnis undefiniert. x: • .TRUE. ... Datei besitzt Namen • .FALSE. ... Datei besitzt keinen Namen

NEXTREC = x NUMBER = x

x ... Nummer des nächsten Datensatzes x ... Nummer der mit einer externen Datei verbundenen I/O-Unit.

139

Ein- und Ausgabe Element OPENED = x

Kommentar x: • .TRUE. ... Datei ist geöffnet • .FALSE. ... Datei ist nicht geöffnet

RECL = x SEQUENTIAL = x

x ... Datensatzlänge bei Direktzugriff x: • ’YES’ ... sequentiell • ’NO’ ... nicht sequentiell • ’UNKNOWN’ ... unbekannt

UNFORMATTED = x • ’YES’ ... unformatierte Datensätze sind erlaubt • ’NO’ ... unformatierte Datensätze sind nicht erlaubt • ’UNKNOWN’ ... unbekannt

Beispiel: Datei vorhanden? 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP LOGICAL L

140

Dateien

C C C

INQUIRE (FILE=’/tmp/testdatei.txt’, EXIST=L, ERR=222) WRITE (*,*) L Ausgabe: wenn Datei existiert: T wenn Datei nicht existiert: F GOTO 999 222 999

WRITE (*,*) ’Fehler!’ CONTINUE END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

Beispiel: Infos zu einer geöffneten Datei 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP LOGICAL EX CHARACTER*15, DI, FO, AC, SE INTEGER NU OPEN (25, FILE=’/tmp/testdatei.txt’, STATUS=’OLD’, ERR=222) INQUIRE (25, EXIST = EX, DIRECT = DI, SEQUENTIAL = SE, FORMATTED = FO, ACCESS = AC, NUMBER = NU, ERR=222) WRITE (*,*) ’EXIST? ’, EX WRITE (*,*) ’DIRECT? ’, DI WRITE (*,*) ’SEQUENTIAL? ’, SE WRITE (*,*) ’FORMATTED? ’, FO WRITE (*,*) ’ACCESS? ’, AC WRITE (*,*) ’NUMBER? ’, NU Ausgabe, z.B. EXIST? T DIRECT? YES SEQUENTIAL? YES FORMATTED? YES & & & & & &

C C C C C

141

Ein- und Ausgabe

C C

ACCESS? SEQUENTIAL NUMBER? 25 GOTO 999

222 999

WRITE (*,*) ’Fehler!’ CLOSE (25) END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

15.4.7. Interne Dateien • Interne Dateien sind vom Datentyp CHARACTER (Zeichen oder Zeichenketten) • Das Lesen aus bzw. das Schreiben in interne Dateien erfolgt immer sequentiell Beispiel: Schreiben in eine interne Datei 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP CHARACTER*15 CH REAL R R = 12.5678 C

Interne Datei "CH" WRITE (CH, *) R

&

WRITE (*,*) ’R lexikalisch groesser als Buchstabe "A"? ’, LGE(CH, ’A’) END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

142

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

Dateien

Beispiel: Lesen aus einer internen Datei 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP CHARACTER*15 CH REAL R CH = ’12.5678’ C

Interne Datei "CH" READ (CH, ’(F15.5)’) R WRITE (*,*) ’R = ’, R WRITE (*,*) ’R**2 = ’, R**2 END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

143

.

8

16. Anhang 16.1. Liste aller FORTRAN 77 Schlüsselwörter 16.2. PAUSE Die PAUSE-Anweisung unterbricht die Programmausführung. Diese Anweisung wurde mit dem Fortran 90/95-Standard aus dem Fortran-Sprachumfang verbannt. Moderne Compiler geben deshalb teilweise bei Verwendung dieser Anweisung eine Warnmeldung (obsolete o.ä.) aus. Das Verfahren zur normalen Fortsetzung des infolge PAUSE-Anweisung angehaltenen Programmes ist compilerabhängig, z. B.: • gfortran und g77: go RETURN • g95: RETURN • Intel Fortran Compiler 9.0: continue RETURN Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP WRITE (*,*) ’Hallo ’ PAUSE WRITE (*,*) ’Welt!’ END

145

Anhang

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

Ausgabe bei Compilierung mit gfortran: Hallo PAUSE To resume execution, type go.

Other input will terminate the job.

Ausgabe bei Compilierung mit g95: Hallo PAUSE statement executed.

Hit Return to continue

Ausgabe bei Compilierung mit ifort: Hallo FORTRAN PAUSE PAUSE prompt>

16.3. INCLUDE INCLUDE ermöglicht das Einbinden einer Datei. INCLUDE ist nicht explizit im FORTRAN 77-Standard angeführt, sondern wurde 1978 als Erweiterung des FORTRAN-Standards vom USamerikanischen DoD im MilStd 1753 festgelegt (siehe auch Abschnitt M IL S TD 17531 ). Beispiel: 1

146

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20FORTRAN% 2077%3A%20A N H A N G %23M I L S T D %201753%2C%20D O D%

.

8

Hollerith-Konstanten

Datei bsp.f: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INCLUDE ’inc.f’

C

WRITE(*,*) ’Fläche ist’, 10**2*PI, ’cm2’ Ausgabe: Fläche ist 314.1593 cm2 END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

Datei inc.f: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 REAL PI PARAMETER(PI=3.141593)

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

16.4. Hollerith-Konstanten Eine veraltete Möglichkeit Zeichenketten anzugeben stellen die Hollerith2 -Konstanten dar. Eine Hollerith-Konstante besteht aus 20S U P P L E M E N T %20T O %20A M E R I C A N %20N A T I O N A L %20S T A N D A R D % 20X3.9-{}1978 2

Herman Hollerith (* 1860, † 1929), Erfinder des HollerithLochkartenverfahrens, H ERMAN H OLLERITH ˆ{ H T T P :// D E . W I K I P E D I A . O R G / W I K I /H E R M A N %20H O L L E R I T H }

147

.

8

Anhang

1. Einer positiven Ganzzahl, welche die Zeichenkettenlänge angibt 2. Dem Buchstaben H 3. Der Zeichenkette Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP CHARACTER*5 C DATA C /5HUralt/

C

WRITE (*,*) C Ausgabe: Uralt END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

16.5. Arithmetisches IF Schon in grauer Vorzeit fanden Programmierer arithmetische IFAnweisungen sehr unterhaltsam, weil damit der Programmcode interessanter gestaltet werden konnte ( QUELLE : E D P OST - R EAL P ROGRAMMERS D ON ’ T U SE PASCAL3 ). Diese Aussage ist begreiflicherweise auch heute noch uneingeschränkt gültig. IF(ausdruck) ziel1, ziel2, ziel3 mit

3

148

H T T P :// W W W . E E . R Y E R S O N . C A /~{} E L F / H A C K / R E A L M E N . H T M L

.

8

ASSIGN und Assigned GOTO ausdruck <0 =0 >0

springe zu ziel1 ziel2 ziel3

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INTEGER I I = -55 IF(I) 100, 200, 300 GOTO 999 100 WRITE(*,*) "Negative Zahl" C Ausgabe: Negative Zahl GOTO 999 200

WRITE(*,*) "Null" GOTO 999

300

WRITE(*,*) "Positive Zahl"

999

CONTINUE END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

16.6. ASSIGN und Assigned GOTO Noch wesentlich amüsanter als bei der unachtsamen Verwendung des arithmetischen IF können die Ergebnisse durch Verwendung von Assign-Anweisungen ausfallen.

149

.

8

Anhang

ASSIGN weist eine Zielmarke einer INTEGER-Variablen zu: ASSIGN zielmarke TO variable

Verwendung finden kann dies neben anderem beim Assigned GOTO: GOTO variable (liste)

Beispiel: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 PROGRAM BSP INTEGER VAR C ... ASSIGN 200 TO VAR C ... C ... C ... GOTO VAR (100, 200, 300) 100

WRITE(*,*) "Negative Zahl" GOTO 999

200 WRITE(*,*) "Null" C Ausgabe: Null GOTO 999 300 999

WRITE(*,*) "Positive Zahl" CONTINUE END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

150

. |

1

.

2

.

3

.

4

.

5

.

6

.

7 |

.

8

MilStd 1753, DoD Supplement To American National Standard X3.9-1978

16.7. MilStd 1753, DoD Supplement To American National Standard X3.9-1978 Nachfolgend stichwortartig die vom amerikanischen Department of Defense im Jahr 1978 ergänzend zu FORTRAN 77 geforderten Spracheigenschaften4 • • • • • •

END DO (gelabelt, für DO-Schleifen) DO WHILE-Schleife INCLUDE IMPLICIT NONE Manipulation von Bitfeldern (IOR, IAND,ISHFT, ...) READ/WRITE-Verhalten nach EOF.



4

http://www.fortran.com/fortran/mil_std_1753.html

151

Teil IV.

Fortran 95

153

17. Programmaufbau 17.1. Beispiel: Hallo Welt Fortran 90/95-Code (free source form) program hallo ! Das typische "Hallo Welt"-Programm write( *, * ) ’Hallo Welt!’ end program hallo

Dieses Programm besteht aus den gleichen Anweisungen wie ein entsprechendes FORTRAN 77-Programm und wurde in der sogenannten "free source form" verfasst. Aus diesem Grund ist die erste Spalte nicht mehr dem Kommentarzeichen vorbehalten. Kommentare werden hier durch ein Rufzeichen eingeleitet. Alles rechts vom Rufzeichen wird als Kommentar behandelt. Ein Kommentar kann also auch nach einer Anweisung stehen. Im Gegensatz zu einem FORTRAN 77-Programm wird in Fortran 90/95 oft die Kleinschreibung bevorzugt. Dies ist aber nicht zwingend erforderlich, da die Fortran-Compiler case-insensitiv sind. D.h. sie unterscheiden nicht zwischen Groß- und Kleinschreibung. Eine Einrückung von Blöcken ist nicht zwingend erforderlich, fördert aber die Übersichtlichkeit des Programmcodes. Die Anweisung in der ersten Zeile kennzeichnet die Programmeinheit als Hauptprogramm und gibt ihr die Bezeichnung hallo. Es folgt eine Kommentarzeile. Dann folgt die Anweisung, einen

155

Programmaufbau

String auf die Standardausgabe zu schreiben. Und schließlich signalisiert die end-Anweisung das Programmende.

17.2. Das Zeilenformat Fortran 90/95 bietet baumöglichkeiten:

zwei

verschiedene

Programmauf-

• free source form • fixed source form Die "free source form" ist neu in Fortran 90/95. Sie bietet die Möglichkeit Programme ohne fixe Spaltenzuordnung zu schreiben, wie dies auch in den meisten anderen gebräuchlichen Programmiersprachen üblich ist. Zusätzlich ist in Fortran 90/95 aus Kompatibilitätsgründen auch das alte FORTRAN 77Zeilenformat (fixed source form) enthalten. Dieses sollte in neuen Programmen aber nicht mehr verwendet werden. Normalerweise gilt, dass jede Fortran-Anweisung in einer eigenen Zeile steht. Bei Verwendung der "free source form" gelten folgende Bedingungen. Eine Zeile darf maximal 132 Zeichen lang sein. Als Zeilenumbruchzeichen dient das Kaufmanns-Und (&). Das Kaufmanns-Und steht in diesem Fall immer am Ende der fortzuführenden Zeile, optional auch zusätzlich am Beginn der Fortsetzungszeile. Standardmäßig sind maximal 40 Fortsetzungszeilen erlaubt. Beispiel: Fortran 90/95-Code (free source form) program bsp ! Leerzeilen werden vom Compiler ignoriert ! Vereinbarungsteil implicit none ! implizite Datentypvereinbarung ausschalten integer :: a, b, c ! Variablendeklaration (Ganzzahlen) character(25) :: str ! Variablendeklaration (String mit einer

156

Das Zeilenformat

Länge von 25 Zeichen) ! Aktionsteil a = 5 b = 7 c = a + & ! und jetzt kommt eine Fortsetzungszeile b write( *, * ) c ! auch Strings oder Schlüsselwörter können auf der nächsten Zeile fortgesetzt werden. ! Dabei ist unbedingt darauf zu achten, dass die Fortsetzungszeile auch mit einem ! Kaufmanns-Und eingeleitet wird, da ansonsten einige Compiler Fehlermeldungen liefern str = "Hal& &lo Welt!" wr& &ite( *, * ) str ! Ausgabe: ! 12 ! Hallo Welt! end program bsp

Mehrere Anweisungen können in eine Zeile geschrieben werden, wenn eine Trennung durch jeweils ein Semikolon erfolgt.

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: a, b, c a = 5; b = 7; c = a + b write( *, * ) c ! Ausgabe: ! 12 end program bsp

157

Programmaufbau

17.3. Die Programmstruktur für das Hauptprogramm Ein Hauptprogramm weist in einfachster Darstellung immer folgende Struktur auf: 1. 2. 3. 4.

program Name Vereinbarungsteil Aktionsteil end [program [Name]]

Die in eckigen Klammern angegebenen Bestandteile sind optional. Sie sollten dennoch stets mit angegeben werden. Genau eine end-Anweisung (mit oder ohne optionale Bestandteile) ist obligatorisch. Bei Hauptprogramm und Unterprogrammen ist end eine ausführbare Anweisung. Ein Fortran-Programm darf genau ein Hauptprogramm enthalten, es ist der Startbereich für die Programmausführung.

17.4. Der Fortran-Zeichenvorrat Fortran 95-Programme bestehen standardmäßig aus folgenden Zeichen: • • • •

Großbuchstaben: A bis Z Kleinbuchstaben: a bis z Ziffern: 0 bis 9 Den 13 FORTRAN 77-Sonderzeichen: + - * / = ( ) : , . ’ $ und dem Leerzeichen • Unterstrich (Underscore): _ • Weitere Sonderzeichen: ! ? " & ; < >

158

Symbolische Namen

Ein Fortran 90/95-Compiler ist case-insensitiv: er unterscheidet nicht zwischen Groß- und Kleinbuchstaben. Stringkonstanten können natürlich alle ASCII-Zeichen beinhalten.

17.5. Symbolische Namen Standardmäßig dürfen symbolische Namen maximal 31 Zeichen lang sein. Das erste Zeichen muss immer ein Buchstabe sein. Anschließend sind alphanumerische Zeichen (Buchstabe oder Ziffer) und Unterstriche erlaubt. Im Gegensatz zu FORTRAN 77 dürfen nun keine Leerzeichen innerhalb eines symbolischen Namens auftreten.

17.6. Reservierte Schlüsselwörter? Im Fortran 95-Standard ist zwar die Rede von Schlüsselwörtern (statement keywords), wie z.B. if, do, real, write. Allerdings wird eindeutig darauf hingewiesen, dass diese nicht reserviert sind. Das heißt, solche Schlüsselwörter können auch für eigene Bezeichner verwendet werden. Beispiel: Folgender Programmcode ist in Fortran 90/95 gültig, aber nicht empfehlenswert Fortran 90/95-Code (free source form) program bsp implicit none integer :: integer, write, if integer = 6 write = 5 if = 1 write( *, * ) integer + write + if

159

Programmaufbau

end program bsp

17.7. Details zur Anordnungsreihenfolge von Anweisungen Fortran schreibt eine gewisse Anordnungsstruktur der einzelnen Programmelemente vor. So ist das folgende Programm Fortran 90/95-Code (free source form) program hallo write( *, * ) "Hallo Welt" implicit none end program hallo

nicht standardkonform, da die implicit none-Vereinbarung nicht nach einer ausführbaren Anweisung folgen darf. So müsste es richtig lauten Fortran 90/95-Code (free source form) program hallo implicit none write( *, * ) "Hallo Welt" end program hallo

Im Fortran 90/95-Standard ist genau festgelegt wann bestimmte Programmelemente auftreten dürfen. Prinzipiell gilt, dass Vereinbarungs-Anweisungen (nichtausführbare Anweisungen) vor Aktions-Anweisungen (ausführbaren Anweisungen) stehen. Doch es gibt Ausnahmen, z.B. darf die nichtexekutierbare format-Anweisung auch zwischen oder nach ausführbaren Anweisungen stehen. Eindeutig ist Folgendes geregelt. Die Programmeinheit beginnt mit dem charakteristischen Schlüsselwort, z.B. function. Werden Module eingebunden (use ...), so erfolgt dies

160

Details zur Anordnungsreihenfolge von Anweisungen

vor jeder anderen Vereinbarung oder ausführbaren Anweisung. Danach folgt ein "Mischbereich" (im Fortran-Standard wird das natürlich nicht "Mischbereich" genannt). Vor dem end-Statement darf ein contains-Abschnitt mit Unterprogrammen stehen. Fortran 90/95-Code (free source form) program (, function, subroutine, ...) ... use ... ! Hier folgt nun der so genannte "Mischbereich" contains interne Unterprogramme oder Modul-Unterprogramme end ...

Im "Mischbereich" ist die Anordnung einzelner Elemente zwar auch im Standard geregelt, jedoch gibt es Elemente die an jeder Stelle des Mischbereichs auftreten dürfen, bei anderen ist wiederum klar festgelegt , dass sie nur nach oder vor anderen Elementen auftreten dürfen. Hier soll deshalb nur eine vereinfachte Variante gezeigt werden. Für genauere Informationen wird auf den Fortran-Working-Draft verwiesen. Fortran 90/95-Code (free source form) program (, function, subroutine, ...) ... use ... ! --------- Beginn "Mischbereich" (mögliche Anordnungsreihenfolge) --------implicit ... ! Definiton von Datenverbunden, Interface-Blöcke, benannte Konstanten, Variablendeklarationen ! ausführbare Anweisungen ... format ... ! --------- Ende "Mischbereich" -------------------------------------------contains

161

Programmaufbau

Interne Unterprogramme bzw. Modul-Unterprogramme end ...

Nicht jede Anweisung ist in jeder Programmeinheit erlaubt. So dürfen z.B. keine format-Anweisungen im Hauptteil eines Moduls (wohl aber in Modul-Unterprogrammen) verwendet werden.

162

18. Datentypen, Variablen, Wertzuweisungen, Konstanten Dieses Kapitel handelt von Datentypen, Variablen, Konstanten und der Wertzuweisung.

18.1. Datentypen 18.1.1. Arithmetische Datentypen Datentyp

Kommentar

integer

Ganzzahlen

real

Gleitkommazahlen einfacher Genauigkeit Gleitkommazahlen doppelter Genauigkeit (aus FORTRAN 77)

(double

precision)

Beispiele (Konstanten) 15, -6500, 200000000 3.1415, -5.5, .7e3, 12.5E-5 3.1415D0, -5.5D0, .7d3, 12.5D-5

163

Datentypen, Variablen, Wertzuweisungen, Konstanten Datentyp

Kommentar

complex

Komplexe Zahlen (zwei realZahlen)

Beispiele (Konstanten) (3.1415, -5.5), (1.4, 7.1E4)

double precision ist in Fortran 95 nur noch aus historischen Gründen (FORTRAN 77) vorhanden. Fortran 95 bietet für Datentypen höherer Genauigkeit bzw. mit größerem Zahlenbereich andere Sprachmittel. Diese Thematik wird später erläutert (D ATENTYPEN HÖHERER G ENAUIGKEIT1 ). Binär-, Oktal- oder Hexadezimalzahlen können als "boz literal constants" angegeben werden: Schreibweise 1 B"zahl" O"zahl" Z"zahl"

Schreibweise 2 B’zahl’ O’zahl’ Z’zahl’

Kommentar Binäre Zahl Oktalzahl Hexadezimalzahl

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: a a = Z"AB1C" write(*,*) a ! Ausgabe: 43804 a = O"7134" write(*,*) a ! Ausgabe: 3676 a = B’101110110001’

1

164

Kapitel 25 auf Seite 217

Datentypen

write(*,*) a ! Ausgabe: 2993 end program bsp

18.1.2. Logischer Datentyp Datentyp logical

Kommentar Logischer Datentyp (wahr oder falsch)

Mögliche Werte .TRUE., .FALSE.

18.1.3. Zeichenketten Datentyp

Kommentar

character(n)

Zeichenkette (String) mit einer Länge von n Zeichen -"-"- (FORTRAN 77Stil, sollte nicht mehr verwendet werden) Zeichenkette (String) mit einer Länge von einem Zeichen

character(len=n) character*n

character

Beispiel (Konstante) ’Hallo, Welt!’, "Hallo, Welt!"

’H’, "h"

Beachte: Zeichenketten können in Fortran 95 in Apostrophe oder Anführungszeichen eingeschlossen werden.

165

Datentypen, Variablen, Wertzuweisungen, Konstanten

Beispiel: "Wie geht’s?"

’Er sagte: "Hallo"’

18.2. Variablen Eine Variable ist charakterisiert durch einen • • • •

symbolischen Namen Datentyp Wert Speicherplatz

Beim Programmstart hat eine Variable keinen definierten Wert. Eine Variable kann ihren Datentyp auf zwei Arten erhalten, durch implizite oder explizite Typanweisung.

18.2.1. Implizite Typanweisung Bei der impliziten Typanweisung bestimmt der Anfangsbuchstabe des Variablenbezeichners den Datentyp. Datentyp integer real

Anfangsbuchstabe der Variablen Buchstaben I bis N (oder i bis n) restliche Buchstaben

Beispiel: Fortran 90/95-Code (free source form)

166

Variablen

program bsp b1 = 8.9 c1 = 3. i1 = B1/C1 write (*,*) i1 ! Das Ergebnis ist 2, da i1 implizit als integer definiert ist end program bsp

Die Standardzuordnung der Anfangsbuchstaben kann durch das Schlüsselwort implicit auch geändert werden. Infolge der durch implizite Typanweisung entstehenden Fehlermöglichkeiten ist es sinnvoll, die implizite Typanweisung komplett auszuschalten. Dies wird durch die Anweisung implicit none

gleich nach der program-Anweisung erreicht. Dann muss der Datentyp jeder Variablen explizit festgelegt werden.

18.2.2. Explizite Typanweisung Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none real :: b real :: c real :: i ! alternativ auch als real :: b, c, i b = 8.9 c = 3. i = b/c write (*,*) i ! Das Ergebnis ist 2.966666

167

Datentypen, Variablen, Wertzuweisungen, Konstanten

end program bsp

18.3. Benannte Konstanten Benannte Konstanten werden in Fortran 95 folgendermaßen festgelegt: datentyp, parameter :: symname = wert

Beispiele: real, parameter:: PI = 3.1415, PIFAC = PI/2.0

character(5), parameter :: str = ’Hallo’

Der zugewiesene Wert kann eine Konstante (Literal) oder eine schon definierte benannte Konstante sein. Für die Zeichenkettenlänge ist bei benannten Konstanten auch eine *-Schreibweise möglich. Dies erspart die explizite Angabe der Stringlänge. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none character(*), parameter :: a = ’Jetzt wird auch die Stringlaenge festgelegt’ write(*,*) a ! Ausgabe: Jetzt wird auch die Stringlaenge festgelegt end program bsp

168

Wertzuweisung

18.4. Wertzuweisung Wertzuweisungen haben wir schon kennengelernt: variable = ausdruck Beispiel: k = 1 k = k + 2

Die Wertzuweisung an eine Variable ist, wie am vorigen und auch am nächsten Beispiel zu ersehen, nicht zu verwechseln mit einer mathematischen Gleichung. Der Ausdruck k + 2 = 5

wäre zwar mathematisch korrekt. Als Wertzuweisung in einem Fortran-Programm ist dies aber keine mögliche Formulierung. k+2 ist kein zulässiger Ausdruck auf der linken Seite des Zuweisungsoperators (L-Wert). In Fortran ist auch keine Kette von Wertzuweisungen möglich. Der folgende Ausdruck ist nicht erlaubt und liefert eine Fehlermeldung. i = j = k = 1.5 ! Fehler

169

19. Felder

19.1. Beispiel

Fortran 90/95-Code (free source form) program bsp implicit none real, dimension(10) :: arr ! ACHTUNG! Array startet mit dem Index 1 ! arr(0) waere ein Fehler! arr(1) = 1.5 arr(2) = 2.5 arr(10) = 10.5 write(*,*) arr(1) ! 1.500000 wird ausgegeben write(*,*) arr(10) ! 10.500000 wird ausgegeben end program bsp

171

Felder

19.2. Eindimensionale Felder 19.2.1. Statische Speicherallokation Variante 1: Die dimension-Anweisung real, dimension(10) :: arr

Der Feldindex läuft von 1 bis 10.

Variante 2: Einfach real :: var(10)

Variante 3: Verwendung von benannten Konstanten integer, parameter :: MAXIND = 10 real, dimension(MAXIND) :: arr

Hier erfolgt die Festlegung der Feldgröße über eine benannte Konstante.

Variante 4: Explizite Angabe der Feldgrenzen real, dimension(0:9) :: arr

Hier wird Unter- und Obergrenze explizit angegeben. Der Index läuft nun von 0 bis 9. Die Feldgrenzen können auch negativ sein.

172

Eindimensionale Felder

19.2.2. Dynamische Speicherallokation Mit Fortran 90/95 kann der benötigte Speicherplatz für ein Feld dynamisch angefordert werden. Zu diesem Zweck gibt es das Schlüsselwort allocatable, welches unmittelbar bei der Felddeklaration die beabsichtigte dynamische Speicherallokation signalisiert. datentyp, dimension(:), allocatable :: variablenbezeichner

Die intrinsische Funktion allocate dient dann der konkreten Speicherallokation im Aktionsteil des Programmes, also u.a. der Festlegung der konkreten Feldgröße. Der reservierte Speicherplatz kann mit der Funktion deallocate auch wieder freigegeben werden. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none real, dimension(:), allocatable :: arr eindimensionales Feld

! dynamisches

integer :: status ! Allokation allocate(arr(0:9), stat=status) ! Feld mit Werten belegen, ! .... ! .... ! Deallokation deallocate(arr, stat=status) end program bsp

Die Statusvariable sollte nach Ausführung der Allokationsfunktionen jeweils den Wert 0 aufweisen. Andere Werte stehen für eine Fehlermeldung.

173

Felder

Die Funktion allocated() hilft bei der Überprüfung des Allokationsstatus eines Feldes. Ist für das abgefragte Feld bereits Speicherplatz allokiert, dann liefert die Funktion .TRUE., ansonsten .FALSE. ! ... if (.not. allocated(arr)) then allocate(arr(groesse), stat=s) end if ! ...

Weitere Funktionen bezüglich Felder sind im Kapitel S TANDARD FUNKTIONEN 1 aufgelistet.

19.3. Mehrdimensionale Felder

Für mehrdimensionale Felder gelten die gleichen Varianten wie für eindimensionale Felder. Die Speicherreihenfolge ist spaltenorientiert. Das bedeutet, der erste Index variiert am schnellsten: a 11 , a 21 , . . . , a (n−1)m , a nm

1

174

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95% 3A_S T A N D A R D F U N K T I O N E N %23F E L D F U N K T I O N E N

Mehrdimensionale Felder

Abb. 20

Ein mehrdimensionales Feld kann auch in Fortran 90/95 maximal 7-dimensional gestaltet werden.

19.3.1. Beispiel: Ein 2-dimensionales Feld Fortran 90/95-Code (free source form) program bsp implicit none character(10), dimension(0:9, 2:5) :: arr arr(0, 2) = ’Hallo’ arr(1, 2) = ’Welt’ ! ... arr(9, 5) = ’Universum’ write (*,*) arr(0, 2) ! Ausgabe: Hallo write (*,*) arr(9, 5)

175

Felder

! Ausgabe: Universum end program bsp

19.3.2. Beispiel: Spaltenorientierte Speicherreihenfolge  1 −5 0 Die 3x3-Matrix A =  40 3 −2 soll in ein Fortran-Programm −1 9 65 eingelesen und wieder komplett ausgegeben werden. Zusätzlich soll auch der Wert des Feldelementes a23 (2. Zeile, 3.Spalte, Wert=2) separat ausgegeben werden. 

Fortran 90/95-Code (free source form) program bsp implicit none integer, dimension(3,3) :: arr(3,3) ! Feldelemente einlesen write (*,*) ’Werte (spaltenorientierte Eingabe):’ read (*,*) arr ! Komplettes Feld ausgeben write (*,*) ’Gesamtfeld = ’ , arr ! a23 ausgeben write (*,*) ’a23 = ’, ARR(2,3) end program bsp

Ein-/Ausgabe: Werte (spaltenorientierte Eingabe): 1 40 -1 -5 3 9 0 -2

176

Feldinitialisierung

65 Gesamtfeld = 3

1 9

-2 a23 =

40

-1

-5

0 65 -2

19.4. Feldinitialisierung Felder lassen sich auch gleich bei der Deklaration mit Werten initialisieren.

19.4.1. Array constructor Bei eindimensionalen Feldern kann die Feldinitialisierung direkt mittels array constructor erfolgen. Beispiel: real, dimension(5) :: arr = (/1.1, 1.2, 1.3, 2.1, 2.4/)

19.4.2. Reshape Für mehrdimensionale Felder besteht die Möglichkeit der direkten Verwendung des array constructors nicht. Stattdessen kann eine derartige Initialisierung über den Umweg der reshapeFunktion geschehen. Beispiel: Die Matrix

177

Felder

1 2 3 1 2 3

soll in einem 2D-Feld gespeichert werden. integer, dimension(2,3) :: arr = reshape( (/1, 1, 2, 2, 3, 3/), (/2, 3/) )

19.5. Teilfelder Ähnlich wie das schon in FORTRAN 77 bei Zeichenketten möglich war, können nun auch Teilfelder direkt angesprochen werden. Prinzip feldname (anfang:ende) feldname (:ende) feldname (anfang:)

Beschreibung von anfang bis ende vom 1. Feldelement bis ende von anfang bis zum letzten Feldelement

• anfang >= untere Indexgrenze • ende <= obere Indexgrenze

Beispiel: Eindimensionale Felder Fortran 90/95-Code (free source form) program bsp implicit none character(2), dimension(5) :: arr = (/’A1’, ’A2’, ’A3’, ’A4’, ’A5’/) integer, dimension(-3:1) :: i = (/-30, -20, -10, 0, 10/)

178

Teilfelder

write (*,*) arr(2:4) ! Ausgabe: A2A3A4 write (*,*) arr(2:) ! Ausgabe: A2A3A4A5 write (*,*) arr(:3) ! Ausgabe: A1A2A3 write (*,*) arr(1) ! Ausgabe: A1 write (*,*) arr ! Ausgabe: A1A2A3A4A5 write (*,*) i(-2:0) ! Ausgabe: -20 -10 end program bsp

0

179

20. Arithmetische Ausdrücke 20.1. Arithmetische Operatoren Fortran 95 kennt wie FORTRAN 77 folgende arithmetische Operatoren Operator + * / **

Kommentar Addition Subtraktion Multiplikation Division Exponentiation

20.1.1. Operatorenpriorität Die Prioriät der arithmetischen Operatoren entspricht den mathematischen Konventionen. • Klammerung vor allem anderen, z.B. (a+b)*c ⇔ a*c+b*c • Exponentiation vor Punktrechnung, z.B. a*b**c ⇔ a*(b**c) • Punktrechnung vor Strichrechnung, z.B. a+b*c ⇔ a+(b*c)

20.1.2. Berechnungsfolge bei gleicher Priorität • Klammerung, Punktrechnung und Strichrechnung: → Beispiel: a*b/c*d⇔((a*b)/c)*d

181

Arithmetische Ausdrücke

• Exponentiation: ← Beispiel: a**b**c⇔ a**(b**c) Außerdem ist zu beachten, dass niemals zwei Operatoren direkt aufeinander folgen dürfen. Beispiel: Der Ausdruck 1.5**-1 ist in Fortran 95 falsch und führt zu einer Fehlermeldung. Richtig ist 1.5**(-1)

20.2. Ergebnisdatentyp

20.2.1. Operanden gleichen Datentyps

Bei Operanden gleichen Datentyps erhält das Ergebnis den Datentyp der Operanden. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none real :: a a = 3/2 ! 3 ist ein integer und 2 ist auch ein integer, ! daher muss das Ergebnis auch ein integer sein, also 1. ! Die Zuweisung an die real-Variable a stellt das ! Ergebnis nicht mehr richtig. write(*,*) a ! Ausgabe: 1.00000 end program bsp

182

Ergebnisdatentyp

20.2.2. Implizite Typumwandlung bei Operanden gemischten Datentyps Weisen die Operanden unterschiedliche Datentypen auf, so wird bei jeder Operation, falls nötig, das Ergebnis dem höherwertigen Datentyp angepasst. integer→ real→ complex Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none real :: a a = 3/2. ! 2. ist ein real. Jetzt stimmt das Ergebnis. write (*,*) a ! Ausgabe: 1.500000 end program bsp

20.2.3. Explizite Typumwandlung Fortran 95 besitzt auch Funktionen zur expliziten Umwandlung des Datentyps. Diese werden im Kapitel S TANDARDFUNKTIONEN1 näher beschrieben. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none real :: r

1

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95% 3A%20S T A N D A R D F U N K T I O N E N %20

183

Arithmetische Ausdrücke

complex :: c r = 2. c = cmplx(r) write (*,*) c ! Ausgabe: ( 2.000000 , 0.000000 ) end program bsp

184

21. Logische Ausdrücke Logische Ausdrücke können zwei Zustände annehmen, .TRUE. oder .FALSE..

21.1. Logische Operatoren Operator .NOT. .AND. .OR. .EQV. .NEQV.

Kommentar logisches NICHT logisches UND logisches ODER logische Äquivalenz logische Antivalenz

21.2. Wahrheitstafel a

b

.TRUE.

.NOT. a

a .AND. b .FALSE. .TRUE.

a .OR. b .TRUE.

a .EQV. b .TRUE.

a .NEQV. b .FALSE.

.TRUE. .TRUE. .FALSE. .FALSE. .FALSE. .TRUE. .FALSE. .TRUE. .FALSE. .TRUE. .TRUE. .FALSE. .TRUE. .FALSE. .TRUE. .FALSE. .FALSE. .TRUE. .FALSE. .FALSE. .TRUE. .FALSE.

185

Logische Ausdrücke

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none logical :: l l = .TRUE. write(*,*) .NOT. l ! Ausgabe: F end program bsp

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none logical :: a, b a = .TRUE. b = .FALSE. write (*,*) a .NEQV. b ! Ausgabe: T end program bsp

21.3. Operatorenpriorität 1. 2. 3. 4. 5.

186

Klammerung () bindet am stärksten

.NOT. .AND. .OR. .EQV., bzw. .NEQV.

22. Vergleichsausdrücke 22.1. Vergleichsoperatoren Zum Vergleichen zweier arithmetischer Ausdrücke oder von Strings gibt es Vergleichsoperatoren. Das Ergebnis eines Vergleichs ist ein logischer Wert (.TRUE. oder .FALSE.). Operator in Fortran 95 <

Operator in FORTRAN 77 .LT.

<=

.LE.

>

.GT.

>=

.GE.

== /=

.EQ. .NE.

Kommentar less than (kleiner als, <) less equal (kleiner gleich, <=) greater than (größer als, >) greater equal (größer gleich, >=) equal (gleich, ==) not equal (ungleich, !=)

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: a, b

187

Vergleichsausdrücke

a = 5 b = 6 write (*,*) A < B ! Ausgabe: T end program bsp

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none character(len=5) :: a, b a = "Halli" b = "Hallo" write (*,*) a < b ! Ausgabe: T end program bsp

22.2. Operatorenpriorität 1. 2. 3. 4.

188

Klammerung Arithmetische Operatoren Vergleichsoperatoren Logische Operatoren

23. Stringoperationen 23.1. Verknüpfungsoperator Operator //

Kommentar Operator zum Verknüpfen von Strings

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none character(len=4) :: a character(len=10) :: b a = ’How ’ b = ’do you do.’ write(*,*) a // b ! Ausgabe: How do you do. end program bsp

23.2. Teilketten Ein String ist ein character-Feld. Auf die Stringelemente kann wie in einem Feld zugegriffen werden.

189

Stringoperationen

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none character(10) :: a a=’Hallo Welt’ write(*,*) a(2:4) ! Ausgabe: all write(*,*) A(5:) ! Ausgabe: o Welt write (*,*) A(:3) ! Ausgabe: Hal end program bsp

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none character(10) :: a a=’Hallo Welt’ a(7:) = ’XYZ’ write(*,*) a ! Ausgabe: Hallo XYZ end program bsp

190

24. Verzweigungen und Schleifen

24.1. Einleitung

Neben der sequentiellen Programmausführung bietet Fortran 90/95 andere grundlegende Kontrollstrukturen zur Steuerung des Programmablaufs.

do

stop exit cycle

191

Verzweigungen und Schleifen

Zwecks komfortabler Manipulation von Feldinhalten stehen zusätzliche Spezialkonstrukte zur Verfügung:

All diese Programmelemente werden in diesem Kapitel detailliert dargestellt. Neben den genannten Steuerkonstrukten sind in Fortran 90/95 auch noch das berüchtigte goto und einige als veraltet gekennzeichnete Sprunganweisungen möglich. Fortran 90 und Fortran 95 unterscheiden sich in Details bei Schleifen und

192

if-Verzweigungen

Verzweigungen. Da Fortran 90 durch Fortran 95 bzw. beide durch den Fortran 2003-Standard abgelöst wurden, wird auf die Unterschiede nicht näher eingegangen.

24.2. if-Verzweigungen 24.2.1. Der if-Einzeiler Form

Strukturbild

if( logischer ausdruck ) anweisung

Abb. 24

Der if-Einzeiler oder das "if statement" ist die einfachste Form, um in Fortran-Programmen eine Verzweigung zu realisieren. Ist der angegebene logische Ausdruck wahr, dann wird die Anweisung ausgeführt, sonst nach dem if-Einzeiler mit der Programmausführung fortgesetzt. Dieses Konstrukt kann nur eine einzelne Anweisung verdauen! Die gesamte if-Struktur inklusive Anweisung muss in einer Zeile angegeben werden. Eine konventionelle Zeilenfortsetzung mit dem &-Zeichen ist aber möglich. Einige Anweisungen sind nicht erlaubt. So kann die Anweisung nicht wieder ein "if statement" sein (geschachtelte if-Einzeiler). Ebenso darf der

193

Verzweigungen und Schleifen

Anweisungsteil nicht aus end program, end function oder end subroutine bestehen. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: i i = 2 ! Der logische Ausdruck ist .true. , "Hallo" wird ausgegeben if( i == 2 ) write( *, * ) ’Hallo’ ! Das funktioniert nicht und ist deshalb auskommentiert ! if( i == 2 ) ! write( *, * ) ’Hallo’ ! So geht’s aber if( i == 2 ) & write( *, * ) ’Hallo’ ! Folgendes wiederum wird nicht das ev. erhoffte Resultat zeigen (= keine ! Ausgabe, da der logische Ausdruck .false.) Die durch Strichpunkt ! abgetrennte write-Anweisung gehört nicht mehr zum "if statement", ! sondern ist schon eine eigenständige Anweisung ausserhalb des ! if-statements if( i == 3 ) write( *, * ) ’Hallo 1’; write( *, * ) ’Hallo 2’ ! Ausgabe: ! Hallo ! Hallo ! Hallo 2 end program bsp

24.2.2. if-then

194

if-Verzweigungen Kurzform

if( logischer ausdruck ) then anweisungsblock end if

Langform name: if( logischer ausdruck ) then anweisungsblock end if name

Strukturbild

Abb. 25

Das if-then-Konstrukt erlaubt eine konventionelle einseitige Verzweigung. Im Gegensatz zum if-Einzeiler ist hier ein Anweisungsblock mit beliebig vielen Anweisungen erlaubt. Einem if-then-Konstrukt, wie auch den meisten nachfolgenden Verzweigungs- und Schleifentypen, kann eine Bezeichnung mitgegeben werden. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: i i = 2 if( i == 2 ) then write( *, * ) ’Hallo1’ end if checkit: if( i /= 3 ) then write( *, * ) ’Hallo2’ end if checkit ! Ausgabe: ! Hallo 1 ! Hallo 2 end program bsp

195

Verzweigungen und Schleifen

24.2.3. if-then-else Kurzform

if( logischer ausdruck ) then ifanweisungsblock else elseanweisungsblock end if

Langform name: if( logischer ausdruck ) then ifanweisungsblock else name elseanweisungsblock end if name

Strukturbild

Abb. 26

Dies ist eine typische zweiseitige Verzweigung. Je nachdem, ob die Bedingung zu wahr oder falsch ausgewertet wird, wird der if- oder der else-Anweisungsblock ausgeführt, um nach dem Verzweigungsende wieder den gleichen Programmcode abzuarbeiten. Bei der Langform (benanntes if-then-else-Konstrukt) ist übrigens auch noch eine andere Variante möglich. So könnte der Bezeichner name nach else auch weggelassen werden. Nach dem end if ist er, sofern die benannte Form gewählt wurde, aber auf jeden Fall anzugeben. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none real :: t, tc, tr character :: conv write( *, * ) "Gib Temperatur in Kelvin ein:" read( *, * ) t checkrange: if( t >= 0.0 ) then write( *, * ) "Umrechnung (c -> in Celsius, anderes Zeichen -> in Rankine):" read( *, * ) conv

196

if-Verzweigungen

if( conv == "c") then tc = t - 273.15 write( *, * ) tc else tr = 1.8 * t write( *, * ) tr end if else checkrange write( *, * ) "Fehler: t < 0.0 K" end if checkrange end program bsp

24.2.4. else-if Kurzform

if (logischer ausdruck 1) then if-anweisungsblock 1 else if (logischerAusdruck 2) then if-anweisungsblock 2 else if (logischerAusdruck n) then if-anweisungsblock n else else-anweisungsblock end if

Langform name: if (logischer ausdruck 1) then if-anweisungsblock 1 else if (logischerAusdruck 2) then name if-anweisungsblock 2 else if (logischerAusdruck n) then name ifanweisungsblock n else name else-anweisungsblock end if name

197

Verzweigungen und Schleifen Kurzform Strukturbild

Langform

Abb. 27

Das ist die allgemeinste Form der if-Verzweigung und wird im Fortran-Standard als "if construct" bezeichnet. Die vorher beschriebenen Formen sind nur vereinfachte Spezialfälle dieses Verzweigungstyps. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: i write( *, * ) "Gib eine natuerliche Zahl ein:" read( *, * ) i ! *** Langform ***

198

Die select case-Verzweigung

i999: if( i == 1 ) then write( *, * ) "A" else if( i > 1 .and. i <= 5 ) then i999 write( *, * ) "BCDE" else if( i > 5 .and. i <= 11 ) then i999 write( *, * ) "FGHIJK" else i999 write( *, * ) "L-Z" end if i999 ! *** Das Gleiche in Kurzform *** if( i == 1 ) then write( *, * ) "A" else if( i > 1 .and. i <= 5 ) then write( *, * ) "BCDE" else if( i > 5 .and. i <= 11 ) then write( *, * ) "FGHIJK" else write( *, * ) "L-Z" end if end program bsp

24.3. Die select case-Verzweigung

199

Verzweigungen und Schleifen Kurzform

select case( variable ) case( fall1 ) anweisungsblock1 ! ... case( falln ) anweisungsblockn [case default anweisungsblockdefault] end select

Langform name: select case( variable ) case( fall1 ) name anweisungsblock1 ! ... case( falln ) name anweisungsblockn [case default name anweisungsblockdefault] end select name

Strukturbild

Abb. 28

Eine andere Möglichkeit zur Erstellung von Verzweigungen stellt die "select case"-Steueranweisung (das "case construct") bereit. Die variable kann vom Typ integer, logical oder character sein. Die Fälle werden durch Konstanten repräsentiert. Es muss nicht jeder Fall einzeln angeschrieben werden. Fälle, die zwar die gleichen Aktionen ausführen sollen, aber durch verschiedene Konstanten dargestellt werden, können zu einem Fall zusammengezogen werden. Optional kann auch noch ein "Default"-Fall angegeben werden. Möglichkeiten um Fälle festzulegen: n n1, n2, n3 n:

200

Einzelne Konstante Fallliste Bereich

gleich n n1 oder n2 oder n3 von n bis ...

Die select case-Verzweigung

:m n:m

Bereich Bereich

von ... bis m von n bis m

Die in der Tabelle gelisteten Alternativen können natürlich auch kombiniert werden, z.B. eine Liste aus Einzelkonstanten und Bereichen. Bei logischem Datentyp ist die Angabe von Bereichen natürlich unsinnig.

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: i read( *, * ) i select case( i ) case( :111 ) write( *, * ) ’Fall 1’ case( 112:332, 334 ) write( *, * ) ’Fall 2’ case( 333 ) write( *, * ) ’Fall 3’ case default write( *, * ) ’unspezifiziertes Ereignis’ end select ! Ausgabe (Eingabe: 222): ! Fall 2 ! Ausgabe (Eingabe: -5): ! Fall 1 ! Ausgabe (Eingabe: 333): ! Fall 3 ! Ausgabe (Eingabe: 5000): ! unspezifiziertes Ereignis end program bsp

201

Verzweigungen und Schleifen

24.4. do-Schleifen Fortran kennt nur einen allgemeinen Schleifentyp − die doSchleife. Diese do-Schleife gibt es aber in verschiedenen Ausprägungen, so dass damit ziemlich alle denkbaren Einsatzfälle abgedeckt sind. Im Prinzip haben alle do-Schleifen die Form do [...] ... end do

24.4.1. do-if-exit Kurzform

do anweisungsblock1 if( logischer ausdruck ) exit anweisungsblock2 end do

Langform name: do anweisungsblock1 if( logischer ausdruck ) exit anweisungsblock2 end do name

Strukturbild

Abb. 29

Lässt man den anweisungsblock1 weg, dann erhält man eine kopfgesteuerte Schleife. Entfällt der anweisungsblock2, so ist die Schleife fußgesteuert. Ohne Abbruchbedingung ist dies eine Endlosschleife.

202

do-Schleifen

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: i = 1 do write( *, * ) i i = i + 1 if( i > 10 ) exit end do write( * , * ) "Die do-Schleife wurde beendet" ! Ausgabe ! 1 ! 2 ! ... ! 10 ! Die do-Schleife wurde beendet end program bsp

24.4.2. Die do-Zählschleife Kurzform

do zählvariable = startwert, endwert [, schrittweite] anweisungsblock end do

Langform name: do zählvariable = startwert, endwert [, schrittweite] anweisungsblock end do name

203

Verzweigungen und Schleifen Kurzform Strukturbild

Abb. 30

204

Langform

do-Schleifen

Zählvariable, Startwert, Endwert und Schrittweite müssen vom Typ integer sein. Die Zählvariable darf in der Schleife nicht manipuliert werden. Wird die Schrittweite nicht explizit vorgegeben, so hat sie den Wert 1. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: i do i = 1, 10 write( *, * ) i end do ! Zeilenweise Ausgabe der Zahlen 1 bis 10 end program bsp

24.4.3. do while Kurzform

do while( logischer ausdruck ) anweisungsblock end do

Langform name: do while( logischer ausdruck ) anweisungsblock end do name

Strukturbild

Abb. 31 Beispiel: Fortran 90/95-Code (free source form)

205

Verzweigungen und Schleifen

program bsp implicit none integer :: i i = 0 do while( i < 5 ) write( *, * ) i i = i + 1 end do ! Die Zahlen 0 bis 4 werden ausgegeben end program bsp

24.4.4. Die implizite do-Liste Bei Eingabe oder Ausgabe ist die Angabe einer impliziten do-Liste möglich. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: i write( *, * ) ( ’Hallo’, i = 1, 10 ) ! Ausgabe: HalloHalloHalloHalloHalloHalloHalloHalloHalloHallo end program bsp

24.5. Spezialkonstrukte für Felder 24.5.1. where Sollen in Feldern Elemente manipuliert werden, so können die where-Anweisungen (das "masked array assignment") hilfre-

206

Spezialkonstrukte für Felder

ich sein. Dabei lassen sich Feldelementen in Abhängigkeit von vorgegebenen Bedingungen (Maske) neue Werte zuweisen.

Der where-Einzeiler Form where( bedingung ) variable = ausdruck

Das "where statement" muss komplett in eine Zeile geschrieben werden, wobei Zeilenumbrüche mit dem &Zeilenumbruchsmarker jedoch erlaubt sind. Für komplexere Probleme ist das im nächsten Abschnitt vorgestellte "where construct" (where-elsewhere) vorgesehen. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer, dimension(5) :: arr = (/ 5, 1, -1, 1, 7 /) write( *, * ) arr ! Ausgabe: 5 1 -1 1 7 where( arr >= 3 ) arr = 99999 write(*,*) arr ! Ausgabe: 99999 1 -1 1 99999 end program bsp

where-elsewhere

207

Verzweigungen und Schleifen Kurzform

Langform name: where( bedingung1 ) anweisungsblock [elsewhere( bedingung2 ) name anweisungsblock2] [elsewhere( bedingungn ) name anweisungsblockn] [elsewhere name anweisungsblockm] end where name

where( bedingung1 ) anweisungsblock [elsewhere( bedingung2 ) anweisungsblock2] [elsewhere( bedingungn ) anweisungsblockn] [elsewhere anweisungsblockm] end where

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer, dimension(10) :: arr = /)

(/ 5, 1, -1, 1, 7, -3, 7, 6, -9, 8

where( arr <= 0 ) arr = 0 elsewhere( arr > 0 .and. arr <= 3 ) arr = 1 elsewhere arr = 2 end where write(*,*) arr ! Ausgabe: 2 1 0 end program bsp

1

2

0

2

2

0

2

24.5.2. forall Auch die forall-Schleife ist für den Einsatz bei Feldern gedacht. Im Gegensatz zum "where construct" werden hier die aus-

208

Spezialkonstrukte für Felder

gewählten Feldelemente in erster Linie über die Indizes und erst in zweiter Linie über den Wert bestimmt.

Der forall-Einzeiler Formen forall( index = subscript:subscript[:stride] ) anweisung forall( ind1 = subs1a:subs1b[:str1], ind2 = subs2a:subs2b[:str2] [, indn = subsna:subsnb[:strn]] ) anweisung

Die erste angegebene Form ist für eindimensionale Felder gedacht, die zweite für mehrdimensionale Felder. Über subscript kann der Indexbereich festgelegt werden. Das optionale stride gibt die Schrittweite vor. Wird dieser Wert nicht angegeben, so ist die Schrittweite = 1. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer, dimension(5) :: a = (/ 1, 2, 3, 4, 5 /) integer, dimension(2, 2) :: b = reshape( (/ 0, 2, -1, 5 /), (/ 2, 2 /) )

!

!

!

!

integer forall( i = write( *, * Ausgabe: 0 forall( i = write( *, * Ausgabe: -1 forall( i = write( *, * Ausgabe: 3 forall( i = write( *, * Ausgabe: 0

:: i, j 1:3 ) a(i) = 0 ) a 0 0 4 5 1:5:2 ) a(i) = -1 ) a 0 -1 4 -1 1:5 ) a(i) = max ( a(i), 3 ) ) a 3 3 4 3 1:2, j = 2:2 ) b(i, j) = -9 ) b 2 -9 -9

209

Verzweigungen und Schleifen

end program bsp

Aber das ist nicht alles, was der forall-Einzeiler zustande bringt. Zusätzlich zur Feldelementbestimmung über Indexbereiche kann auch eine Maske vorgegeben werden. Die forall-Schleife ist also auch eine erweiterte where-Anweisung. Form forall( ind1 = s1a:s1b[:s1] [, indn = sna:snb[:sn] [, maske] ) anweisung Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer, dimension(5)

:: a = (/ 1, 2, 3, 4, 5 /)

integer :: i, j forall( i = 1:4, a(i) > 2 ) a(i) = 0 write( *, * ) a ! Ausgabe: 1 2 0 0 5 end program bsp

Bei der Verwendung von forall-Anweisungen sind einige Prämissen zu beachten. So müssen nebst anderem in Masken oder im Anweisungsbereich verwendete Funktionen pure sein. Was das genau bedeutet wird später im Kapitel U NTERPROGRAMME1 erläutert Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer, dimension(5)

1

210

:: a = (/ 1, 2, 3, 4, 5 /)

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20U N T E R P R O G R A M M E %23D I E %20 P U R E %20A N W E I S U N G

Spezialkonstrukte für Felder

integer :: i ! Die Funktion berechne_1() darf nicht innerhalb einer forall-Anweisung ! aufgerufen werden, da sie nicht "pure" ist ! forall( i = 1:4, a(i) > 2 ) a(i) = berechne_1( a(i) ) ! FEHLERMELDUNG ! Die Funktion berechne_2 macht das Gleiche wie berechne_1(), ! ist aber als "pure" gekennzeichnet und darf in der forall-Anweisung ! aufgerufen werden forall( i = 1:4, a(i) > 2 ) a(i) = berechne_2( a(i) ) ! OK write( *, * ) a ! Ausgabe: 1 2 9 12 5 contains integer function berechne_1( val ) integer, intent( in ) :: val integer :: res res = val * 3 berechne_1 = res end function berechne_1 pure integer function berechne_2( val ) integer, intent( in ) :: val integer :: res res = val * 3 berechne_2 = res end function berechne_2 end program bsp

Das "forall construct"

Kurzform

Langform

forall( index = subscript:subscript[:stride] ) anweisungsblock end forall name: forall( index = subscript:subscript[:stride] ) anweisungsblock end forall name

211

Verzweigungen und Schleifen

Es gilt im Prinzip das gleiche wie für den forall-Einzeiler. Es sind innerhalb der Schleife eben mehrere Anweisungen erlaubt. Es gelten auch die Formen für mehrdimensionale Felder und mit Vorgabe einer Maske. Diese sind in diesem Abschnitt aber nicht mehr explizit angeführt.

24.6. Terminierung 24.6.1. stop Die stop-Anweisung beendet das Programm. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none write( *, * ) ’Vor Stop-Statement’ stop write( *, * ) ’Nach Stop-Statement’ ! Ausgabe: ! Vor Stop-Statement end program bsp

Der stop-Anweisung kann auch ein "stop-code" mitgegeben werden. Dieser "stop-code" kann eine Ganzzahl (maximal 5-stellig) oder eine Zeichenkette sein. Der "stop-code" wird bei der Programmtermination ausgegeben. Wo die Ausgabe erfolgt und wie sie aussieht ist aber betriebssystem- und compilerabhängig. Fortran 90/95-Code (free source form) program bsp implicit none integer :: i read( *, * ) i if( i == 1 ) then stop 999

212

Terminierung

else stop "Sonstiger Stop" end if ! Ausgabe (bei Eingabe von 1): ! ifort (Linux): ! 999 ! gfortran, g95 (Linux): ! STOP 999 ! Sun f95 (Linux): ! STOP: 999 end program bsp

24.6.2. exit Mit der Anweisung exit kann eine do-Schleife verlassen werden. Wird eine do-Schleife mit einer Bezeichnung versehen, so kann bei der exit-Anweisung explizit auf die benannte Schleife Bezug genommen werden. Wird kein Schleifenname angegeben, so bezieht sich die exit-Anweisung immer auf die innerste Schleife, mit der sie im Zusammenhang steht. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: i, j outerloop: do i = 1, 5 write( *, * ) "Outer", i, "Beginn" innerloop: do j = 1, 3 if( i == 1 ) exit if( i == 2 ) exit innerloop if( i == 4 ) exit outerloop write( *, * ) "Inner", j end do innerloop write( *, * ) "Outer", i, "Ende" end do outerloop ! Ausgabe: ! Outer 1 Beginn ! Outer 1 Ende

213

Verzweigungen und Schleifen

! Outer 2 Beginn ! Outer 2 Ende ! Outer 3 Beginn ! Inner 1 ! Inner 2 ! Inner 3 ! Outer 3 Ende ! Outer 4 Beginn end program bsp

24.6.3. cycle Mit cycle wird der aktuelle do-Schleifendurchlauf beendet und wieder zum Schleifenkopf gesprungen. Wird eine do-Schleife mit einer Bezeichnung versehen, so kann bei der cycle-Anweisung explizit auf die benannte Schleife Bezug genommen werden. Wird kein Schleifenname angegeben, so bezieht sich die cycleAnweisung immer auf die innerste Schleife, mit der sie im Zusammenhang steht. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: i, j outerloop: do i = 1, 5 write( *, * ) "Outer", i, "Beginn" innerloop: do j = 1, 3 if( i == 1 ) cycle outerloop if( i == 4 ) cycle innerloop if( i == 5 ) cycle write( *, * ) "Inner", j end do innerloop

! ! ! !

write( *, * ) "Outer", i, "Ende" end do outerloop Ausgabe: Outer 1 Beginn Outer 2 Beginn Inner 1

214

Terminierung

! ! ! ! ! ! ! ! ! ! ! ! end

Inner Inner Outer Outer Inner Inner Inner Outer Outer Outer Outer Outer program bsp

2 3 2 3 1 2 3 3 4 4 5 5

Ende Beginn

Ende Beginn Ende Beginn Ende

215

25. Datentypen höherer Genauigkeit Fortran 95 bietet für die Festlegung von Datentypen höherer Genauigkeit einen neuen Ansatz.

25.1. Einfache Variante Mittels kind (dt.: Art, Sorte, Gattung, Wesen) kann die Genauigkeit bzw. der Wertebereich eines Datentyps festgelegt werden. Die einfache Variante ist aber system- und compilerabhängig. datentyp (kind=wert) :: var Kurzform: datentyp (wert) :: var

Für wert ist meist (aber nicht immer) die Anzahl der Bytes einzusetzen. Literale eines solchen Datentyps sind mit einem entsprechenden Anhängsel zu kennzeichnen, z.B.: • 3.141592654_8 • -4.9e55_8 Beispiel: Fortran 90/95-Code (free source form)

217

Datentypen höherer Genauigkeit

program bsp implicit none real(kind=8) :: variable ! variable ist nun vom Datentyp "double precision" variable = 1.55555555555_8 write(*,*) variable ! Ausgabe: 1.55555555555000 ! Hier wird nur eine gewöhnliche real-Zahl mit 7 Nachkommastellen ! zugewiesen variable = 1.55555555555 write(*,*) variable ! Ausgabe: 1.55555558204651 end program bsp

25.2. System- und compilerunabhängige Variante Das kind-Attribut darf über eine Konstante oder eine benannte Konstante belegt werden. So kann statt real(kind=8) :: var

auch

integer, parameter :: dp = 8 real(kind=dp) :: var

geschrieben werden. Der entsprechende kind-Wert ist auch per Funktion ermittelbar. Die Variable var

218

System- und compilerunabhängige Variante

integer, parameter :: dp = kind(0.0d0) real(kind=dp) :: var

ist in diesem Beispiel somit vom Datentyp double precision. Das ist schon compilerunabhängig verwendbarer Fortran-Code. Nachfolgend wird die selected_real_kind(p, r)-Funktion vorgestellt, die durch Vorgabe der gewünschten Nachkommastellen und/oder des Exponentenmaximalwertes einen potentiell geeigneten kind-Wert für Gleitkommazahlen ermittelt.

25.2.1. selected_real_kind integer, parameter :: name = selected_real_kind(anzahl_nachkommastellen, max_exponentenwert)

Die Funktion selected_real_kind gibt einen Wert zurück, der alle Gleitkommazahlen mit mindestens anzahl_nachkommastellen Dezimalstellen Genauigkeit und einem Exponentenbereich von max_exponentenwert berücksichtigt. Gibt es keinen solchen systemspezifischen Wert, so wird einer der folgenden Werte zurückgegeben: • -1 ... die geforderte Anzahl an Dezimalstellen ist nicht verfügbar • -2 ... der Exponentenbereich ist nicht verfügbar • -3 ... nichts von beidem ist verfügbar Wird eine solche Konstante mit negativem Wert nachfolgend als kind-Wert bei der Deklaration einer Variablen, Konstanten etc. verwendet, so führt dies in aller Regel zu einer Fehlermeldung bereits beim Kompiliervorgang.

219

Datentypen höherer Genauigkeit

Es ist auch möglich die selected_real_kind-Funktion mit nur einem Argument aufzurufen. Die Argumente sind mit p (für precision) bzw. r (für range) benannt. Beispiele: integer, parameter :: dp = selected_real_kind(r=60)

integer, parameter :: dp = selected_real_kind(p=15)

integer, parameter :: ultrap = selected_real_kind(1000, 5000) ! liefert höchstwahrscheinlich ! die negative Zahl -3

25.2.2. Variablendeklaration real (kind=name) :: variable

Kurzform: real (name) :: variable

Beispiel: integer, parameter :: dp = selected_real_kind(r=60) real(kind=dp) :: var

25.2.3. Konstanten

220

System- und compilerunabhängige Variante

zahl_name

Literale eines solchen Datentyps sind mit dem im Programmcode festgelegten charakteristischen Anhängsel zu kennzeichnen, z.B.: • 3.141592654_dp • -4.9e55_dp

25.2.4. Beispiel Fortran 90/95-Code (free source form) program bsp implicit none integer, parameter :: dp = selected_real_kind(15, 300) real(kind=dp) :: variable variable = 1.5555555555_dp / 2_dp write(*,*) variable ! Ausgabe: 0.777777777750000 write(*,*) kind(variable) ! Ausgabe: 8 end program bsp

221

26. Datenverbund 26.1. Einleitung Datenelemente lassen sich auch zu eigenen zusammengesetzten Datentypen verbinden. Der Datenverbund ist in anderen Programmiersprachen auch als Struktur (structure, struct) bekannt. Der Fortran 95-Standard spricht vom "derived type", also einem abgeleiteten Datentyp. Zulässig als Komponenten eines Datenverbundes sind Skalare, Felder, Zeiger oder auch andere Datenverbunde. Ein Datenverbund ist durch das Schlüsselwort type gekennzeichnet und kann in folgenden Formen auftreten type name ... end type [name]

type [,zugriffsspezifizierer] :: name ... end type [name]

Die Elemente in eckigen Klammern sind optional. Die Angabe eines Zugriffsspezifizierers (public, private) ist nur bei Verwendung von Datenverbunden in Modulen erlaubt.

26.2. Einen Datenverbund anlegen

223

Datenverbund

type :: name [sequence] ! optional sequentielle Speicherplatzablage datentyp :: komponentenname_1 ! ... datentyp :: komponentenname_n end type [name] Beispiel (Programmausschnitt): Fortran 90/95-Code (free source form) ! ... type :: koord integer :: id real, dimension(3) :: x end type koord ! ...

26.3. Eine Variable vom Typ "Datenverbund" anlegen Die Variablendeklaration erfolgt in der Form type( name ) :: var

Beispiel (Programmausschnitt): Fortran 90/95-Code (free source form) ! ... type :: koord integer :: id real, dimension(3) :: x end type koord type( koord ) :: k ! ...

224

Zugriff auf einen Datenverbund als Ganzes

26.4. Zugriff auf Einzelkomponenten eines Datenverbunds Eine Einzelkomponente in einem Datenverbund lässt sich als Kombination des Datenverbundvariablenbezeichners und des Komponentennamen ansprechen. Verknüpft werden diese beiden Bezeichner mit dem %-Zeichen. var%komponentenname Beispiel (Programmausschnitt): Fortran 90/95-Code (free source form) ! ... type :: koord integer :: id real, dimension(3) :: x end type koord type( koord ) :: k k%id = 999 k%x(1) = 0.0 k%x(2) = 20.5 k%x(3) = 10.0 write( *, * ) k%x(2) ! ...

26.5. Zugriff auf einen Datenverbund als Ganzes Ein Datenverbund kann in bestimmten Situation nicht nur komponentenweise angesprochen werden, sondern auch als Einheit, z.B. bei der Ein-/Ausgabe oder beim Zuweisen der Werte einer Datenverbundvariablen an eine andere. Beispiel (Programmausschnitt): Fortran 90/95-Code (free source form)

225

Datenverbund

! ... type :: koord integer :: id real, dimension(3) :: x end type koord type( koord ) :: k1, k2 read( *, * ) k1 k2 = k1 write( *, * ) k2 ! ...

26.6. Elemente eines Datenverbunds initialisieren 26.6.1. Default-Werte im Datenverbund setzen Innerhalb eines Datenverbundes lassen sich die einzelnen Variablen mit Vorgabewerten belegen, z.B. integer :: i = 5 character, dimension( 2, 2 ) :: c = reshape( (/ "A", "B", "C", "D" /), (/ 2, 2 /) )

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none type :: koord integer :: id = -999999 real, dimension( 3 ) :: x = 0.0 end type koord type( koord ) :: k write( *, * ) k ! Ausgabe:

226

Elemente eines Datenverbunds initialisieren

! -999999 0.0 end program bsp

0.0

0.0

26.6.2. Der "structure constructor" Die Initialisierung der Datenverbundelemente bzw. eine spätere Wertzuweisung kann auch per "structure constructor" ("derived type value constructor") vorgenommen werden. name( wertliste ) Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none type :: koord integer :: id real, dimension( 3 ) :: x end type koord type( koord ) :: k = koord( 12, (/ 0.0, 1.5, 20.5 /) ) write( *, * ) k k = koord( 13, (/ 5.5, 0.0, 0.5 /) ) write( *, * ) k ! Ausgabe: ! 12 0.0 1.5 ! 13 5.5 0.0 end program bsp

20.5 0.5

Enthält ein Datenverbund bereits Variablen mit Vorgabewerten, so werden diese durch die Werte im "structure constructor" überschrieben. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none

227

Datenverbund

type :: person character(25) :: vorname = ’NN’ character(25) :: nachname = ’NN’ integer :: alter end type person type(person), dimension(5) :: p p(1) = person(’Harri’, ’P.’, 41) p(5) = person(’Creszenzia’, ’T.’, 18) write(*, fmt=111) p ! Ausgabe: ! Harri ! NN ! NN ! NN ! Creszenzia write(*,*) p(1)%vorname ! Ausgabe: ! Harri

! ! ! ! ! !

P. NN NN NN T.

41 0 0 0 18

p(2)%vorname = ’Holger’ write(*, ’(A)’) p%vorname Ausgabe: Harri Holger NN NN Creszenzia

111 format(2A, I3) end program bsp

Beispiel: Verwendung eines Datenverbunds in einem anderen Datenverbund Fortran 90/95-Code (free source form) program bsp implicit none type :: tripel real :: x, y, z end type tripel type :: koerper integer :: id type( tripel ) :: bezugskoordinate type( tripel ) :: orientierung

228

Das Attribut sequence

end type koerper type( koerper ) :: k k = koerper( 1005, tripel( 10.5, 0.0, -6.5 ), tripel( 0.0, 0.0, -0.8 ) ) write( *, * ) k ! Ausgabe: ! 1005 10.50000 ! 0.000000 end program bsp

0.000000

-6.500000

0.000000

-0.8000000

26.7. Das Attribut sequence Im Datenverbund kann zu Beginn auch das Attribut sequence angegeben werden. Dieses spezifiziert, dass die Werte eines Datenverbunds sequentiell gespeichert werden. Wird dieses Attribut weggelassen, so ist nicht gewährleistet, dass die Werte von Datenverbundvariablen in der selben Reihenfolge, wie sie im Datenverbund gereiht wurden im Speicher wiederzufinden sind, oder dass sie zusammenhängend gespeichert werden. Oft wird die Speicherreihenfolge keine wesentliche Rolle spielen. Ein Spezialfall, wo die Speicherreihenfolge jedoch essenziell ist, wird anschließend dargestellt.

26.8. Die Verwendung eines Datenverbunds in separaten Programmeinheiten Ein Datenverbund kann über ein Modul verschiedenen Programmeinheiten bekannt gemacht werden. Dazu aber später. Es ist nämlich auch so möglich in komplett getrennten Programmein-

229

Datenverbund

heiten auf ein und denselben Datenverbund-Datentyp zuzugreifen. Beispiel: Ein ähnliches Beispiel findet sich auch im J3/97-007R2 Working Draft, Note 4.31 Fortran 90/95-Code (free source form) program bsp implicit none type :: koord sequence integer :: id real, dimension( 3 ) :: x end type koord type( koord ) :: k = koord( 555, (/ 3.0, 4.0, 5.5 /) ) call ausgabe( k ) ! Ausgabe ! 555 3.0000000 4.0000000 end program bsp subroutine ausgabe( coord ) type :: koord sequence integer :: id real, dimension( 3 ) :: x end type koord

5.5000000

type( koord ), intent( in ) :: coord write( *, * ) coord end subroutine ausgabe

In diesem speziellen Fall muss der Datenverbund lt. Standard mit dem Attribut sequence versehen werden. Desweiteren muss der im Hauptprogramm deklarierte Datenverbund komplett identisch mit jenem im Unterprogramm sein (Datenverbundname, Variablenbezeichner, Reihenfolge, Datentypen). In der Praxis sehen das viele Compiler nicht so eng. Allerdings können bei Nichtbeachtung dieser Vorgaben spätestens beim Wechsel des Compilers oder auf andere Rechnerarchitekturen gröbere Probleme auftreten.

230

27. Standardfunktionen 27.1. Tabellenlegende Abkürzung i r x d z

c l any arr aarr ptr

Beschreibung Integer-Datentyp (integer) Real-Datentyp (real) Complex-Datentyp (complex) Double-precision-Datentyp (real(z, kind(0.0D0))) beliebiger numerischer Datentyp (integer, real, complex) Zeichen (character) Logical-Datentyp (logical) beliebiger intrinsischer Datentyp Feld (Array) dynamisches Feld Zeiger (Pointer)

Die in den nachfolgenden Unterkapiteln angeführten Tabellen und Listen geben die im Fortran 95-Working Draft gelisteten intrinsischen Funktionen in simplifizierter Form wieder. Auch die Standard-Subroutinen wurden berücksichtigt. Die einzelnen Compiler kennen zum Teil wesentlich mehr Funktionen als im

231

Standardfunktionen

Standard vorgegeben. Bei Verwendung solcher Funktionen sind die Programme jedoch nicht mehr quellcodekompatibel. Auf die Wiedergabe solcher compilerspezifischen Funktionen wird hier deshalb verzichtet.

27.2. D ATENTYPFUNKTIONEN1 • • • • • •

Umwandlung in INTEGER Umwandlung in REAL Umwandlung in DOUBLE PRECISION Umwandlung in COMPLEX Umwandlung in CHARACTER kind-Parameter

27.3. M ATHEMATISCHE F UNKTIONEN2 • • • • • • • • • •

Rundung Absolutwert Modulo Vorzeichentransfer Positive Differenz Maximum Minimum Komplexe Zahlen Quadratwurzel Exponentialfunktion

1

2

232

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A% 20F O R T R A N %2095%3A%20S T A N D A R D F U N K T I O N E N %3A% 20D A T E N T Y P F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20S T A N D A R D F U N K T I O N E N %3A%20M A T H E M A T I S C H E % 20F U N K T I O N E N %20

S TRINGFUNKTIONEN9

• • • •

Logarithmen Winkelfunktionen Arkusfunktionen Hyperbelfunktionen

27.4. S TRINGFUNKTIONEN3 • Lexikalische Funktionen • Sonstige

27.5. F ELDFUNKTIONEN4 • • • •

3

4

Konstruktion und Umgestaltung von Feldern Abfragen von Feldstatus, Felddaten und Feldmetadaten Funktionen für Vektoren und Matrizen Sonstige

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20S T A N D A R D F U N K T I O N E N %3A%20S T R I N G F U N K T I O N E N % 20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20S T A N D A R D F U N K T I O N E N %3A%20F E L D F U N K T I O N E N %20

233

Standardfunktionen

27.6. Z EIGERFUNKTIONEN5 27.7. B ITFUNKTIONEN6 27.8. W EITERE F UNKTIONEN7 27.9. I NTRINSISCHE S UBROUTINEN8

5

6 7

8

234

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20S T A N D A R D F U N K T I O N E N %3A%20Z E I G E R F U N K T I O N E N % 20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20S T A N D A R D F U N K T I O N E N %3A%20B I T F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20S T A N D A R D F U N K T I O N E N %3A%20W E I T E R E % 20F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20S T A N D A R D F U N K T I O N E N %3A%20I N T R I N S I S C H E % 20S U B R O U T I N E N %20

28. Unterprogramme Werden Programme umfangreicher und komplexer oder werden einzelne Programmabschnitte öfter verwendet, dann ist es sinnvoll Unterprogramme (Prozeduren) zu verwenden. Fortran 95 kennt zwei Typen von Unterprogrammen: • Funktionen (function) • Subroutinen (subroutine) Darüber hinaus existiert in Fortran die Möglichkeit Unterprogramme und Daten mittels Modulen in das Programm einzubeziehen.

28.1. Das function Unterprogramm Eine Funktion ist ein Unterprogramm, das genau einen Wert zurück gibt. Welcher Art von Datentyp der Wert ist, wird durch eine Zuweisung an den Funktionsnamen erreicht ( z. B. real). Die allgemeine Funktionsdeklaration lautet: datentyp function funktionsname ( [formale parameter] ) Vereinbarungsteil Anweisungsteil funktionsname = wert [return] end function funktionsname

235

Unterprogramme

Wird der Dateityp bei der Funktionsdeklaration nicht angegeben, so muss der Datentyp der Funktion im Vereinbarungsteil festgelegt werden: function funktionsname ( [formale parameter] ) Vereinbarungsteil datentyp :: funktionsname Anweisungsteil funktionsname = wert [return] end function funktionsname Mittels return kann zur aufrufenden Programmeinheit zurückgekehrt werden. Ein return unmittelbar vor der end-Anweisung ist nicht unbedingt erforderlich, da das Programm beim Erreichen der end-Anweisung zur aufrufenden Programmeinheit zurück springt. Deswegen sollte bei allen neueren Programmen darauf verzichtet werden. Wichtig ist die return-Anweisung für alternative Rücksprünge zur aufrufenden Programmeinheit. Eine Funktion wird meist mittels folgender allgemeiner Anweisung von der ausführenden Programmeinheit aufgerufen: variable = funktionsname( aktuelle parameter )

Dabei orientiert sich diese Unterprogrammtechnik direkt an mathematischen Funktionen. Im folgenden Beispiel ruft das Programm test die Funktion funk auf, führt das Unterprogramm aus und gibt den entsprechenden Rückgabewert an das Programm test zurück: Datei bsp.f95: Fortran 90/95-Code (free source form) program test ! implicit none real :: funk real :: x, y write(*,*) ’x -> ’ read(*,*) x y = funk( x )

236

Das function Unterprogramm

write(*,*) ’funk -> ’, y end program test real function funk( a ) ! implicit none real :: a funk = a**2 end function funk

Das Unterprogramm funk kann sich direkt unter der aufrufenden Programmeinheit in der selben Textdatei oder in einer separaten Datei befinden. Befindet sich das Unterprogramm in einer separaten Datei, so muss diese und die aufrufende Programmeinheit zusammen kompiliert werden: Übersetzung mit gfortran im vorliegenden Fall: gfortran -o bsp bsp.f95

Übersetzung mit gfortran bei separaten Dateien (bspw.): gfortran -o bsp bsp.f95 funk.f95

Es ist aber auch möglich eine Funktion nur durch ihren Namen aufzurufen. Der Rückgabewert der Funktion wird dann direkt ausgegeben: Datei bsp.f95: Fortran 90/95-Code (free source form) program test ! implicit none real :: funk real :: x write(*,*) ’x -> ’ read(*,*) x write(*,*) ’funk -> ’, funk( x ) end program test real function funk( a )

237

Unterprogramme

! implicit none real :: a funk = a**2 end function funk

28.2. Das subroutine Unterprogramm Eine subroutine ist ein Unterprogramm, die mehr als einen Wert zurückgeben kann. Eine Subroutine besitzt im Gegensatz zu einer Funktion keinen Datentyp und Rückgabewert. Die allgemeine Deklaration einer Subroutine lautet: subroutine subroutinenname ([formale parameter]) Vereinbarungsteil Anweisungsteil [return] end subroutine subroutinenname Mittels return kann zur aufrufenden Programmeinheit zurückgekehrt werden. Ein return unmittelbar vor der end-Anweisung ist nicht unbedingt erforderlich, da das Programm beim Erreichen der end zur aufrufendenen Programmeinheit zurück springt. Deswegen sollte bei allen neueren Programmen darauf verzichtet werden. Wichtig ist die return Anweisung für alternative Rücksprünge zur aufrufenden Programmeinheit. Aufgerufen wird eine Subroutine aus der aufrufenden Programmeinheit mittels der call-Anweisung: call subroutinenname [([aktuelle parameter])]

Im folgenden Beispiel wird die Subroutine sub aufgerufen. Diese gibt dann zwei Werte zurück:

238

Weitere Anweisungen für die Unterprogrammtechnik

Datei bsp.f95 Fortran 90/95-Code (free source form) program bsp ! implicit none real :: x, y, z write( *, * ) ’x -> ’ read( *, * ) x call sub( x, y, z ) write( *, * ) ’y -> ’, y, ’z -> ’, z end subroutine sub( a, b, c ) ! implicit none real :: a, b, c b = a**2 c = a**2 + b end subroutine sub

28.3. Weitere Anweisungen für die Unterprogrammtechnik 28.3.1. Das intent-Attribut Im Vereinbarungsteil der Funktion wird der Parameterdeklaration das Schlüsselwort intent mitgegeben. datentyp, intent( in ) :: var

Mit intent( in ) wird angezeigt, dass der Parameter var in der Funktion nicht geändert wird und kein Rückfluss der Information in die aufrufende Programmeinheit stattfindet. Ein intent( out ) oder intent( inout ) wie bei Subroutinen wäre meist auch möglich, widerspricht aber dem Grundgedanken des FortranFunktionsbegriffs und der strukurierten Programmierung. Bei

239

Unterprogramme

einer Funktion soll der Informationsrückfluss über den Rückgabewert stattfinden und nicht über Parameter. Bei der Parameterübergabe bietet eine Subroutine folgende intent-Möglichkeiten: • datentyp, intent(in) :: var ... Informationfluss von der aufrufenden Programmeinheit in die Funktion • datentyp, intent(out) :: var ... Informationfluss von der Subroutine zur aufrufenden Programmeinheit • datentyp, intent(inout) :: var ... beidseitiger Informationsfluss Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none real :: a, b, c a = 1.0 b = 2.0 c = 3.0 call sub(a, b, c) write (*,*) ’Hauptprogramm: ’, a, b, c ! Ausgabe: 1.000000 22.20000 end subroutine sub(x, y, z) implicit none real, intent(in) :: x real, intent(out) :: y real, intent(inout) :: z write (*,*) ’Unterprogramm: ’, x, y, z ! Ausgabe: 1.000000 2.000000

33.30000

3.000000

y = 22.2 z = 33.3 end subroutine sub

Die aktuellen und formalen Parameter müssen hinsichtlich Datentyp, Anzahl, Reihenfolge übereinstimmen.

240

Weitere Anweisungen für die Unterprogrammtechnik

28.3.2. Die pure Anweisung Ein Unterprogramm welches keine Seiteneffekte hat ist eine bloßes bzw. reines (pure) Unterprogramm. Ein Unterprogramm erzeugt dann keine Seiteneffekte, wenn es weder seine Eingabedaten, noch die Daten verändert, die außerhalb des Unterprogrammes liegen, es sei denn, es wären seine Ausgabedaten. In einem reinen Unterprogramm haben die lokalen Variablen keine save Attribute, noch werden die lokalen Variablen in der Datendeklaration initialisiert. Reine Unterprogramme sind für das forall-Konstrukt notwendig: das forall-Konstrukt wurde für das parallele Rechnen konzipiert, weshalb hier der Computer entscheidet, wie das Konstrukt abgearbeitet werden soll. Dazu ist es aber notwendig, das es egal ist in welcher Reihenfolge das Konstrukt abgearbeitet wird. Gilt dies nicht - hat das Unterprogramm also Seiteneffekte - so kann das forall-Konstrukt nicht verwendet werden. Jedes Ein- und Ausgabeargument in einem reinen Unterprogramm muss mittels des intent-Attributs deklariert werden. Darüberhinaus muss jedes Unterprogramm, das von einem reinen Unterprogramm aufgerufen werden soll, ebenfalls ein reines Unterprogramm sein. Sonst ist das aufrufende Unterprogramm kein reines Unterprogramm mehr.

28.3.3. Die elemental Anweisung Ein Unterprogramm ist elementar, wenn es als Eingabewerte sowohl Skalare als auch Felder akzeptiert. Ist der Eingabewert ein Skalar, so liefert ein elementares Unterprogramm einen Skalar als Ausgabewert. Ist der Eingabewert ein Feld, so ist der Ausgabewert ebenfalls ein Feld.

241

Unterprogramme

28.3.4. Die return Anweisung Eine return-Anweisung darf nur im Gültigkeitsbereich von Unterprogrammen verwendet werden. Sie bewirkt einen Abbruch der Unterprogrammausführung und eine Rückkehr zum Aufrufpunkt, wo mit der nächsten Anweisung fortgesetzt wird. Beispiel: Fortran 90/95-Code (free source form) program main implicit none call xyz( -2 ) write( *, * ) "UP-Ende" stop write( *, * ) "Programmende" contains subroutine xyz( n ) integer, intent( in ) :: n integer :: k do k = n, n+20 write( *, * ) k if( k == 5 ) return end do write( *, * ) "k_max =", k end subroutine xyz ! Ausgabe: ! -2 ! -1 ! 0 ! 1 ! 2 ! 3 ! 4 ! 5 ! UP-Ende end program main

Einige Compiler erlauben zwecks Programmabbruch auch ein return anstelle des stop im Hauptprogramm. Das ist aber nicht standardkonform. Andere Compiler würden solchen Code mit

242

Felder als Parameter

einer Fehlermeldung abweisen, das Programm wäre somit nicht mehr uneingeschränkt portabel. Ein exit in der Schleife anstelle der return-Anweisung würde nur den Schleifendurchlauf abbrechen und die Unterprogrammausführung würde nach der Schleife fortgesetzt.

28.4. Felder als Parameter Beispiel: Übergabe eines ganzen Feldes Datei bsp.f95: Fortran 90/95-Code (free source form) program bsp implicit none integer, dimension(3,3) :: feld integer :: cnt, i, j cnt = 1 do i = 1, 3 do j = 1, 3 feld(j,i) = cnt cnt = 1 + cnt end do end do ! Unterprogrammaufruf call sub(feld) ! Ausgabe: 1 2 3 end program bsp

4

5

6

7

8

9

Datei sub.f95 Fortran 90/95-Code (free source form) subroutine sub(arr) implicit none integer, dimension(3,3), intent(in) :: arr write(*,*) arr

243

Unterprogramme

end subroutine sub

Beispiel: Übergabe einer Feld-Teilkette Datei bsp.f95: Fortran 90/95-Code (free source form) program bsp implicit none integer,dimension(3,3) :: feld integer :: cnt, i, j cnt = 1 do i = 1, 3 do j = 1, 3 feld(j,i) = cnt cnt = 1 + cnt end do end do ! Unterprogrammaufruf call sub(feld(1:2,2:3)) ! Ausgabe: 4 5 7 end program bsp

8

Datei sub.f95 Fortran 90/95-Code (free source form) subroutine sub(arr) implicit none integer, dimension(0:1, 0:1), intent(in) :: arr write(*,*) arr end subroutine sub

Beispiel: Übergabe eines Feld-Einzelelements Datei bsp.f95: Fortran 90/95-Code (free source form) program bsp implicit none integer, dimension(3,3) :: feld integer cnt, i, j

244

Prozeduren als Parameter

cnt = 1 do i = 1, 3 do j = 1, 3 feld(j,i) = cnt cnt = 1 + cnt end do end do ! Unterprogrammaufruf call sub(feld(1,2)) ! Ausgabe: 4 end program bsp

Datei sub.f95 Fortran 90/95-Code (free source form) subroutine sub(arr) implicit none integer, intent(in) :: arr write(*,*) arr end subroutine sub

28.5. Prozeduren als Parameter Auch Prozeduren können als Parameter übergeben werden. Standardfunktionen (intrinsic functions) werden dazu folgendermaßen im Vereinbarungsteil gekennzeichnet: intrinsic namensliste oder datentyp, intrinsic :: namensliste

245

Unterprogramme

Eigene Unterprogramme oder Unterprogramme aus Bibliotheken mit: external namensliste

oder datentyp, external :: namensliste Beispiel: Fortran 90/95-Code (free source form) program bsp real, parameter :: PI=3.1415927 ! intrinsic functions intrinsic sin, cos ! Unterprogrammaufrufe call sub(sin, PI) ! Ausgabe: 0.000000 call sub(cos, PI) ! Ausgabe: -1.000000 end program bsp subroutine sub(funk, x) implicit none real :: funk, x write(*,*) nint(funk(x)*1000)/1000.0 end subroutine sub

28.6. Optionale Parameter Ab Fortran 90 sind auch optionale Parameter für Unterprogramme erlaubt. Solche Parameter sind durch das Attribut optional zu kennzeichnen. Auch der aufrufenden Programmeinheit muss diese Parameter-Optionalität bekannt gegegeben werden, z.B. über ein Interface. Das aktuelle Vorhandensein eines als optional

246

Module

markierten Parameters beim Unterprogrammaufruf kann im Unterprogramm selbst durch die Funktion present geprüft werden. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none interface subroutine ab(a, b) integer, intent( in ) :: a integer, intent( in ), optional :: b end subroutine ab end interface call ab( 1 ) call ab( 8, 12 ) ! Ausgabe: ! Nur a gegeben 1 ! Beide Parameter gegeben 8 12 end program bsp subroutine ab(a, b) integer, intent( in ) :: a integer, intent( in ), optional :: b if( present( b ) ) then write (*,*) "Beide Parameter gegeben", else write (*,*) "Nur a gegeben", a end if

a, b

end subroutine ab

28.7. Module Module ersetzen in Fortran 95 die FORTRAN 77-COMMON-Blöcke. In einem Modul können Variablen, Konstanten und auch Unterprogramme abgelegt werden. Diese können dann von verschiedenen Programmeinheiten angesprochen werden.

247

Unterprogramme

module modulname [implicit none] [save] Deklaration von Variablen, Konstanten [contains Unterprogramme ] end module modulname Das Einbinden eines Moduls in eineProgrammeinheit geschieht mittels der Anweisung use modulname [, only liste]

only signalisiert, dass nur die in liste angegebenen Variablen oder Konstanten verwendet werden sollen. Beispiel: Fortran 90/95-Code (free source form) module m1 implicit none save real, parameter :: PI=3.1415 real :: a end module m1 program bsp use m1 implicit none a = 1.5 write(*,*) ’Hauptprogramm 1: ’, PI, a ! Ausgabe: Hauptprogramm 1: 3.141500 call sub write(*,*) ’Hauptprogramm 2: ’, PI, a ! Ausgabe: Hauptprogramm 2: 3.141500 end program bsp

1.500000

2.500000

subroutine sub use m1 implicit none write(*,*) ’Unterprogramm: ’, PI, a ! Ausgabe: Unterprogramm: 3.141500 a = 2.5

248

1.500000

Rekursiver Unterprogrammaufruf

end subroutine sub

Das save-Statement in Modulen stellt sicher, dass die aktuellen Werte von Modulvariablen beim Wechsel zwischen den verschiedenen Programmeinheiten sicher erhalten bleiben.

28.8. Rekursiver Unterprogrammaufruf In Fortran 95 können Unterprogramme (Funktionen, Subroutinen) auch rekursiv aufgerufen werden. Rekursion bedeutet, dass ein Unterprogramm sich selbst wieder aufruft (lat. recurrere oder en. recur ... wiederkehren, zurückkommen). Beispiel: Berechnung von n! (vereinfacht) Fortran 90/95-Code (free source form) program bsp implicit none integer :: zahl, ergebnis, fac write(*,*) "Gib eine Ganzzahl ein: " read(*,*) zahl ergebnis = fac(zahl) write(*,*) "Ergebnis ist: ", ergebnis end program bsp

recursive function fac(n) result(zerg) implicit none integer, intent(in) :: n integer :: zerg ! Vereinfacht: Keine Überprüfung ob Überlauf, negative Zahl, etc. zerg = n if (n > 1) then zerg = n * fac(n-1)

249

Unterprogramme

end if return end function fac

Der Funktionskopf ist bei diesem Beispiel etwas anders gestaltet als üblich. Während der Intel-Fortran-Compiler auch ein recursive integer function fac(n)

oder ein integer recursive function fac(n)

problemlos akzeptiert, wirft der gfortran-Compiler bei diesen Varianten einen Syntaxfehler.

250

29. Ein- und Ausgabe 29.1. read Die read-Anweisung dient dem Einlesen von Daten. Typisches Beispiel ist die Dateneingabe mittels Tastatur. Formal sieht eine read-Anweisung so aus: read([unit=]unit, [fmt=]fmt [, iostat=iostat] [, advance=advance]) [eingabeliste] • unit ... Nummer der Eingabeeinheit (ist systemabhängig), Sternoperator oder auch die einer Datei mittels open-Anweisung zugeordnete Nummer. • fmt ... Anweisungsnummer zu einer format-Anweisung, Sternoperator oder Formatliste • iostat ... read-Status • advance ... siehe WRITE1 Listengesteuerte Eingabe auf der Standardeingabe (normalerweise die Tastatur): read (*,*) a, b, c

1

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20E I N -{}%20 U N D %20A U S G A B E %23 W R I T E %20

251

Ein- und Ausgabe

Alternativ kann das auch so geschrieben werden: read (unit=*, fmt=*) a, b, c

Beim Intel Fortran Compiler, gfortran und g95 ist auch unit = 5 als stdin (Tastatur) vorbelegt. Das Einlesen aus Dateien und die Einstellung des Formates werden später erläutert. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: i(5) ! Einlesen in ein Feld (unit ... Standardeingabe, fmt ... listengesteuert) read (*,*) i ! ... end program bsp

Kurze Erläuterung zu iostat: Wert 0 positiver Wert (systemabhängig) negativer Wert (systemabhängig)

Erläuterung kein Fehler Fehler End Of File und kein Fehler

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: i, st ! Einlesen eines Wertes read (*, *, iostat=st) i !

Ausgabe des IO-Status write (*,*) ’IO-Status:’, st

252

write

end program bsp

Ausgabe: Für Eingabe: 5 → 0 Für Eingabe: 5.3 → Positiver Wert = Fehler Das Einlesen aus Dateien und die Einstellung des Formates werden später erläutert.

29.2. write

Abb. 32

Die write-Anweisung dient der Datenausgabe. Typisches Beispiel ist die Anzeige von Daten auf dem Bildschirm. Formal sieht eine write-Anweisung so aus: write([unit=]unit, [fmt=]fmt [, iostat=iostat] [, advance=advance]) [ausgabeliste] • unit ... Nummer der Ausgabeeinheit (ist systemabhängig), Sternoperator oder auch die einer Datei mittels openAnweisung zugeordnete Nummer. • fmt ... Anweisungsnummer zu einer format-Anweisung, Sternoperator oder Formatliste • iostat ... write-Status • advance ... nur bei sequentieller formatierter I/O. Formatspezifizierer muss explizit gegeben sein. • ’no’ ... kein Vorschub des file position pointers zum nächsten Datensatz (z.B. kein Zeilenvorschub).

253

Ein- und Ausgabe

• ’yes’ ... mit Vorschub des file position pointers zum nächsten Datensatz (voreingestellt) Listengesteuerte Ausgabe auf der Standardausgabe (normalerweise der Bildschirm): write (*,*) a, b, c

Alternativ kann das auch so geschrieben werden: write (unit=*, fmt=*) a, b, c

Beim Intel Fortran Compiler, gfortran und g95 sind auch • unit=0 als stderr (Bildschirm) und • unit=6 als stdout (Bildschirm) vorbelegt. Bezüglich iostat gilt auch hier der im vorigen Abschnitt kurz geschilderte Sachverhalt. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: i(5) = (/ 5, 4, 1, -1, -7 /) ! ... ! Ausgabe der Feldwerte (unit ... Standardausgabe, fmt ... listengesteuert) write (*,*) i ! ... end program bsp

Beispiel: advance Fortran 90/95-Code (free source form) program bsp implicit none character(10) :: ch integer :: st write(*, ’(A)’, advance=’YES’) "Hallo" write(*, ’(A)’, advance=’YES’) "Welt"

254

Kürzer: print, read, write und Namenslisten

write(*, *) "ABCDEFGHIJKLMN" end program bsp

Ausgabe: advance=’YES’ Hallo Welt ABCDEFGHIJKLMN

advance=’NO’ HalloWelt ABCDEFGHIJKLMN

Die Ausgabe in Dateien und die Einstellung des Formates werden etwas später erläutert.

29.3. Kürzer: print, read, write und Namenslisten Für die listengesteuerte Ein- und Ausgabe existieren auch vereinfachte Formen. Für Eingaben wird wieder der read-Befehl verwendet, für Ausgaben gibt es die print-Anweisung. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: a, b real :: r complex :: z character( len = 10 ) :: str read *, a, b, r, z, str ! Eingabe per Tastatur: ! 10, 30, 55.5, (10.8,7.0), Hallo print *, str, a, b, r, z ! Ausgabe am Bildschirm: ! Hallo 10 30 55.5 (10.8,7.) end program bsp

255

Ein- und Ausgabe

Bei mehrfachem Aufruf gleicher Ein- bzw. Ausgabeanweisungen kann durch Verwendung von Namenslisten der Programmcode kürzer gestaltet werden. Die Dateneingabe wird dadurch aber etwas komplizierter:

• eingeleitet wird die Eingabe durch ein &-Zeichen, unmittelbar gefolgt vom Namenslistenbezeichner • danach folgen ein oder mehrere Leerzeichen • es folgen die Zuweisungen von Werten zu den Variablennamen • abgeschlossen wird die Eingabe durch einen Slash /

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: a, b real :: r complex :: z character( len = 10 ) :: str namelist / LISTEA / a, b, r, z, str namelist / LISTEB / str, r, z read( *, nml = LISTEA ) ! Eingabe per Tastatur: ! &LISTEA b = 30, a = 10, r = 55.5, z = (10.8,7.0), str = "Hallo" / write( *, nml = LISTEB ) ! Ausgabe auf dem Bildschirm (Intel 9.1): ! &LISTEB ! STR = Hallo , ! R = 55.50000 , ! Z = (10.80000,7.000000) ! / end program bsp

256

Formatierung

29.4. Formatierung

Abb. 33

Die Ein- und Ausgabeformatierung kann beeinflusst werden. Zu diesem Zweck gibt es die format-Anweisung. ... (..., fmt = marke, ...) ... marke format (formatliste) Alternativ kann die Formatliste auch direkt in die read- oder write-Anweisung eingebunden werden ... (..., fmt = ’(formatliste)’, ...) ...

29.4.1. Formatlistenelemente Formatspezifizierer Ix[.z]

Kommentar Ganzzahl mit einer Feldlänge von x Zeichen. z gibt die Mindestanzahl der auszugebenden Zeichen an (Feld wird, wenn nötig, mit führenden Nullen aufgefüllt).

257

Ein- und Ausgabe Formatspezifizierer Fx.y

Ex.y

Dx.y A Ax Lx xX /

Kommentar Fixkommazahl mit einer Gesamtfeldlänge von x Zeichen. y ist die Anzahl der Nachkommastellen (Vorzeichen und Dezimalpunkt müssen in der Gesamtfeldlänge berücksichtigt werden). Gleitkommazahl mit einer Gesamtfeldlänge von x Zeichen. y ist die Anzahl der Nachkommastellen. (Vorzeichen, Dezimalpunkt und die Zeichen für den Exponenten müssen in der Gesamtfeldlänge berücksichtigt werden). -"Eine Zeichenkette. Eine Zeichenkette mit x Zeichen. Ein logischer Wert, T bzw. F x Leerzeichen. Zeilenvorschub

Obige Tabelle der Formatlistenelemente ist nicht vollständig. Fortran kennt noch weitere Formatierungsmöglichkeiten. Die Ausgabe erfolgt normalerweise rechtsbündig. Reicht die Gesamtfeldlänge bei numerischen Werten nicht aus, so werden anstelle einer Zahl Sternchen angezeigt. Beispiel: Fortran 90/95-Code (free source form)

258

Formatierung

program bsp implicit none integer :: a a = 999 write(*, 3333) a ! Ausgabe: 999 a = -999 write (*, 3333) a ! Ausgabe: *** 3333 FORMAT (I3, /, /) ! / ... nach jeder 3333-write-Anweisung werden zwei Leerzeilen eingefügt end program bsp

Alternativ könnte die Formatliste auch so in die write-Anweisung eingebaut werden: write(*, ’(I3, /, /)’) a

Weitere Formatierungsbeispiele: Code WRITE(*, 999) 1234 WRITE(*, 999) 1234567 WRITE(*, 999) 1234567890 999 FORMAT(I9.6) WRITE(*, 999) 555.6666 WRITE(*, 999) +5.6 WRITE(*, 999) -55.666E7 WRITE(*, 999) -55555.666 999 FORMAT(F9.3)

Ausgabe 001234 1234567 *********

555.667 5.600 ********* *********

259

Ein- und Ausgabe Code WRITE(*, 999) 555.6666 WRITE(*, 999) +5.6 WRITE(*, 999) -55.666E7 WRITE(*, 999) -55555.666 999 FORMAT(E9.3) WRITE(*, 999) ’Hallo’ WRITE(*, 999) ’ABCDEFGHIJKL’ WRITE(*, 888) ’ABCDEFGHIJKL’ 888 FORMAT(A) 999 FORMAT(A10) WRITE(*, *) ’FORTRAN’, ’77’ WRITE(*, 999) ’FORTRAN’, ’77’ 999 FORMAT(A, 1X, A) WRITE(*, 888) ’FORTRAN’, ’77’ WRITE(*, 999) ’FORTRAN’, ’77’ 888 FORMAT(A, T3, A) 999 FORMAT(A, T20, A) WRITE(*, 999) ’FORTRAN’, ’77’ 999 FORMAT(A, /, A) WRITE(*, 999) 34.56 WRITE(*, *) 34.56 C SP ... Sign Plus (+) 999 FORMAT(SP, F12.3)

260

Ausgabe 0.556E+03 0.560E+01 .557E+09 -.556E+05

Hallo ABCDEFGHIJ ABCDEFGHIJKL

FORTRAN77 FORTRAN 77

FO77RAN FORTRAN 77

FORTRAN 77

+34.560 34.56

Formatierung

29.4.2. Wiederholung von Formatteilen Beispiel: write(*, 100) ’abc’, 10.3, ’xxx’, 23.4 100 format (2(A3, F6.1))

29.4.3. write etwas anders Beispiel: write (*, 100) 100 format (’Hallo’, X, ’Welt!’)

29.4.4. Dynamische Mehrfach Formatierung Formatierungsanweisungen können auch als String bearbeitet werden, indem die z.B. die Anzahl der auszugebenden Variablen per write-Befehl in die Formatierung schreibt. Mehrfachformatierung - Beispiel: character(4) :: formatierung integer, dimension(1:4) :: einsen = 1 integer :: anzahl anzahl = 4 formatierung = ’( I)’ write(formatierung(2:2), ’(I1)’) anzahl write(*, formatierung) einsen

261

Ein- und Ausgabe

29.5. Dateien

Abb. 34

29.5.1. Datensatz Datensätze können in folgender Form auftreten: • Formatierter Datensatz: Textdatensatz • Unformatierter Datensatz: Datensatz in einer maschineninternen Form. • Dateiendesatz

29.5.2. Datei Für Fortran ist alles eine Datei, das durch read oder write bearbeitbar ist. Zugriffsmethoden: • Sequentieller Zugriff: Lesen ab Beginn der Datei (file) und dann immer den nächsten Datensatz einlesen. Geschrieben wird jeweils ans Dateiende. Auf interne Dateien kann nur sequentiell zugegriffen werden.

262

Dateien

• Direkter Zugriff: Bearbeiten in beliebiger Reihenfolge durch Angabe der Satznummer. • Binärer Zugriff: Bearbeiten von Dateien, die binäre Daten enthalten, z. B. Bilder von CCD-Kamera, Scilab/Matlab saveDateien Dateitypen: • Externe Datei: Eine konventionelle Datei • Interne Datei: character-Variable oder -Feld. Dateien haben im Betriebsystem einen Dateinamen. In Fortran wird eine Datei über eine Dateinummer (unit) angesprochen. Die Zuordnung erfolgt mit dem Befehl open.

29.5.3. open Zum Öffnen einer externen Datei dient die open -Anweisung. open (liste) mit folgender liste Element [unit =] x

file = x iostat = x

Kommentar x ist eine Dateinummer (Ganzzahl, sollte über 10 liegen, da oft Nummern unter 10 fix zugeordnet sind, z.B. der Standardein-, ausgabe). x ist der externe Dateiname x ist 0 wenn open fehlerfrei ausgeführt wurde, ansonsten eine systemabhängige Fehlernummer

263

Ein- und Ausgabe Element status = x

access = x

position = x

form = x

action = x

recl = x err = x

264

Kommentar Dateistatus: ’old’ ... Datei existiert bereits ’new’ ... Datei wird neu erzeugt ’scratch’ ... namenlose temporäre Datei ’unknown’ ... System bestimmt Dateistatus selbst ’replace’ ... der Inhalt einer bereits vorhandenen Datei wird gelöscht. Zugriffsmethode: ’sequential’ ... Sequentielle Datei ’direct’ ... direkter Zugriff ’stream’ ... binärer Zugriff Den Dateisatzzeiger beim Öffnen der Datei an eine bestimmte Position setzen. (’asis’, ’rewind’, ’append’) Format: ’formatted’ oder ’unformatted’ ’read’ ... nur Lesezugriff ’write’ ... nur Schreibzugriff ’readwrite’ ... Lesen und Schreiben Datensatzlänge (positive Zahl, access=’direct’, in Bytes) Im Fehlerfall Sprung zur Marke x

Dateien Element blank = x delim = x

pad = x

Kommentar ’null’ oder ’zero’ (nur für form=’formatted’) ’apostrophe’ ’quote’ ’none’ ’yes’ oder ’no’ (nur für form=’formatted’)

Eingestellte Vorgabewerte sind: • • • •

status = ’unknown’ position = ’asis’ access = ’sequential’ form = ’formatted’

Wird access=’direct’ gesetzt, so gilt form=’unformatted’ als Vorgabewert. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer :: stat character(80) :: str open(20, file=’/tmp/testdatei.txt’, iostat=stat) if(stat == 0) then write(*,*) ’Das Öffnen der Datei war ein voller Erfolg’ do read(20, ’(A)’, iostat=stat) str ! Bei EOF wird stat /= 0 if (stat /= 0) exit write(*,*) str end do else write(*,*) ’Datei konnte nicht geöffnet werden’ end if

265

Ein- und Ausgabe

close(20) end program bsp

29.5.4. close Geschlossen wird die Verbindung zur externen Datei mit dem close-Befehl. close (liste)

liste: Element [unit =] x iostat = x err = x status = x

Kommentar wie bei open wie bei open wie bei open ’keep’ ... Datei erhalten (voreingestellt) ’delete’ ... Datei löschen

29.5.5. Lesen und Schreiben Gelesen oder geschrieben wird mit den bereits bekannten readund write-Anweisungen. Element [unit =] x

266

Kommentar Dateinummer bzw. CHARACTER-Variable oder Feld (interne Datei)

Dateien Element [fmt =] x [nml] = x rec = x

iostat = x err = x end = x

advance = x eor = x size = x

Kommentar siehe F ORMATIERUNG2 x ... namelist-group-name Datensatznummer bei Direktzugriff (siehe Abschnitt D IREKTZUGRIFF3 ) wie bei read4 Bei Fehler Sprung zur Anweisungsnummer x Bei Dateiende Sprung zur Anweisungsnummer x (nicht erlaubt bei Direktzugriff, nicht bei write) ’yes’ oder ’no’ Bei End of Record Sprung zur Marke x (nicht bei write) x ... Zeichenzähler (nicht bei write, advance=’no’)

Es existiert eine Menge von Einschränkungen, wann welche Elemente erlaubt sind, bzw. welche nur kombiniert auftreten sollen, z.B. • wenn der rec-Spezifizierer Verwendung findet, dann darf kein end-Element angegeben werden • Bei Dateneingabe nur dann ein size-Spezifizierer, wenn advance=’no’ gesetzt ist. 2 3 4

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20E I N -{}%20 U N D %20A U S G A B E %23F O R M A T I E R U N G H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20E I N -{}%20 U N D %20A U S G A B E %23D I R E K T Z U G R I F F H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20E I N -{}%20 U N D %20A U S G A B E %23 R E A D

267

Ein- und Ausgabe

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none character (len = 80) :: a integer :: st = 0 open (20, file=’/tmp/testdatei.txt’, status=’OLD’, iostat=st) if (st /= 0) then stop "open-Fehler!" end if ! Aus Datei lesen do read (20, 888, iostat=st) a ! Auf Standardausgabe schreiben if (st == 0) then write (*, 888) a else if (st > 0) then write (*,*) "read-Fehler!" exit else if (st < 0) then exit end if end do close(20) 888 format(A) end program bsp

Direktzugriff OPEN: Element access = x

268

Kommentar x ... ’DIRECT’

Dateien Element recl = x

fmt = x

Kommentar x ... Datensatzlänge (positive Zahl, access=’DIRECT’, in Bytes bzw. bei formatierten Dateien in Characters) x ... Formatangabe (wird eine Datei ’FORMATTED’ geöffnet, dann muss auch eine konkrete Formatliste angegeben werden, ansonsten tut’s auch der Sternoperator)

READ/WRITE: Element REC = x

Kommentar x ... Satznummer bei Direktzugriff

Beispiel: Gegeben ist die Textdatei /tmp/testdatei.txt mit dem Inhalt Die WRITE-Anweisung dient der Datenausgabe aus einem FORTRAN-Programm auf ein externes Gerät. Typisches Beispiel ist die Anzeige von Daten auf dem Bildschirm. Formal sieht eine WRITE-Anweisung so aus:

Fortran 90/95-Code (free source form) program bsp implicit none character (len = 10) :: c integer :: st

269

Ein- und Ausgabe

open (20, file=’/tmp/testdatei.txt’, status=’OLD’, form=’FORMATTED’, & access=’DIRECT’, recl=15, iostat=st) if (st /= 0) then stop "open-Fehler!" end if read (20, fmt=’(A)’, rec=4, iostat=st) c if (st /= 0) then write (*,*) "read-Error" else write (*,*) c end if close (20) end program bsp

Ausgabe: s einem FO

29.5.6. Positionieren bei sequentiellen Dateien Datensatzzeiger um einen Datensatz zurücksetzen: backspace ([unit=]x [,iostat=y] [,err=z]) Positionieren an den Dateibeginn: rewind ([unit=]x [,iostat=y] [,err=z]) Schreiben eines Dateiendsatzes: endfile ([unit=]x [,iostat=y] [,err=z]) Beispiel: Fortran 90/95-Code (free source form) program bsp

270

Dateien

implicit none character (len = 100), dimension(3) :: c integer :: st = 0 open (20, file=’/tmp/testx.txt’, status=’NEW’, iostat=st) call checkStatus(st, "open-") write (20,*) ’Das ist eine Testdatei’ write (20,*) ’Dies ist Zeile 2 der Testdatei’ write (20,*) ’Jenes die Zeile 3 der Testdatei’ write (20,*) "Jetzt ist’s aber genug" endfile (20) rewind (20, iostat=st) call checkStatus(st, "rewind-") read (20, fmt=555, iostat=st) c call checkStatus(st, "read-") write (*, fmt=555) c backspace (20, iostat=st) call checkStatus(st, "backspace-") read (20, fmt=555, iostat=st) c(1) call checkStatus(st, "read-") write (*, fmt=555) c(1) close (20) 555 format (A) end program bsp subroutine checkStatus(st, ch) integer, intent (in) :: st character (*), intent (in) :: ch if (st /= 0) then close(20) write (*,*) ch // "Fehler!" stop end if end subroutine checkStatus

Ausgabe:

271

Ein- und Ausgabe

Das ist eine Testdatei Dies ist Zeile 2 der Testdatei Jenes die Zeile 3 der Testdatei Jenes die Zeile 3 der Testdatei

29.5.7. inquire Die Anweisung inquire dient der Abfrage einiger Eigenschaften von Dateien oder I/O-Units. inquire (file = x, liste)

mit x ... Dateiname (inkl. Pfad) inquire ([unit =] x, liste)

mit x ... Nummer der I/O-Unit. liste: Element access = x

Kommentar x: • ’SEQ’ ... sequentieller Dateizugriff • ’DIRECT’ ... Direktzugriff

272

Dateien Element action = x

Kommentar x: • ’READ’ • ’WRITE’ • ’READWRITE’ • ’UNDEFINED’

blank = x

x: • ’NULL’ • ’ZERO’

delim = x

x: • ’APOSTROPHE’ • ’QUOTE’ • ’NONE’ • ’UNDEFINED’

direct = x

x: • ’YES’ ... Direktzugriff • ’NO’ ... kein Direktzugriff für diese Datei erlaubt • ’UNKNOWN’ ... unbekannt

err = x

Bei Fehler Sprung zur Anweisungsnummer x

273

Ein- und Ausgabe Element exist = x

Kommentar x: • .TRUE. ... Datei existiert • .FALSE. ... Datei existiert nicht

form = x

x: • ’FORMATTED’ ... Datei geöffnet für formatierte Datensätze • ’UNFORMATED’ ... Datei geöffnet für unformatierte Datensätze • ’UNDEFINED’

formatted = x

x: • ’YES’ ... formatierte Datensätze sind erlaubt • ’NO’ ... formatierte Datensätze sind nicht erlaubt • ’UNKNOWN’ ... unbekannt

iostat = x

274

x ist 0 wenn OPEN fehlerfrei ausgeführt wurde, ansonsten eine systemabhängige positive Fehlernummer

Dateien Element name = x

named = x

Kommentar Der Dateiname wird der Zeichenketten-Variablen x zugewiesen. Hat die Datei keinen Namen, dann ist ist das Ergebnis undefiniert. x: • .TRUE. ... Datei besitzt Namen • .FALSE. ... Datei besitzt keinen Namen

nextrec = x number = x

opened = x

x ... Nummer des nächsten Datensatzes x ... Nummer der mit einer externen Datei verbundenen I/O-Unit. x: • .TRUE. ... Datei ist geöffnet • .FALSE. ... Datei ist nicht geöffnet

pad = x

x: • ’YES’ • ’NO’

275

Ein- und Ausgabe Element position = x

Kommentar x: • ’REWIND’ • ’ASIS’ • ’APPEND’ • ’UNDEFINED’

read = x

x: • ’YES’ • ’NO’ • ’UNKNOWN’

readwrite = x

x: • ’YES’ • ’NO’ • ’UNKNOWN’

recl = x sequential = x

x ... Datensatzlänge bei Direktzugriff x: • ’YES’ ... sequentiell • ’NO’ ... nicht sequentiell • ’UNKNOWN’ ... unbekannt

276

Dateien Element unformatted = x

Kommentar x: • ’YES’ ... unformatierte Datensätze sind erlaubt • ’NO’ ... unformatierte Datensätze sind nicht erlaubt • ’UNKNOWN’ ... unbekannt

write = x

x: • ’YES’ • ’NO’ • ’UNKNOWN’

Beispiel: Datei vorhanden? Fortran 90/95-Code (free source form) program bsp implicit none logical :: l integer :: st inquire (file=’/tmp/testdatei.txt’, exist=l, iostat=st) if (st == 0) then write (*,*) "Datei existiert?", l else write(*,*) "Fehler!" end if ! wenn Datei existiert: Datei existiert? T ! wenn Datei nicht existiert: Datei existiert? F ! wenn aus irgendeinem ein inquire-Fehler auftrat: Fehler! end program bsp

277

Ein- und Ausgabe

Beispiel: Infos zu einer geöffneten Datei Fortran 90/95-Code (free source form) program bsp implicit none logical :: ex character (15) :: di, fo, ac, se integer :: nu, st open (25, file=’/tmp/testdatei.txt’, status=’old’, iostat=st) if(st /= 0) stop "open-Fehler!" inquire (25, exist = ex, direct = di, sequential = se, formatted = fo, & access = ac, number = nu, iostat=st) if(st == 0) then write (*,*) ’EXIST? ’, ex write (*,*) ’DIRECT? ’, di write (*,*) ’SEQUENTIAL? ’, se write (*,*) ’FORMATTED? ’, fo write (*,*) ’ACCESS? ’, ac write (*,*) ’NUMBER? ’, nu else write (*,*) "inquire-Fehler!" end if close(25) ! Ausgabe, z.B. ! EXIST? T ! DIRECT? YES ! SEQUENTIAL? YES ! FORMATTED? YES ! ACCESS? SEQUENTIAL ! NUMBER? 25 end program bsp

29.5.8. Interne Dateien • Interne Dateien sind vom Datentyp character (Zeichen oder Zeichenketten)

278

Dateien

• Das Lesen aus bzw. das Schreiben in interne Dateien erfolgt immer sequentiell Beispiel: Schreiben in eine interne Datei Fortran 90/95-Code (free source form) program bsp character(15) :: ch real :: r = 12.5678 ! Interne Datei "ch" write (ch, *) r write (*,*) ’r lexikalisch groesser als Buchstabe "A"? ’, lge(ch, ’A’) end program bsp

Beispiel: Lesen aus einer internen Datei Fortran 90/95-Code (free source form) program bsp character(15) :: ch = ’12.5678’ real :: r ! Interne Datei "ch" read (ch, ’(F15.5)’) r write (*,*) ’r = ’, r write (*,*) ’r**2 = ’, r**2 end program bsp

279

30. Zeiger 30.1. Was sind Zeiger? Z EIGER (I NFORMATIK )1

30.2. Zeiger in Fortran 95 In Fortran 95 werden Zeiger durch Zufügen des Attributes pointer bei der Deklaration von Variablen erzeugt. datentyp, pointer :: variable Ein so deklarierter Zeiger kann auf andere Zeiger oder auf mittels target gekennzeichnete Variablen verweisen. datentyp, target :: variable Die Zeigerzuordnung erfolgt durch das Symbol =>

1

H T T P :// D E . W I K I P E D I A . O R G / W I K I /Z E I G E R %20% 28I N F O R M A T I K %29

281

Zeiger

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none real, pointer :: ptr real, target :: trg trg = 5.5 ptr => trg write(*,*) ptr ! Ausgabe: 5.50000 ! Zeiger werden bei Bedarf automatisch dereferenziert end program bsp

Abb. 35

30.3. Assoziationsstatus Ein Zeiger kann einen der folgenden Assoziationzustände annehmen: • undefiniert (dangling) • nicht zugeordnet (disassociated, null) • zugeordnet (associated) Der Zuordnungsstatus eines Zeigers ist unmittelbar nach der Deklaration undefiniert. Mittels zeiger => null() oder

282

Assoziationsstatus

nullify(zeiger) kann ein Zeiger auf einen nicht zugeordneten Status gesetzt werden. Verweist ein Zeiger auf einen anderen zugeordneten Zeiger oder ein Target, so ist sein Zustand zugeordnet.

Der Assoziationsstatus eines Zeigers lässt sich über die Funktion associated (zeiger [, ziel])

abfragen. Sinnvoll ist eine derartige Abfrage nur dann, wenn der Zuordnungsstatus nicht undefiniert ist.

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer, pointer :: ptr1 => null() character(20), pointer :: ptr2 character(20), target :: str str = "Hallo, Welt!" ptr2 => str write(*,*) associated(ptr1) ! Ausgabe: F write(*,*) associated(ptr2) ! Ausgabe: T write(*,*) associated(ptr2, ptr1) ! Ausgabe: F write(*,*) associated(ptr2, str) ! Ausgabe: T end program bsp

283

Zeiger

30.4. Speicherplatz dynamisch reservieren und freigeben Für normale Variablen läuft die Speicherplatzverwaltung automatisch ab. Bisher wurden Zeiger immer solchen normalen (Target)Variablen, für die bereits Speicherplatz reserviert war, zugeordnet. Aber auch für Zeiger selbst kann Speicherplatz reserviert werden. Bei der Zeigerdeklaration ist der Zeigerstatus undefiniert oder nicht zugeordnet. Eine Wertzuweisung an eine solche Zeigervariable würde zur Laufzeit einen Speicherzugriffsfehler ergeben. Die Funktion allocate (zeiger1, [zeiger2, ...] [,stat=integervar])

reserviert in Abhängigkeit des Zeiger-Datentyps Speicherplatz für die einzelnen Zeiger. Die Funktion deallocate (zeiger1, [zeiger2, ...] [,stat=integervar])

gibt diesen Speicherplatz wieder frei. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer, pointer :: ptr1 => null(), ptr2 => null() integer :: status allocate(ptr1, stat = status) ptr1 = 2222 write (*,*) "Status = ", status ! Wenn status = 0, dann wurde erfolgreich Speicherplatz reserviert write (*,*) ptr1 ! Ausgabe: 2222

284

Zeiger und Felder

ptr2 => ptr1 ptr1 = 5555 write (*,*) ptr1, ptr2 ! Ausgabe: 5555 5555 deallocate(ptr1) end program bsp

30.5. Zeiger und Felder

Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none integer, dimension(:), pointer :: ptr => null() integer, dimension(5:10), target :: arr = (/55, 66, 77, 88, 99, 111/) ptr => arr write(*,*) ptr ! Ausgabe: 55 ptr => arr(7:) write(*,*) ptr ! Ausgabe: 77 end program bsp

66

77

88

88

99

111

99

111

Beispiel: "ragged array"

285

Zeiger

Abb. 36

Fortran 90/95-Code (free source form) program bsp implicit none type element integer, dimension(:), pointer end type element integer, dimension(5), target :: integer, dimension(2), target :: integer, dimension(4), target ::

286

:: ptr a = (/ 1, 2, 3, 4, 5 /) b = (/ 99, 55 /) c = (/ -11, -12, -13, -14 /)

Verkettete Listen

integer :: i type( element ), dimension(3) :: rarr rarr(1)%ptr => a rarr(2)%ptr => b rarr(3)%ptr => c do i = 1,3 write (*,*) "rarr(", i, "): ", rarr(i)%ptr end do ! Ausgabe ! rarr( 1 ! rarr( 2 ! rarr( 3 end program

): 1 2 3 4 5 ): 99 55 ): -11 -12 -13 -14 bsp

30.6. Verkettete Listen Beispiel: Einfach verkettete Liste (LIFO) Fortran 90/95-Code (free source form) module m1 implicit none type node integer :: id character(5) :: value type(node), pointer :: next => null() end type type(node), pointer :: first => null() private ! Auf alle nachfolgenden Anweisungen kann von aussen nicht zugegriffen werden public :: add_node, write_all, free_all ! Auf die Subroutinen add_node, write_all und free_all ! kann von aussen explizit zugegriffen werden, ! jedoch nicht auf innerhalb der Subroutinen ! deklarierte Datentypen contains subroutine add_node(id, str)

287

Zeiger

implicit none integer, intent(in) :: id character(5), intent(in) :: str type(node), pointer :: new, tmp ! Speicher reservieren allocate(new) ! Werte setzen new%id = id new%value = str ! Am Beginn der Liste einfügen if (associated(first) .eqv. .FALSE.) then first => new else tmp => first first => new first%next => tmp end if end subroutine add_node

subroutine write_all() implicit none type(node), pointer :: tmp tmp => first do if (associated(tmp) .eqv. .FALSE.) exit write(*,*)tmp%id, tmp%value tmp => tmp%next end do end subroutine write_all subroutine free_all() implicit none type(node), pointer :: tmp do tmp => first

288

Verkettete Listen

if (associated(tmp) .eqv. .FALSE.) exit first => first%next deallocate(tmp) end do end subroutine free_all end module m1

program bsp use m1 implicit none call add_node (1, "AAAAA") call add_node (2, "BBBBB") ! ... call add_node (150, "ZZZZZ") call write_all ! Ausgabe: ! 150 ZZZZZ ! 2 BBBBB ! 1 AAAAA call free_all ! Die verkettete Liste wird wieder freigegeben end program bsp

289

Zeiger

Abb. 37

290

31. Vektoren- und Matrizenrechnung In Fortran95 können einige elementare Vektoren- und Matrizenoperationen sehr einfach ausgeführt werden. Beispiel: Addition und Subtraktion von Vektoren (Matrizen) Fortran 90/95-Code (free source form) program bsp implicit none real, dimension(3) :: a = (/3, 2, -5/), b = (/1, -3, -1/) write(*,*) "a+b: ", a+b ! Ausgabe: a+b: 4. -1. -6. write(*,*) "a-b: ", a-b ! Ausgabe: a-b: 2. 5. -4. end program bsp

Beispiel: Multiplikation eines Vektors (einer Matrix) mit einem Skalar Fortran 90/95-Code (free source form) program bsp implicit none real, dimension(3) :: a = (/3, 2, -5/) write(*,*) "3.5*a: ", 3.5*a ! Ausgabe: 3.5*a: 10.5 7. -17.5 end program bsp

Beispiel: Skalarprodukt Fortran 90/95-Code (free source form)

291

Vektoren- und Matrizenrechnung

program bsp implicit none real, dimension(3) :: a = (/3, 2, -5/), b = (/1, -3, -1/) real :: dot_product write(*,*) "a.b: ", dot_product(a, b) ! Ausgabe: 2 end program bsp

Beispiel: Euklidische Norm eines Vektors |x| = Fortran 90/95-Code (free source form)

qP p n 2 x2 = i =1 x i

program bsp implicit none real, dimension(3) :: x = (/3, 2, -5/) real :: x_n ! Norm des Vektors x x_n = sqrt(sum(x**2)) write(*,*) "Die Norm des Vektors (", x, ") beträgt: ", x_n ! Ausgabe: Die Norm des Vektors ( 3.0 2.0 -5.0 ) beträgt: end program bsp

6.164414

Beispiel: Matrizenmultiplikation Fortran 90/95-Code (free source form) program bsp implicit none real, dimension(3,2) :: A = reshape( (/3., 2., 1., 1., 1., 2.5/), (/3, 2/) ) real, dimension(2,2) :: B = reshape( (/1., -3., -1., 5./), (/2, 2/) ) real, dimension(3,2) :: C C = matmul(A, B) write(*,*) write(*,*) write(*,*) write(*,*) ! Ausgabe:

292

"Matrix C =" C(1, :) C(2, :) C(3, :) Matrix C =

Verkettete Listen

! 0.000000 ! -1.000000 ! -6.500000 end program bsp

2.000000 3.000000 11.50000

Beispiel: Transponierte Matrix Fortran 90/95-Code (free source form) program bsp implicit none real, dimension(2,2) :: A = reshape( (/3., 2., 1., -1.5/), (/2, 2/) ), AT AT = transpose(A) write(*,*) write(*,*) write(*,*) ! Ausgabe: ! 3.000000 ! 2.000000

"A =" A(1, :) A(2, :) A = 1.000000 -1.500000

write(*,*) "AT =" write(*,*) AT(1, :) write(*,*) AT(2, :) ! Ausgabe: AT = ! 3.000000 2.000000 ! 1.000000 -1.500000 end program bsp

293

32. Systemroutinen 32.1. Datum und Zeit Die Subroutine date_and_time(datum,zeit)

liefert die Systemzeit in der Form YYYYMMTT und HHMMSS.SSS zurück. datum und zeit sind Character von mindestens 8 bzw. 10 Zeichen Länge. Die vom Programm verbrauchte Rechenzeit (Prozessorzeit) in Sekunden liefert die Subroutine (zeit ist vom Typ Real) cpu_time(zeit)

32.2. Zufallszahlen Die Subroutine random_number(r)

295

Systemroutinen

schreibt gleichverteilte Zufallszahlen im Intervall [0,1) in eine Variable r vom Typ Real (Skalar oder Feld). Mit der Subroutine random_seed()

kann der Zufallszahlengenerator (zufällig) initialisiert werden.

32.3. Kommandozeilenargumente Nicht unbedingt Standard, aber bei etlichen Fortran-Compilern doch als Standardfunktion implementiert, sind die Prozeduren iargc und getarg zum Erfragen der beim Programmstart mitgegebenen Kommandozeilenargumente. Die Funktion i = iargc()

liefert die Anzahl der Kommandozeilenargumente. Der Programmname selbst wird dabei nicht mitgezählt. Die Subroutine getarg(i, c)

liefert den Wert eines bestimmten Kommandozeilenargumentes. i gibt die Position vor (0 ...Programmname, 1 ... 1.Argument, etc.). Der Parameter c ist vom Typ Character. Dort findet sich nach Abarbeitung der Subroutine der zu i gehörende Wert des Kommandozeilenargumentes.

296

33. Von der modularen zur objektorientierten Programmierung 33.1. Module im Detail Die Bezeichnung des Schlüsselworts module weist schon darauf hin, dass Fortran 90/95 eine modulare Softwareentwicklung ermöglicht.

33.1.1. Modulare Programmierung Was ist modulare Programmierung? M ODULARE P ROGRAM MIERUNG 1

Das Modul-Konzept in Fortran 90/95 unterstützt diesen Ansatz vollständig. Das module-Konstrukt gliedert sich schematisch so module ... Datenbereich

1

H T T P :// D E . W I K I P E D I A . O R G / W I K I /M O D U L A R E % 20P R O G R A M M I E R U N G

297

Von der modularen zur objektorientierten Programmierung

Methodenbereich end module ...

Vor dem Datenbereich können noch einige Deklarationen (implicit none, save, etc.) eingefügt sein. Der Methodenbereich wird durch das Schlüsselwort contains angekündigt oder als Interface deklariert. Aber prinzipiell gilt, dass zusammengehörende Daten und die dazugehörenden Methoden (Unterprogramme) in einem Modul zusammengefasst werden.

33.1.2. Zugriffsteuerung Durch Angabe des Schlüsselwort private läßt sich die Sichtbarkeit von Datenelementen einschränken. Auf solcherart deklarierte Variablen läßt sich außerhalb des Moduls nicht zugreifen. public erlaubt den Zugriff auf entsprechend deklarierte Variablen auch von außerhalb. Zweiteres ist Standardverhalten und das Schlüsselwort public muss somit nicht explizit angegeben werden. Beispiel: Fortran 90/95-Code (free source form) module mod_bsp implicit none save ! Datenbereich real, private :: x = 1.2 real :: y = 9.8 contains ! Methodenbereich real function addX (a) real, intent (in) :: a addX = x + a end function addX

298

Module im Detail

end module mod_bsp program bsp use mod_bsp implicit none write (*,*) "Ergebnis1 = ", addX (2.1) write (*,*) "Ergebnis2 = ", y + 2.1 ! Ausgabe: ! Ergebnis1 = 3.300000 ! Ergebnis2 = 11.90000 ! Folgendes geht nicht -> Fehlermeldung: ! write (*,*) "Ergebnis3 = ", x + 2.1 ! 1) x ist private und somit außerhalb des Moduls nicht bekannt ! 2) auch im Hauptprogramm selbst ist kein x deklariert (implicit none, es wäre ohnehin nicht die gleiche Variable wie im Modul mod_bsp) end program bsp

Rein formal läßt sich der Zugriff auf die Daten und/oder Methoden eines Moduls (module procedures) auch auf andere Arten einschränken, z.B. module mod_bsp implicit none save private :: x

! , ....

real :: x = 1.2, y = 9.8 ! ...

oder module mod_bsp implicit none save private

299

Von der modularen zur objektorientierten Programmierung

public :: y, addX

! , ...

real :: x = 1.2, y = 9.8 ! ...

33.1.3. Datenkapselung, COMMONS-Ersatz: Module als Datenbereich

Abb. 38

Module als reinen Datenbereich zu nutzen ist vor allem dann interessant, wenn aus mehreren Programmeinheiten auf die gleichen Daten zugegriffen werden muss, jedoch die zugreifenden Unterprogramme nicht wirklich modulspezifisch sind und dementsprechend nicht als Bestandteil des Moduls angelegt werden. Beispiel: Fortran 90/95-Code (free source form) module konstanten real, parameter :: PI = 3.141593 real, parameter :: E = 2.718282 end module konstanten

! Hauptprogramm program bsp use konstanten implicit none

300

Module im Detail

real :: kreisflaeche write(*,*) ’PI = ’, PI write(*,*) ’E = ’, E write(*,*) ’Kreisflaeche fuer r=2.1 = ’, kreisflaeche(2.1) call calcPiMalE end program bsp

! Unterprogramm 1 real function kreisflaeche(r) use konstanten implicit none real, intent (in) :: r kreisflaeche = r**2 * PI end function kreisflaeche ! Unterprogramm 2 subroutine calcPiMalE() use konstanten implicit none write (*,*) ’PI * E = ’, PI * E end subroutine calcPiMalE ! Ausgabe: ! PI = 3.141593 ! E = 2.718282 ! Kreisflaeche fuer r=2.1 = 13.85442 ! PI * E = 8.539735

301

Von der modularen zur objektorientierten Programmierung

33.1.4. Datenabstraktion: Zusammenfassung von Daten und Methoden in einem Modul

Abb. 39

Sind Daten und Unterprogramme als zusammengehörend zu betrachten, so ist es sinnvoll diese auch gemeinsam in einem Modul abzulegen. Ein Vorteil dabei ist, dass somit die Zugriffssteuerung gezielt eingesetzt werden kann. Moduldaten, die nicht von außerhalb des Moduls geändert werden dürfen, werden als private deklariert. Der Zugriff auf diese Daten kann dann nur noch mittels Methoden des Moduls erfolgen. Beispiel: Fortran 90/95-Code (free source form) module kreis implicit none save real, parameter :: PI = 3.141593 real, private :: r = 0.0 contains subroutine setR(val) real, intent(in) :: val r = val end subroutine setR

302

Module im Detail

real function getR() getR = r end function getR real function kreisflaeche() kreisflaeche = r**2 * PI end function kreisflaeche end module kreis

! Hauptprogramm program bsp use kreis implicit none call setR(5.0) write (*,*) "r = ", getR() write (*,*) "Flaeche = ", kreisflaeche() call sub1(5.0) end program bsp

! Unterprogramm subroutine sub1(val) use kreis implicit none real, intent(in) :: val call setR(val*2.56) write (*,*) "r = ", getR() write (*,*) "Flaeche = ", kreisflaeche() end subroutine sub1 ! Ausgabe: ! r = 5. ! Flaeche = 78.539825 ! r = 12.799999 ! Flaeche = 514.7185

303

Von der modularen zur objektorientierten Programmierung

33.1.5. Modul und Datenverbund

Abb. 40

Das Schlüsselwort private darf in einem Datenverbund nur in Verbindung mit einem Modul Anwendung finden. Einerseits kann die Sichtbarkeit aller Variablen im Datenverbund eingeschränkt werden. Anderseits kann auch der Datenverbund selbst als private deklariert werden. Ein Zugriff auf derart deklarierte Datenelemente ist dann nur noch durch Unterprogramme des gleichen Moduls möglich. Standardmäßig sind sowohl Datenverbund als auch seine Einzelkomponenten, so wie alle anderen nicht zugriffsbeschränkten Datenelemente, in einem Modul öffentlich (public). Beispiel: Öffentlicher Datenverbund Fortran 90/95-Code (free source form) module mod1 save type :: tripel real:: x, y, z end type tripel end module mod1 program bsp use mod1

304

Module im Detail

implicit none type(tripel) :: tr = tripel(10.5, 0.0, -6.5) write(*, *) tr ! Ausgabe: ! 10.5 0.0 -6.5 end program bsp

Beispiel: Öffentlicher Datenverbund mit privaten Datenelementen Fortran 90/95-Code (free source form) module mod1 save type :: tripel private real:: x, y, z end type tripel

contains subroutine createTripel(this, valX, valY, valZ) type(tripel) :: this real, intent(in) :: valX, valY, valZ this%x = valX this%y = valY this%z = valZ end subroutine createTripel

subroutine writeTripel(this) type(tripel) :: this write(*,*) this end subroutine writeTripel end module mod1 program bsp use mod1 implicit none type(tripel) :: tr call createTripel(tr, 10.5, 0.0, -6.5) call writeTripel(tr) ! Ausgabe: ! 10.50000 0.000000 -6.500000

305

Von der modularen zur objektorientierten Programmierung

end program bsp

Beispiel: Privater Datenverbund Fortran 90/95-Code (free source form) module mod1 save type, private :: tripel real :: x = 0.0, y=0.0, z=0.0 end type tripel type(tripel), private :: t contains subroutine changeTripel(valX, valY, valZ) real, intent(in) :: valX, valY, valZ t = tripel(valX, valY, valZ) end subroutine changeTripel subroutine writeTripel() write (*,*) t end subroutine writeTripel end module mod1 program bsp use mod1 implicit none ! Hier könnte z.B. keine Variable vom Typ "triple" angelegt werden, da in dieser PE nicht ! sichtbar (privater Datenverbund des Moduls mod1) call writeTripel ! Ausgabe: ! 0.0 0.0 0.0 call changeTripel(10.5, -5.0, -3.5) call writeTripel ! Ausgabe: ! 10.5 -5. -3.5 call unterprogramm ! Ausgabe: ! 10.5 -5. -3.5 end program bsp subroutine unterprogramm use mod1 call writeTripel end subroutine unterprogramm

306

Module im Detail

Dieses Beispiel scheint auf den ersten Blick im Gegensatz zu den beiden vorherigen Varianten unnötige Einschränkungen aufzuweisen. Im Haupt- und Unterprogramm können keine Variablen des Typs tripel angelegt werden. Im Modul wird immer auf die gleiche Variable t zugegriffen. Das gewählte Beispiel könnte somit als S INGLETON2 beschrieben werden. Es ist außerhalb des Moduls sichergestellt, dass immer nur ein Tripel existiert. Singletons werden auch in der objektorientierten Softwareentwicklung verwendet. Daneben sind auch andere Situationen vorstellbar, in denen sich das Konzept eines privaten Datenverbunds als nützlich erweisen kann.

33.1.6. Die Schnittstelle: Das Modul als Unterprogrammbibliothek

Abb. 41

2

H T T P :// D E . W I K I P E D I A . O R G / W I K I /S I N G L E T O N %20% 28M A T H E M A T I K %29

307

Von der modularen zur objektorientierten Programmierung

Ein Modul kann als Sammelstelle für Unterprogramme dienen quasi eine Bibliothek für häufig und in verschiedenen Kontexten benötigte Prozeduren. Vorteile: • Ordnung • Modul kann in eine eigenständige Datei ausgelagert werden. • Parameter-Datentypüberprüfung. Beispiel: Parameter-Datentypüberprüfung ohne Modul program bsp implicit none integer :: zahl = 5 call unterprogramm(zahl) end program bsp subroutine unterprogramm(a) implicit none real, intent(in) :: a write (*,*) a end subroutine unterprogramm

308

mit Modul module test contains subroutine unterprogramm(a) implicit none real, intent(in) :: a write (*,*) a end subroutine unterprogramm end module test program bsp use test implicit none integer :: zahl = 5 call unterprogramm(zahl) end program bsp

Module im Detail ohne Modul

• gfortran und ifort compilieren dieses Programm ohne Warnhinweis. • Der g95 liefert in diesem Fall zumindest eine Warnung, compiliert jedoch auch das Programm.

mit Modul Bereits beim Compilieren tritt eine Fehlermeldung auf, z.B. bei g95: In file ....f90:20 call unterprogramm(zahl) 1 Error: Type mismatch in parameter ’a’ at (1). Passing INTEGER(4) to REAL(4) Das Programm lässt sich so nicht compilieren.

Die Datenausgabe zur Programmlaufzeit liefert jeweils einen fehlerhaften Wert.

Der Schnittstellenblock: interface Fortran 90/95 kennt das Sprachkonstrukt interface, welches sich in vielerlei Hinsicht nutzbringend verwenden läßt. Schnittstellenblöcke sind modulunabhängig verwendbar. interface [name] [interface-Spezifikationsteil] end interface [name]

Der interface-Spezifikationsteil beinhaltet nur diejenigen Informationen, die für die Deklaration der Schnittstelle relevant sind (z.B. Unterprogrammbezeichnung, Variablendeklaration). Die genaue Festlegung der Unterprogramme (inkl. Ausführungsteil) erfolgt dann außerhalb des Schnittstellenblocks. Ein wesentliches Merkmal des Schnittstellenblocks ist die penible Überprüfung der Unterprogrammparameterdatentypen, so wie das auch beim Einsatz von Modulen geschieht.

309

Von der modularen zur objektorientierten Programmierung

Beispiel: Parameter-Datentypüberprüfung ohne Schnittstellenblock program bsp implicit none integer :: zahl = 5 call unterprogramm(zahl) end program bsp subroutine unterprogramm(a) implicit none real, intent(in) :: a write (*,*) a end subroutine unterprogramm

• gfortran und ifort compilieren dieses Programm ohne Warnhinweis. • Der g95 liefert in diesem Fall zumindest eine Warnung, compiliert jedoch auch das Programm.

mit Schnittstellenblock program bsp implicit none integer :: zahl = 5 interface subroutine unterprogramm(a) real, intent(in) :: a end subroutine unterprogramm end interface call unterprogramm(zahl) end program bsp subroutine unterprogramm(a) implicit none real, intent(in) :: a write (*,*) a end subroutine unterprogramm Bereits beim Compilieren tritt eine Fehlermeldung auf, z.B. bei gfortran: In file ....f90:15 call unterprogramm(zahl) 1 Error: Type/rank mismatch in argument ’a’ at (1) Das Programm lässt sich so nicht compilieren.

Die Datenausgabe zur Programmlaufzeit liefert jeweils einen fehlerhaften Wert.

Generische Unterprogrammschnittstelle Fortran 90/95 ermöglicht generische Methoden. Die im Schnittstellenblock deklarierten Unterprogramme können

310

Module im Detail

damit über den gleichen Unterprogrammnamen aufgerufen werden. Intern erfolgt dann der Aufruf des jeweils passenden Unterprogramms durch die Unterschiede der Datentypen der Unterprogrammparameter. Mittel zum Zweck ist der benannte Schnittstellenblock. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none interface gensub subroutine writeReal(val) real, intent(in) ::val end subroutine writeReal subroutine writeInteger(val) integer, intent(in) ::val end subroutine writeInteger subroutine writeCharacter(val) character, intent(in) :: val end subroutine writeCharacter end interface gensub call gensub(5.5) call gensub(3) call gensub("H") call writeCharacter("X") ! Ausgabe: ! Real-Wert = 5.500000 ! Integer-Wert = 3 ! Zeichen = H ! Zeichen = X end program bsp subroutine writeReal(val) real, intent(in) ::val write (*,*) "Real-Wert = ", val end subroutine writeReal subroutine writeInteger(val) integer, intent(in) ::val write (*,*) "Integer-Wert = ", val end subroutine writeInteger subroutine writeCharacter(val) character, intent(in) ::val write (*,*) "Zeichen = ", val end subroutine writeCharacter

311

Von der modularen zur objektorientierten Programmierung

Operatorüberladung Fortran 90/95 verwendet von Haus aus Operatorüberladung. So können z.B. Variablen arithmetischen Datentyps einfach miteinander addiert werden: c = a + b

Dieser Ausdruck funktioniert unabhängig davon, ob die Variablen vom Typ Ganzzahl oder Gleitkommzahl sind. Und auch für Felder funktioniert diese einfache Form der Addition. Die einzelnen Feldkomponenten werden korrekt addiert. Das ist in anderen Programmiersprachen nicht selbstverständlich. Zusätzlich kann in Fortran 90/95 auch der Programmierer mit Hilfe von Schnittstellenblöcken sogenannte defined operations festlegen. Beispiel: Fortran 90/95-Code (free source form) program bsp implicit none interface operator (.PLUS.) function charAdd(c1, c2) character, intent(in) :: c1, c2 character(len=2) :: charAdd end function charAdd end interface operator (.PLUS.) ! "Addition" mittels definiertem .PLUS.-Operator write (*,*) "c1 .PLUS. c2 = ", "A" .PLUS. "B" ! oder auch mittels Funktion write (*,*) "charAdd () = ", charAdd("A", "B") ! Ausgabe: ! c1 .PLUS. c2 = AB ! charAdd () = AB end program bsp function charAdd(c1, c2) implicit none character, intent(in) :: c1, c2 character(len=2) :: charAdd charAdd = c1 // c2 end function charAdd

312

Module im Detail

Beispiel: nur mit gfortran compilierbar, nicht mit g95 oder ifort Fortran 90/95-Code (free source form) module mod type :: tripel real x, y, z end type end module mod program bsp use mod implicit none interface operator (*) function tripelMult(t1, t2) type(tripel), intent(in) :: t1, t2 type(tripel) :: tripelMult end function tripelMult end interface operator (*) ! Multiplikation mittels überladenem *-Operator write (*,*) "t1 * t2 =", tripel(2.0, 3.0, 4.0) * tripel(1.5, 0.5, 2.0) ! oder auch mittels Funktion write (*,*) "tripelMult () =", tripelMult(tripel(2.0, 3.0, 4.0), tripel(1.5, 0.5, 2.0)) ! Ausgabe: ! t1 * t2 = 3.000000 1.500000 8.000000 ! tripelMult () = 3.000000 1.500000 8.000000 end program bsp function tripelMult(t1, t2) use mod implicit none type(tripel), intent(in) :: t1, t2 type(tripel) :: tripelMult tripelMult = tripel(t1%x * t2%x, t1%y*t2%y, t1%z*t2%z) end function tripelMult

Bei der Verwendung von defined operations sind jedoch einige Bedingungen zu beachten. Neben den defined operations (interface operator) gibt es auch noch defined assignments (interface assignment) für die Überladung des Zuweisungsoperators.

313

Von der modularen zur objektorientierten Programmierung

Schnittstellenblock und Modul

Beim vorigen Beispiel bestand das Problem, dass nur einer der getesteten Compiler eine ausführbare Datei zu Stande brachte. Abhilfe schaffen kann die Verlagerung des Schnittstellenblocks in das Modul unter Zuhilfenahme von module procedure. Beispiel: Diesen Programmcode schlucken sowohl gfortran, g95 als auch ifort problemlos Fortran 90/95-Code (free source form) module mod type :: tripel real x, y, z end type interface operator (*) module procedure tripelMult end interface operator (*) contains function tripelMult(t1, t2) implicit none type(tripel), intent(in) :: t1, t2 type(tripel) :: tripelMult tripelMult = tripel(t1%x * t2%x, t1%y*t2%y, t1%z*t2%z) end function tripelMult end module mod program bsp use mod implicit none ! Multiplikation mittels überladenem *-Operator write (*,*) "t1 * t2 =", tripel(2.0, 3.0, 4.0) * tripel(1.5, 0.5, 2.0) ! oder auch mittels Funktion write (*,*) "tripelMult () =", tripelMult(tripel(2.0, 3.0, 4.0), tripel(1.5, 0.5, 2.0)) ! Ausgabe: ! t1 * t2 = 3.000000 1.500000 8.000000 ! tripelMult () = 3.000000 1.500000 8.000000 end program bsp

314

Module im Detail

Unterprogramme: Die Übergabe optionaler und benannter Parameter

Der Einsatz optionaler Parameter wurde bereits im Kapitel U NTERPROGRAMME3 abgehandelt. Zusätzlich unterstützt Fortran 90/95 auch die Verwendung von benannten Parametern (argument keywords). Dazu ist es erforderlich, dass das Unterprogramm ein explizites Interface aufweist, wie das z.B. bei Einbindung von Unterprogrammen in Module automatisch der Fall ist. Beispiel: Fortran 90/95-Code (free source form) module m1 contains subroutine abc( var1, var2 ) implicit none integer, intent( in ) :: var1, var2 write( *, * ) var1, var2 end subroutine abc end module m1 program bsp use m1 implicit none call abc( 12, 99 ) call abc( var2 = 99, var1 = 12 ) call abc( var2 = 12, var1 = 99 ) call abc( 12, var2 = 99 ) ! call abc( var1 = 12, 99 ) ! so funktioniert das nicht ! Ausgabe: ! 12 99 ! 12 99 ! 99 12 ! 12 99 end program bsp

3

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20U N T E R P R O G R A M M E %23O P T I O N A L E %20P A R A M E T E R

315

Von der modularen zur objektorientierten Programmierung

33.1.7. Sonstiges • use modulbezeichnung, only : modulelemente • use modulbezeichnung => bezeichnung

33.2. Objektorientierte Programmierung Modulares Programmieren reißt heutzutage niemanden mehr vom Hocker und selbst objektorientierte Konzepte sind seit spätestens Ende der 80-Jahre des vergangenen Jahrhunderts Stand der Technik. Im akademischen Bereich waren diese Dinge natürlich schon früher bekannt. Fortran hat in diesem Bereich also nie eine Vorreiterrolle inne gehabt. Nach jeweils kurzen Nachdenkphasen haben aber die Fortran-Leute unerschrocken auch in diesem Bereich nachgezogen. Fortran bildet also aufgrund seiner langen Geschichte ein weites Spektrum der Programmierparadigmen ab: vom prozeduralen Programmieren (FORTRAN 77) über das modulare Programmieren (Fortran 90/95) hin zum objektorientierten Programmieren (Fortran 2003). Fortran 90/95 ist keine typisch objektorientierte Sprache. Trotzdem lässt sich mit den modularen Spracheigenschaften von Fortran 90/95 bereits in weiten Bereichen Objektorientierung simulieren beziehungsweise nachbauen. Aber erst mit Fortran 2003 lässt sich wirklich komfortabel objektorientiert programmieren. Diese Fortran-Version wirbt dann auch „offiziell“ mit diesem Merkmal. Welche Eigenschaften verbindet man typischerweise mit Objektorientierung? Da wären 1. Klassen - Datenkapselung und Datenabstraktion 2. Objekte

316

Objektorientierte Programmierung

3. Vererbung 4. Statische Polymorphie: Überladen von Funktionen (und Operatoren) 5. Run-Time-Polymorphie Welche dieser Merkmale bietet Fortran 90/95 von Haus aus und was läßt sich relativ einfach nachbauen?

33.2.1. Klassen - Datenkapselung und Datenabstraktion Was ist eine Klasse? • K LASSE ( OBJEKTORIENTIERTE P ROGRAMMIERUNG )4 • K LASSE (UML)5 Ein Fortran 90/95-Modul sieht sehr ähnlich aus wie eine Klasse in der objektorientierten Programmierung und ist dementsprechend auch Ausgangspunkt für den objektorientierten Ansatz in Fortran 90/95. Klasse Klassenbezeichner Datenbereich (Attribute) Methodenbereich (Operationen)

Fortran 90/95 module ... ! Datenbereich contains ! Methodenbereich end module ...

Einen grundlegenden Mechanismus zum Schreiben objektorientierter Programme stellt Fortran 90/95 somit in Form der Module zur Verfügung. Jetzt stellt sich aber die Frage, wie diese Klasse instantiiert werden soll. Das wird im Abschnitt Objekte gezeigt. 4 5

H T T P :// D E . W I K I P E D I A . O R G / W I K I /K L A S S E %20% 28 O B J E K T O R I E N T I E R T E %20P R O G R A M M I E R U N G %29 H T T P :// D E . W I K I P E D I A . O R G / W I K I /K L A S S E %20%28UML%29

317

Von der modularen zur objektorientierten Programmierung

33.2.2. Objekte

Was sind Objekte? O BJEKT (P ROGRAMMIERUNG )6

Ein einfaches Modul mit ein paar konventionellen Datenelementen und Prozeduren ist noch keine Klasse, aus der Objekte zu erzeugen wären. Dazu bedarf es noch eines Unterscheidungskriteriums zwischen den einzelnen Objekten. Dieses Unterscheidungskriterium kann, wie auch schon früher im Teilkapitel Modul und Datenverbund7 gezeigt, mittels Datenverbund hergestellt werden. Die Objekte werden somit nicht über den Modulnamen als Klasse angesprochen, sondern über die DatenverbundBezeichnung. Auch das ist keine neue Erkenntnis, sondern eine geschickte Ausnutzung eines Mechanismus, den Fortran 90/95 standardmäßig mit Modulen und Datenverbund zur Verfügung stellt.

Beispiel:

6 7

318

H T T P :// D E . W I K I P E D I A . O R G / W I K I /O B J E K T %20% 28P R O G R A M M I E R U N G %29 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 2095%3A%20M O D U L E %20 U N D %20OOP%23M O D U L %20 U N D % 20D A T E N V E R B U N D

Objektorientierte Programmierung

Abb. 42

Fortran 90/95-Code (free source form) module tripelClass implicit none save type :: tripel real:: x, y, z end type tripel contains subroutine write(this) type(tripel), intent(in) :: this write(*, *) "********** Tripel **********" write(*, *) this end subroutine end module tripelClass program bsp use tripelClass implicit none type(tripel) :: obj1 = tripel(1.5, 0.0, -6.5)

319

Von der modularen zur objektorientierten Programmierung

type(tripel) :: obj2 = tripel(2.5, 1.0, -4.5) type(tripel) :: obj3 = tripel(3.5, 2.0, -2.5) call write(obj1) call write(obj2) call write(obj3) ! Ausgabe: ! ********** Tripel ********** ! 1.500000 0.000000 ! ********** Tripel ********** ! 2.500000 1.000000 ! ********** Tripel ********** ! 3.500000 2.000000 end program bsp

-6.500000 -4.500000 -2.500000

Weitere wichtige Elemente beim Erzeugen und Zerstören von Objekten sind in der OOP die sogenannten Konstruktoren und Destruktoren. Was sind Konstruktoren und Destruktoren? KONSTRUKTOREN UND D ESTRUKTOREN8 Konstruktoren und Destruktoren kennt Fortran 90/95 natürlich nicht. Im Bedarfsfall sind diese Elemente also mittels konventioneller Unterprogramme nachzubilden und dann jeweils explizit in den entsprechenden Programmabschnitten, nach Erzeugung beziehungsweise beim Abbau des jeweiligen Objektes, manuell aufzurufen.

33.2.3. Vererbung Was ist Vererbung? V ERERBUNG (P ROGRAMMIERUNG )9 8 9

320

H T T P :// D E . W I K I P E D I A . O R G / W I K I /K O N S T R U K T O R E N %20 U N D % 20D E S T R U K T O R E N H T T P :// D E . W I K I P E D I A . O R G / W I K I /V E R E R B U N G %20% 28P R O G R A M M I E R U N G %29

Objektorientierte Programmierung

Das OOP-Prinzip „Vererbung“ ist in Fortran 90/95 nur über Umwege realisierbar. Fortran 90/95 kennt konzeptionsbedingt für diesen Zweck keinen einfachen programmtechnischen Mechanismus. Nachfolgend wird anhand eines kleinen und überschaubaren Beispiels eine mögliche Lösung demonstriert. Beispiel:

Abb. 43

Fortran 90/95-Code (free source form) module tripelClass implicit none save type :: tripel real:: x, y, z end type tripel contains subroutine write(this) type(tripel), intent(in) :: this write(*, *) "********** Tripel **********" write(*, *) this

321

Von der modularen zur objektorientierten Programmierung

end subroutine end module tripelClass module coordClass use tripelClass implicit none save type :: coord type(tripel) :: tr integer :: id end type contains subroutine constructCoord(this, t, i) implicit none type(coord), intent(out) :: this type(tripel), intent(in) :: t integer :: i this%tr = t this%id = i end subroutine constructCoord

subroutine writeCoord(this) implicit none type(coord), intent(in) :: this write(*, "(A, I5, A)") "******************* KOORDINATE ", this%id, " *******************" call write(this%tr) end subroutine writeCoord end module coordClass program bsp use coordClass implicit none type(coord) :: obj1 = coord(tripel(1.5, 0.0, -6.5), 1005) type(coord) :: obj2 = coord(tripel(2.5, 1.0, -4.5), 1006) type(coord) :: obj3 = coord(tripel(3.5, 2.0, -2.5), 1007) call writeCoord(obj1) call writeCoord(obj2) call writeCoord(obj3) ! Ausgabe: ! ******************* KOORDINATE

322

1005 *******************

Objektorientierte Programmierung

! ********** Tripel ********** ! 1.500000 0.000000 ! ******************* KOORDINATE ! ********** Tripel ********** ! 2.500000 1.000000 ! ******************* KOORDINATE ! ********** Tripel ********** ! 3.500000 2.000000 end program bsp

-6.500000 1006 ******************* -4.500000 1007 ******************* -2.500000

33.2.4. Statische Polymorphie: Überladen von Funktionen (und Operatoren) Das Überladen von Funktionen und Operatoren unterstützt Fortran 90/95 wiederum standardmäßig. Diese Konzepte wurden schon in den Abschnitten • G ENERISCHE _U NTERPROGRAMMSCHNITTSTELLE10 • O PERATORÜBERLADUNG11 und • S CHNITTSTELLENBLOCK UND M ODUL12 kurz erläutert.

33.2.5. Run-Time-Polymorphie Polymorphie zur Laufzeit eines Programmes ist mit den Mitteln von Fortran 90/95 nur einigermaßen aufwendig und kompliziert 10

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_ F O R T R A N _95%3A_M O D U L E _ U N D _OOP%23G E N E R I S C H E _ UN T E R P R O G R A M M S C H N I T T S T E L L E 11 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95% 3A_M O D U L E _ U N D _OOP%23O P E R A T O R .C3.BC B E R L A D U N G 12 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _ 95%3A_M O D U L E _ U N D _OOP%23S C H N I T T S T E L L E N B L O C K %20 U N D % 20M O D U L

323

Von der modularen zur objektorientierten Programmierung

nachzubauen, jedoch prinzipiell möglich. Es sei zu diesem Thema auf die weiterführende Literatur verwiesen.

33.3. Ausblick Sind die Methoden zur Nachbildung objektorientierter Mechanismen auch in Fortan 2003 verwendbar? Prinzipiell schon, jedoch bietet Fortran 2003 bessere und erweiterte Möglichkeiten zur Behandlung dieses Themas. Dort wurde nämlich das Prinzip des Datenverbunds wesentlich erweitert. Ein type-Block kann dann neben den Datenelementen auch Unterprogramme beinhalten, das Schlüsselwort extends zwecks Vererbungmechanismus ist vorhanden, etc. Das in Fortran 90/95 als Datenbund/Struktur verwendbare type-Konstrukt wurde also in Fortran 2003 zu einer Klasse, ähnlich wie es in anderen Programmierspachen unter der Bezeichnung class bekannt ist, aufgerüstet.

33.4. Literatur 33.4.1. Quellen • D ECYK : S CIENTIFIC C OMPUTING WITH F ORTRAN 9513 • G RAY, R OBERTS : O BJECT-B ASED P ROGRAMMING IN F ORTRAN 9014

13

H T T P :// E X O D U S . P H Y S I C S . U C L A . E D U /F O R T R A N 95/ PSTIR E S E A R C H L E C S E R I E S 1. H T M L 14 H T T P :// W W W . C C S . L A N L . G O V /CCS/CCS-{}4/ P D F / O B F 90. P D F

324

Literatur

33.4.2. Weiterführende Literatur • • • • •

D ECYK , N ORTON , S ZYMANSKI : I NTRODUCTION TO O BJECTO RIENTED C ONCEPTS U SING F ORTRAN 90, 199615 D ECYK , N ORTON , S ZYMANSKI : H OW TO E XPRESS C++ C ONCEPTS IN F ORTRAN 90. 1997 16 D ECYK , N ORTON , S ZYMANSKI : H OW TO S UPPORT I NHERITANCE AND R UN -T IME P OLYMORPHISM IN F ORTRAN 90, 1998 17 D ECYK , N ORTON : A S IMPLIFIED M ETHOD FOR I MPLEMENTING RUN -T IME P OLYMORPHISM IN F ORTRAN 95, 200418 D ECYK , G ARDNER : O BJECT-O RIENTED D ESIGN PATTERNS IN F ORTRAN 95, 200619

15

H T T P :// E X O D U S . P H Y S I C S . U C L A . E D U /F O R T R A N 95/F90_ OB J E C T S.P D F 16 H T T P :// E X O D U S . P H Y S I C S . U C L A . E D U /F O R T R A N 95/E X P R E S S C+ +. P D F 17 H T T P :// E X O D U S . P H Y S I C S . U C L A . E D U /F O R T R A N 95/S T O P W A T C H . PDF

18

H T T P :// E X O D U S . P H Y S I C S . U C L A . E D U /F O R T R A N 95/

19

H T T P :// E X O D U S . P H Y S I C S . U C L A . E D U /F O R T R A N 95/

S I M P L I F I E D RT. P D F

FO R T R A NPA T T E R N S.P D F

325

34. Offizielle Fortran 95-Erweiterungen Hier sind jene ISO/IEC-Standards angeführt, die nicht Teil des Original-Fortran 95-Standards sind, sondern erst später als offizielle Fortran 95-Erweiterungen formuliert wurden. Etliche Fortran 95-Compiler bieten diese Features derzeit noch nicht oder nur teilweise.

34.1. Zeichenketten variabler Länge • Offizielle Bezeichnung: Fortran, Part 2, Varying length character strings • Standards: ftp://ftp.liv.ac.uk/pub/fortran_std/is1539-2.html ISO/IEC 1539-2 : 1994 ftp://ftp.nag.co.uk/sc22wg5/N1351-N1400/N1375.pdf ISO/IEC 1539-2 : 2000

• Referenzmodul-Download-Adressen: ftp://ftp.nag.co.uk/sc22wg5/ISO_VARYING_STRING/Sample_Module/iso_vs - programmiert in Standard-Fortran 95 und daher portabel ftp://ftp.nag.co.uk/sc22wg5/ISO_VARYING_STRING/Sample_Module/iso_vs - verwendet Sprachmittel gem. Fortran 95-Erweiterung ISO/IEC TR 15581 : 1999 bzw. 2001 (enhanced data type facilities). Dieses Modul soll effizienter als iso_vst.f95 sein und Speicherlecks vermeiden

327

Offizielle Fortran 95-Erweiterungen

Diese Fortran 95-Erweiterung ermöglicht in einfacher Weise das Arbeiten mit Zeichenketten variabler Länge. Die notwendigen Datenelemente und Funktionen sind im Modul iso_varying_string hinterlegt. Die nötigen Programmabläufe zur dynamische Anpassung des jeweils erforderlichen Speicherplatzes übernehmen somit die Unterprogramme dieses Moduls. Eine explizite Begrenzung der maximalen Zeichenkettenlänge ist nicht vorgesehen. Einschränkungen ergeben sich nur durch Hardwarerestriktionen bzw. die Programmkomplexität. In den getesteten aktuellen Fortran 95-Compilern (gfortran, g95 und ifort) ist mit Stand 01.01.2007 diese Funktionalität noch nicht inkludiert. Zur Nutzung dieses Features mit diesen Compilern ist deshalb der Download und die Einbindung einer der o.a. Moduldateien erforderlich (oder man schreibt selbst ein entsprechendes standardkonformes Modul). Beispiel: Fortran 90/95-Code (free source form) program bsp use iso_varying_string implicit none type( varying_string ) :: str str = "Wiki" write (*,*) len(str) write (*,*) char(str) str = str // "books" write (*,*) len(str) write (*,*) char(str) ! Ausgabe ! 4 ! Wiki ! 9 ! Wikibooks end program bsp

Compilieren, Linken:

328

Bedingte Compilierung

gfortran -o bsp iso_vsta.f95 bsp.f90

Prinzipiell gelten für Zeichenketten mit variabler Länge die gleichen generisch-intrinsischen Funktionsbezeichner wie für normale Zeichenketten. Auch Stringkonkatenation, Zuweisung und Vergleichsoperationen sind wie gewohnt erlaubt. Zuätzlich kommen noch einige neue Funktionen hinzu: Funktionsbezeichner var_str

Kommentar Datentypkonvertierung. character → varying_-

string get, put, put_line insert replace remove extract split

I/O Einfügen eines Teilstrings Ersetzen eines Teilstrings Entfernen eines Teilstrings Extrahierung eines Teilstrings Einen String in zwei Strings splitten.

34.2. Bedingte Compilierung • Standard: [ftp://ftp.nag.co.uk/sc22wg5/N1301N1350/N1306.pdf ISO/IEC 1539-3 : 1998. Conditional Compilation] Mannigfaltig sind die Gründe, welche den Einsatz bedingter Compilierung (conditional compilation, Kurzform: coco) erstrebenswert erscheinen lassen. Seien es die unterschiedlichen Betriebssystemkonventionen zur Vergabe von Pfad- und Dateinamen, unterschiedliche Anforderungen an Entwickler- und Releaseversionen eines Programmes oder auch spezielle interna-

329

Offizielle Fortran 95-Erweiterungen

tionale Marktbedürfnisse, die Programmvarianten erfordern. All diese Bedürfnisse und noch viel mehr kann coco befriedigen. Weder g95, noch gfortran oder ifort bieten bisher von Haus aus die Möglichkeit zur "conditional compilation". Es gibt aber externe Tools zur ISO/IEC 1539-3, die als Präprozessor fungieren können und somit das gewünschte Verhalten erzeugen, z.B. das Programm COCO 1 . Beispiel: Die Datei bsp.fpp: ?? integer, parameter :: varianteA = 1, varianteB = 2 ?? integer :: flag = 1 program bsp ?? if ( flag == varianteA ) then write (*,*) "Variante A" ?? else if (flag == varianteB) then write (*,*) "Variante B" ?? endif end program bsp

mit der Set-Datei bsp.set: ?? integer :: flag = 2 ?? alter: delete

ergibt nach einem Präprozessorlauf coco bsp folgendes FortranProgramm bsp.f90

program bsp write (*,*) "Variante B"

1

330

H T T P :// U S E R S . E R O L S . C O M / D N A G L E / C O C O . H T M L

Floating-point Exceptions

end program bsp

Beispiel: Wird die coco-Anweisung alter: delete in der Set-Datei weggelassen, so werden die überflüssigen Zeilen nicht gelöscht, sondern nur auskommentiert (shift). Standardmäßig entspricht dies beim coco-Präprozessor einer alter: shift3-Set-Anweisung (!?>). Die Set-Datei bsp.set ?? integer :: flag = 2

würde mit der obigen bsp.fpp-Datei nach einem coco bsp also diesen Fortran-Code liefern

!?>?? integer, parameter :: varianteA = 1, varianteB = 2 !?>?? integer :: flag = 1 program bsp !?>?? if ( flag == varianteA ) then !?>

write (*,*) "Variante A"

!?>?? else if (flag == varianteB) then write (*,*) "Variante B" !?>?? endif end program bsp !?>?? This was produced using the following SET file !?>?? integer :: flag = 2

34.3. Floating-point Exceptions • Standard: [ftp://ftp.nag.co.uk/sc22wg5/N1351N1400/N1378.pdf ISO/IEC TR 15580 : 1998. Floating-point exception handling]

331

Offizielle Fortran 95-Erweiterungen

Im Fortran 2003-Standard sind Module betreffend IEEE 754Standard (IEEE Standard for Binary Floating-Point Arithmetic) enthalten. Näheres dazu wird im Fortran 2003-Kapitelabschnitt D IE INTRINSISCHEN IEEE-M ODULE 2 beschrieben.

34.4. Allocatable Components • Standard: [ftp://ftp.nag.co.uk/sc22wg5/N1351N1400/N1379.pdf ISO/IEC TR 15581 : 1999. Enhanced data type facilities] Diese

Erweiterung

bezieht

sich

auf

das

Schlüsselwort

allocatable. In Standard-Fortran 90/95 ist die dynamische Allokation von Speicherplatz für Felder mit dem Attribut allocatable eigentlich nur in einem lokalen Kontext möglich. Der Technical Report 15581 fordert, dass solche Felder darüber hinaus auch in den Anwendungsbereichen • Rückgabewert von Funktionen • Unterprogrammparameter • Feldelemente in Datenverbunden uneingeschränkt verwendbar sein sollen. Die Enhanced Data Type Facilities werden bereits standardmäßig vom aktuellen g95-, gfortran-, ifort- und Sun-Fortran-Compiler unterstützt. Beispiel: Rückgabewert Fortran 90/95-Code (free source form) program bsp implicit none

2

332

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A% 20F O R T R A N %202003%3A%20I N T R I N S I S C H E %20M O D U L E %23D I E % 20 I N T R I N S I S C H E N %20IEEE-{}M O D U L E

Allocatable Components

write ( *, * ) fun_all( 5 ) write ( *, * ) fun_all( 7 ) ! Ausgabe: ! 1 2 3 4 5 ! 1 2 3 4 5 6 7 contains function fun_all( n ) implicit none integer, dimension( : ), allocatable :: fun_all integer, intent( in ) :: n integer :: j, st allocate( fun_all( n ), stat = st ) if( st == 0 ) then forall( j = 1 : n ) fun_all(j) = j end forall else write( *, * ) "Allocate-Fehler" end if end function fun_all end program bsp

Beispiel: Unterprogrammparameter Fortran 90/95-Code (free source form) program bsp implicit none integer, dimension( : ), allocatable :: dynarr integer :: j allocate( dynarr( 3 ) ) forall( j = 1 : 3 ) dynarr( j ) = j * 2 end forall call fun_all( dynarr ) write( *, * ) "Out: ", dynarr deallocate( dynarr ) allocate( dynarr( 5 ) ) forall( j = 1 : 5 ) dynarr( j ) = j * 3 end forall

333

Offizielle Fortran 95-Erweiterungen

! ! ! ! ! !

call fun_all( dynarr ) deallocate( dynarr ) Ausgabe: Argument: 2 4 6 (De)Allocate im UP: 88 99 Out: 88 99 Argument: 3 6 9 12 15 (De)Allocate im UP: 88 99 contains subroutine fun_all( a ) implicit none integer, dimension( : ), allocatable, intent( inout ) :: a write( *, * ) "Argument:", a

deallocate( allocate( a a(1) = 88 a(2) = 99 write( *, * end subroutine end program bsp

a ) (2) )

) "(De)Allocate im UP:", fun_all

a

Mit Standard-Fortran 90/95 könnten sie zwar das allozierte Feld als Parameter aus dem Hauptprogramm an das Unterprogramm übergeben, dort wäre es aber nicht als allocatable kennzeichenbar und somit im Unterprogramm nicht in der gezeigten Art und Weise (de)allozierbar. Mittels StandardkonformitätsCompileroptionen, z.B. • Intel Fortran Compiler: -stand • g95, gfortran: -std=f95 ist überprüfbar, welche Möglichkeiten Standard-Fortran 95 bietet und welche Eigenschaften den Erweiterungen zuschreibbar sind. Beispiel: allocatable array im Datenverbund Fortran 90/95-Code (free source form) program bsp implicit none type struktur

334

Allocatable Components

integer :: nr integer, dimension( : ), allocatable :: arr end type struktur type( struktur ) :: a1, a2 allocate( a1%arr( 5 ) ) allocate( a2%arr( 2 ) ) a1%nr a1%arr(1) a1%arr(5) a2%nr a2%arr(1) a2%arr(2)

= = = = = =

9453 1 5 9454 11 22

write ( *, * ) "a1 =" , a1%nr, a1%arr write ( *, * ) "a2 =", a2%nr, a2%arr ! Ausgabe: ! a1 = 9453 1 0 0 0 5 ! a2 = 9454 11 22 end program bsp

335

Teil V.

Fortran 2003

337

35. Programmaufbau 35.1. Programmaufbau und Zeilenformat Der grundlegende Programmaufbau und das Zeilenformat von Fortran 90/95 wurden in Fortran 2003 beibehalten. Neben der free source form ist aus Kompatibilitätsgründen auch noch immer die alte, aus FORTRAN 77 bekannte, fixed source form gültig. Eine Zeile darf auch in Fortran 2003 bei Verwendung der free source form standardmäßig maximal 132 Zeichen beinhalten. Ein symbolischer Name darf nun höchstens 63 Zeichen lang sein. Eine Anweisung darf sich maximal über 256 Zeilen erstrecken. Das Zeilenfortsetzungszeichen ist wie in Fortran 90/95 das Kaufmanns-Und: &.

35.2. Zeichenvorrat Der Fortran 2003-Zeichenvorrat wurde gegenüber Fortran 90/95 erweitert:

339

Programmaufbau

35.3. Anwendungsgebiet der neu hinzugekommenen Zeichen Von den in Fortran 2003 neu zugefügten Zeichen haben nur die eckigen Klammern einen konkreten Anwendungsbereich als Kennzeichnung von Feldkonstruktoren. Ein Feldkonstruktor darf neben der aus Fortran 95 bekannten Form (/ werte /)

nun auch mit eckigen Klammern geschrieben werden [ werte ]

Beispiel: Fortran 2003-Code ! bsp.f03 program bsp implicit none integer, dimension( 3 ) :: a = [ 20, 33, 55 ] integer, dimension( 2 ) :: b = (/ 44, 55 /) write( *, *) a write( *, *) b ! Ausgabe: ! 20 33 55 ! 44 55 end program bsp

Kompilieren, linken: g95 -o bsp bsp.f03

340

36. Datentypen 36.1. Intrinsische Datentypen Die aus Fortran 90/95 bekannten intrinsischen Datentypen sind weiterhin uneingeschränkt gültig. Datentyp integer real (double precision) complex logical character

Kommentar Ganzzahlen Reelle Zahlen einfacher Genauigkeit Reelle Zahlen doppelter Genauigkeit Komplexe Zahlen Logischer Datentyp (.true., .false.) Zeichen(kette)

Im Umfeld des character-Datentyps gab es einige kleinere Ergänzungen: • Unterstützung internationaler Zeichensätze in Rahmen der ISO 10646-Norm (U NIVERSAL C HARACTER S ET1 )

1

H T T P :// D E . W I K I P E D I A . O R G / W I K I /U N I V E R S A L %20C H A R A C T E R % 20S E T

341

Datentypen

• Die Funktion selected_char_kind ist neu. Ihre Funktionsweise ist äquivalent zu den bereits aus Fortran 90/95 bekannten Funktionen selected_int_kind und selected_real_kind.

36.2. Enumeration Mit Fortran 2003 sind auch in dieser Programmiersprache Enumerationen (Aufzählungstypen) möglich. Die Werte in einer solchen Enumeration besitzen einen integer-Datentyp. enum, bind( C ) enumerator :: wert(e) // ... end enum Die von C-Enumerationen bekannten Eigenschaften gelten gleichermaßen für Fortran-Enumerationen, z.B.: • ohne explizite Zuweisung von Werten wird mit dem Wert 0 gestartet. • ohne explizite Zuweisung von Werten wird in der Anordnungsreihenfolge der Elemente sukzessiv immer um 1 hochgezählt. • Wurde dem Vorgängerelement eine Ganzzahl zugewiesen, dem Element jedoch nicht, so ist der Wert dieses Elementes die dem Vorgängerelement zugeordnete Ganzzahl + 1. Beispiel: Fortran 2003-Code program bsp implicit none integer :: wert enum, bind( C ) enumerator :: MON, DIE, MIT = 3, DON, FRE = 5, SAM = 66, SON = 77 end enum write( *, * ) MON write( *, * ) MIT write( *, * ) SAM

342

Derived Type

wert = 4 if( wert == MIT + 1 ) then write( *, * ) "Donnerstag" endif ! Ausgabe: ! 0 ! 3 ! 66 ! Donnerstag end program bsp

Obwohl der Fortran 2003-Working Draft J3/04-007 durch das bind(c) eine zwingende Anbindung an einen Aufzählungstyp in der Programmiersprache C vorgaukelt, ist dies nicht der Fall. Fortran-Enumerationen funktionierten auch ohne entsprechendes C-Gegenstück. Sie werden im Fortran 2003-Working Draft auch nicht im Abschnitt Interoperability with C geführt, sondern direkt im Abschnitt über die Fortran-Datentypen. Diese Tatsache dürften die Compilerbauer auch unterschiedlich interpretieren. So wäre beim g95-Compiler das Attribut bind(C) nicht unbedingt erforderlich, ist jedoch möglich. Beim Einsatz des gfortran ist der Zusatz bind(C) obligatorisch. Aus Kompatibilitätsgründen ist somit immer die strikte Schreibweise nach Fortran 2003-Standard empfehlenswert. Der Intel Fortran Compiler 9.1 unterstützt dieses Sprachmerkmal ohnehin noch nicht.

36.3. Derived Type Der Derived Type wurde in Fortran 2003 wesentlich erweitert. Er ist nun kein reiner Datenverbund wie noch in Fortran 90/95, sondern eine richtige Klasse. Genauer beschrieben wird dieser Typ später im Kapitel zur OOP, hier zunächst nur einige einfache Erweiterungsmerkmale gegenüber Fortran 90/95.

343

Datentypen

36.3.1. Benannte Parameter Beispiel: Fortran 2003-Code program bsp implicit none type test integer :: i character( 20) :: str end type

type( test ) :: t1 = test ( i = 1, str = "Wiesenfeld" ) write( *, *) t1 ! Ausgabe: ! 1 Wiesenfeld end program bsp

Die Verwendung von benannten Parametern bei der Konstruktion einer Derived Type-Variable kann vor allem in Verbindung mit Vorgabewerten sinnvoll sein.

36.3.2. Vorgabewerte Ab Fortran 2003 dürfen Variablen in einem Derived Type auch mit Vorgabewerten (default values) belegt werden. Beispiel: Fortran 2003-Code program bsp implicit none type test integer :: i = -1 character( 20) :: str = "NN" end type type( test ) :: t1 = test () type( test ) :: t2 = test ( str = "Wiesenfeld" ) type( test ) :: t3 = test ( str = "Walddorf", i = 1 )

344

Derived Type

write( *, *) t1 write( *, *) t2 write( *, *) t3 ! Ausgabe: ! -1 NN ! -1 Wiesenfeld ! 1 Walddorf end program bsp

345

37. Zeiger 37.1. Prozedurenzeiger 37.1.1. Einführung Mit dem 2003er-Standard unterstützt auch Fortran Zeiger auf Prozeduren (procedure pointer, Funktionszeiger). Diese spielen auch eine wichtige interne Rolle bei der Realisierung objektorientierter Mechanismen und beim C-Binding. Schematisch wird ein Prozedurenzeiger so deklariert: procedure( [name] ), pointer :: zeigername Die Angabe von name ist optional. Wird an dieser Stelle ein Name, z.B. ein Unterprogrammbezeichner angegeben, so bedeutet dies, dass der Prozedurenzeiger mit allen Unterprogrammen, die das gleiche Interface aufweisen, kompatibel ist. Prozedurenzeiger können wie normale Zeiger gehandhabt werden. Beispiel: Fortran 2003-Code program bsp implicit none procedure(up), pointer :: pptr => null() pptr => ooops call pptr ! Ausgabe:

347

Zeiger

!

ooops

contains subroutine ooops() write( *, * ) "ooops" end subroutine ooops subroutine up() end subroutine up end program bsp

37.1.2. Prozedurenzeiger mit implizitem Interface Bei der Deklaration eines Prozedurenzeigers muss keine explizite Schnittstelle angegeben werden. Im Folgenden wird dies am Beispiel eines mit pptr2 benannten Prozedurenzeigers demonstriert. Beispiel: Fortran 2003-Code program bsp implicit none procedure( up ) , pointer :: pptr1 => null() procedure( ) , pointer :: pptr2 => null() procedure( add ), pointer :: pptr3 => null() pptr1 => ooops pptr2 => ooops call pptr1 call pptr2 ! Ausgabe: ! ooops ! ooops pptr3 => add write( *, * ) pptr3( 5 , 12 ) ! Ausgabe: ! 17 ! Folgende auskommentierte Zuordnung waere nicht erlaubt: ! pptr1 => add

contains subroutine up()

348

Prozedurenzeiger

end subroutine up subroutine ooops() write( *, * ) "ooops" end subroutine ooops

function add( a, b ) integer :: add integer, intent( in ) :: a, b add = a + b end function add end program bsp

37.1.3. Abstraktes Interface Das bei der Deklaration eines Prozedurenzeigers als Schnittstelle genannte Unterprogramm muss nicht real implementiert sein. Es können statt dessen auch abstrakte Interfaces Verwendung finden. Diese sind gleich wie konventionelle Interface-Blöcke aufgebaut, mit dem Unterschied, dass sie als abstract interface gekennzeichnet sind. Ein mit einem abstrakten Interface deklarierter Prozedurzeiger passt dann für jedes Unterprogramm, welches mit identer Schnittstelle ausgestattet ist. Fortran 2003-Code program bsp implicit none abstract interface function afunc( x, y ) integer :: afunc integer, intent( in ) :: x, y end function afunc end interface

procedure( afunc ), pointer :: pptr1 => null() procedure( add ) , pointer :: pptr2 => null() pptr1 => add

349

Zeiger

write( *, * ) pptr1( 5 , 12 ) ! Ausgabe: 17 pptr1 => mult write( *, * ) pptr1( 3 , 2 ) ! Ausgabe: 6 ! Folgendes funktioniert uebrigens auch, da add() und mult() das gleiche Interface ! aufweisen: pptr2 => mult write( *, * ) pptr2( 5 , 5 ) ! Ausgabe: 25

contains function add( a, b ) integer :: add integer, intent( in ) :: a, b add = a + b end function add function mult( a, b ) integer :: mult integer, intent( in ) :: a, b mult = a * b end function mult end program bsp

37.2. Zeiger und das intent-Attribut Nun ist bei der Übergabe von Zeigern an Unterprogramme auch die Angabe eines intent-Attributs möglich. Das war mit Fortran 90/95 noch nicht erlaubt. Diese intent-Angaben beziehen sich aber nicht auf die Variablenwerte an sich, sondern beschränken nur die Möglichkeiten zur Zeigerzuordnung im Unterprogramm selbst. Beispiel: Fortran 2003-Code program bsp

350

Zeiger und Felder

implicit none integer, target :: x = 15 integer, pointer :: ptr1 => null(), ptr2 => null() ptr1 => x ptr2 => x call mult( ptr1, ptr2)

! ! ! ! !

write( *, *) "Zuordnungsstatus ptr1:", associated( ptr1 ) write( *, *) "Zuordnungsstatus ptr2:", associated( ptr2 ) write( *, *) "Wert ptr1:", ptr1 write( *, *) "Wert x:", x Ausgabe: Zuordnungsstatus ptr1: T Zuordnungsstatus ptr2: F Wert ptr1: 45 Wert x: 45

contains subroutine integer, integer, integer,

mult( a, b ) pointer, intent( in ) :: a pointer, intent( inout ) :: b target :: val = 3

! Folgendes waere nun nicht erlaubt, da a nur intent( in ) ! a => null() ! Das auch nicht: ! a => val ! Das allerdings ist erlaubt: a = a * val ! b ist mit intent( inout ) spezifiziert, also ist hier eine Zeigerzuordnung ! erlaubt: b => null() end subroutine mult end program bsp

37.3. Zeiger und Felder Auch im Zusammenspiel von Zeigern mit Feldern bringt der Fortran 2003-Standard einige Ergänzungen.

351

38. Ein- und Ausgabe 38.1. Streams Fortran 2003 bietet zusätzlich zum altbekannten datensatzbasierten I/O nun auch Dateieingabe und -ausgabe in Form von Streams, wie das z.B. in der Programmiersprache C seit jeher üblich ist.

38.1.1. Unterschied zum alten I/O-Konzept? • Streams ermöglichen das Lesen und Schreiben von Binärdateien, ohne sich mit den auf Datensätzen aufbauenden Strukturen der konventionellen Fortran-I/O herumschlagen zu müssen. • Bei der Ein-/Ausgabe mit Streams wird die Datei als kontinuierliche Byte-Sequenz betrachtet. • Stream-I/O ist logischerweise nicht für interne Dateien gedacht.

38.1.2. Anwendung Auch wenn Stream-I/O in Fortran 2003 ein neues Konzept ist, so sind die altbekannten open-, read-, write-und close-Befehle dafür zuständig. • Öffnen eines Streams:

353

Ein- und Ausgabe

open( ..., access = "STREAM", ... ) • Lesen und Schreiben: read( ... ) ... write( ... ) ... • Schließen eines Streams: close( ... )

38.1.3. Unformatierte Stream-I/O Beispiel: Fortran 2003-Code program bsp implicit none real :: a = 55.678 real :: b character( len = 3 ) :: str open( 50, file = "test", access = "STREAM", status = "REPLACE") write( 50 ) "Hallo Welt" write( 50 ) "Hello World" ! Ausgabe in Datei: siehe Bild 1 write( 50, pos = 100 ) "Greetings" ! Ausgabe in Datei: siehe Bild 2 write( 50, pos = 60 ) a ! Ausgabe in Datei: siehe Bild 3 read( 50, pos = 60 ) b write( *, * ) b ! Ausgabe: ! 55.678 read( 50, pos = 8 ) str write( *, * ) str ! Ausgabe: ! elt close( 50 ) end program bsp

354

Streams

Da es sich um eine unformatierte Ein-/Ausgabe handelt, darf natürlich kein Formatspezifizierer bei den read- und writeAnweisungen angegeben werden, auch kein *. Mittels posSpezifizierer kann an eine bestimmte Position in der Datei gesprungen werden. Bild 1 Abb. 44 Bild 2

Abb. 45 Bild 3

Abb. 46

38.1.4. Formatierte Stream-I/O Beispiel: Fortran 2003-Code program bsp implicit none real :: real :: character( len = 20 ) :: integer :: open( 50, file = "test", status = "REPLACE")

a = 55.678 b = 13.9876 str1, str2, str3 fposition access = "STREAM", form = "FORMATTED",

write( 50, "(2A20)" ) "Hallo Welt", "Hello World" inquire( 50, pos = fposition ) write( *, * ) fposition write( 50, * ) a, new_line( "x" ), b, " abcdef" read( 50, *, pos = fposition ) a write( *, * ) a

355

Ein- und Ausgabe

read( 50, *, pos = 1 ) str1, str2, str3 write( *, * ) str1, str2, str3

! ! ! ! ! ! ! ! !

read( 50, * ) str1, a write( *, * ) str1, a Ausgabe in Datei: Hallo Welt 55.678 13.9876 abcdef Ausgabe auf Bildschirm: 42 55.678 Hallo Welt 55.678 13.9876

Hello World

Hello

close( 50 ) end program bsp

38.2. Asynchrone I/O 38.3. Rekursive I/O 38.4. Sonstiges 38.5. Weblinks • S TREAM I NPUT /O UTPUT IN F ORTRAN1

1

356

H T T P :// W W W . S T A R . L E . A C . U K /%7E C G P / S T R E A M IO. H T M L

39. Intrinsische Funktionen und Subroutinen Die Fortran 90/95-Funktionen und -Subroutinen sind natürlich auch in Fortran 2003 uneingeschränkt gültig. Einige Unterprogramme wurden neu aufgenommen, andere in ihrer Funktionalität etwas erweitert.

39.1. Neu 39.1.1. Datentypfunktionen

357

Intrinsische Funktionen und Subroutinen Funktion i= selected_char_kind (c)

Beschreibung Gibt den kind-Wert des Parameters zurück. Der Rückgabewert ist von Datentyp integer. Parameter: • name Rückgabewert: • name = "DEFAULT": der Default-Wert für Zeichen wird zurückgegeben • name = "ASCII": der Wert für ASCII-Zeichen wird zurückgegeben • name = "ISO_10646": der Wert für "ISO 10646"-Zeichen wird zurückgegeben • -1 ... Zeichentyp wird nicht unterstützt Beispiel: i = selected_char_kind( "ASCII" ) i => 1

39.1.2. Kommandozeile und Environment Funktion

Beschreibung Anzahl der übergebenen Kommandozeilenari= gumente (der Programmname selbst wird nicht command_- mitgezählt). Der Rückgabewert ist vom Typ argument_- integer. count ( Beispiel: Programmaufruf mit: ./a.out opt1 opt2 ) i = command_argument_count( ) i => 2

358

Neu Subroutine get_command ( [c, i, i] )

Beschreibung Übergebene Kommandozeilenargumente (ohne Programmname) Parameter: • command: Kommandozeilenargumente als Zeichenkette, intent( out ), optional • length: Länge der Zeichenkette, intent( out ), optional • status: Status, intent( out ), optional • 0 ... OK • -1 ... command-Argument existiert und ist kürzer als length • andere Zahl ... Fehler Beispiel: Programmaufruf mit: ./a.out opt1 opt2 call get_command( str, len, st ) str => opt1 opt2 len => 9 st => 0

359

Intrinsische Funktionen und Subroutinen Subroutine

Beschreibung

Ein bestimmtes Kommandozeilenargument (inkl. Programmname) get_command_- Parameter: argument • number: Nummer des gewünschten Kom( i, [c, i, i] ) mandozeilenargumentes beginnend bei 0,

intent( in ) • value: Wert des Kommandozeilenargumentes, intent( out ), optional • length: Länge der Zeichenkette, intent( out ), optional • status: Status, intent( out ), optional • 0 ... OK • -1 ... Argument existiert und ist kürzer als length • andere Zahl ... Fehler Beispiel: Programmaufruf mit: ./a.out opt1 opt2 call get_command_argument( 1, str, len, st ) str => opt1 len => 4 st => 0

360

Neu Subroutine

Beschreibung

Wert einer bestimmten Umgebungsvariable. Parameter: get_environment_• name: Name der Umgebungsvariable, variable ( intent( in ) c1, [c2, i, i, l] ) • value: Wert der Umgebungsvariablen,

intent( out ), optional • length: Länge der Zeichenkette c2, intent( out ), optional • status: Status, intent( out ), optional • trim_name: intent( in ), optional • 0 ... OK • -1 ... Umgebungsvariable existiert, Wert ist kürzer als length • 1 ... Umgebungsvariable existiert nicht • 2 ... keine Unterstützung von Umgebungsvariablen • andere Zahl ... sonstiger Fehler Beispiel: call get_environment_variable( "PWD", str, len, st, .TRUE. ) str => /usr/bin len => 8 st => 0

361

Intrinsische Funktionen und Subroutinen

39.2. Erweitert • system_clock(i1, ir, i2) ... Das zweite Argument (count_rate) darf nun vom Datentyp integer oder real sein. • max, maxloc, maxval, min, minloc, minval ... Funktionieren nunmehr auch für Werte vom Datentyp character. • atan2(r1, r2), log(rx), sqrt(rx) ... Unterscheidung von positiven und negativen Nullen im Argument.

362

40. Intrinsische Module 40.1. Grundlegendes Module gab es bereits mit Fortran 90/95. Neu in Fortran 2003 sind die sogenannten "intrinsischen Module". Das sind jene Module, die bereits standardmäßig von Fortran-2003-Compilern bereitgestellt werden. Werden Datenelemente oder Funktionen aus solchen intrinsischen Modulen benötigt, so ist das entsprechende Modul mittels use, intrinsic :: modulname

in die jeweilige Programmeinheit einzubinden. Der Unterschied zu konventionellen (nonintrinsischen) Modulen ist das Wörtchen intrinsic, das dem Compiler mitteilt, dass er das Modul bereits mitbringt und nicht irgendwo extern danach suchen soll. Wird nach dem use-Schlüsselwort kein entsprechendes Attribut oder das non_intrinsic-Attribut angegeben, so zeigt dies an, dass ein nonintrinsisches Modul benutzt wird.

40.2. Das intrinsische Modul iso_fortran_env Das iso_fortran_env-Modul enthält umgebungsspezifische Konstanten.

einige

Fortran-

363

Intrinsische Module

Beispiel: Fortran 2003-Code program bsp use, intrinsic :: iso_fortran_env implicit none write( *, * ) INPUT_UNIT write( *, * ) OUTPUT_UNIT write( *, * ) ERROR_UNIT write( *, * ) IOSTAT_END write( *, * ) IOSTAT_EOR write( *, * ) NUMERIC_STORAGE_SIZE write( *, * ) CHARACTER_STORAGE_SIZE write( *, * ) FILE_STORAGE_SIZE ! Ausgabe, z.B.: ! 5 ! 6 ! 0 ! -1 ! -2 ! 32 ! 8 ! 8 end program bsp

Erläuterung: Konstante

Anmerkung

INPUT_UNIT

Standard-Eingabeeinheit (entspricht unit=* bei read) Standard-Ausgabeeinheit (entspricht unit=* bei write) StandardFehlerausgabeeinheit end-of-file (EOF) end-of-record (EOR) Speicherplatzbedarf (in bits)

OUTPUT_UNIT

ERROR_UNIT IOSTAT_END IOSTAT_EOR NUMERIC_STORAGE_SIZE

364

Das intrinsische Modul iso_c_binding Konstante CHARACTER_STORAGE_SIZE FILE_STORAGE_SIZE

Anmerkung Speicherplatzbedarf (in bits) Speicherplatzbedarf (in bits)

All diese Konstanten sind Skalare vom Datentyp integer.

40.3. Das intrinsische Modul iso_c_binding Das iso_c_binding-Modul liefert die Konstanten und Unterprogramme, die für die Einbindung von C-Bibliotheken in FortranProgramme erforderlich sind. Näheres dazu findet sich im Kapitel F ORTRAN 2003 UND C1 .

40.4. Die intrinsischen IEEE-Module Die bereits aus dem dem TR 15580 : 1998 (floating-point exception handling) bekannten Module • ieee_exceptions • ieee_arithmetic • ieee_features wurden in Fortran 2003 in Form von intrinsischen Modulen aufgenommen. Diese Module decken den IEEE 754-1985Standard (auch IEC 559:1989) ab.

1

Kapitel 61.5 auf Seite 478

365

Intrinsische Module

40.4.1. Wovon handelt der IEEE 754-1985-Standard? Im Bereich der Gleitkommazahlen (real, float, ...) herrschte bis in die 1980er-Jahre Anarchie. Es gab keine verbindlichen Regeln wie Gleitkommazahlen repräsentiert werden, wie gerundet wird, wie Under- und Overflows gehandhabt werden, wie mit Unendlich und NaN verfahren wird, etc. Das führte dazu, dass das gleiche Computerprogramm auf unterschiedlichen Rechnerarchitekturen und mit verschiedenen Compilern unterschiedliche Resultate liefern konnte. Um diesem Manko zu begegnen wurde in den frühen 1980er-Jahren eine Standardisierung angestrebt. Resultat war die Verabschiedung des IEEE 754-1985-Standards (IEEE Standard for Binary Floating-Point Arithmetic for microprocessor systems). Dieser Standard regelt im Wesentlichen • die Repräsentation von Gleitkommazahlen: Darstellung: zahl = (−1)s · m · b e s m b

... ... ...

e

...

Vorzeichen Mantisse Basis (2 für normalisierte Zahlen) Exponent

... ...

4 Bytes 8 Bytes

Abb. 47

Zahlenformate: single double

366

Die intrinsischen IEEE-Module

double-extended

...

≥10 Bytes, optional

• die Darstellung normalisierter und denormalisierter Zahlen: • Normalisierte Zahlen: G LEITKOM 2 MAZAHLEN #N ORMALISIERUNG • Denormalisierte Zahlen: Bereich zwischen der kleinsten darstellbaren normalisierten Zahl und Null (Exponent hat einen reservierten Wert, führende Bit der Mantisse ist 0) • NaN (Not a Number), ±∞ , ±0 • Rundungen (zur nächstgelegenen darstellbaren Zahl, in Richtung Null, in Richtung +∞ oder in Richtung −∞) • das Verhalten verschiedener Operationen (Grundrechenarten, Wurzelberechnung, Konvertierung Gleitkommazahl → Ganzzahl, Binär-Dezimal-Konvertierung, Vergleiche mit Nan und ∞, etc.) • Exception-Handling (Overflow, Underflow, Division by Zero, Inexact, Invalid) Weiterführende Weblinks: • IEEE 7543 • Kahan, W.: Why do we need a floatingpoint arithmetic standard?, UC Berkeley, 1981, HTTP :// HTTP. CS . BERKELEY. EDU / WKAHAN / IEEE 754 STATUS / WHYIEEE . PDF 4 • Kahan, W.: Lecture Notes on the Status of IEEE Standard 754 for Binary Floating-Point Arithmetic, UC

2 3 4

H T T P :// D E . W I K I P E D I A . O R G / W I K I /G L E I T K O M M A Z A H L E N % 23N O R M A L I S I E R U N G H T T P :// D E . W I K I P E D I A . O R G / W I K I /IEEE%20754 H T T P :// H T T P . C S . B E R K E L E Y . E D U /~{} W K A H A N / I E E E 754 S T A T U S / W H Y -{} I E E E . P D F

367

Intrinsische Module

Berkeley, 1996, HTTP :// HTTP. CS . BERKELEY. EDU / WKA HAN / IEEE 754 STATUS /IEEE754.PDF 5 • L INKSAMMLUNG BEI "C ENTRE C HARLES H ERMITE "6 • IEEE 754-1985 "S TANDARD FOR BINARY FLOATING - POINT ARITHMETIC " 7

40.4.2. Implementierung in Fortran 2003 Wie bereits erwähnt, besitzt Fortran 2003 intrinsische Module, mit denen der Zugriff auf bestimmte IEEE-Eigenschaften erfolgen kann. Dazu stehen eine Reihe von Funktionen, Subroutinen, Verbundtypen und Konstanten zur Verfügung. Merkmal ist, dass diese immer mit dem Präfix ieee beginnen.

ieee_arithmetic Das aus Programmiersicht umfangreichste Modul ist sicherlich ieee_arithmetic. Dieses enthält zahlreiche Funktionen, Subroutinen und Konstanten. Abfragefunktionen für die Unterstützung bestimmter IEEEElemente, z.B.:

5

H T T P :// H T T P . C S . B E R K E L E Y . E D U /~{} W K A H A N / I E E E 754 S T A T U S /IEEE754.PDF

6 7

368

H T T P :// C C H . L O R I A . F R / D O C U M E N T A T I O N /IEEE754 H T T P ://754 R . U C B T E S T . O R G / S T A N D A R D S /754. P D F

Die intrinsischen IEEE-Module

l = ieee_support_datatype( [x] )

l = ieee_support_nan( [x] ) l = ieee_support_rounding( round_value, [x] )

Prüft ob die IEEE-Arithmetik für einen speziellen realDatentyps, charakterisiert durch x (Zahl oder Feld), unterstützt wird. Wird kein Argument angegeben, so wird geprüft, ob die IEEEArithmetik für alle realDatentypen unterstützt wird. Prüft, ob NaN-Werte unterstützt werden Prüft, ob ein bestimmter IEEE-Rundungsmodus unterstützt wird. Mögliche Rundungsmodi sind: • ieee_nearest • ieee_to_zero • ieee_up • ieee_down • ieee_other

Elementare Funktionen, z.B.: l = ieee_is_finite( x ) r = ieee_next_after( x, y )

Prüft, ob der Wert x endlich ist Liefert die nächste darstellbare Zahl von x in Richtung

y

369

Intrinsische Module

r = ieee_rint( x )

Rundet gemäß eingestelltem Rundungsmodus zu einer Ganzzahl und liefert diese Zahl mit dem Datentyp von x zurück.

Die Kind-Funktion: r = ieee_selected_real_kind( [p, r] )

Liefert einen kind-Wert

Nichtelementare Subroutinen, z.B.: ieee_get_underflow_mode( gradual ) ieee_set_rounding_mode( round_value )

Liefert den aktuellen Underflow-Modus Setzt den IEEERundungsmodus, mögliche Werte für round_value • ieee_nearest • ieee_to_zero • ieee_up • ieee_down • ieee_other

370

Die intrinsischen IEEE-Module

ieee_exceptions Das ieee_exceptions-Modul enthält zwei Funktionen, mit denen abgefragt werden kann, welche Exceptions unterstützt werden bzw. inwieweit IEEE-Halting unterstützt wird: l = ieee_support_flag( flag, [x] ) l = ieee_support_halting( flag )

Mögliche Flags sind • • • • •

ieee_invalid ieee_overflow ieee_divide_by_zero ieee_underflow ieee_inexact

Desweiteren sind in diesem Modul einige Subroutinen zum Setzen bzw. Abfragen diverser Flags enthalten: ieee_get_status( status_value ) ieee_set_flag( flag, flag_value ) ieee_set_halting_mode( flag, halting ) ieee_set_status( status_value )

Bei Einbindung des ieee_arithmetic-Moduls ist auch automatisch Zugriff auf die public-Elemente des Moduls ieee_exceptions gegeben.

ieee_features Das ieee_features-Modul liefert einige benannte Konstanten, z.B. ieee_datatype, ieee_inf, ieee_sqrt.

371

Intrinsische Module

Beispiel: Rundungsmodus IEEE-Subroutinen: ieee_get_rounding_mode( val ) ieee_set_rounding_mode( flag )

Mögliche Wert für flag sind: ... • ieee_nearest

... • ieee_to_zero ...

Rundung Richtung −∞

...

Rundung Richtung +∞

• ieee_down

• ieee_up

Fortran 2003-Code program bsp use, intrinsic :: ieee_arithmetic implicit none

372

default, Rundung zur nächstgelegenen Zahl (wenn das nicht eindeutig möglich ist, dann Rundung zur nächstgelegenen geraden Zahl) Rundung in Richtung 0

Die intrinsischen IEEE-Module

real, dimension(6)

:: a = (/ -1.5, -0.5, 0.5, 1.5, 2.5, 3.5 /)

! Standard-Fortran-Rundungsfunktion write( *, * ) anint( a ) ! IEEE-Rundungsfunktion (default) write( *, * ) ieee_rint( a ) ! IEEE-Rundungsfunktion mit Flag ieee_round_type = ieee_nearest call ieee_set_rounding_mode( ieee_nearest ) write( *, * ) ieee_rint( a ) ! IEEE-Rundungsfunktion mit Flag ieee_round_type = ieee_to_zero call ieee_set_rounding_mode( ieee_to_zero ) write( *, * ) ieee_rint( a ) ! IEEE-Rundungsfunktion mit Flag ieee_round_type = ieee_down call ieee_set_rounding_mode( ieee_down ) write( *, * ) ieee_rint( a ) ! IEEE-Rundungsfunktion mit Flag ieee_round_type = ieee_up call ieee_set_rounding_mode( ieee_up ) write( *, * ) ieee_rint( a ) end program bsp

Ausgabe: IEEEStandard- Default Fortran -2.0 0.0 -2.0 0.0 2.0 1.0 1.0 2.0 4.0 2.0 3.0 4.0

ieee_nearest

ieee_to_zero

ieee_down

ieee_up

-2.0 0.0 0.0 2.0 2.0 4.0

-1.0 0.0 0.0 1.0 2.0 3.0

-2.0 1.0 0.0 1.0 2.0 3.0

-1.0 0.0 1.0 2.0 3.0 4.0

Beispiel: Halting-Modus Dieser Modus bestimmt, ob nach einer Exception das Programm angehalten oder fortgesetzt wird. Die in diesem Beispiel eingesetzten IEEE-Unterprogramme sind:

373

Intrinsische Module

• ieee_support_halting( flag ) ... prüft, ob auf dem System das IEEE-Halting für das angegebenen Flag überhaupt unterstützt wird (Rückgabewert: .true.). Mögliche Flags: • ieee_invalid • ieee_overflow • ieee_divide_by_zero • ieee_underflow • ieee_inexact • ieee_set_halting_mode( flag, mode ) ... setzt den HaltingModus für ein bestimmtes Flag. • flag ... wie bei ieee_support_halting( flag ) • mode: • .true. ... anhalten • .false. ... Programm weiter ausführen Fortran 2003-Code program main use, intrinsic :: ieee_arithmetic implicit none real :: a, b if( ieee_support_halting( ieee_divide_by_zero ) ) then call ieee_set_halting_mode( ieee_divide_by_zero, .false. ) read( *, * ) a, b write( *, * ) "Resultat: ", a / b write( *, * ) "Programm wird fortgesetzt ..." else write( *, * ) "IEEE-Halting wird nicht unterstuetzt" end if end program main

Eingabe: • 10.0 (... für a) • 0.0 (... für b)

374

Die intrinsischen IEEE-Module

Ausgabe (bei Programmerstellung mit dem Sun-Express-FortranCompiler f95):

ieee_set_halting_mode( ieee_divide_by_zero, .false. )

ieee_set_halting_mode( ieee_divide_by_zero, .true. ) Gleitkomma-Ausnahme

Resultat: Inf Programm wird fortgesetzt ...

Weitere Beispiele zum Thema "Exceptions and IEEE arithmetic" sind im Fortran 2003-Working Draft J3/04-007 ab Seite 386 enthalten.

375

Teil VI.

Bibliotheken

377

Quelltextbibliotheken

Eine Programmbibliothek bezeichnet in der Programmierung eine Sammlung von Programmfunktionen für zusammengehörende Aufgaben. Bibliotheken sind im Unterschied zu Programmen keine eigenständig lauffähigen Einheiten, sondern Hilfsmodule, die Programmen zur Verfügung gestellt werden.

40.5. Quelltextbibliotheken Quelltextbibliotheken enthalten Sammlungen von Wertedefinitionen, Deklarationen, Funktionen, Klassen, generischen Bestandteilen, usw.

40.5.1. API Eine Programmierschnittstelle ist eine Schnittstelle die von einem Softwaresystem anderen Programmen zur Anbindung an das System zur Verfügung gestellt wird. Oft wird dafür die Abkürzung API (für engl. application programming interface, deutsch: Schnittstelle zur Anwendungsprogrammierung) verwendet. Im Gegensatz zu einer Binärschnittstelle (ABI) definiert ein API nur die Verwendung der Schnittstellen auf Quelltextebene. Neben dem Zugriff auf Datenbanken, die Hardware wie Festplatte oder Grafikkarte kann ein API auch das Erstellen von Komponenten der grafischen Benutzeroberfläche ermöglichen oder vereinfachen. Im weiteren Sinne wird die Schnittstelle jeder Bibliothek (Library) als API bezeichnet.

379

Intrinsische Module

40.6. Statische Bibliotheken Statische Bibliotheken werden nach dem Kompiliervorgang durch einen so genannten Linker oder Binder in einem eigenen Schritt mit dem ausführbaren Programm verbunden. Der Linker sucht aus den Bibliotheksdateien Unterprogramme heraus, für die es im Programm keine Implementierung gibt. Diese werden dann aus den Dateien extrahiert und an das Programm gebunden, d.h. der Unterprogrammcode wird an den Programmcode angefügt und die Aufrufverweise werden auf die Unterprogrammadressen gerichtet.

40.7. Dynamische Bibliotheken Dynamische Bibliotheken werden erst bei Bedarf in den Arbeitsspeicher geladen und durch den sogenannten Lader mit dem ausführbaren Programm verbunden. Dadurch muss eine Bibliothek, die von mehreren Programmen genutzt wird, nur einmal im Speicher gehalten werden. Dies ist beispielsweise bei Multitasking-Systemen vorteilhaft, wenn die Bibliotheken insgesamt sehr groß sind und von vielen Prozessen gleichzeitig verwendet werden. Dort wird eine Bibliotheksdatei bei ihrer ersten Verwendung in den Speicher geladen. Trifft ein Programm auf den Verweis zu einem Unterprogramm, das noch nicht eingebunden wurde, dann wird ein Laufzeitbinder aktiviert. Dieser sucht das Unterprogramm in den im Speicher vorhandenen Bibliotheken, fügt die Adresse am Aufrufpunkt ein und führt das Unterprogramm erstmalig aus. Bei jedem weiteren Aufruf des Unterprogramms ist dann die Adresse vorhanden, so dass das Unterprogramm direkt aufgerufen

380

Bibliotheken in verschiedenen Programmiersprachen

wird. Die Ausführungszeit, insbesondere die Startzeit eines Programms, ist hier geringfügig erhöht. Dies wird in Kauf genommen, da der Programmcode der Bibliotheksfunktionen von allen Prozessen geteilt wird. Der Speicherbedarf aller Programme zusammen ist daher in der Regel kleiner als beim statischen Linken.

Unterstützt das Betriebssystem virtuellen Speicher, so entfällt das Laden der gesamten Bibliothek bei der ersten Verwendung. Stattdessen wird die Bibliothek in den Speicherbereich jedes sie verwendenden Prozesses eingeblendet. Die virtuelle Speicherverwaltung lädt danach nur tatsächlich benötigte Teile der Bibliothek bei Bedarf von der Festplatte in den Arbeitsspeicher.

40.8. Bibliotheken in verschiedenen Programmiersprachen

Bibliotheken in Programmiersprachen enthalten Leistungen, die nicht im Compiler implementiert sind, sondern in der Sprache selbst programmiert sind und mit dem Compiler zusammen oder völlig von ihm getrennt dem Programmierer zur Verfügung stehen. Im ersten Fall ist die Bibliothek meist in der Sprachbeschreibung festgelegt. Im zweiten Fall spricht man von einer externen Bibliothek.

381

Intrinsische Module

40.9. Bibliotheken bei verschiedenen Betriebssystemen 40.9.1. Windows Bei den Betriebssystemen Windows und auch bei OS/2 wird eine Bibliotheksdatei, die dynamisch bindet, als Dynamic Link Library (DLL) bezeichnet. Entsprechend haben diese Dateien meist die Dateiendung .dll. Ihr Dateiformat ist Portable Executable. Problematisch ist bei Windows 95, Windows 98 und Windows Me, dass durch unzureichende Schutzmaßnahmen die DLLs nicht kontrolliert werden - jedes Programm darf sie austauschen und kann dem Betriebssystem damit möglicherweise Schaden zufügen. Windows 2000 und Windows XP hingegen verfügen über einen Systemschutz, der auch die DLLs einbezieht.

Vorteile • Außer Code können auch Daten (z. B. Dialog-Ressourcen) von mehreren Prozessen gemeinsam genutzt werden. • DLLs werden häufig statisch gelinkt, können aber auch dynamisch (daher der Name) gelinkt werden. Dynamisch heißt hier, dass die DLL explizit vom Programm zur Laufzeit geladen wird und die Funktionen, die sich in der DLL befinden, „per Hand“ mit dem Programm verbunden werden. Dadurch wird es möglich, durch Austauschen der DLL die Funktionalität des Programms zur Laufzeit zu verändern. • DLLs können unabhängig vom Hauptprogramm gewartet werden. D. h. Funktionen in der DLL können ohne Wissen des Programms verändert werden. Danach wird die DLL einfach ausgetauscht (die alte DLL-Datei wird überschrieben), ohne dass das Hauptprogramm verändert werden muss.

382

Bibliotheken bei verschiedenen Betriebssystemen

• Da die DLL als unabhängige Datei dem Hauptprogramm beiliegen muss, können Anbieter von Programmcode besser sicherstellen, dass Programmierer, die die Funktionen ihrer DLL nutzen, dafür auch bezahlen. Die Funktionalität der DLL verschwindet so nicht (wie bei einer Library) im Code des Programms. Dieser Vorteil wird von Befürwortern freier Software als Nachteil gesehen.

Nachteile Änderungen in DLLs ziehen oft auch Änderungen im Programm mit sich. Dadurch kommt es leicht zu Versionskonflikten, die oft nur sehr schwer aufzuspüren sind. Eine der Grundideen der DLLs war, Programmcode zwischen mehreren Programmen zu teilen, um so kostbaren Speicher zu sparen. In der Praxis ist es jedoch dazu gekommen, dass viele Programme bei der Installation DLLs in das WindowsSystemverzeichnis schreiben, die außer diesem speziellen Programm kein anderes benutzen kann. Außerdem ist die Entwicklung und insbesondere die Anbindung im Vergleich aufwändiger als zur statischen Bibliothek.

Quintessenz DLLs sollte man nur benutzen, wenn man ihre spezielle Funktionalität benötigt und man ausschließlich unter Windows arbeitet. Sind statische Bibliotheken für den Zweck ausreichend, sollte man diese vorziehen. In der Praxis ergeben sich keinerlei Einsparungen bei der Größe des Codes.

383

Intrinsische Module

40.9.2. Unix-artige Auf Unix-artigen Betriebssystemen ist für dynamische Bibliotheken die Bezeichnung shared library (englisch shared, geteilt) gebräuchlich. Für diese Dateien hat sich die Endung .so (s’hared object) eingebürgert. In der Regel folgt dem Bibliotheksnamen noch eine Versionsnummer.

384

41. Grafik und GUI 41.1. DISLIN D ISLIN1

1

H T T P :// D E . W I K I P E D I A . O R G / W I K I /%20D I S L I N

385

42. Allgemeines Die DISLIN Scientific Plotting Software ist eine Bibliothek für die grafische Datendarstellung. Auch für die Gestaltung grafischer Benutzeroberflächen läßt sich DISLIN verwenden. DISLIN greift zu diesem Zwecke auf die Motif-Bibliothek zu. Die DISLIN-Bibliothek ist für mehrere Programmiersprachen konzipiert, so auch auch für die Programmiersprache Fortran.

387

43. Beispiele 43.1. Beispiel 1: Strings und Zahlen Fortran 90/95-Code (free source form) program dbsp1 implicit none real, parameter :: PI = 3.1415926 ! *** Initialisierung *** call setpag ("DA4P") call metafl ("CONS") (Bildschirm) call disini ! *** Zeichnen *** call messag ("Hallo, Welt!", 50,50) call number (PI, 4, 50, 150) ! *** Aufräumen *** call disfin end program dbsp1

! DIN-A4 Hochformat ! Ausgabe auf Konsole ! DISLIN initialisieren

! Message schreiben ! 3.1416 schreiben

! DISLIN beenden

Programm erstellen: • Variante 1: gfortran -c dateiname.f95 dlink dateiname

• Variante 2:

389

Beispiele

gfortran -o dateiname dateiname.f95 -ldislin

Abb. 48

Eine Auswahl von möglichen aktuellen Parametern für die Subroutine metafl: • • • • • •

"CONS" ... Konsole (Bildschirm) "XWIN" ... X-Window (Bildschirm) "EPS" ... Encapsulated Postscript-Datei "PNG" ... PNG-Datei "SVG" ... SVG-Datei "PDF" ... PDF-Datei

43.2. Beispiel 2: Zeichnen von Kurven und Funktionen Fortran 90/95-Code (free source form) program dbsp2 implicit none

390

Beispiel 2: Zeichnen von Kurven und Funktionen

real, dimension(0:99) :: x, y integer :: i, setrgb do i = 0, 99 x(i) = i / 20.0 y(i) = sin(x(i)) end do ! *** Initialisierung *** call setpag ("DA4P") call metafl ("PNG") eine PNG-Datei call disini initialisieren

! DIN-A4 ! Ausgabe in ! DISLIN

! *** Zeichnen *** call pagfll (255) ! Hintergrundfarbe auf weiß setzen call color (setrgb (0., 0., 0.)) ! Vordergrundfarbe auf schwarz setzen call graf (0.0, 5.0, 0.0, 0.5, -1.0, 1.0, -1.0, 0.1) ! 2D-Koordinatensystem setzen call curve (x, y, 100) ! Graphen zeichnen ! *** Aufräumen *** call disfin beenden end program dbsp2

! DISLIN

391

Beispiele

Abb. 49

43.3. Beispiel 3: Ein Pie-Chart Fortran 90/95-Code (free source form) program dbsp3 implicit none real, dimension(3) :: part = (/5.5, 2.5, 1.0/) integer, dimension(3) :: partcol1 = (/10, 100, 150/) integer, dimension(3) :: partcol2 = (/10, 100, 150/) integer :: setrgb ! *** Initialisierung ***

392

Beispiel 3: Ein Pie-Chart

call setpag ("DA4P") call metafl ("CONS") (Bildschirm) call disini initialisieren ! *** Zeichnen *** call pagfll (255) Hintergrundfarbe auf weiß setzen call color (setrgb (0., 0., 0.)) Vordergrundfarbe auf schwarz setzen call shdpat (16) Shadingpattern (16 = voll) call chnpie ("NONE") Shadingpattern call pieclr (partcol1, partcol2, 3) call pietyp ("3D") call piegrf ("Hallo", 0 , part, 3) zeichnen ! *** Aufräumen *** call disfin beenden end program dbsp3

! DIN-A4 ! Console ! DISLIN

! ! ! ! Farbe und ! Teilfarben ! 3D ! Pie-Chart

! DISLIN

Abb. 50

393

Beispiele

43.4. Beispiel 4: Ein Meldungsfenster

Fortran 90/95-Code (free source form) program dbsp4 implicit none call disini call dwgmsg ("Hallo, Welt") call disfin end program dbsp4

394

Beispiel 4: Ein Meldungsfenster

Abb. 51

395

Beispiele

Weitere (auch komplexere) Beispiele finden sich im ausführlichen DISLIN-Manual. Dieses ist auf der unten genannten Webpräsenz abrufbar.

396

44. Weblinks • M AX -P LANCK -G ESELLSCHAFT: DISLIN1

44.1. f03gl 44.2. Allgemeines f03gl ist ein Fortran 2003-Interface für O PEN GL2 , speziell für GLUT3 , freeglut und OpenGLUT. f03gl kann als der Nachfolger von F 90 GL4 betrachtet werden.

44.3. Beispiel Fortran 2003-Code module bsp_ogl contains subroutine display() use opengl_gl use opengl_glut

1 2 3 4

H T T P :// W W W . D I S L I N . D E H T T P :// D E . W I K I P E D I A . O R G / W I K I /O P E N GL H T T P :// D E . W I K I P E D I A . O R G / W I K I /O P E N GL%20U T I L I T Y % 20T O O L K I T H T T P :// M A T H . N I S T . G O V / F 90 G L /

397

Weblinks

implicit none call glclear(GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT) call glColor3f( 0.2, 1.0, 0.3 ) call glutSolidTeapot( 50.0_gldouble ) call glutswapbuffers end subroutine display subroutine gfxinit use opengl_gl use opengl_glu implicit none real( glfloat ), dimension( 4 ) :: pos = (/ 100.0, 100.0, 200.0, 1.0 /) call glenable( GL_LIGHTING ) call glenable( GL_LIGHT0 ) call glenable( GL_DEPTH_TEST ) call glenable( GL_COLOR_MATERIAL ) call glenable( GL_NORMALIZE ) call glenable( GL_POLYGON_SMOOTH ) call gllightfv( GL_LIGHT0, GL_POSITION, pos ) call glClearColor( 0.7, 0.7, 0.7, 0.0 ) call glmatrixmode( GL_PROJECTION ) call glOrtho( -100.0_gldouble, 100.0_gldouble, -100.0_gldouble, 100.0_gldouble, & -100.0_gldouble, 100.0_gldouble ); call glmatrixmode( GL_MODELVIEW ) call glrotatef( 35.0, 1.0, 0.0, 0.0 ) call glrotatef( -25.0, 0.0, 1.0, 0.0 ) end subroutine gfxinit end module bsp_ogl program bsp use opengl_glut use bsp_ogl use, intrinsic :: iso_c_binding implicit none integer :: i call glutinit() call glutinitdisplaymode( GLUT_DOUBLE + GLUT_RGB + GLUT_DEPTH ) i = glutcreatewindow( "Beispiel" // c_null_char ) call gfxinit call glutdisplayfunc( display ) call glutmainloop end program bsp

Um das Beispiel nutzen zu können, müssen die Dateien OpenGL_gl.f90, OpenGL_glu.f90 und wahlweise OpenGL_glut,f90,

398

Beispiel

OpenGL_freeglut.f90 oder OpenGL_openglut.f90 von der Webseite „F ORTRAN 2003 I NTERFACE TO O PEN GL"5 herunter geladen werden. Die ersten beiden Dateien sind das Interface zu den beiden Bibliotheken GL (Graphics Library) und GLU6 . Die drei anderen Dateien sind das Interface für die Utility Toolkits GLUT7 , freeglut bzw. OpenGLUT. Diese Dateien müssen dann kompiliert werden, beispielsweise für die Verwendung der freeglut: g95 -c OpenGL_gl.f90 g95 -c OpenGL_glu.f90 g95 -c OpenGL_freeglut.f90

Kompilieren und Linken des Beipielprogrammses bsp.f03, hier als Beispiel, wenn sich die opengl_*.mod-Dateien und OpenGL_*.o-Dateien im gleichen Verzeichnis wie die Beispieldatei bsp.f03 befinden und die freeglut-Bibliothek verwendet wird (wie in einigen L INUX8 -Distrubtionen wie z. B. R ED H AT9 ): g95 -o bsp bsp.f03 OpenGL_gl.o OpenGL_glu.o OpenGL_freeglut.o -lGL -lGLU -lglut

Die Parameter -lGL, -lGLU geben die Pfade der beiden Bibliotheken GL und GLU an, während -lglut den Pfad des Utility Toolkits angibt.

5 6 7 8 9

H T T P :// W W W -{} S T O N E . C H . C A M . A C . U K / P U B / F 03 G L / H T T P :// D E . W I K I P E D I A . O R G / W I K I /O P E N GL%20U T I L I T Y % 20L I B R A R Y H T T P :// D E . W I K I P E D I A . O R G / W I K I /O P E N GL%20U T I L I T Y % 20T O O L K I T H T T P :// D E . W I K I P E D I A . O R G / W I K I /L I N U X H T T P :// D E . W I K I P E D I A . O R G / W I K I /R E D %20H A T %20L I N U X

399

Weblinks

Für Mac OS X ist folgende Sequenz zu verwenden: g95 -o bsp bsp.f03 OpenGL_gl.o OpenGL_glu.o OpenGL_glut.o -framework Carbon -framework OpenGL -framework GLUT

Nach der Eingabe von: ./bsp

sollte als Ausgabe die U TAH -T EEKANNE10 erscheinen:

Abb. 52

10

400

H T T P :// D E . W I K I P E D I A . O R G / W I K I /U T A H -{}T E E K A N N E

Besonderheiten

44.4. Besonderheiten Die Routinen für OpenGl und die GLUT sind in C geschrieben und auch die meisten Anwendungen von OpenGL und GLUT erfolgen in C. Daraus ergeben sich einige Besonderheiten für die Einbindung von OpenGL und GLUT unter Fortran. In C lässt sich folgender Code erzeugen: int main( int argc, char* argv[]) { ... glutReshapeFunc(ChangeSize); ... return 0; }

void ChangeSize(GLsizei w, GLsizei h) { ... }

Dabei ist GLsizei ein von OpenGL spezifizierter Datentyp vom Typ integer. In Fortran 2003 sieht das selbe Code-Fragement unter Verwendung der C-Interoperabilität von Fortran 2003 zum Beispiel folgenderweise aus: Fortran 2003-Code module simple_opengl_things use opengl_gl use opengl_glu use opengl_glut contains ... subroutine ChangeSize(w, h) bind(c) implicit none integer( kind=GLsizei ), value :: w

401

Weblinks

integer( kind=GLsizei ), value :: h ... end subroutine ChangeSize ... end module simple_open_gl_things program simple_opengl use opengl_glut use simple_opengl_things ... call glutReshapeFunc( ChangeSize ) ... end program simple_opengl

44.5. Weblinks • • • • •

O PEN GL11 F ORTRAN 2003 I NTERFACE TO O PEN GL12 FREEGLUT 13

O PEN GLUT14 M ANUEL FÜR GLUT VERSION 315

44.6. Japi

11 12 13 14 15

H T T P :// W W W . O P E N G L . O R G / H T T P :// W W W -{} S T O N E . C H . C A M . A C . U K / P U B / F 03 G L / H T T P :// F R E E G L U T . S O U R C E F O R G E . N E T / H T T P :// O P E N G L U T . S O U R C E F O R G E . N E T / H T T P :// W W W . O P E N G L . O R G / D O C U M E N T A T I O N / S P E C S / G L U T / S P E C 3/ S P E C 3. H T M L

402

45. Allgemeines Auch für den Bereich des Graphical-User-Interface-Building sind Fortran-Bibliotheken verfügbar. Einerseits gibt es kommerziellproprietäre Bibliotheken wie Interacter, Winteracter oder GinoMenu, die allerdings eindeutig auf rein professionellen Einsatz abzielen und deren Preise auch dementsprechend hoch liegen. Hier soll darum anhand eines einfachen Beispiels auf eine mögliche Open-Source-Alternative zu diesen kommerziellen Bibliotheken hingewiesen werden, nämlich japi. japi steht unter der GNU Lesser General Public License und ist ein J AVA AWT1 Wrapper. japi ist für verschiedene Programmiersprachen erhältlich, so auch für FORTRAN 77. Mit kleineren Adaptierungen kann diese Bibliothek aber auch mit Fortran 90/95 verwendet werden. Mit japi ist derzeit nur ein Teil der AWT-Möglichkeiten abrufbar. Der Einsatz von japi setzt zwingend eine aktuelle JavaInstallation (JRE oder JDK) auf dem Computer voraus.

1

H T T P :// D E . W I K I B O O K S . O R G / W I K I /J A V A %20S T A N D A R D %3A% 20G R A F I S C H E %20O B E R F L %E4 C H E N %20 M I T %20AWT%20

403

46. japi-Installation 1. Download der Dateien "japi.f" und "libjapi.zip" von der japi-Homepage. 2. Entpacken der "libjapi.zip" (die Linux-Version enthält z.B. nur die "libjapi.a"-Bibliotheksdatei). 3. Verschieben der Bibliotheksdatei in ein geeignetes Verzeichnis, z.B. unter Linux in "/usr/lib" oder "/usr/local/lib".

405

47. Beispiel Fortran 90/95-Code (free source form) program jbsp include "japi.f95" integer :: frame, obj integer, dimension(5) :: button if( .not. j_start()) then write(*,*) "JAPI-Problem" call end () end if frame = j_frame("JAPI-Beispiel") call j_setborderlayout(frame) button(1) button(2) button(3) button(4) button(5) call call call call

= = = = =

j_button(frame, j_button(frame, j_button(frame, j_button(frame, j_button(frame,

"Button "Button "Button "Button "Button

j_setborderpos(button(1), j_setborderpos(button(2), j_setborderpos(button(3), j_setborderpos(button(4),

1") 2") 3") 4") 5")

J_LEFT) J_RIGHT) J_TOP) J_BOTTOM)

call j_show(frame) do obj=j_nextaction() if(obj if(obj if(obj if(obj

== == == ==

frame) call end () button(1)) write (*,*) "Button 1 gedrückt" button(2)) write (*,*) "Button 2 gedrückt" button(3)) write (*,*) "Button 3 gedrückt"

407

Beispiel

if(obj == button(4)) write (*,*) "Button 4 gedrückt" if(obj == button(5)) write (*,*) "Button 5 gedrückt" end do call end () end program jbsp

subroutine end call j_quit() stop end subroutine end

Die Include-Datei "japi.f95" ist eine adaptierte "japi.f"-Datei. "japi.f" ist als Teil der japi-Bibliothek im FORTRAN 77-Format auf der unten genannten japi-Webseite zu finden. Für eine Minimalanpassung müssen nur die C-Kommentarzeichen aus FORTRAN 77 gegen die !-Kommentarzeichen von Fortran 95 ausgewechselt werden.

Kompilieren, Linken: gfortran -o jbsp jbsp.f95 -ljapi

408

Japi

Abb. 53

Reference Manuals, sowie Programming Manuals zu japi sind auf der nachfolgend angeführten Homepage in verschiedenen Dateiformaten abrufbar.

409

48. Weblinks •

JAVA APPLICATION PROGRAMMING INTERFACE 1

48.1. Pilib

1

H T T P :// W W W . J A P I . D E

411

49. Allgemeines Auch pilib ist ein Open-Source-Ansatz für die Erstellung von GUIs mittels Fortran. Anders als japi verwendet pilib zu diesem Zweck die GTK+-Bibliothek. Momentan befindet sich dieses Projekt in einer frühen Entwicklungsphase (Alpha-Status, Stand: Anfang 2006). Für nähere Informationen hinsichtlich der GTK+-Bibliothek wird auf die GTK+-Homepage verwiesen.

413

50. pilib-Installation 1. Download des pilib-Softwarepakets von der im Abschnitt Weblinks angegebenen pilib-Internetadresse. 2. Entpacken (gunzip, tar). 3. Installation der Bibliotheksbestandteile für Linux mit dem üblichen ./configure, make, make install. Für eine detailliertere Installationsanleitung wird auf die im Softwarepaket enthaltene INSTALL- und README-Datei, sowie das pilib-Manual im HTML-Format verwiesen.

415

51. Beispiel Fortran 90/95-Code (free source form) module bspmod implicit none save integer :: myedit1, myedit2, myedit3 end module bspmod

program bsp use pimod use bspmod implicit none integer :: mywin, mycontainer, mybutton, mytext, myclose, myclick call piinit call gkwindow(c("Addition"), 1, 0, mywin, myclose) ! Container (in diesem Fall eine Table) call gkcontain(3, 2, 4, 5, mycontainer) call gkput(0, 0, -1, -1, mywin, mycontainer) ! Label call gktext(c("Zahl 1: "), mytext) call gkputtable(0, 0, 0, 0, 4, 4, 5, 5, -1, -1, mycontainer, mytext)

! Einzeiliges Eingabefeld mit einer Breite von 10 Zeichen call gkxedt(10, myedit1) call gkputtable(1, 0, 1, 0, 4, 4, 5, 5, -1, -1, mycontainer, myedit1) ! Label call gktext(c("+"), mytext)

417

Beispiel

call gkputtable(0, 1, 1, 1, 4, 4, 5, 5, -1, -1, mycontainer, mytext)

! Label call gktext(c("Zahl 2: "), mytext) call gkputtable(0, 2, 0, 2, 4, 4, 5, 5, -1, -1, mycontainer, mytext)

! Einzeiliges Eingabefeld mit einer Breite von 10 Zeichen call gkxedt(10, myedit2) call gkputtable(1, 2, 1, 2, 4, 4, 5, 5, -1, -1, mycontainer, myedit2) ! Schaltfläche call gkbutton(c("="), mybutton, myclick) call gkputtable(0, 3, 2, 3, 4, 4, 5, 5, -1, -1, mycontainer, mybutton) ! Label call gktext(c("Ergebnis: "), mytext) call gkputtable(0, 4, 0, 4, 4, 4, 5, 5, -1, -1, mycontainer, mytext)

! Einzeiliges Eingabefeld mit einer Breite von 10 Zeichen call gkxedt(10, myedit3) call gkputtable(1, 4, 1, 4, 4, 4, 5, 5, -1, -1, mycontainer, myedit3) call gkshow(mywin) do while(myclose == 0) call gkproc if(myclick /= 0) then call calculate myclick = 0 end if end do call gkdestroy(mywin) end program bsp

subroutine calculate use pimod use bspmod implicit none

418

Pilib

real :: k1, k2, string2real character(30) :: cstr k1 = string2real(myedit1) k2 = string2real(myedit2) write(cstr, *) k1+k2 call gksetstring (c(cstr), myedit3) end subroutine calculate

function string2real(widget) use pimod implicit none real integer, intent(in) character(30) type(string)

:: :: :: ::

string2real, zahl widget cstr str

call gkgetstring(str, widget) cstr = f_str2char(str) read(cstr, *) zahl ! Umwandlung eines character-Wertes in eine real-Zahl ! unter Zuhilfenahme des internal-file-Mechanismus string2real = zahl end function string2real

Kompilieren, Linken: g95 bsp.f95 -lpilib -lpilibf -I/usr/local/include

Bei der pilib-Installation werden mod-Dateien in ein StandardInclude-Verzeichnis geschrieben. Der Optionsschalter "-I" weist den Compiler an, im gegebenem Verzeichnis nach IncludeDateien zu suchen, in diesem Fall nach mod-Dateien. Das Format der mod-Dateien ist compilerabhängig.

419

Beispiel

Abb. 54

Dieses Beispiel soll nur einen ersten Eindruck von pilib geben. Eine genauere Beschreibung der verwendeten pilibUnterprogramme und Subroutinenparameter, sowie eine Auflistung weiterer Möglichkeiten der pilib-Bibliothek wird hier mit Hinweis auf die dem pilib-Softwarepaket beiliegenden Dokumentationsdateien nicht getätigt.

420

52. Weblinks • PILIB -W IKI1 • PILIB -F ORUM2 • PILIB BEI S OURCE F ORGE3 • PILIB -M ANUAL4 • GTK+5

1 2 3 4 5

H T T P :// P I L I B . B E T A -{} C E N T A U R I . D E H T T P :// F O R U M . P I L I B . B E T A -{} C E N T A U R I . D E H T T P :// S O U R C E F O R G E . N E T / P R O J E C T S / P I L I B H T T P :// P I L I B . S O U R C E F O R G E . N E T / P I L I B . H T M L H T T P :// W W W . G T K . O R G

421

53. Mathematik 53.1. BLAS und ATLAS B ASIC L INEAR A LGEBRA S UBPROGRAMS1

1

H T T P :// D E . W I K I P E D I A . O R G / W I K I /%20B A S I C %20L I N E A R % 20A L G E B R A %20S U B P R O G R A M S

423

54. Allgemeines Die Basic Linear Algebra Subprograms (BLAS) stellen eine Sammlung von Unterprogrammen für die Vektor- und Matrizenrechnung dar. • Level 1: Skalar-Vektor-, Vektor-Vektor-Operationen • Level 2: Matrix-Vektor-Operationen • Level 3: Matrix-Matrix-Operationen Die Automatically Tuned Linear Algebra Software (ATLAS) ist ein um einige LAPACK-Funktionen erweitetertes BLAS-Paket und bietet die Möglichkeit, automatisiert eine rechneroptimierte Algebra-Bibliothek zu erzeugen.

425

55. Installation von BLAS BLAS wird in Form von Fortran-Quellcodedateien in einem gepackten tar-Paket zur Verfügung gestellt. Ein Makefile zur Generierung einer Bibliotheksdatei wird nicht mitgeliefert. Eine derartige Bibliotheksdatei kann aber einfach selbst erstellt werden. Eine Anleitung findet sich z.B. auf der gfortranDokumentationsseite. Die notwendigen Schritte sind: 1. blas.tgz downloaden 2. Dieses Paket in ein leeres Verzeichnis entpacken 3. Bibliothek erstellen ("shared library" oder "static library"): a) In Form einer "shared library": gfortran -shared -O2 *.f -o libblas.so -fPIC b) In Form einer "static library": gfortran -O2 -c *.f ar cr libblas.a *.o 4. Die daraus resultierende Bibliotheksdatei in ein geeignetes Verzeichnis verschieben (z.B. /usr/lib/ oder /usr/local/lib/)

427

56. Beispiele 56.1. Beispiel: Die Level 1-Funktionen sdot und dnrm2 Fortran 90/95-Code (free source form) program bsp implicit none real, dimension(3) :: a = (/2.,1.,-1./), b = (/5., -2., 1.5/) real :: c, sdot real(kind=8) :: d, dnrm2 ! *** Skalarprodukt *** ! sdot: s ... REAL, dot ... Skalarprodukt (inneres Produkt) ! 1. Argument ... Dimension des Vektors ! 2. und 4. A. ... die Vektoren ! 3. und 5. A. ... Inkrement (hier 1) c = sdot(3, a, 1, b, 1) write(*,*) c ! Ausgabe: 6.500000 ! *** Norm des Vektors *** ! dnrm2: d ... DOUBLE PRECISION, nrm2 ... (euklidische) Norm ! 1. Argument: Dimension des Vektors ! 2. A.: Vektor ! 3. A.: Inkrement (hier 1) d = dnrm2(3, dble(a), 1) write(*,*) d ! Ausgabe: 2.44948974278318 end program bsp

Kompilieren und Linken:

429

Beispiele

gfortran bsp.f95 -lblas

56.2. Beispiel: Die Level 2-Subroutine sger sger steht für: • s ... REAL • ge ... general matrix • r ... rank 1 operation Mathematisch ist damit folgende Operation gemeint: A ← αxyT + A wobei A eine mxn-Matrix ist, x und y stellen Vektoren dar. Das nachfolgende Beispiel führt konkret folgende Rechnung aus: · ¸ · ¸ ¤ 2.0 £ 1.0 −1.0 1.0 0.0 + A= 1.0 2.0 7.0 Fortran 90/95-Code (free source form) program bsp implicit none real, dimension(2) :: x = (/2., 1./), y = (/1., 0./) real, dimension(2,2) :: a = reshape ( (/1., 2., -1., 7./), (/2, 2/) ) call sger (2, 2, 1., x, 1, y, 1, a, 2) write(*,*) a ! Ausgabe: 3.000000 3.000000 -1.000000 end program bsp

430

7.000000

57. Weblinks • BLAS (B ASIC L INEAR A LGEBRA S UBPROGRAMS )1 • AUTOMATICALLY T UNED L INEAR A LGEBRA S OFTWARE (ATLAS)2

57.1. FGSL G NU S CIENTIFIC L IBRARY3

57.2. Allgemeines Bei der "GNU Scientific Library" (GSL) handelt es sich um eine in C geschriebene Bibliothek. Diese bietet Funktionen für ein weites Spektrum der Mathematik. Beispielhaft seien folgende Bereiche genannt: • • • • •

Komplexe Zahlen Lineare Algebra Polynome Statistik Fast Fourier Transformation (FFT)

1 2 3

H T T P :// W W W . N E T L I B . O R G / B L A S / H T T P :// M A T H -{} A T L A S . S O U R C E F O R G E . N E T / H T T P :// D E . W I K I P E D I A . O R G / W I K I /%20G N U %20S C I E N T I F I C % 20L I B R A R Y

431

Weblinks

• • • •

Numerische Differentiation Numerische Integration Gewöhnliche Differentialgleichungen IEEE Floating-Point-Arithmetik

FGSL ist ein Fortran-Interface für diese GSL-Bibliothek. FGSL selbst deckt nicht die komplette Funktionspalette von GSL ab, inzwischen sind aber auch lineare Algebra und die FFT-Funktionen Bestandteil von FGSL, auch wenn zu diesem Zweck der Einsatz der optimierten Bibliotheken LAPACK und FFTW empfohlen wird. Für einige Teilbereiche werden nicht alle in C implementierten Datentypen unterstützt. FGSL wurde unter Verwendung einiger Fortran 2003Sprachmerkmale erstellt. Die Einbindung von FGSL in eigene Programme setzt aus diesem Grunde einen entsprechenden Fortran-Compiler voraus. Der g95-Compiler erfüllt z.B. diese Voraussetzungen. Derzeit ist die FGSL-Version 0.9.3 vom 1. Mai 2010 aktuell.

57.3. Beispiele 57.3.1. Beispiel: Datentypen, Potenzierung und mathematische Konstanten

432

Beispiele C

• include • include int main (void) { double a; double d = 5.0; a = gsl_pow_2 (d) * M_PI_4; printf ("Kreisflaeche = %f\n", a); return 0; } Kompilieren, Linken: gcc bsp.c

-I/usr/local/include -L/usr/local/lib -lgsl -lgslcblas -lm

Fortran program bsp use fgsl implicit none real( kind = fgsl_double ) :: a real( kind = fgsl_double ) :: d = 5.0_fgsl_double a = d ** 2 * m_pi_4 write( *, * ) "Kreisflaeche = ", a end program bsp

Kompilieren, Linken:

g95 bsp.f03 -I/usr/local/include/g95 -L/usr/local/lib -lgsl -lfgsl_g95 -lgslcblas

Der kind-Wert fgsl_double entspricht dem c_double aus dem iso_c_binding-Modul. FGSL kennt die speziellen powFunktionen aus GSL nicht, da Fortran ohnehin über einen eigenen Potenzierungsoperator verfügt. Neben der m_pi_4-Konstante ( = π/4) kennt FGSL noch eine ganze Reihe anderer mathematischer Konstanten, z.B.:

m_e

...

m_euler

...

m_pi m_pi_2 m_sqrt2

... ... ...

e, Eulersche Zahl, 2,714... Eulersche Konstante, 0,577... π π/2 p 2

433

Weblinks

Auch jede Menge physikalische Konstanten kennt FGSL, z.B.:

fgsl_const_mksa_speed_of_light

...

fgsl_const_mksa_molar_gas

...

fgsl_const_mksa_inch fgsl_const_mksa_torr fgsl_const_num_giga

...

Lichtgeschwindigkeit im Vakuum, 2.9979... x 108 m / s Allgemeine Gaskonstante, 8.314472 J / (K · mol) 0.0254m

...

133.322... Pa

...

109

57.3.2. Beispiel: Lösen einer quadratischen Gleichung Gesucht ist die Lösung der quadratischen Gleichung x 2 + 12x + 37 = 0

434

Beispiele C

• include • include • include int main (void) { double a, b, c; gsl_complex z1, z2; int i; a = 1.0; b = 12.0; c = 37.0; i = gsl_poly_complex_solve_quadratic(a, b, c, &z1, &z2); if(i == 1) { /* nur eine Lsg.*/ printf("z = (%f, %f)\n", z1.dat[0], z1.dat[1]); } else { /* 2 Lsg., reell oder komplex */ printf( "z1 = (%f, %f)\n", z1.dat[0], z1.dat[1]); printf( "z2 = (%f, %f)\n", z2.dat[0], z2.dat[1]); } return 0; /* Ausgabe: z1 = (-6.000000, -1.000000) z2 = (-6.000000, 1.000000)

Fortran program bsp use fgsl implicit none real( kind = fgsl_double ) :: a, b, c complex( fgsl_double ), dimension( 2 ) :: z integer( kind = fgsl_int ) :: i a = 1.0_fgsl_double b = 12.0_fgsl_double c = 37.0_fgsl_double i = fgsl_poly_complex_solve_quadratic( a, b, c, z(1), z(2) ) if( i == 1 ) then ! nur eine Lsg. write( *, * ) " z =", z(1) else ! 2 Lsg., reell oder komplex write( *, * ) " z1,2 =", z end if ! Ausgabe: ! z1,2 = (-6.,-1.) (6.,1.) end program bsp

• / }

435

Weblinks

57.3.3. Beispiel: Numerische Integration Gesucht ist die Lösung des Integrals I = C

• include • include • include double f(double x, void *params) { return(sin(x) / x); } int main () { double result, error; size_t neval; gsl_function func; func.function = &f; func.params = 0; gsl_integration_qng (&func, 0.0, 1.0, 1e-9, 1e-9, &result, &error, &neval); printf ("Ergebnis = %f\n", result); return 0; /* Ausgabe: Ergebnis = 0.946083 • / }

436

R 1 sin x 0

x

dx

Fortran module integral implicit none contains function f( x, params ) bind(c) use, intrinsic :: iso_c_binding implicit none real( kind = c_double ) :: f real( kind = c_double ), value :: x type( c_ptr ), value :: params f = sin( x ) / x end function f end module integral program bsp use fgsl use integral use, intrinsic :: iso_c_binding implicit none real( kind = fgsl_double ) :: result, error integer( kind = fgsl_size_t) :: neval integer( kind = fgsl_int) :: i type( fgsl_function ) :: func func = fgsl_function_init( f, c_null_ptr ) i = fgsl_integration_qng ( func, & 0.0_fgsl_double, & 1.0_fgsl_double, & 1e-9_fgsl_double, & 1e-9_fgsl_double, & result, error, neval ) write( *, * ) "Ergebnis =", result ! Ausgabe: ! Ergebnis = 0.946083070367183 end program bsp

Beispiele

(F)GSL stellt verschiedene Möglichkeiten der numerischen Integration zur Verfügung. Hier wurde die Funktion für den QNGAlgorithmus (non-adaptive Gauss-Kronrod) gewählt.

57.3.4. Beispiel: IEEE-Floating-Point-Arithmetik Darstellung einer Fließkommazahl nach IEEE 754-Standard: (−1)s (1. f f f f ...)2E Beispielsweise wird eine 32-bit-Fließkommazahl binär so aufgegliedert: seeeeeeeefffffffffffffffffffffff

• s ... sign, 1 bit • e, E ... exponent, 8 bit (28 = 256; Emin = -127; Emax = 128) • f ... fraction, 23 bit Näheres zum IEEE 754-Standard findet sich z.B. bei IEEE 7544 FGSL bietet Subroutinen, um Fießkommazahlen anschaulich entsprechend dem IEEE 754-Standard auszugeben: • fgsl_ieee_printf( x ) ... Ausgabe der Zahl x im IEEE-Format auf stdout • fgsl_ieee_fprintf( str, x ) ... Ausgabe der Zahl x im IEEEFormat. str ist ein C-Zeiger (C: FILE *, Fortran: type( c_ptr )).

4

H T T P :// D E . W I K I P E D I A . O R G / W I K I /IEEE%20754

437

Weblinks C

• include

Fortran program bsp use fgsl implicit none real( kind = fgsl_float ) :: a = 1.5 real( kind = fgsl_double ) :: b = -2.6666666666666666d0 call fgsl_ieee_printf( a ) call fgsl_ieee_printf( b ) end program bsp

int main() { float a = 1.5; double b = -2.6666666666666666; gsl_ieee_printf_float( &a ); gsl_ieee_printf_double( &b ); } Ausgabe: 1.10000000000000000000000*2ˆ0 1.0101010101010101010101010101010101010101010101010101*2ˆ1

Mit der Subroutine fgsl_ieee_env_setup() lassen sich über die Environment-Variable GSL_IEEE_MODE einige nützliche Attribute (Rundungsmodus etc.) festlegen. C

• include • include int main() { float a = 1.5; int i; gsl_ieee_env_setup(); for(i = 0; i < 5; i++) { a /= 0.11; printf("%f\n", a); } }

438

Fortran program bsp use fgsl implicit none real :: a = 1.5 integer :: i call fgsl_ieee_env_setup() do i = 0, 4 a = a / 0.11 write( *, * ) a end do end program bsp

Weblinks C Programmaufruf: GSL_IEEE_MODE="round-to-nearest" ./a.out Ausgabe: GSL_IEEE_MODE="round-tonearest,trap-common" 13.636364 123.966942 1126.972168 10245.201172 93138.195312 Programmaufruf: GSL_IEEE_MODE="round-up" ./a.out Ausgabe: GSL_IEEE_MODE="round-up,trapcommon" 13.636364 123.966949 1126.972290 10245.203125 93138.210938 Programmaufruf: GSL_IEEE_MODE="round-down" ./a.out Ausgabe: GSL_IEEE_MODE="round-down,trapcommon" 13.636363 123.966934 1126.972046 10245.200195 93138.179688

Fortran Programmaufruf: GSL_IEEE_MODE="round-to-nearest" ./a.out Ausgabe: GSL_IEEE_MODE="round-tonearest,trap-common" 13.636364 123.96695 1126.9723 10245.203 93138.21 Programmaufruf: GSL_IEEE_MODE="round-up" ./a.out Ausgabe: GSL_IEEE_MODE="round-up,trapcommon" 13.636364 123.96695 1126.9723 10245.203 93138.21 Programmaufruf: GSL_IEEE_MODE="round-down" ./a.out Ausgabe: GSL_IEEE_MODE="round-down,trapcommon" 13.636363 123.966934 1126.972 10245.2 93138.18

57.4. Weblinks • GSL - GNU S CIENTIFIC L IBRARY5

5

H T T P :// W W W . G N U . O R G / S O F T W A R E / G S L /

439

Weblinks



FGSL: A F ORTRAN

INTERFACE TO THE

GNU S CIENTIFIC L I -

BRARY 6

57.5. LAPACK LAPACK7

57.6. Allgemeines LAPACK steht für "Linear Algebra Package". LAPACK ist eine Bibliothek zwecks Lösung von • • • •

linearen Gleichungssystemen LLS-Aufgaben Eigenwertproblemen Singulärwertproblemen

LAPACK ist in FORTRAN 77 geschrieben. Die daraus resultierende Namensbeschränkung auf eine maximale Länge von 6 Zeichen führt zu sehr kryptischen Unterprogrammbezeichnungen, z.B. D G Zeichenposition: D1 M1

E M2

T O1

R O2

F O3

Erläuterung der Zeichenpositionen:

6

H T T P :// W W W . L R Z -{} M U E N C H E N . D E / S E R V I C E S / S O F T W A R E / M A T H E M A T I K/G S L/F O R T R A N/I N D E X.H T M L

7

440

H T T P :// D E . W I K I P E D I A . O R G / W I K I /%20LAPACK

Beispiel: Lösen eines einfachen Gleichungssystems

D1

Datentyp: S D

C Z M1, M2

O1, O2, (O3)

... ...

... ...

Matrixtyp, z.B. GE ... DI ... OR ...

SY ... Operation, z.B. TRF ...

real double precision complex double complex generell diagonal orthogonal (reelle Zahlen) symmetrisch faktorisiere

Eine detailliertere und umfassendere Beschreibung des Funktionsumfanges und der Anwendungsmöglichkeiten der LAPACKBibliothek bietet der LAPACK U SERS ’ G UIDE8 . Die einzelnen Subroutinen inklusive Unterprogrammparameter sind zudem auch in den LAPACK-Sourcecode-Dateien ausführlich dokumentiert.

57.7. Beispiel: Lösen eines einfachen Gleichungssystems Gegeben ist folgendes Gleichungssystem: 8

H T T P :// W W W . N E T L I B . O R G / L A P A C K / L U G / I N D E X . H T M L

441

Weblinks

2x + y = 5 3x + y = 6 bzw. in Matrixschreibweise: ¸· ¸ · ¸ · 5 2 1 x ⇔ Ax = B = 6 3 1 y

Gesucht sind die Unbekannten x und y: Fortran 90/95-Code (free source form) program bsp implicit none integer :: info real, dimension(2,2) :: a = reshape ( (/2.,3.,1.,1./), (/2,2/) ) real, dimension(2) :: b = (/5., 6./), ipiv ! !

SUBROUTINE SGESV(N, NRHS, A, LDA, IPIV, B, LDB, INFO) s ... real, ge ... general matrix type, sv ... solver call sgesv(2, 1, a, 2, ipiv, b, 2, info) write(*,*) "Lösung (x, y): ", b if(info == 0) then write(*,*) "Ergebnis OK" else write(*,*) "Ergebnis NOK" end if

! Ausgabe: Lösung (x, y): ! Ausgabe: Ergebnis OK end program bsp

1.000000

Kompilieren, Linken: gfortran bsp.f95 -llapack -lblas

442

3.000000

Beispiel: Inverse Matrix

57.8. Beispiel: Inverse Matrix Gegeben ist eine 3x3-Matrix   3 −2 1 A = −3 5 0 2

−1 2

die invertiert werden soll. Die Zahlenwerte dieser Matrix A entsprechen einem Beispiel aus Bartsch: Mathematische Formeln, 21. Auflage, VEB Fachbuchverlag Leipzig, 1986, Seite 109, ebenfalls zum Thema "Inverse Matrix". Verwendet werden hierzu die beiden LAPACK-Subroutinen: • SGETRF • S ... Datentyp: real • GE ... Matrixtyp: general • TRF ... Operation: LU-Faktorisierung (Dreiecksform) • SGETRI • S ... Datentyp: real • GE ... Matrixtyp: general • TRI ... Operation: Invertierung einer LU-faktorisierten Matrix Fortran 90/95-Code (free source form) program bsp implicit none real, dimension( 3, 3 ) :: A integer, dimension( 3 ) :: ipiv real, dimension( 3 ) :: work integer :: m = 3, n = 3, lda = 3, lwork = 3, info

A = /),

reshape( (/ 3.0, -3.0, & shape( A ) )

2.0, -2.0,

5.0, -1.0, 1.0,

0.0,

2.0

! LU-Faktorisierung (Dreieckszerlegung) der Matrix A call sgetrf( m, n, A, lda, ipiv, info ) ! Inverse der LU-faktorisierten Matrix A

443

Weblinks

call sgetri( n, A, lda, ipiv, work, lwork, info ) write( *, * ) "Inverse Matrix Ai =", A write( *, * ) "Testweise wie im Bartsch-Beispiel, Ai = 1/11 * (", A * 11, ")" if( info == 0 ) then write( *, * ) "OK" else write( *, * ) "Nicht OK" end if ! Ausgabe: ! Inverse Matrix Ai = 0.909091 0.54545456 -0.63636374 0.2727273 ! 0.36363637 -0.090909116 -0.45454553 -0.2727273 0.81818193 ! Testweise wie im Bartsch-Beispiel, Ai = 1/11 * ( 10.000001 6. -7.000001 ! 3.0000005 4. -1.0000002 -5.000001 -3.0000005 9.000001 ) ! OK end program bsp

57.9. Weblinks • • • •

LAPACK - L INEAR A LGEBRA PACKAGE9 LAPACK S EARCH E NGINE10 LAPACK95 - F ORTRAN 95 INTERFACE TO LAPACK11 E RSTELLEN DER LAPACK-B IBLIOTHEK MIT gfortran12

9 10 11 12

444

H T T P :// W W W . N E T L I B . O R G / L A P A C K / H T T P :// W W W . C S . C O L O R A D O . E D U /~{} J E S S U P / L A P A C K / H T T P :// W W W . N E T L I B . O R G / L A P A C K 95/ H T T P :// G C C . G N U . O R G / W I K I /G F O R T R A N B U I L D

58. Parallele Programmierung 58.1. OpenMP O PEN MP1

58.2. Was ist OpenMP OpenMP ist die Abkürzung für "Open specifications for M’ulti Processing" und ist eine API für Fortran und C/C++, die zum Zwecke der PARALLELEN P ROGRAMMIERUNG2 mittels SharedMemory-Ansatz für Mehrprozessor-Systeme erschaffen wurde. Durch Anwendung von Compiler-Direktiven und spezieller Unterprogramme wird die Abarbeitung von bestimmten Programmkonstrukten auf mehrere Threads aufgeteilt. Der "Master Thread" mit der Nummer 0 ist in einem OpenMPProgramm standardmäßig immer aktiv. Der Programmierer bestimmt im Programmcode, wann eine Gabelung (fork) in mehrere Threads gefordert wird und wann das Ganze wieder in einen einzelnen Thread vereint werden soll (join). OpenMP wird schon von vielen Fortran-Compilern unterstützt. 1 2

H T T P :// D E . W I K I P E D I A . O R G / W I K I /%20O P E N MP H T T P :// D E . W I K I P E D I A . O R G / W I K I /P A R A L L E L E %

20P R O G R A M M I E R U N G

445

Parallele Programmierung

58.3. Ein einfaches Beispiel Fortran 90/95-Code (free source form) program bsp use omp_lib implicit none ! fork !$omp parallel num_threads(3) ! Das nur 1x ausgeben (beim Master Thread) if( omp_get_thread_num() == 0 ) then write( *, * ) ’Insgesamt gibt es ’, omp_get_num_threads(), ’Thread(s)’ end if ! Das bei jedem Thread ausgeben write( *, * ) ’Thread ’, omp_get_thread_num(), ’ist aktiv’ ! join !$omp end parallel ! Ausgabe: ! Insgesamt gibt es 3 Thread(s) ! Thread 0 ist aktiv ! Thread 1 ist aktiv ! Thread 2 ist aktiv end program bsp

Unter Umständen muss das Modul omp_lib eingebunden werden. Dieses Module enthält die interface für die OpenMPRoutinen. Eine mögliche Form des OpenMP-Modus ist am Ende dieses Abschnittes angegeben. Kompilieren und Linken des Beispielprogramms: gfortran: Intel Fortran Compiler:

gfortran -fopenmp -o bsp bsp.f90 ifort -openmp -o bsp bsp.f90

Erläuterung: • OpenMP-Direktiven werden als Kommentare gekapselt. Bei Verwendung der "free source form" lautet der erste Direktiven-

446

Thread-Erzeugung: Die parallel-Direktive

Abschnitt (en. sentinel, dt. Wächter) immer !$omp. Groß/Kleinschreibung spielt keine Rolle. Es folgt die Anweisung, dass sich nun das Programm gabeln soll (parallel). Die Anzahl der gewünschten Threads wird hier explizit mittels der Option num_threads() festgelegt. • Verwendete OpenMP-Funktionen: • omp_get_thread_num() ... Aktuelle Thread-Nummer • omp_get_num_threads() ... Anzahl der Threads • Beendet wird der parallele Programmteil mit !$omp end

parallel

58.4. Thread-Erzeugung: Die parallel-Direktive

Wie im vorigen Beispiel bereits angedeutet, wird ein "fork" (die Threaderzeugung) immer mit der Direktive !$omp parallel [optionen]

eingeleitet und mit !$omp end parallel

beendet. Es kann hier auch eine Reihe von optionalen Steueranweisungen angegeben werden (siehe vorheriges Beispiel und nachfolgende Beispiele).

447

Parallele Programmierung

58.5. Thread-Anzahl bestimmen • Festlegung im Rahmen der OpenMP-Direktive !$omp parallel über die Option num_threads( nr ) • Mittels OpenMP-Subroutinenaufruf vor dem fork: call omp_-

set_num_threads( nr ) • Festlegung in der Kommandozeile vor Ausführung des Programmes, z.B.: export OMP_NUM_THREADS=nr • Default (normalerweise 1 Thread pro CPU) • Dynamische Anpassung zur Programmlaufzeit per Run-TimeEnvironment: call omp_set_dynamic( .true. )

58.6. Sichtbarkeit/Gültigkeit von Daten Aufgrund des Shared-Memory-Ansatzes werden Daten standardmäßig zwischen den Threads geteilt. Dieses Verhalten kann aber auch optional geändert werden. Mögliche Varianten für die parallel-Direktive: • shared ... Solche Daten sind explizit in allen Threads sichtbar und gültig. Eine Änderung solcher Daten in einem Thread wirkt sich auf alle anderen Threads aus. • private ... Solche Daten sind nur im aktuellen Thread sichtbar und gültig, sie werden beim Eintritt in den parallelen Programmabschnitt nicht speziell initialisiert. Änderungen dieser Werte wirken sich nicht auf nachfolgende serielle Programmteile aus. • firstprivate ... Ähnlich wie private. Der Unterschied zu private ist, dass solcherart markierte Daten mit dem letztgültigen Wert aus dem vorhergehenden seriellen Programmabschnitt initialisiert werden. Beispiel: Fortran 90/95-Code (free source form)

448

Sichtbarkeit/Gültigkeit von Daten

program bsp use omp_lib implicit none integer :: a, b, c, tnr a = 123 b = 123 c = 123 ! Seriell write( *, write( *, write( *, write( *, write( *,

* * * * *

) ) ) ) )

’Seriell:’ ’a = ’, a ’b = ’, b ’c = ’, c ’-------------------------------’

call omp_set_num_threads( 3 ) !$omp parallel shared( a ) private( b ) firstprivate( c ) write( *, * ) ’Parallel:’ tnr = omp_get_thread_num() if( a b c end

tnr = a = b = c if

! Aktuelle Threadnummer

== 0 ) then + 5 + 5 + 5

write( *, * ) ’a = ’, a write( *, * ) ’b = ’, b write( *, * ) ’c = ’, c write( *, * ) ’-------------------------------’ !$omp end parallel ! Seriell write( *, * ) ’Seriell:’ write( *, * ) ’a = ’, a write( *, * ) ’b = ’, b write( *, * ) ’c = ’, c end program bsp

Ausgabe: Seriell: a =

123

449

Parallele Programmierung

b = 123 c = 123 ------------------------------Parallel: 0 a = 128 b = 5 c = 128 ------------------------------Parallel: 1 a = 128 b = 0 c = 123 ------------------------------Parallel: 2 a = 128 b = 0 c = 123 ------------------------------Seriell: a = 128 b = 123 c = 123

Für andere OpenMP-Direktiven sind auch noch andere Sichtbarkeits- und Gültigkeitsbereiche möglich (z.B. lastprivate).

58.7. Die do-Direktive Innerhalb eines parallel-Blocks können auch do-Schleifen parallelisiert werden. Die Schleifendurchläufe werden auf die einzelnen Threads bzw. CPUs aufgeteilt. Beispiel: Fortran 90/95-Code (free source form) program bsp use omp_lib implicit none integer :: i, tnr

450

Die do-Direktive

call omp_set_num_threads( 3 ) !$omp parallel private( i ) !$omp do do i = 1, 20 tnr = omp_get_thread_num() ! Aktuelle Threadnummer write( *, * ) ’Thread’, tnr, ’:’, i end do !$omp end do !$omp end parallel end program bsp

Ausgabe: Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread

0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 2

: : : : : : : : : : : : : : : : : : : :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Die Zuweisung der Schleifendurchläufe an die Threads kann gesteuert werden. Dazu wird der do-Direktive eine scheduleAnweisung mit dem Argument Typ und ev. auch mit dem Argument Chunk-Größe beigefügt. Als Typen sind möglich • static • dynamic

451

Parallele Programmierung

• guided • runtime Diese Bezeichnungen beziehen sich auf die Art der ThreadErzeugung. Beispiel: Fortran 90/95-Code (free source form) program bsp use omp_lib implicit none integer :: i, tnr call omp_set_num_threads( 3 ) !$omp parallel private( i ) !$omp do schedule(static, 3) do i = 1, 20 tnr = omp_get_thread_num() ! Aktuelle Threadnummer write( *, * ) ’Thread’, tnr, ’:’, i end do !$omp end do !$omp end parallel end program bsp

Ausgabe: Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread

452

0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2

: : : : : : : : : : : : : : : :

1 2 3 10 11 12 19 20 4 5 6 13 14 15 7 8

Die sections-Direktive

Thread Thread Thread Thread

2 2 2 2

: : : :

9 16 17 18

Eine do while-Schleife kann nicht auf diese Art und Weise mittels OpenMP-Direktive parallel ausgeführt werden.

58.8. Die sections-Direktive Auch die Festlegung, dass bestimmte Programmabschnitte auf je einen Thread verteilt werden sollen, ist möglich. Dazu wird das Konstrukt !$omp sections [optionen] !$omp section block !$omp section block ... !$omp end sections

innerhalb eines parallel-Blocks eingesetzt. Beispiel: Fortran 90/95-Code (free source form) program bsp use omp_lib implicit none integer :: a, b a = 20 b = 30 call omp_set_num_threads( 3 ) !$omp parallel shared( a, b ) !$omp sections

453

Parallele Programmierung

!$omp section write( *, * ) omp_get_thread_num(), write( *, * ) omp_get_thread_num(), !$omp section write( *, * ) omp_get_thread_num(), write( *, * ) omp_get_thread_num(), !$omp end sections !$omp end parallel ! Ausgabe (ifort): ! 0 20 ! 0 --! 1 30 ! 1 ---end program bsp

a "---" b "----"

58.9. Weitere Direktiven • workshare • single

58.10. Kombinierte Direktiven Unmittelbar aufeinanderfolgende Einzeldirektiven können auch in einer einzigen Direktive zusammengefasst werden. Möglich sind • parallel do • parallel sections • parallel workshare Beispiel: Fortran 90/95-Code (free source form) program bsp use omp_lib implicit none integer :: i, tnr

454

Synchronisation

call omp_set_num_threads( 3 ) !$omp parallel do private(i) schedule(static, 3) do i = 1, 20 tnr = omp_get_thread_num() ! Aktuelle Threadnummer write( *, * ) ’Thread’, tnr, ’:’, i end do !$omp end parallel do end program bsp

Eine zusammengehörende OpenMP-Direktive darf auch auf mehrere Zeilen verteilt werden. Beispiel: Fortran 90/95-Code (free source form) program bsp use omp_lib implicit none integer :: i, tnr call omp_set_num_threads( 3 ) !$omp parallel do & !$omp private(i) & !$omp schedule(static, 3) do i = 1, 20 tnr = omp_get_thread_num() ! Aktuelle Threadnummer write( *, * ) ’Thread’, tnr, ’:’, i end do !$omp end parallel do end program bsp

58.11. Synchronisation Bei der parallelen Programmierung können Situationen auftreten, die bei einer seriellen Programmausführung nie passieren würden, z.B. RACE CONDITIONS3 . Damit es nicht soweit kommt, bietet 3

H T T P :// D E . W I K I P E D I A . O R G / W I K I /R A C E %20C O N D I T I O N

455

Parallele Programmierung

OpenMP einige Direktiven zur Synchronisation der Threadausführung.

58.11.1. master-Direktive !$omp master ... !$omp master end

Der eingeschlossene Programmblock wird nur vom Master Thread ausgeführt und von den anderen Threads ignoriert.

58.11.2. critical-Direktive !$omp critical ... !$omp critical end

Dieser Programmteil wird zwar von allen Threads ausgeführt, allerdings ist sichergestellt, dass dies nicht gleichzeitig erfolgt.

58.11.3. atomic-Direktive !$omp atomic

Ähnlich zu critical. Allerding gilt dies Direktive nur für eine einzelne unmittelbar nachfolgende spezielle Programmanweisung.

456

Synchronisation

58.11.4. barrier-Direktive !$omp barrier

Sobald ein Thread eine solche Barriere erreicht, wartet er bis alle andere Threads diese Barriere auch erreicht haben. Erst dann geht’s weiter.

58.11.5. flush-Direktive !$omp flush

Erstellung eines konsistenten Speicherbildes.

58.11.6. ordered-Direktive !$omp do ordered do ... ... !$omp ordered ... !$omp end ordered ... end do !$omp end do

"Geordnete Ausführung" von do-Schleifen in der gleichen Reihenfolge einer seriellen Abarbeitung. Beispiel: Fortran 90/95-Code (free source form) program bsp use omp_lib implicit none integer :: i, tnr

457

Parallele Programmierung

call omp_set_num_threads( 3 ) !$omp parallel private( i ) !$omp do ordered schedule(static, 3) do i = 1, 20 !$omp ordered tnr = omp_get_thread_num() ! Aktuelle Threadnummer write( *, * ) ’Thread’, tnr, ’:’, i !$omp end ordered end do !$omp end do !$omp end parallel end program bsp

Ausgabe: Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread Thread

458

0 0 0 1 1 1 2 2 2 0 0 0 1 1 1 2 2 2 0 0

: : : : : : : : : : : : : : : : : : : :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Das Modul omp_lib

58.12. Das Modul omp_lib Das Modul omp_lib enthält die interface für die Routinen von OpenMP. Eine mögliche Form des Modules ist nachfolgend abgebildet. In dem Modul wird die import-Anweisung verwendet, die Teil des Standards Fortran 2003 ist. Fortran 90/95-Code (free source form) module omp_lib ! ! OpenMP Fortran API v2.5 ! implicit none integer, parameter, private :: sgl = kind( 0.0 ) integer, parameter, private :: dbl = kind( 0.0d0 ) integer, integer, integer, integer, integer,

parameter, parameter, parameter, parameter, parameter,

private private private private private

:: :: :: :: ::

omp_real_kind = dbl omp_integer_kind = sgl omp_logical_kind = sgl omp_lock_kind = dbl omp_nest_lock_kind = dbl

interface subroutine omp_destroy_lock ( var ) import :: omp_lock_kind integer ( kind=omp_lock_kind ), intent(inout) :: var end subroutine omp_destroy_lock subroutine omp_destroy_nest_lock ( var ) import :: omp_nest_lock_kind integer ( kind=omp_nest_lock_kind ), intent(inout) :: var end subroutine omp_destroy_nest_lock function omp_get_dynamic () import :: omp_logical_kind logical ( kind=omp_logical_kind ) :: omp_get_dynamic end function omp_get_dynamic function omp_get_max_threads () import :: omp_integer_kind integer ( kind=omp_integer_kind ) :: omp_get_max_threads end function omp_get_max_threads function omp_get_nested () import :: omp_logical_kind logical ( kind=omp_logical_kind ) :: omp_get_nested end function omp_get_nested

459

Parallele Programmierung

function omp_get_num_procs () import :: omp_integer_kind integer ( kind=omp_integer_kind ) :: omp_get_num_procs end function omp_get_num_procs function omp_get_num_threads () import :: omp_integer_kind integer ( kind=omp_integer_kind ) :: omp_get_num_threads end function omp_get_num_threads function omp_get_thread_num () import :: omp_integer_kind integer ( kind=omp_integer_kind ) :: omp_get_thread_num end function omp_get_thread_num function omp_get_wtick () import :: omp_real_kind real ( kind=omp_real_kind ) :: omp_get_wtick end function omp_get_wtick function omp_get_wtime () import :: omp_real_kind real ( kind=omp_real_kind ) :: omp_get_wtime end function omp_get_wtime subroutine omp_init_lock ( var ) import :: omp_lock_kind integer ( kind=omp_lock_kind ), intent(out) :: var end subroutine omp_init_lock subroutine omp_init_nest_lock ( var ) import :: omp_nest_lock_kind integer ( kind=omp_nest_lock_kind ), intent(out) :: var end subroutine omp_init_nest_lock function omp_in_parallel () import :: omp_logical_kind logical ( kind=omp_logical_kind ) :: omp_in_parallel end function omp_in_parallel subroutine omp_set_dynamic ( enable_expr ) import :: omp_logical_kind logical ( kind=omp_logical_kind ), intent(in) :: enable_expr end subroutine omp_set_dynamic subroutine omp_set_lock ( var ) import :: omp_lock_kind integer ( kind=omp_lock_kind ), intent(inout) :: var end subroutine omp_set_lock subroutine omp_set_nest_lock ( var ) import :: omp_nest_lock_kind integer ( kind=omp_nest_lock_kind ), intent(inout) :: var end subroutine omp_set_nest_lock subroutine omp_set_nested ( enable_expr ) import :: omp_logical_kind logical ( kind=omp_logical_kind ), intent(in) ::

460

Literatur

enable_expr end subroutine omp_set_nested subroutine omp_set_num_threads ( number_of_threads_expr ) import :: omp_integer_kind integer ( kind=omp_integer_kind ), intent(in) :: number_of_threads_expr end subroutine omp_set_num_threads function omp_test_lock ( var ) import :: omp_logical_kind, omp_lock_kind logical ( kind=omp_logical_kind ) :: omp_test_lock integer ( kind=omp_lock_kind ), intent(inout) :: var end function omp_test_lock function omp_test_nest_lock ( var ) import :: omp_integer_kind, omp_nest_lock_kind integer ( kind=omp_integer_kind ) :: omp_test_nest_lock integer ( kind=omp_nest_lock_kind ), intent(inout) :: var end function omp_test_nest_lock subroutine omp_unset_lock ( var ) import :: omp_lock_kind integer ( kind=omp_lock_kind ), intent(inout) :: var end subroutine omp_unset_lock subroutine omp_unset_nest_lock ( var ) import :: omp_nest_lock_kind integer ( kind=omp_nest_lock_kind ), intent(inout) :: var end subroutine omp_unset_nest_lock end interface end module omp_lib

58.13. Literatur • Rohit Chandra, Leonardo Dagum, Dave Kohr, Dror Maydan, Jeff McDonald, Ramesh Menon, Parallel Programming in OpenMP, Morgan Kaufmann Publishers, 2001, ISBN-13: 978-1-55860-6715, ISBN-10: 1-55860-671-8

461

Parallele Programmierung

58.14. Weblinks • • • • •

O PEN MP4 O PEN MP-H OMEPAGE5 O PEN MP F ORTRAN S UMMARY6 O PEN MP T UTORIAL7 O PEN M P IN GFORTRAN8

4 5 6 7 8

462

H T T P :// D E . W I K I P E D I A . O R G / W I K I /O P E N MP H T T P :// W W W . O P E N M P . O R G / D R U P A L / H T T P :// S T U D I E S . A C . U P C . E D U /FIB/MP/ O P E N M P _ F . P D F H T T P :// W W W . L L N L . G O V / C O M P U T I N G / T U T O R I A L S / O P E N MP/ H T T P :// K A R M I N G H E N R Y . S I N A M A N . C O M / G F O R T R A N . H T M L

Teil VII.

Fortran in Kombination mit anderen Programmiersprachen

463

59. Fortran und Tcl Tcl/Tk kann im Zusammenhang mit Fortran zwecks Erstellung einer Tk-Benutzeroberfläche für Fortran-Programme interessant sein. Die zeitkritischen oder mathematisch orientierten Programmteile werden mittels Fortran-Code realisiert. Der Programmcode für die Benutzerschnittstelle wird mittels Tcl/TkSkript zur Verfügung gestellt.

59.1. Beispiel 59.1.1. Prinzipskizze

Abb. 55

465

Fortran und Tcl

59.1.2. Tcl/Tk-Code #!/usr/bin/wish wm title . Sinus

;# Fenstertitel

entry .e1 button .b1 -text "Hier drücken" -command fcall label .l1 -bg green

;# Eingabefeld ;# Schaltfläche ;# Textfeld

pack .e1 -padx 10 -pady 5 pack .b1 -padx 10 -pady 5 pack .l1 -padx 10 -pady 5

;# Widgets packen

proc fcall { } { Fortran, Ergebnis schreiben set f [open "|./a.out" r+] kompilierte und gelinkte Fortran-Programm set val [.e1 get]

;# Kommunikation mit

puts $f $val flush $f gets $f wert close $f .l1 config -text $wert }

59.1.3. Fortran-Code Fortran 90/95-Code (free source form) program bsp implicit none real :: val, sin read (*,*) val write(*,’(A12F6.3)’) "Ergebnis = ", sin(val) end

466

;# a.out ist das

Beispiel

59.1.4. Programmausführung Das Fortran-Programm muss selbstverständlich vorab einmal kompiliert und gelinkt werden. Im Beispielsfall muss die exekutierbare Ausgabedatei a.out heißen. Unter Linux wird das TclSkript vor dem ersten Start als ausführbar (-> mittels chmodBefehl) markiert. Der Programmaufruf erfolgt über das Tcl-Skript, das wie ein normales Programm durch Eingabe des Programmnamens gestartet wird.

59.1.5. Ergebnis

Abb. 56

467

Fortran und Tcl

59.2. Alternativen Tcl/Tk bietet eine Schnittstelle zur Programmiersprache C (tcl.h, tk.h, libtcl*.so, libtk*.so). Mit dem im nächsten Kapitel behandelten Fortran-C-Binding kann auf diese CFunktionen zugegriffen werden. Die Ftcl-Bibliothek nutzt diesen Mechanismus.

468

60. Weblinks • • • •

1 2 3

T CL /T K -H OMEPAGE1 P ROGRAMMING :T CL ( ENGLISCHSPRACHIGES W IKIBOOK )2 T CL /T K C OOKBOOK - T CL /T K AND FORTRAN3 F TCL : U SING T CL IN F ORTRAN PROGRAMS AND VICE VERSA4

H T T P :// W W W . T C L . T K / H T T P :// E N . W I K I B O O K S . O R G / W I K I /P R O G R A M M I N G :T C L H T T P :// C A R P A N T A . D C . F I . U D C . E S / D O C S / T C L T K -{} C O O K B O O K / C H A P 7. H T M L

4

H T T P :// F T C L . S O U R C E F O R G E . N E T /

469

61. Fortran und C 61.1. Interface Ein Interface ist die Schnittstellendefinition zu einem externen Unterprogramm. Das externe Unterprogramm kann, muss aber nicht in Fortran geschrieben sein. interface Spezifikation der externen Unterprogramme end interface

Beispiel: interface ! subroutine x(a, b, c) sei ein externes Unterprogramm subroutine x(a, b, c) real, intent(in) :: a integer :: b, c end subroutine x end interface call x(2.5, 1, 3)

61.2. Fortran 90/95 In Fortran 90/95 ist der Zugriff auf C-Funktionen nicht standardisiert. Derartige Zugriffe sind compilerabhängig zu lösen. Es

471

Fortran und C

sind je nach verwendetem Fortran-Compiler verschiedene Compilerdirektiven zu setzen, Optionen beim Compileraufruf und ähnliches zu beachten. Fortran 2003 bietet eine standardisierte Schnittstelle für den Zugriff auf C-Funktionen.

61.3. g95 (gfortran) und gcc 61.3.1. Beispiel: "call by value" und "call by reference" Fortran übergibt die Argumente eines Unterprogrammes standardmäßig "call by reference". Im Zusammenspiel mit C besteht nun das Problem, dass in C Argumente "call by reference" via Pointer oder "call by value" übergeben werden . In g77, g95 und gfortran ist die Funktion %val inkludiert, mit der auch in Fortran der "call by value"-Mechanismus nachgebildet werden kann. Fortran-Code bsp.f90: Fortran 90/95-Code (free source form) program bsp implicit none interface subroutine zahl(a, b) integer :: a, b end subroutine zahl end interface call zahl(%val(5), 7) end program bsp

C-Code bsp.c: Programmcode #include void zahl(int a, int *b) { printf("%s%d\n", "Ergebnis = ", a * *b); }

472

g95 (gfortran) und gcc

Compilieren und Linken: gcc -c -o bsp1.o bsp.c g95 -c -fno-underscoring -o bsp2.o bsp.f90 g95 bsp1.o bsp2.o

Ausgabe: Ergebnis = 35

61.3.2. Beispiel: Übergabe von Zeichenketten In C sind Strings im Gegensatz zu Fortran Null-terminiert. Dies muss beim Aufruf einer C-Prozedur aus Fortran berücksichtigt werden. Fortran Code bsp.f90: Fortran 90/95-Code (free source form) program bsp implicit none interface subroutine hallo(str) character(*) :: str end subroutine end interface call hallo("Hallo, Sonne" // char(0)) Nulltermination für C call hallo("Hallo, Protuberanz" // char(0)) Nulltermination für C call hallo("Hallo, Mond") ! Ausgabe: ! Hallo, Sonne ! Hallo, Protuberanz ! Hallo, Mond ... More segments remain end program bsp

! char(0) -> ! char(0) -> ! keine Nulltermination

473

Fortran und C

C-Code bsp.c: Programmcode #include void hallo(char *str) { printf("%s\n", str); }

Compilieren und Linken: gcc -c -o bsp1.o bsp.c g95 -c -fno-underscoring -o bsp2.o bsp.f90 g95 bsp1.o bsp2.o

61.3.3. Beispiel: Rückgabewert Die Rückgabe eines Wertes einfachen Datentyps aus einer CFunktion nach Fortran stellt kein Problem dar. Es ist einzig zu beachten, dass der Datentyp in C und Fortran übereinstimmt. Fortran-Code bsp.f90: Fortran 90/95-Code (free source form) program bsp implicit none interface function zahl(x, y) integer :: zahl integer :: x, y end function end interface integer :: res res = zahl(%val(76), %val(32)) write(*,*) res ! Ausgabe: 108 end program bsp

474

ifort und gcc

C-Code bsp.c: Programmcode int zahl(int a, int b) { return (a+b); }

61.4. ifort und gcc 61.4.1. Beispiel: "call by value" und "call by reference" Fortran-Code bsp.f90: Fortran 90/95-Code (free source form) program bsp implicit none interface subroutine zahl(a, b) !dec$ attributes c :: zahl !dec$ attributes reference :: b integer :: a, b end subroutine zahl end interface call zahl(5, 7) end program bsp

C-Code bsp.c: Programmcode #include void zahl(int a, int *b) { printf("%s%d\n", "Ergebnis = ", a * *b); }

Compilieren, Linken:

475

Fortran und C

gcc -c -o bsp1.o bsp.c ifort -c -o bsp2.o bsp.f90 ifort bsp1.o bsp2.o

Ausgabe: Ergebnis = 35

61.4.2. Beispiel: Übergabe von Zeichenketten Fortran-Code bsp.f90: Fortran 90/95-Code (free source form) program bsp implicit none interface subroutine hallo(str) !dec$ attributes c :: hallo !dec$ attributes reference :: str character(*) :: str end subroutine end interface call hallo("Hallo, Sonne" // char(0)) call hallo("Hallo, Protuberanz"C) (bei Intel-Fortran-Compiler) call hallo("Hallo, Mond") Nullterminiation ! Ausgabe: ! Hallo, Sonne ! Hallo, Protuberanz ! Hallo, Mond end program bsp

C-Code bsp.c: Programmcode #include void hallo(char *str) {

476

! char(0) -> Nulltermination ! C -> Nulltermination ! keine explizite

ifort und gcc

printf("%s\n", str); }

Compilieren und Linken: gcc -c -o bsp1.o bsp.c ifort -c -o bsp2.o bsp.f90 ifort bsp1.o bsp2.o

61.4.3. Beispiel: Rückgabewert Fortran-Code bsp.f90: Fortran 90/95-Code (free source form) program bsp implicit none interface function zahl(x, y) !dec$ attributes c :: zahl integer :: zahl integer :: x, y end function end interface integer :: res res = zahl(76, 32) write(*,*) res ! Ausgabe: 108 end program bsp

C-Code bsp.c: Fortran 90/95-Code (free source form) int zahl(int a, int b) { return (a+b); }

477

Fortran und C

61.5. Fortran 2003 In Fortran 2003 ist es viel einfacher auf C zu zugreifen, als in Fortran 95. Es wurde im Fortran 2003-Standard ein intrinsisches Modul namens iso_c_binding vorgesehen, das die zum Zugriff auf C-Programme nötigen Elemente enthält.

61.6. Ein einfaches Beispiel Beispiel funktioniert mit Compiler • • • •

g95 (0.91!) May 10 2007: ja gfortran 4.3.0 20070723 (experimental): ja Intel Fortran Compiler 10.0: ja Sun Studio Express - June 2007: ja

Anmerkungen: Fortran 2003-Code: bsp.f95 Fortran 2003-Code program bsp implicit none interface function addition( a, b ) bind( c[, name="c_func"] ) use, intrinsic :: iso_c_binding real( kind = c_float ), value :: a real( kind = c_float ), value :: b real( kind = c_float ) :: addition end function addition end interface write (*,*) addition( 2.5, 3.3 ) ! Ausgabe: 5.8 end program bsp

C-Code: bsp.c Programmcode float addition(float a, float b) {

478

Ein einfaches Beispiel

return (a + b); }

Makefile: Programmcode FC = g95 # oder gfortran, ... CC = gcc # oder icc, ... bsp: bsp_c.o bsp_f95.o $(FC) -o bsp bsp_c.o bsp_f95.o bsp_c.o: bsp.c $(CC) -c -o bsp_c.o bsp.c bsp_f95.o: bsp.f95 $(FC) -c -o bsp_f95.o bsp.f95 .PHONY: clean clean: rm *.o

Was ist neu gegenüber Fortran 95?

... • bind( c[,

name="c_func"] )

... • use,

bind-Attribut, stellt unter anderem die Interoperabilität mit C bezüglich Prozedurnamenskonventionen nach der Übersetzung sicher. Mittels des optionalen Arguments "name" kann die Funktion in Fortran umbenannt werden. "c_func" ist dabei der Name der Funktion in C. Einbindung des intrinsischen Moduls iso_c_binding

intrinsic :: iso_c_binding

479

Fortran und C

...

C-Datentyp float.

...

call by value

• real( kind =

c_float )

• value

61.7. Datentyp-Zuordnung Das iso_c_binding-Modul stellt benannte Konstanten zur Verfügung, die bei Fortran-Datentypen als kind-Wert zu verwenden sind, um den jeweiligen C-Datentyp zu charakterisieren. Weist eine solche Konstante einen negativen Wert auf, dann ist keine Entsprechung von Fortran-Datentyp zu C-Datentyp vorhanden. Fortran-Datentyp

Benannte iso_c_bindingKonstante (kindWert) c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t

integer 480

C-Datentyp

int short int long int long long int signed char, unsigned char size_t int8_t int16_t

Datentyp-Zuordnung Fortran-Datentyp

Benannte iso_C-Datentyp c_bindingKonstante (kindWert) c_int32_t int32_t c_int64_t int64_t c_int_least8_t int_least8_t c_int_least16_t int_least16_t c_int_least32_t int_least32_t c_int_least64_t int_least64_t c_int_fast8_t int_fast8_t c_int_fast16_t int_fast16_t c_int_fast32_t int_fast32_t c_int_fast64_t int_fast64_t c_intmax_t intmax_t c_intptr_t intptr_t c_float float real c_double double c_long_double long double c_float_complex float _Complex complex c_double_complex double _Complex c_long_double_long double _complex Complex logical c_bool _Bool character c_char char Quelle: J3/04-007 Fortran 2003 Working Draft Das iso_c_binding-Modul stellt keine speziellen kind-Werte für unsigned-Integer-Datentypen zur Verfügung. Im Bedarfsfall sind die entsprechenden kind-Werte für die signed-Datentypen zu verwendet. Nicht jeder Fortran-Compiler unterstützt alle genannten CDatentypen und die unterstützten Datentypen können sich com-

481

Fortran und C

pilerspezifisch in der Byteanzahl unterscheiden. Die nächste Tabelle zeigt kurz auf, welche kind-Konstanten derzeit (1. Dez. 2007) von einigen Compilern definiert werden. c_int

c_c_c_c_long_- signed_-size_- int8_long char t t g95 4 2 4 8 1 4 1 gfortran4 2 4 8 1 4 1 ifort 4 2 4 8 1 4 1 f95 4 2 4 8 1 4 c_c_c_c_c_c_c_int16_- int32_- int64_- int_int_int_int_t t t least8_- least16_-least32_-least64_t t t t g95 2 4 8 1 2 4 8 gfortran2 4 8 1 2 4 8 ifort 2 4 8 1 2 4 8 f95 1 2 4 8 c_c_c_c_c_c_c_int_int_int_int_intmax_-intptr_- float fast8_- fast16_- fast32_- fast64_- t t t t t t g95 1 4 4 8 4 4 4 gfortran(1) (1) (1) (1) 8 (1); 4 4 oder 8 ifort 1 4 4 8 8 4 4 f95 1 2 4 8 8 4

482

c_short

c_long

„call by value“ vs. „call by reference“

c_c_c_c_c_c_double long_- float_- double_-long_- bool double complexcomplexdouble_complex g95 8 -1 4 8 -1 -1 gfortran8 (1), 4 8 (1), 1 oft oft 10 10 ifort 8 -1 4 8 -1 1 f95 8 -3 4 8 -3 1

c_char

1 1

1 1

(1) Der Wert ist systemabhängig • • • •

g95: g95 0.91! Nov 29 2007 gfortran: GNU Fortran (GCC) 4.3.0 20071201 (experimental) ifort: Intel Fortran Compiler 10.1 20070913 f95: Sun Studio Express, June 2007 positive Zahl negative Zahl

Konstante ist bekannt, CDatentyp wird unterstützt Konstante ist bekannt, CDatentyp wird nicht unterstützt unbekannte Konstante

61.8. „call by value“ vs. „call by reference“ Im EINFÜHRENDEN B EISPIEL1 wurden die Funktionsargumente „call by value“ übergeben. Das Variablenattribut value stellt 1

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _ U N D _C%23E I N _ E I N F A C H E S _B E I S P I E L %20

483

Fortran und C

dieses Verhalten sicher. Wird dieses Attribut nicht gesetzt, so gilt „call by reference“. Beispiel: Beispiel funktioniert mit Compiler • • • •

g95 (0.91!) May 10 2007: ja gfortran 4.3.0 20070723 (experimental): ja Intel Fortran Compiler 10.0: ja Sun Studio Express - June 2007: ja

Anmerkungen: Fortran-Code bsp.f95: Fortran 2003-Code program bsp implicit none interface subroutine zahl( a, b ) bind( c ) use, intrinsic :: iso_c_binding integer( kind=c_int ), value :: a integer( kind=c_int ) :: b end subroutine zahl end interface call zahl(5, 7) ! Ausgabe: ! Ergebnis = 35 end program bsp

C-Code bsp.c: Programmcode #include void zahl(int a, int *b) { printf("%s%d\n", "Ergebnis = ", a * *b); }

484

Globale C-Variablen

61.9. Globale C-Variablen Muss in Fortran auf globale C-Variablen zugegriffen werden, so sind diese im Gültigkeitsbereich eines Fortran-Modul zu spezifizieren.

61.10. Felder Interoperabilität zwischen Fortran und C ist nur mit Feldern definierter Größe gegeben. Allozierbare Felder oder Zeigerfelder sind nicht erlaubt. Beispiel: Beispiel funktioniert mit Compiler • • • •

g95 (0.91!) May 10 2007: ja gfortran 4.3.0 20070723 (experimental): ja Intel Fortran Compiler 10.0: ja Sun Studio Express - June 2007: ja

Anmerkungen: Fortran 2003-Code program bsp implicit none integer, dimension( 3 ) :: a = (/ 1, 2, 3 /) interface subroutine feld1( f ) bind( c ) use, intrinsic :: iso_c_binding integer( c_int ), dimension(*) :: f end subroutine feld1 end interface write (*,*) "Feld a vorher: ", a call feld1( a ) write (*,*) "Feld a nachher: ", a

485

Fortran und C

! Ausgabe: ! Feld a vorher: 1 2 3 ! Feld a nachher: 999 2 3 end program bsp

Programmcode void feld1(int f[]) { f[0] = 999; }

61.11. Übergabe von Zeichenketten Beispiel: Beispiel funktioniert mit Compiler • • • •

g95 (0.91!) May 10 2007: ja gfortran 4.3.0 20070723 (experimental): nein Intel Fortran Compiler 10.0: ja Sun Studio Express - June 2007: ja

Anmerkungen: gfortran lehnt dies ab, da dies ungültiger Fortran-Syntax ist: Fehler: Character argument ’str_in’ at (1) must be length 1 because procedure ’string1’ is BIND(C) Fortran-Code bsp.f95: Fortran 2003-Code program bsp use, intrinsic :: iso_c_binding implicit none interface subroutine string1( str_in ) bind( c ) use, intrinsic :: iso_c_binding character( kind=c_char, len=* ) :: str_in ! Ungültiges Fortran

486

Übergabe von Zeichenketten

2003 da nur len=1 erlaubt ist end subroutine string1 end interface call string1( c_char_"Greetings from Fortran" // c_null_char ) ! Ausgabe: ! "Greetings from Fortran" end program bsp

C-Code bsp.c: Programmcode #include void string1(char str_in[]) { printf("%s \n", str_in); }

Für len=1 funktioniert das Beispiel mit allen angeführten Compilern. Das len-Attribut kann im Übrigen auch weggelassen werden; einige unterstützen als compilerspezifische Erweitungen auch andere Längen. Im Fortran 2003-Working-Draft wird in „Note 15.23“ eine andere Möglichkeit für die Übergabe von Zeichenketten angeführt. Diese folgt im wesentlichen der Annahme: C-Zeichenketten sind char-Felder mit einem terminierenden \0-Zeichen und können deshalb in Fortran als Felder vom Datentyp character mit einem kind-Wert c_char angesprochen werden. Daher wird im Interface der Dummy-Parameter in Form eines Feldes aus Zeichen des Typs c_char deklariert. Das entspräche auch genau der aufzurufenden C-Funktion. Allerdings ist solcherart verfasster Code dann nicht mit allen Compilern übersetzbar (Stand Juli 2007). Beispiel:

487

Fortran und C

{{Fortran:Vorlage: Isocbinding|ja|ja|ja|nein|Sun Studio ExpressFehlermeldung:

... Zusicherung >>addr<< nicht erf?llt. "bsp.f95", Line = 13, Column = 1: INTERNAL: Interrupt: Abgebrochen}} Fortran-Code bsp.f95: Fortran 2003-Code program bsp use, intrinsic :: iso_c_binding implicit none interface subroutine string1( str_in ) bind( c ) use, intrinsic :: iso_c_binding character( kind=c_char ), dimension(*) :: str_in end subroutine string1 end interface call string1( c_char_"Greetings from Fortran" // c_null_char ) ! Ausgabe: ! "Greetings from Fortran" end program bsp

Beispiel: Damit das obige Beispiel auch mit dem "Sun StudioFortrancompiler" funktioniert, darf der String nicht direkt dem Unterprogramm übergeben werden, sondern muss zuvor in einer Variablen abgelegt werden. Beispiel funktioniert mit Compiler • • • •

g95 (0.91!) May 10 2007: ja gfortran 4.3.0 20070723 (experimental): ja Intel Fortran Compiler 10.0: ja Sun Studio Express - June 2007: ja

488

Übergabe von Zeichenketten

Anmerkungen: Fortran-Code bsp.f95: Fortran 2003-Code program bsp use, intrinsic :: iso_c_binding implicit none character(len=35) :: str interface subroutine string1( str_in ) bind( c ) use, intrinsic :: iso_c_binding character( kind=c_char ), dimension(*) end subroutine string1 end interface

:: str_in

str = "Greetings from Fortran" // c_null_char call string1( str ) ! Ausgabe: ! "Greetings from Fortran" end program bsp

Benannte iso_c_binding-Konstanten für Zeichen mit spezieller Bedeutung in C: Benannte Konstante c_null_char c_alert c_backspace c_form_feed c_new_line c_carriage_return c_horizontal_tab c_vertical_tab

Wert ’\0’ ’\a’ ’\b’ ’\f’ ’\n’ ’\r’ ’\t’ ’\v’

489

Fortran und C

61.12. Enumerationen Mit Fortran 2003 sind auch in dieser Programmiersprache Enumerationen (Aufzählungstypen) möglich. Die Werte in einer solchen Enumeration besitzen einen integer-Datentyp. Der kind-Wert ist nicht festgelegt, wird jedoch so gewählt, dass im Rahmen der jeweiligen Möglichkeiten alle Enumeratoren erfasst sind. Die von C-Enumerationen bekannten Eigenschaften gelten gleichermaßen für Fortran-Enumerationen, z.B.: • ohne explizite Zuweisung von Werten wird mit dem Wert 0 gestartet. • ohne explizite Zuweisung von Werten wird in der Anordnungsreihenfolge der Elemente sukzessiv immer um 1 hochgezählt. • Wurde dem Vorgängerelement eine Ganzzahl zugewiesen, dem Element jedoch nicht, so ist der Wert dieses Elementes die dem Vorgängerelement zugeordnete Ganzzahl + 1. Beispiel: Beispiel funktioniert mit Compiler • • • •

g95 (0.91!) May 10 2007: ja gfortran 4.3.0 20070723 (experimental): ja Intel Fortran Compiler 10.0: nein Sun Studio Express - June 2007: nein

Anmerkungen:

Sun-Fortran-Compiler und Intel-Fortran-Compiler unterstützen momentan noch keine Enumerationen.

490

Enumerationen

Fortran-Code bsp.f95: Fortran 2003-Code program bsp implicit none enum, bind(c) enumerator :: MO=1, DI=2, MI=3, DO=4, FR=5, SA=6, SO=7 end enum interface subroutine tag( w ) bind( c ) use, intrinsic :: iso_c_binding integer( c_int ), value :: w end subroutine tag end interface call tag(MI); ! Ausgabe: ! Mittwoch end program bsp

C-Code bsp.c: Programmcode #include typedef enum { MO=1, DI=2, MI=3, DO=4, FR=5, SA=6, SO=7 } wochentag; void tag(wochentag w) { switch(w) { case MO: printf("Montag\n"); break; case DI: printf("Dienstag\n"); break; case MI: printf("Mittwoch\n"); break; case DO: printf("Donnerstag\n"); break; case FR: printf("Freitag\n"); break; case SA: printf("Samstag\n");

491

Fortran und C

break; case SO: printf("Sonntag\n"); break; default: printf("Kein Tag\n"); } }

61.13. Zeiger Für das C-Zeiger-Handling stellt Fortran 2003 im iso_c_bindingModul den Datenverbund c_ptr und einige Unterprogramme bereit. UP l = c_associated ( c_ptr1 [, c_ptr2] )

Beschreibung Prüft den Assoziationsstatus von c_ptr1. Diese Funktion ermittelt also, ob c_ptr1 überhaupt assoziert ist, oder ob c_ptr1 mit c_ptr2 assoziert ist. Gibt die Adresse von x zurück.

c_ptr = c_loc ( x )

c_f_pointer ( c_ptr, fptr [, shape] )

Wandelt einen C-Zeiger c_ptr in einen Fortran-Zeiger fptr um. Die Vorgabe von shape ist nur dann erforderlich und möglich, wenn fptr ein Feld ist. fptr ist intent( inout ).

Beispiel: Beispiel funktioniert mit Compiler • g95 (0.91!) May 10 2007: ja

492

Zeiger

• gfortran 4.3.0 20070723 (experimental): ja • Intel Fortran Compiler 10.0: ja • Sun Studio Express - June 2007: ja Anmerkungen:

Sun-Linker-Warnmeldung:

Warning: alignment 4 of symbol ‘ptr1’, ... in bsp_c.o is smaller than 16 in bsp_f90.o Intel-Linker-Warnmeldung:

Warning: alignment 4 of symbol ‘ptr1’, ... in bsp_c.o is smaller than 8 in bsp_f90.o Fortran-Code bsp.f95: Fortran 2003-Code module cglob use, intrinsic :: iso_c_binding type( c_ptr ), bind( c ) :: ptr1, ptr2, ptr3 real( kind=c_float ), target, bind( c ) :: a, b end module cglob program bsp use cglob implicit none real, pointer :: p => null() ! *** Zuordnungsstatus *** write (*,*) "Ist ptr1 assoziert? ", c_associated( ptr1 ) write (*,*) "Ist ptr2 assoziert? ", c_associated( ptr2 ) write (*,*) "Ist ptr2 mit ptr3 assoziert? ", c_associated( ptr2, ptr3 ) write (*,*) "Ist ptr2 mit &a assoziert? ", c_associated( ptr2, c_loc(a) ) ! *** Wert von ptr2? *** call c_f_pointer( ptr2, p )

493

Fortran und C

write (*,*) "Wert von ptr2? ", p ! *** ptr1 neu setzen *** ptr1 = c_loc( b ) ! *** Wert von ptr1 *** call c_f_pointer( ptr1, p ) write (*,*) "Wert von ptr1? ", p ! Ausgabe: ! Ist ptr1 assoziert? F ! Ist ptr2 assoziert? T ! Ist ptr2 mit ptr3 assoziert? F ! Ist ptr2 mit &a assoziert? T ! Wert von ptr2 (bzw. p)? 5555.66 ! Wert von ptr1 (bzw. p)? -12.3 end program bsp

C-Code bsp.c: Programmcode float float float float float

a = 5555.66; b = -12.3; *ptr1 = 0; *ptr2 = &a; *ptr3 = &b;

Nun ist die Zeiger-Verwendung wie im obigen Beispiel skizziert, eher die Ausnahme als die Regel. Wesentlich häufiger trifft man Zeiger in C-Bibliotheken im Zusammenhang mit Funktionen an. Dort dienen sie aus Anwendersicht als return-Werte oder der Parameterübergabe „call-by-reference“. Oft sind dabei auch Zeiger auf Strukuren im Spiel. Näheres dazu folgt im nächsten Abschnitt. Für C-Zeiger auf den Wert NULL bietet das ISO-C-Binding-Modul die Konstante C_NULL_PTR.

61.14. Datenverbund Die einzelnen Datenelemente der Struktur / des Datenverbundes müssen in Fortran und C selbstverständlich äquivalenten Datentyp aufweisen. Die Bezeichnungen der jeweiligen Datenele-

494

Datenverbund

mente müssen nicht beibehalten werden. Sehr wohl müssen aber die Positionen der Einzelelemente im Fortran-Datenverbund der nachzubildenden C-Struktur entsprechen. Für die Gewährleistung der Interoperabilität darf ein an C gebundener Datenverbund in Fortran (struct) keine Zeiger mit dem pointer-Attribut oder allozierbaren Felder als Datenelemente enthalten. Sind in der C-Struktur Zeiger vorhanden, so sind diese im entsprechenden Fortran-Datenverbund mittels type( c_ptr ) zu beschreiben. Für Bitfelder oder Unions gibt es in Fortran keine entsprechenden Gegenstücke. Beispiel: Beispiel funktioniert mit Compiler • • • •

g95 (0.91!) May 10 2007: ja gfortran 4.3.0 20070723 (experimental): ja Intel Fortran Compiler 10.0: ja Sun Studio Express - June 2007: ja

Anmerkungen: gfortran: Im Gegensatz zu den anderen Compilern müssen bei der Deklaration der Subroutine print_v im Interface die Klammern für die leere Parameterliste vor dem bind(C) zwingend angestschrieben werden, ansonsten Fehlermeldung beim Compilieren; diese Klammer ist im Fortran 2003 Standard vorgeschrieben. Fortran 2003-Code module cglob use, intrinsic :: iso_c_binding type, bind( c ) :: verbund integer( kind=c_int ) :: a real( kind=c_float ) :: b end type verbund type(verbund), bind( c ) :: v

495

Fortran und C

end module cglob program bsp use cglob implicit none interface subroutine set_v( a_in, b_in) bind( c ) use, intrinsic :: iso_c_binding integer( c_int ), value :: a_in real( c_float ), value :: b_in end subroutine set_v subroutine print_v() bind( c ) end subroutine print_v end interface call set_v( 5, -10.9) call print_v() write (*,*) "Fortran-Ausgabe: ", v v%a = 99 call print_v() write (*,*) "Fortran-Ausgabe: ", v ! Ausgabe: ! C-Ausgabe: 5 -10.900000 ! Fortran-Ausgabe: 5 -10.9 ! C-Ausgabe: 99 -10.900000 ! Fortran-Ausgabe: 99 -10.9 end program bsp

Programmcode #include typedef struct { int a; float b; } verbund; verbund v; void set_v(int a_in, float b_in) { v.a = a_in; v.b = b_in; } void print_v() { printf("C-Ausgabe: %i %f\n", v.a, v.b); }

496

Datenverbund

Beispiel: Struktur als Rückgabewert und Argument einer Funktion - Teil 1 Bekannt seien zwei Funktionsprototypen in der Programmiersprache C: Xyz *get_xyz();

und void set_xyz(Xyz *x);

Xyz sei ein C-struct, dessen Inhalt hier nicht näher interessiert. Die Schnittstelle, mit dem in Fortran die C-Anbindung der Funktionen realisiert wird, könnte so aussehen: interface function get_xyz() bind( c ) use, intrinsic :: iso_c_binding type( c_ptr ) :: get_xyz end function get_xyz subroutine set_xyz( x ) bind( c ) use, intrinsic :: iso_c_binding type( c_ptr ), value :: x end subroutine set_xyz end interface

Und schon können diese Funktionen auch in Fortranroutinen direkt Anwendung finden, z.B: type( c_ptr ) :: x56 x56 = get_xyz()

497

Fortran und C

call set_xyz( x56 )

Wie man anhand dieses Beispiels erkennt, ist die interne Struktur von Xyz in diesem Fall vollkommen irrelevant. Es ist nicht nötig, in der API-Dokumentation oder in den C-Headerdateien nachzuforschen, wie der C-struct konkret aufgebaut ist. Für den Fortran-Programmierer ist dies immer ein type( c_ptr ) (natürlich nur, solange Zeiger auf Strukturen gefordert sind). Wird ein Zeiger des Typs c_ptr nur via Fortranprogramm zwischen verschiedenen C-Funktionen übergeben oder zurückgeliefert, so ist auch keine Umwandlung in einen Fortran-Zeiger erforderlich und wäre mangels genauer Kenntnis des Aufbaus von Xyz hier auch nicht möglich. Erst dann, wenn von Fortran aus auf einzelne Elemente eines C-struct zugegriffen werden soll oder mit Kopien der Struktur hantiert wird, muss diese Struktur in Fortran nachgebaut werden. Beispiel: Struktur als Rückgabewert und Argument einer Funktion - Teil 2 Beispiel funktioniert mit Compiler • • • •

g95 (0.91!) May 10 2007: ja gfortran 4.3.0 20070723 (experimental): ja Intel Fortran Compiler 10.0: ja Sun Studio Express - June 2007: ja

Anmerkungen: Fortran 2003-Code module test use, intrinsic :: iso_c_binding implicit none

498

Datenverbund

type, bind( c ) :: A ! Das funktioniert nicht mit allen Kompilern; versuchen Sie ansonsten: ! type A ! sequence integer( c_int ) :: xc, yc type( c_ptr ) :: str end type interface function get_a() bind( c ) use, intrinsic :: iso_c_binding type( c_ptr ) :: get_a end function get_a subroutine print_a( x ) bind( c ) use, intrinsic :: iso_c_binding type( c_ptr ), value :: x end subroutine print_a end interface end module test program main use test implicit none type( c_ptr ) :: x type( A ), pointer :: fptr character( len=9 ), pointer :: strptr x = get_a() ! C-Ausgabe call print_a( x ) ! Ausgabe: ! x = 5 ! y = 997 ! str = Irgendwas ! Fortran-Ausgabe call c_f_pointer( x, fptr) call c_f_pointer( fptr%str, strptr ) gfortran write(*,*) fptr%xc, fptr%yc, strptr ! Ausgabe ! 5 997 Irgendwas end program main

! <--- Fehlerquelle bei

Programmcode #include #include typedef struct

499

Fortran und C

{ int x; int y; const char *str; } A; A *get_a() { A *a = ( A * )malloc( sizeof( A ) ); a->x = a->y = a->str return

5; 997; = "Irgendwas"; a;

} void print_a( { printf("x = printf("y = printf("str }

A *v ) %d\n", v->x); %d\n", v->y); = %s\n", v->str);

Bei der Umwandlung des C-String-Zeigers in einen Fortran-Zeiger ist die genaue Stringlänge erforderlich. Ist diese zu klein gewählt, so ist nur ein Teil des C-Strings über den Fortran-Zeiger sichtbar. Wird diese Stringlänge zu groß gewählt, dann wird diese Länge auch voll ausgenutzt und nach dem eigentlich gewünschten String folgen noch ein Menge x-beliebige Zeichen, da in Fortran der CString-Begrenzer \0 nicht die Bedeutung wie in C besitzt. Im obigen Beispiel wurde die Speicherplatzreservierung und Wertebelegung für eine Variable des Typs A in einer CFunktion erledigt. Nun soll diese Aufgabe im Fortran-Programm wahrgenommen werden und dann diese in Fortran mit Werten belegte Variable an die print_a-Funktion übergeben werden. Kein Problem, möchte man im ersten Augenblick meinen. Doch der c_ptr-Typ im Datenverbund für den Zeiger auf eine Zeichenkette macht Probleme. Der g95-Compiler duldet bspw. in der c_loc-Funktion keine Zeichenketten mit einer Länge größer als 1. Der Compiler "castet" auch nicht von selbst im Datenverbundkonstruktor eine Zeichenkette in den Typ c_ptr. Eine Möglichkeit,

500

Datenverbund

diese Probleme zu umgehen, besteht darin, einfach einer CFunktion einen String zu übergeben und die Adresse dieses Strings zurückgeben zu lassen. Diese Variante wird auch im folgenden Beispiel verwendet. Beispiel: Struktur als Rückgabewert und Argument einer Funktion - Teil 3 Beispiel funktioniert mit Compiler • • • •

g95 (0.91!) May 10 2007: ja gfortran 4.3.0 20070723 (experimental): ja Intel Fortran Compiler 10.0: ja Sun Studio Express - June 2007: ja

Anmerkungen: Fortran 2003-Code module test use, intrinsic :: iso_c_binding implicit none type, bind( C ) :: A integer( c_int ) :: xc, yc type( c_ptr ) :: str end type type( A ), target :: a1 diese Var.deklaration

! bei Verwendung des g95 könnte ! auch im Hauptprogramm als lokale

Variable ! vorgenommen werden. Der Sun-Compiler erlaubt ! kein gleichzeitiges C-Binding mit einer lokalen Var. interface subroutine print_a( x ) bind( c ) use, intrinsic :: iso_c_binding type( c_ptr ), value :: x end subroutine print_a function c_string_addr( s ) bind( c ) use, intrinsic :: iso_c_binding character( c_char ) :: s

501

Fortran und C

type( c_ptr ) :: c_string_addr end function c_string_addr end interface end module test program main use test implicit none character( len = 30 ) :: str str = "Das ist ein Beispiel" // C_NULL_CHAR a1 = A( 14, 56, c_string_addr( str ) ) call print_a( c_loc( a1 ) ) ! Ausgabe: ! x = 14 ! y = 56 ! str = Das ist ein Beispiel end program main

Programmcode #include #include typedef struct { int x; int y; const char *str; } A; void print_a( A *v ) { printf("x = %d\n", v->x); printf("y = %d\n", v->y); printf("str = %s\n", v->str); } char *c_string_addr( char *str ) { return str; }

502

Problematische Kamelhöckerschreibweise?

61.15. Problematische Kamelhöckerschreibweise? C ist case-sensitive, Fortran nicht. Oft sind Funktionen in CBibliotheken in der K AMELHÖCKERSCHREIBWEISE2 vorzufinden, z.B. void writeHallo();

Die Einbindung dieser C-Funktion in ein Fortran-Programm mit interface subroutine writeHallo() bind(c) end subroutine writeHallo end interface

könnte beim Linken eine Fehlermeldung der Art undefined reference to ‘writehallo’

liefern. Was ist passiert? Wie schon angedeutet, ist Fortran caseinsensitive. Für einen Fortran-Compiler ist writeHallo gleich writehallo oder WRITEHaLLO. Für einen C-Compiler wären das alles unterschiedliche Funktionsbezeichner. Also wandelt der Fortran-Compiler die "unnütze" Groß-/Kleinschreibung in eine einheitliche Schreibweise um und der C-Compiler nicht. Dementsprechend findet der Linker auch keine Funktion writehallo. Es gibt eben nur die nicht-idente C-Funktion writeHallo. 2

H T T P :// D E . W I K I P E D I A . O R G / W I K I /B I N N E N M A J U S K E L

503

Fortran und C

Aber auch für dieses Problem gibt es in Fortran eine Lösung. Mit dem bind-Attribut können zusätzlich auch noch Labels (Benennungen) vergeben werden, z.B.: bind( c, name="xyz" )

Solche Labels in Stringform sind nicht von der "Kopf ab"-Strategie des Fortran-Compilers betroffen. Das ist keine C-BindingSpezialität, sondern trifft generell für alle Zeichenketten zu. Ein interface subroutine writeHallo() bind(c, name="writeHallo") end subroutine writeHallo end interface

sollte das beschriebene Link-Problem lösen.

61.16. Sonstiges • Auch C-Funktionszeiger kennt das iso_c_binding-Modul. Zu diesem Zwecke gibt es den Datenverbund c_funptr, einige Umwandlungsfunktionen ähnlich jenen im Abschnitt Z EIGER3 behandelten und die Konstante C_NULL_FUNPTR.

3

504

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20F O R T R A N % 20 U N D %20C%23Z E I G E R %20

62. Fortran und Python F2PY F2py (Fortran to Python interface generator) ist ein Wrapper, der Fortran-Module, -Subroutinen oder -Funktionen in sogenannte SharedObject-Dateien kompiliert, die dann in Python als normales Modul importiert werden können. Einsatzgebiete sind vor allem numerische Berechnungen, in denen sowohl die Geschwindigkeit der Fortanroutinen, aber auch die Flexibilität von Pythonscripten genutzt werden soll.

62.1. Voraussetzungen Erforderlich für die Installation von f2py sind einerseits eine Python-Version ab 2.0 zusammen mit den Erweiterungsmodulen NumPy und SciPy und außerdem ein Fortran-Compiler. Genaue Informationen finden Sie auf der Homepage des f2py-Projekts, die unten angegeben ist. Es ist sehr wichtig, dass Sie zunächst alle Komponenten installiert haben, bevor Sie fortfahren. Die Erfahrung hat gezeigt, dass dies manchmal gar nicht so einfach ist. Um zu überprüfen, ob Ihr f2py funktionsfähig ist, tippen Sie einfach f2py in die Konsole ein. Wünschenswerterweise sollte dies einige Informationen über das Programm auf Ihrem Bildschirm anzeigen.

505

Fortran und Python

62.2. Beispiel Als Testbeispiel wählen wir ein kleines Programm namens punktrechnung.f90. Es enthält ein Modul und eine Subroutine zur Berechnung von Division und Multiplikation. Wir wollen diese Routinen später von Python aus aufrufen können und die Funktionalitäten nutzen.

62.2.1. Fortran Code Fortran 90/95-Code (free source form) !File: punktrechnung.f90 module punktrechnung real,parameter::pi=3.14

contains

subroutine division(x,y) integer::x,y print*, "x/y = ",x/y end subroutine division

end module punktrechnung

subroutine multi(x,y) integer::x,y print*, "x*y= ",x*y end subroutine multi

506

Weblinks

62.2.2. Wrappen Mit dem Befehl: f2py -c -m meinmodul punktrechnung.f90 Erstellen wir eine Objekt-Datei mit der Endung .so, die von Python als Modul importiert werden kann. Das Modul trägt den Namen "meinmodul" und es beinhaltet alle Funktionalitäten der Datei punktrechnung.f90

62.2.3. Zugriff Im interaktiven Modus von Python können wir dieses Modul nun importieren und die Funktionen nutzen: >>> import meinmodul >>> meinmodul.multi(5,4) x*y= 20 >>> meinmodul.punktrechnung.diff(36,6) x/y = 6

62.3. Weblinks • O FFIZIELLE S ITE DES F2PY-P ROJEKTS1

1

H T T P :// C E N S . I O C . E E / P R O J E C T S / F 2 P Y 2 E /

507

Teil VIII.

Fortran-„Dialekte“

509

63. F

63.1. Was ist F?

F ist ein Fortran 90/95-Subset. Das bedeutet auch, dass sich FProgrammcode immer mit Fortran 90/95-Compilern übersetzen lassen sollte. Umgekehrt ist das natürlich oft nicht möglich. Grob gesagt, wurde bei F auf die bedingungslose Kompatibilität mit FORTRAN 77-Code gepfiffen und nur die moderneren Fortran 90/95-Sprachmittel erlaubt. Die überbordenden Möglichkeiten und Schreibweisen zur Erreichung ein und desselben Ziels wurden also deutlich eingebremst. F ist somit ein bisschen leichter erlernbar als Fortran 90/95 in seiner Gesamtheit und führt durch restriktivere Regeln automatisch zu einem etwas stringenteren Programmierstil. Und das war bei der Einführung von F auch das Ziel: Einsatz von F in der Ausbildung und Lehre, wenngleich natürlich von den F-Schöpfern der Einsatz in praktischen Projekten auch gerne gesehen worden wäre. Ein expliziter F-Compiler ist auf [ftp://ftp.swcp.com/pub/walt/F ftp.swcp.com/pub/walt/F unter FortranTools] für die Betriebssysteme MS Windows und Linux zu finden. In diesen Softwarepaketen sind unter anderem das F-Manual und etliche Beispiele in der F-Programmiersprache enthalten.

511

F

63.2. Einige Unterschiede zu Fortran 90/95 Im Nachfolgenden werden Fortran 90/95- und F-Beispiele gegenüber gestellt. Das soll aber nicht bedeuten, dass die Fortran 90/95-Beispiele zwingend so formuliert werden müssen oder optimaler Fortran 90/95-Code sind. Es soll nur gezeigt werden, welche Freiheiten Fortran 90/95 im Gegensatz zu F erlaubt. F ist ein Subset von Fortran 90/95 und die als F-Code deklarierten Beispiele enthalten somit auch immer gültigen Fortran 90/95-Code.

63.2.1. Diverses • Strengere Regeln bei end-Statements für Hauptprogramm, Unterprogramme und Module: Fortran 90/95 program bsp ! ... end

F program bsp ! ... end program bsp

63.2.2. Datentypen • In F gibt es den Datentyp double precision nicht. Er kann aber problemlos wie in Fortran 90 /95 mittels real und kindAttribut ersetzt werden. • Die alte (FORTRAN 77)-Form ohne Doppel-Doppelpunkt zwecks Variablendeklaration ist in F nicht erlaubt: Fortran 90/95 program bsp real r r = 12.5 ! ... end program bsp

512

F program bsp real :: r r = 12.5 ! ... end program bsp

Einige Unterschiede zu Fortran 90/95

• In F gibt es keine impliziten Datentypvereinbarungen. Der Datentyp muss immer explizit festgelegt werden: Fortran 90/95 program bsp i = 12 ! ... end program bsp

F program bsp integer :: i = 12 ! ... end program bsp

63.2.3. Ein- / Ausgabe • Die vereinfachte Schreibweise write( *, * ) und read( *, * ) funktioniert bei F nicht. F akzeptiert Apostrophe nicht als Zeichenkettenbegrenzer: Fortran 90/95 program bsp write( *, * ) ’Hallo Welt!’ ! Alternativ auch: print *, ’Hallo Welt!’ end program bsp

F program bsp write( unit = *, fmt = * ) "Hallo Welt!" ! Alternativ auch: print *, "Hallo Welt!" end program bsp

• Kein format, keine Marken: Fortran 90/95 program bsp real :: a = 30.0 write( *, fmt = 999 ) a 999 format( F10.3 ) end program bsp

F program bsp real :: a = 30.0 write( unit = *, fmt = "(F10.3)" ) a end program bsp

63.2.4. Schleifen • F kennt keine do-while-Schleife.

513

F

63.2.5. Funktionen und Subroutinen • Egal, ob die Parameterliste leer ist oder nicht, in F müssen immer die Klammern im Anschluss an den Unterprogrammnamen geschrieben werden • Externe Unterprogramme sind nicht erlaubt. Fortran 90/95 program bsp call schreibe end program bsp subroutine schreibe write( *, * ) "Hallo" end subroutine schreibe

F program bsp call schreibe() contains subroutine schreibe() write( unit = *, fmt = * ) "Hallo" end subroutine schreibe end program bsp

63.2.6. Module F ist restriktiver bei der Verwendung von Modulen als Fortran 90/95. Für Modulvariablen und -unterprogramme muss immer ein Zugriffspezifizierer public oder private vorgegeben werden. Fortran 90/95 module modu real :: pi = 3.1416 contains subroutine schreibe() write( *, * ) "Hallo" end subroutine schreibe end module modu program bsp use modu write( *, * ) pi call schreibe() end program bsp

514

F module modu private real, public :: pi = 3.1416 public :: schreibe contains subroutine schreibe() write( unit = *, fmt = * ) "Hallo" end subroutine schreibe end module modu program bsp use modu write( unit = *, fmt = * ) pi call schreibe() end program bsp

Weblinks

Weitere Unterschiede sind mittels angegebener Weblinks auffindbar bzw. dem F-Manual zu entnehmen.

63.3. Weblinks • • • •

F P ROGRAMMING L ANGUAGE H OMEPAGE1 I NTRODUCTION TO F2 N EUE F ORTRAN -S PRACHE F3 T HE F ORTRAN J OURNAL V OLUME 8, N UMBER 6, 1996 N OVEM BER /D ECEMBER 4

1 2 3

H T T P :// W W W . F O R T R A N . C O M /F/

4

H T T P :// W W W . F O R T R A N . C O M / F O R T R A N /FJ/9611/

H T T P :// S I P . C L A R K U . E D U / T U T O R I A L S /F. H T M L H T T P :// W W W . H R Z . U N I -{} W U P P E R T A L . D E / I N F O S / H R Z -{} I N F O / H R Z -{} I N F O -{}9607/ N O D E 15. H T M L

515

64. Ratfor 64.1. Allgemeines Ratfor (Rational Fortran) ist zum Großteil eine Mischung aus C und Fortran. Es entstand aus der Begeisterung Brian W. Kernighans1 für die Programmiersprache C. In einer Zeit, als C seinen Siegeszug antrat und Programmierer mit den zum Teil noch archaischen Sprachmerkmalen von FORTRAN 66 und 77 konfrontiert waren, hatte er die fixe Idee, dass auch FortranProgrammierer mit der Syntax von C beglückt werden müssen. Ratfor-Code wurde dann per Präprozessor in Fortran-Code umgewandelt, um danach den Gang alles Fortran-irdischen zu gehen und per schnödem Fortran-Compiler in Maschinencode übersetzt zu werden. Ratfor dürfte sich einer gewissen Popularität erfreut haben. Darauf deutet auch hin, dass sogar für Fortran 90 ein entsprechender Ratfor-Präprozessor in Form eines Perl-Skripts geschaffen wurde. Gerüchten zufolge wurde in den ’80er Jahren des vergangenen Jahrhunderts als möglicher Nachfolger von Ratfor ein Ratfiv 2 realisiert. Hier nun einige der wesentlichen Ratfor-Sprachmerkmale: • Die fixe Zeilenform aus FORTRAN 77 entfällt 1 2

B RIAN W. K ERNIGHAN ˆ{ H T T P :// D E . W I K I P E D I A . O R G / W I K I /B R I A N % 20W.%20K E R N I G H A N } EN :R ATFIV ˆ{ H T T P :// D E . W I K I P E D I A . O R G / W I K I / E N %3AR A T F I V }

517

Ratfor

• Anweisungen werden mit Strichpunkt abgeschlossen • Blöcke werden in geschweifte Klammern eingefasst • for-Schleifen, if-Verzweigungen, etc. nach Art der Programmiersprache C • switch-Verzweigung (nur Ratfor 77, ohne break) • Kommentare werden mit # eingeleitet • <, <=, ..., != anstelle von .LT., .LE., ..., .NE. • etc. Nachfolgend je ein kleineres Beispiel, um einen kurzen Einblick in Ratfor 77 und Ratfor 90 und die aus diesen Ratfor-Codes per Präprozessor generierten Fortran-Codes zu geben.

64.2. Ratfor 77 Ratfor program bsp i = 2 switch(i){ case 1: write(*, *) "Fall 1"; case 2: write(*, *) "Fall 2" default: write(*, *) "Default" } end

64.3. Ratfor 90

518

FORTRAN 77 C Output from Public domain Ratfor, version 1.0 program bsp i = 2 I23000=(i) goto 23000 23002 continue write(*, *) "Fall 1" goto 23001 23003 continue write(*, *) "Fall 2" goto 23001 23004 continue write(*, *) "Default" goto 23001 23000 continue if (I23000.eq.1)goto 23002 if (I23000.eq.2)goto 23003 goto 23004 23001 continue end

Weblinks Ratfor

• Rator 90 - Beispiel program bsp integer :: i real :: x = 10.5 if( x != 10.0 ) { for( i = 0; i < 3; i = i + 1 ) { write(*,*) ’IF Hallo ’, i; } } else { write(*,*) ’ELSE Hallo’; } end program bsp

Fortran 90 ! Rator 90 - Beispiel program bsp implicit none integer :: i real :: x = 10.5 if ( x .ne. 10.0 ) then i=0 do if(.not. (i<3)) then exit end if write(*,*) ’IF Hallo ’, i i=i+1 end do else write(*,*) ’ELSE Hallo’ end if end program bsp

64.4. Weblinks • R ATFOR 773 • R ATFOR 904 • B RIAN W. K ERNIGHAN : RATFOR -- A P REPROCESSOR FOR A R A TIONAL F ORTRAN 5

3 4 5

H T T P :// S E P W W W . S T A N F O R D . E D U / S O F T W A R E / R A T F O R . H T M L H T T P :// S E P W W W . S T A N F O R D . E D U / S O F T W A R E / R A T F O R 90. H T M L H T T P :// W O L F R A M . S C H N E I D E R . O R G / B S D /7 T H E D M A N V O L 2/ R A T F O R/R A T F O R.H T M L

519

Teil IX.

Sonstiges

521

65. Cray Pointer 65.1. Einleitung Cray Pointer (auch Integer Pointer genannt) waren und sind teilweise heute noch in Fortran ein Ersatz für die aus der Programmiersprache C bekannten Zeiger. Sie sind nicht Teil der FortranStandards, werden jedoch von einigen Compilerherstellern als Erweiterung des Fortran-Sprachumfangs angeboten. Cray Pointer haben nicht viel mit den unter Fortran 90/95 neu eingeführten Zeigern gemeinsam und können Portabilitätsprobleme bereiten. Die Bezeichnung Cray Pointer deutet auf den "Erfinder" dieser Erweiterung hin - Cray Research1 (firmiert aktuell als Cray Inc.).

65.2. Grundlagen 65.2.1. Pärchenbildung: Speicheradresse ⇔ Objekt pointer( pointeradr, pointee ) [, ...]

• pointeradr ... integer-Skalar (Speicheradresse) • pointee ... Skalar oder Vektor 1

C RAY ˆ{ H T T P :// D E . W I K I P E D I A . O R G / W I K I /C R A Y }

523

Cray Pointer

Der Datentyp für pointeradr muss groß genug gewählt werden, damit die Speicheradresse auch aufgenommen werden kann. Dies stellt schon das erste Problem dar, da diese "Zeigergröße" systemabhängig ist. In weitere Folge muss dieser Speicherplatzbedarf je Zeiger auch bei der Verwendung von "zeigerarithmetischen Kunststücken" beachtet werden. Um portabel zu bleiben darf pointeradr gar nicht deklariert werden. Das Codeschnipsel

! ... integer :: ptradr pointer( ptradr, var ) ! ...

würde von gfortran und ifort auf 32bit-Systemen akzeptieren werden. Der Sun-Compiler weist diesen Code jedoch in jedem Fall mit einer eindeutigen Fehlermeldung ab.

65.2.2. Speicheradresse ermitteln i = loc( var )

Diese Funktion gibt die Speicheradresse von var zurück.

65.2.3. Speicherplatz anfordern ptradr = malloc( bytes )

Fordert bytes Speicherplatz an und gibt die erste dazugehörende Speicheradresse zurück.

524

Beispiel

65.2.4. Speicherplatz freigeben free( ptradr )

65.2.5. Sonstiges • Cray Pointer können auch auf Unterprogramme zeigen.

65.3. Beispiel Fortran 90/95-Code (free source form) program bsp implicit none real, dimension(4) :: arr = (/ 12.5, -3.3, -55.0, -144.9 /) real :: pointee ! ***** Pärchenbildung und loc() ***** ! iptradr wird nicht explizit deklariert, der Compiler ermittelt automatisch ! den erforderlichen Datentyp (kind-Wert) -> 4 Byte-Integer bei ! 32bit-Systemen, 8 Byte-Integer bei 64bit-Systemen, ... pointer( iptradr, pointee(2, 2) )

! ! ! !

! ! !

! !

iptradr = loc( arr(1) ) write( *,* ) pointee Ausgabe: 12.5 -3.3 -55.0 -144.9 write( *,* ) pointee(:, 2) Ausgabe: -55.0 -144.9 iptradr = loc ( arr(2) ) write( *,* ) pointee Ausgabe: -3.3 -55.0 -144.9 1.4012985E-45 ***** Zeigerarithmetik, Ergebnis systemabhängig ***** iptradr = iptradr + 4 ! + 4 Bytes write( *,* ) pointee(1, 1) Ausgabe: -55.0

525

Cray Pointer

! ***** malloc() und free() ***** iptradr = malloc( 16 ) pointee( 1, 1 ) = 99.9 pointee( 2, 1 ) = 999.9 write( *,* ) pointee ! Ausgabe: ! 99.9 999.9 call free( iptradr ) end program bsp

0.0E+0

0.0E+0

Kompilieren, Linken: • gfortran: gfortran -fcray-pointer bsp.f90 • Sun: f95 bsp.f90 • Intel: ifort bsp.f90

65.4. Weblinks • GFORTRAN - C RAY P OINTERS2 • C OMPARING POINTERS IN C RAY F ORTRAN AND F ORTRAN 903 • XLF: I NTEGER-P OINTER ("CRI-P OINTER ", "C RAY-P OINTER ")4

2 3 4

526

H T T P :// G C C . G N U . O R G / O N L I N E D O C S / G F O R T R A N / C R A Y -{} P O I N T E R S . H T M L H T T P :// W W W . C I S L . U C A R . E D U / T C G / C O N S W E B /F O R T R A N 90/ S C N P O I N T.H T M L H T T P :// W W W . U N I C S . U N I -{} H A N N O V E R . D E / R R Z N / G E H R K E / C R I -{} P O I N T E R . H T M

Teil X.

Anhang

527

66. Eine Gegenüberstellung von grundlegenden Fortran- und C-Sprachelementen Nachfolgend werden einige grundlegende Sprachelemente von Fortran95 und C tabellarisch gegenübergestellt. Die Gegenüberstellung erfolgt nur schematisch, da hier nur ein Überblick über die Gemeinsamkeiten und Unterschiede der beiden Programmiersprachen aufgezeigt werden soll. Tabellenlegende: • ----- : nicht vorhanden • ... : nicht näher bestimmt, aber irgendwas Sinnvolles und Zulässiges • kursiv Geschriebenes steht für beliebige (aber natürlich nur sinnvolle und zulässige) Variablennamen, Zahlen, etc.

529

67. Programmgrundstruktur 67.1. Groß-, Kleinschreibung Fortran95 Fortran ist case-insensitiv

C C ist case-sensitiv

67.2. Kommentare Fortran95

C /* xyz */

! xyz

67.3. Das Ende einer Anweisung

531

Programmgrundstruktur

Fortran95

C

• Jede Anweisung steht grundsätzlich in einer eigenen Zeile.

• Einzelne Anweisungungen sind immer durch Semikolon ; zu trennen.

• Die Zeilenlänge ist begrenzt.

• Eine Anweisung kann sich über mehrere Zeilen erstrecken.

• Mehrere Anweisungen dürfen auch in einer Zeile stehen, wenn sie durch Semikolon ; voreinander getrennt sind. • Eine Zeilenfortsetzung muss durch ein Kaufmanns-Und & am Ende der fortzusetzenden Zeile angezeigt werden. • Die Anzahl der erlaubten Fortsetzungzeilen ist begrenzt.

67.4. Hauptprogramm Fortran95 program bsp ... end program bsp

532

C int main(int argc, char **argv) { ... }

Unterprogramme

67.5. Unterprogramme Fortran95 call sub1(...) ... subroutine sub1(...) ... end subroutine sub1 var = fun1(...) ... function fun1(...) datentyp :: fun1 ... fun1 = ... end function fun1

C void sub1(...); ... sub1(...); ... void sub1(...) { ... } datentyp fun1(...); ... var = fun1(...); ... datentyp fun1(...) { ... return ...; }

• Prinzipiell werden Parameter per "call by reference" übergeben.

• Prinzipiell werden Parameter per "call by value" übergeben.

• Die Datenübertragungsrichtung lässt sich mittels intent-Angabe steuern.

• "call by reference" wird mittels Übergabe von Zeigern realisiert.

533

68. Einfache Datentypen Fortran95 ----integer integer(kind=1) integer(kind=2) integer(kind=4) integer(kind=8) real double precision real(kind=4) real(kind=8) complex

logical

character character(len=...)

C unsignedDatentypen int signed char short int int long int float double float double ----- (ab ISO C99 -> complex.hBibliothek) ----- (-> intZahlen, ab ISO C99 -> stdbool.hBibliothek) unsigned char unsigned char[...]

Bytes ... 4 1 2 4 8 4 8 4 8 8

4

1 ...

(Zu beachten ist, dass die Byteanzahl der Datentypen teilweise maschinenabhängig ist. Die kind-Angaben sind zudem auch compilerabhängig.)

535

69. Variablendeklaration Fortran95 datentyp :: var1, var2, ...

C datentyp var1, var2, ...

537

70. Konstanten Fortran95 ’Hallo’ oder "Hallo" ’A’, "A" Arithmetische Konstanten höherer Genauigkeit sind zwingend mit einer speziellen Datentypendung zu versehen

C "Hallo" Character: ’A’, Zeichenkette: "A" -----

539

71. Benannte Konstanten Fortran95 datentyp, parameter :: konstante = wert

C const datentyp konstante = wert oder #define konstante wert

541

72. Operatoren 72.1. Arithmetische Operatoren Fortran95 + * / ** ---- (-> intrinsic functions)

C + * / ----- (-> Bibliotheksfunktion) % (Modulo)

72.2. Vergleichsoperatoren Fortran95 == < <= > >= /=

C == < <= > >= !=

72.3. Logische Operatoren

543

Operatoren

Fortran95 .AND. .OR. .NOT. .EQV. .NEQV.

C && || ! ---------

72.4. Stringverknüpfung Fortran95 //

C ----- (-> Bibliotheksfunktion)

72.5. Bitoperatoren Fortran95 ----- (-> intrinsic functions)

C <<, >>, &, |, ˆ, ˜

72.6. Weitere Operatoren Fortran95 -----

544

C ++, --, +=, -=, etc.

73. Zusammengesetzte Datentypen Fortran95 type :: name sequence integer :: a ... end type name ... type(name) :: var var%a = wert

C struct name { int a; ... }; ... struct name var; var.a = wert;

545

74. Felder Fortran95 datentyp, dimension(zahl) :: var datentyp, dimension(zahl1, zahl2, ...) :: var;

• Ein Feldindex startet standardmäßig bei 1. Dieser Indexstartwert kann aber vom Programmierer verschoben werden.

C datentyp var[zahl] datentyp var[zahl1][zahl2]...;

• Ein Feldindex starten immer bei 0. • Ein mehrdimensionales Feld wird zeilenweise gespeichert.

• Ein mehrdimensionales Feld wird spaltenweise gespeichert. • Fortran95 kennt standardmäßig viele Möglichkeiten mit Feldern (Vektoren und Matrizen) zu hantieren (z.B. Feldkonstruktor, reshape, where, Zugriff auf eine Teilmenge eines Feldes, etc.). var(zahl) = wert

var[zahl] = wert;

547

Felder

Fortran95 var(zahl1, zahl2) = wert var = wert

var(zahl1:zahl2) = wert

548

C var[zahl1][zahl2] = wert; ----- (-> mittels Schleifendurchlauf über das ganze Feld) ----- (-> mittels Schleifendurchlauf über die Feldteilmenge)

75. Zeichenketten Fortran95 character(len=zahl) :: var -----

C char var[zahl] Zeichenketten werden (intern) mit einem \0-Zeichen terminiert. Dies muss bei der Variablendeklaration hinsichtlich der Feldlänge berücksichtigt werden.

549

76. Blöcke, Verzweigungen, Schleifen 76.1. Block Fortran95

C { ... }

...

76.2. Verzweigungen Fortran95 if (bedingung) anweisung if (bedingung) then ... end if if (bedingung) then ... else ... end if ----select case (...) case (...) ... case (...) ... ... case default ... end select

C if (bedingung) anweisung; if (bedingung) { ... } if (bedingung) { ... } else { ... } ... ? ... : ... switch (...) { case ...: ... break; case ...: ... break; ... default: ... }

76.3. Schleifen

551

Blöcke, Verzweigungen, Schleifen

Fortran95 do schleifenvar = anfangswert, endwert, schrittweite ... end do do while (...) ... end do do ... if (...) exit end do

C for (anfangsbedingung; endbedingung; durchgangsanweisung) { ... } while (...) { ... } do { ... } while (...);

76.4. Sonstiges Fortran95 stop exit cycle

552

C #include exit(status); oder im Hauptprogramm return; break; continue;

77. Ein-, Ausgabe Fortran95 write(*, format) ... read(*, format) ...

C #include printf(...); #include scanf(...);

553

78. Dateien Fortran95 open (unit=nr, ...) write (nr, format) ... read (nr, format) ... ... close(unit=nr)

C #include ... FILE *f = fopen(...); fprintf (f, ...); fscanf(f, ...); ... fclose(f);

555

79. Zeiger Fortran95 datentyp, pointer :: var ... datentyp, pointer :: var1 => null(); datentyp, target :: var2 = wert; ... var1 => var2 write(*,*) var1

C datentyp *var; ... datentyp *var1 = 0; datentyp var2 = wert; ... var1 = &var2; printf("%d", *var1);

557

80. Anwendungsbeispiele 80.1. Dreiecksberechnung

559

81. Aufgabe Es sollen einige charakteristische Dreieckswerte berechnet werden. Der Programmanwender gibt die Koordinatenwerte (x, y) für die Dreieckseckpunkte P1 , P2 und P3 vor.

Abb. 57

Das Programm berechnet u.a. folgende Werte und übermittelt diese an die Standardausgabe: • Längen der Dreiecksschenkel und Dreiecksumfang • Innenwinkel

561

Aufgabe

• • • •

Fläche Umkreis (Mittelpunkt und Radius) Inkreis (Mittelpunkt und Radius) Schwerpunkt

562

82. Grundlagen Die Dreiecksberechnung erfolgt in diesem Anwendungsbeispiel hauptsächlich mittels Vektorrechnung. Näheres zu Dreiecken und zur Vektorrechnung ist folgenden Enzyklopädieartikeln und Büchern zu entnehmen: • • • • • • •

1 2 3 4 5 6 7

W IKIPEDIA : D REIECK1 W IKIPEDIA : V EKTOR2 F ORMELSAMMLUNG M ATHEMATIK : G EOMETRIE3 F ORMELSAMMLUNG M ATHEMATIK : T RIGONOMETRIE4 M ATHEMATIK : S CHULMATHEMATIK5 M ATHEMATIK : L INEARE A LGEBRA6 I NG M ATHEMATIK : V EKTOREN7

H T T P :// D E . W I K I P E D I A . O R G / W I K I / D E %3AD R E I E C K %20 H T T P :// D E . W I K I P E D I A . O R G / W I K I / D E %3AV E K T O R %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R M E L S A M M L U N G % 20M A T H E M A T I K %3A%20G E O M E T R I E H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R M E L S A M M L U N G % 20M A T H E M A T I K %3A%20T R I G O N O M E T R I E H T T P :// D E . W I K I B O O K S . O R G / W I K I /M A T H E M A T I K %3A% 20S C H U L M A T H E M A T I K H T T P :// D E . W I K I B O O K S . O R G / W I K I /M A T H E M A T I K %3A% 20L I N E A R E %20A L G E B R A H T T P :// D E . W I K I B O O K S . O R G / W I K I /I N G %20M A T H E M A T I K %3A% 20V E K T O R E N

563

Grundlagen

82.1. Koordinatenwerte ---> Richtungsvektoren

Abb. 58

a = p3 − p1

b = p2 − p 1

c = b−a

82.2. Seitenlängen und Umfang a nor m = |a|

564

Winkel

b nor m = |b|

c nor m = |c|

U = a nor m + b nor m + c nor m Bedingung: a nor m 6= 0, b nor m 6= 0, c nor m 6= 0

82.3. Winkel

Abb. 59

∠ab = arccos anor ma·bbnor m

565

Grundlagen

∠bc = arccos bnor mb·ccnor m ∠ac = π − ∠ab − ∠bc Bedingung: ∠ab 6= 0, ∠ac 6= 0, ∠bc 6= 0

82.4. Fläche

Abb. 60

Es gilt A P ar al l el og r amm = |a × b| = a nor m b nor m sin ∠ab und somit A=

566

A par al l el og r amm 2

=

a nor m b nor m sin ∠ab 2

Umkreis

82.5. Umkreis

Abb. 61

Normalen: a·n = 0 b·m = 0 |n| = 1 |m| = 1 ⇒

567

Grundlagen

n 1 = −a 2

n2 = a1

q

q

m 1 = −b 2

m2 = b1

1 a 12 +a 22

1 a 12 +a 22

q

q

1 b 12 +b 22

1 b 12 +b 22

Geradenschnittpunkt: g 1 : x1 = a2 + t 1 n

g 2 : x2 =

b 2

+ t2 m

Der Umkreismittelpunkt ergibt sich als Schnittpunkt dieser beiden Geraden: x = x1 = x2 ⇒ t2 =

n 1 (a 2 −b 2 )+n 2 (b 1 −a 1 ) 2(m 2 n 1 −m 1 n 2 )

Bedingung: m 2 n 1 − m 1 n 2 6= 0 Umkreismittelpunkt und -radius: xo = p1 + b2 + t 2 m ¯ ¯ ¯ ¯ r o = ¯ b2 + t 2 m¯

568

Inkreis

82.6. Inkreis

Abb. 62

v= w=

1 2

³

a a nor m

³

1 b 2 b nor m

b + bnor m

´

+ cnorc m

´

g 1 : x1 = t 1 v g 2 : x2 = b + t 2 v Der Inkreismittelpunkt ergibt sich als Schnittpunkt dieser beiden Geraden: x = x1 = x2 ⇒

569

Grundlagen

t2 =

b 1 v 2 −b 2 v 1 w 2 v 1 −w 1 v 2

Bedingung: w 2 v 1 − w 1 v 2 6= 0 Inkreismittelpunkt: xi = p2 + t 2 w Inkreisradius: ri =

2A a nor m +b nor m +c nor m

82.7. Schwerpunkt

Abb. 63

570

Schwerpunkt v = a + 2c w=

b 2

−a

g 1 : x1 = t 1 v g 2 : x2 = a + t 2 w Der Dreiecksschwerpunkt ergibt sich als Schnittpunkt dieser beiden Geraden: x = x1 = x2 t2 =

a 1 v 2 −a 2 v 1 w 2 v 1 −w 1 v 2

Bedingung: w 2 v 1 − w 1 v 2 6= 0 ⇒ x = a + t2 w xcog = p1 + x

571

83. Code • M AKEFILE1 • TRIANGLE . F 902 • MODUL 1. F 903

1 2 3

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_A N H A N G _B% 3A_D R E I E C K S B E R E C H N U N G %3A_M A K E F I L E %20%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_A N H A N G _B% 3A_D R E I E C K S B E R E C H N U N G %3A_T R I A N G L E . F 90%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_A N H A N G _B% 3A_D R E I E C K S B E R E C H N U N G %3A_M O D U L 1. F 90%20

573

84. Screenshots

Abb. 64

575

Screenshots

84.1. Kettenlinie

576

85. Aufgabe Der Programmbenutzer gibt die Kettenlänge L, die Abstände der beiden Abhängepunkte in x- und y-Richtung (b und h), sowie das spezifische Kettengewicht q vor. Aus diesen Angaben werden diverse Daten (Seilparameter, Kräfte, Durchhang, ...) für die Kette berechnet. Zusätzlich wird die aus den Angaben resultierende Kettenlinie grafisch am Bildschirm ausgegeben. Diese grafische Ausgabe erfolgt mit Hilfe der DISLIN-Grafikbibliothek.

577

86. Grundlagen • S EILSTATIK1 • siehe N ULLSTELLENBESTIMMUNG NACH N EWTON -R APHSON2

1 2

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20A N H A N G % 20B%3A%20K E T T E N L I N I E %3A%20S E I L S T A T I K %20 H T T P :// D E . W I K I P E D I A . O R G / W I K I / D E %3AN E W T O N -{}V E R F A H R E N % 20

579

87. Code • M AKEFILE1 • CATENARY. F 902 • CATMOD 1. F 903 • CATDISL . F 904 • dislin.f90 (diese Datei ist Bestandteil der DISLIN-Bibliothek)

1 2 3 4

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_A N H A N G _B% 3A_K E T T E N L I N I E %3A_M A K E F I L E %20%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_A N H A N G _B% 3A_K E T T E N L I N I E %3A_C A T E N A R Y . F 90%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_A N H A N G _B% 3A_K E T T E N L I N I E %3A_C A T M O D 1. F 90%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_A N H A N G _B% 3A_K E T T E N L I N I E %3A_C A T D I S L . F 90%20

581

88. Screenshots

Abb. 65

583

Screenshots

Abb. 66

88.1. Inverse Matrix

584

89. Aufgabe Der Programmbenutzer gibt eine reelle nxn-Matrix vor. Das Programm berechnet dazu die inverse Matrix.

585

90. Grundlagen Mit Hilfe der LAPACK-Bibliothek ist die Berechnung einer inversen Matrix sehr einfach durchzuführen. Aus diesem Grund soll bei diesem Beispiel das Hauptaugenmerk auf das Einbinden einer C-Bibliothek in ein Fortran-Programm gelegt werden. Für diesen Zweck bietet sich hier die ncurses-Bibliothek an. Ncurses ist eine Bibliothek zur Erstellung von TUIs (Text User Interfaces). In diesem Beispiel soll die Datenein- und -ausgabe mit Hilfe der ncurses-Bibliothek über einfache Formulare menügeführt erfolgen. • Berechnung der inversen Matrix: • I NVERSE M ATRIX1 • LU-Z ERLEGUNG2 • LAPACK3 • Gestaltung der Benutzerschnittstelle: N CURSES4

1 2 3 4

H T T P :// D E . W I K I P E D I A . O R G / W I K I /I N V E R S E %20M A T R I X %20 H T T P :// D E . W I K I P E D I A . O R G / W I K I /LR-{}Z E R L E G U N G %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A%20LAPACK%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /N C U R S E S %20

587

91. Code

589

92. Screenshots

591

93. Debugger Werden Programme länger und komplexer, so kann der Einsatz eines Debuggers das Auffinden von logischen Fehlern erleichtern.

593

94. Der GNU Debugger Der gdb (GNU Debugger) wird besonders im Open Source-Bereich im Zusammenspiel mit der GCC verwendet. Die Anwendung im Zusammenhang mit gfortran-compilierten Programmen ist relativ einfach, wenn auch nicht so problemlos wie bei C- oder C++Programmen.

94.1. gdb und gfortran Das Programm muss mit dem Optionsschalter -g erstellt werden. gfortran kennt noch andere erweiterte Optionen, die spezialisiertere Ergebnisse liefern. Für einfache Beispiele wie sie in diesem Buch vorzufinden sind reicht aber die -g-Option vollkommen aus. gfortran -g -o bsp bsp.f90 Aufruf des Debuggers mittels gdb bsp Zu beachten ist, dass nach dem Start des Debuggers ein Breakpoint b MAIN__ gesetzt wird, ansonsten findet der Debugger das zu debuggende Fortran-Programm nicht. Danach wird der Debuggerlauf mit run

595

Der GNU Debugger

gestartet. Einige wichtige gdb-Befehle:

b list next step print c until quit

Breakpoint in der Zeile setzen Codelisting Zur nächsten Zeile springen Sprung in eine Subroutine Gibt den Wert der Variablen aus Das Programm fortsetzen (continue) Programm bis zur Zeile ausführen Debugger beenden

94.2. gdb und g95 Das Debuggen von g95-compilierten Programmen funktioniert beinahe identisch zur Vorgehensweise mit gfortran. Allerdings ist zu beachten, dass ein Breakpoint b MAIN_ (nur mit einem Unterstrich) vor dem run-Befehl gesetzt wird.

596

95. Der Intel Debugger Die Firma Intel liefert bei ihren Fortran- und C++-Compilern den Kommandozeilendebugger idb mit. Gestartet wird der Intel-Debugger mittels idb -gdb bsp Der Debugger befindet sich dann im gdb-Modus. Wird der idb ohne -gdb-Schalter aufgerufen, so wird er im dbx-Modus gestartet. Prinzipiell ist es ziemlich egal, in welchem Modus debugged wird. Die Befehlsbezeichungen und der Befehlsumfang unterscheiden sich etwas. Vor dem run sollte ein Breakpoint gesetzt werden. Das allerdings ganz normal mit Angabe einer Zeilennummer.

597

96. Quellcodedokumentation 96.1. ROBODoc ROBODoc ist freie Software unter der GNU General Public License. Dieses Tool verwendet die normalen Kommentarzeichen der jeweiligen Programmiersprache und nutzt für die Dokumentationsgenerierung eigene Auszeichnungstags innerhalb dieser Kommentare.

96.2. Ein einfaches Beispiel 96.2.1. Beispielcode Fortran 90/95-Code (free source form) !****h* Beispielprogramm/circle ! NAME ! circle ! ! DESCRIPTION ! Modul fuer Kreisfunktionen ! ! AUTHOR ! Intruder ! ! CREATION DATE ! 04.08.2007 !****** module circle implicit none

599

Quellcodedokumentation

!****d* circle/pi ! NAME ! pi ! ! DESCRIPTION ! pi = 3.14 !****** real, parameter :: pi = 3.14 contains !****f* circle/area ! NAME ! area ! ! DESCRIPTION ! Berechnet Kreisflaeche ! ! INPUTS ! r ... Radius (real) ! ! RESULT ! Kreisflaeche (real) !****** real function area( r ) implicit none real, intent( in ) :: r area = r ** 2 * pi end function area end module circle

Fortran 90/95-Code (free source form) !****h* Beispielprogramm/main ! NAME ! main ! ! DESCRIPTION ! Hauptprogramm ! ! AUTHOR ! Intruder ! ! CREATION DATE ! 04.08.2007 !****** program main use circle

600

Ein einfaches Beispiel

implicit none real

:: r, a

read( *, * ) r a = area( r ) write( *, * ) "Flaeche = ", a end program main

96.2.2. Erstellen der Dokumentation

Erstellen der Dokumentation im HTML-Format als Multidokument mit Index: robodoc --src . --doc doc --multidoc --html --index

601

Quellcodedokumentation

96.2.3. Screenshot

Abb. 67

96.2.4. Kurze Erläuterung ROBODoc filtert die erforderlichen Angaben für die Dokumentation aus den Fortran-Kommentaren heraus. Zu diesem Zweck sind in den Kommentaren Header einzubauen. Diese Header bestehen aus • begin marker • items • end marker Ein begin marker beginnt immer mit 4 Sternchen, dann kommt ein Buchstabe als Elementkennzeichner. Es folgt ein Stern und dann

602

Ein einfaches Beispiel

Angaben zur Stellung des Elementes in der Dokumentationshierarchie. In diesem Beispiel wurden folgende Elementkennzeichner verwendet: • h ... Modul • f ... Funktion • d ... Konstante (Definition) Der Hierarchiebaum wird durch die strikte Angabe von übergeordnetes Element/aktuelles Element

erstellt. Die verschiedenen Items sind dann unterhalb dieses begin markers durch Schlüsselworte gekennzeichnet: • • • •

NAME DESCRIPTION AUTHOR etc.

Sie dienen zur konkreten Beschreibung des jeweiligen Elementes. Abgeschlossen wir ein solcher Dokumentations-Header durch den end marker. Dieser wird durch mindestens drei Sternchen gebildet. Zwecks Erstellung der Dokumentation sind viele Optionen verfügbar. Die unbedingt erforderlichen Angaben sind • --src mit Angabe der Quelldatei bzw. dem Verzeichnis, in dem die Quelldateien liegen

603

Quellcodedokumentation

• --doc mit einem Vornamen für die Dokumentationsdateien bzw. der Bezeichnung des gewünschten Dokumentationsverzeichnisses • eine Angabe zu der Dokumentationsform: • --multidoc ... Die Dokumentation wird in Form mehrerer Einzeldateien in des Dokumentationsverzeichnis geschrieben • --singledoc ... Der Dokumentationsinhalt wird in eine einzige Datei geschrieben • die Angabe des Dokumentationsformates: • --html ... HTML • --rtf ... RTF • --latex ... LaTeX • --dbxml ... XML DocBook Für dieses Beispielprojekt wird auch noch ein Index erstellt (--index). Detaillierte Informationen zu ROBODoc sind unter dem nachfolgend angeführten Weblink zur ROBODoc-Homepage abrufbar.

96.3. Weblinks • ROBOD OC1

96.4. Natural Docs Auch der Dokumentationsgenerator Natural Docs unterstützt bereits Fortran ab dem Standard 90/95 (free source form) in einer Basisvariante. Natural Docs ist in der Programmiersprache Perl verfasst. Als Softwarelizenz wurde die General Public License 1

604

H T T P :// W W W . X S 4 A L L . N L /%7E R F S B E R /R O B O / R O B O D O C . H T M L

Ein einfaches Beispiel

gewählt. Zum Zeitpunkt der Kapitelerstellung war die Version 1.35 aktuell.

96.5. Ein einfaches Beispiel Fortran 90/95-Code (free source form) ! Section: Beispielprogramm ! Autor: Intruder, Datum: 04.08.2007 ! Group: circle ! Modul fuer Kreisfunktionen module circle implicit none ! Constant: pi ! pi = 3.14 real, parameter :: pi = 3.14 contains ! Function: area ! Berechnet Kreisflaeche ! ! Parameters: ! r ... Radius (real) ! ! Returns: ! Kreisflaeche (real) real function area( r ) implicit none real, intent( in ) :: r area = r ** 2 * pi end function area end module circle ! Group: main ! Hauptprogramm program main use circle implicit none real

:: r, a

read( *, * ) r a = area( r ) write( *, * ) "Flaeche = ", a

605

Quellcodedokumentation

end program main

Erstellung der HTML-Dokumentation: NaturalDocs -i . -o HTML bsp -p .

Screenshot:

Abb. 68

96.6. Kurze Erläuterung Natural Docs filtert die benötigten Informationen mit Hilfe von Schlüsselwörtern aus den Kommentarbereichen der Fortrandateien. Die im Beispielprogramm verwendeten Schlüsselwörter sind:

606

Weblinks

• • • • • •

Section Group Constant Function Parameters Returns

Groß- Kleinschreibung spielt bei diesen Schlüsselwörtern kein Rolle. Abgeschlossen wird ein Schlüsselwort mit einem Doppelpunkt. Beim Ausgabeschalter (-o) muss neben einem Ausgabeverzeichnis auch noch ein Ausgabeformat angegeben werden. Möglich sind • HTML • FramedHTML Beim Schalter -p ist ein (Projekt)Verzeichnis anzugeben, wo Natural Docs einige benötigte Dateien ablegen kann, die nicht direkt zur erstellten Dokumentation gehören. Für weitergehende Infos zu Natural Docs wird auf die unten angegebene Webpräsenz zu dieser Software verwiesen.

96.7. Weblinks • N ATURAL D OCS2

96.8. Doxygen Mit Version 1.5.4 vom 27. Oktober 2007 kann auch doxygen aus Fortran 90/95-Dateien Dokumentationen erstellen. 2

H T T P :// W W W . N A T U R A L D O C S . O R G /

607

Quellcodedokumentation

96.9. Ein einfaches Beispiel Fortran 90/95-Code (free source form) !> \file testprogramm.f90 !! \brief Datei fuer geometrische Berechnungen !> Modul: circle !> \author Intruder !> \date 28.10.2007 module circle implicit none real, parameter :: pi = 3.14 !< PI contains !> Berechnet Kreisflaeche !> \param r ... Radius !> \return Kreisflaeche real function area( r ) implicit none real, intent( in ) :: r area = r ** 2 * pi end function area end module circle !> Hauptprogramm program main use circle implicit none real

:: r, a

read( *, * ) r a = area( r ) write( *, * ) "Flaeche = ", a end program main

Erstellen einer Konfigurationsdatei: doxygen -g Doxyfile

Anschließend sollte man die Doxyfile bearbeiten und nach seinen eigenen Wünschen anpassen (Projektname, Outputordner etc.).

608

Weblinks

Wichtig ist, dass das Flag OPTIMIZE_FOR_FORTRAN auf YES gesetzt wird. Erstellen der Dokumentation (standardmäßig im HTML- und LaTeX-Format, optional auch XML, RTF und man-pages): doxygen Doxyfile

Screenshot (HTML-Variante):

Abb. 69

96.10. Weblinks • 3

DOXYGEN -H OMEPAGE 3

H T T P :// W W W . S T A C K . N L /~{} D I M I T R I / D O X Y G E N

609

Quellcodedokumentation

• A NKÜNDIGUNG DER F ORTRAN 90-U NTERSTÜTZUNG IN doxygen 1.5.44 • DOUG - D OXYGEN F905

4

H T T P :// W W W . S T A C K . N L /~{} D I M I T R I / D O X Y G E N / C H A N G E L O G . HTML

5

610

H T T P :// W W W . D O U G D E V E L . O R G / I N D E X . P H P ? P A G E = D O X Y G E N

97. Make & Co.

Abb. 70

611

Make & Co.

97.1. Einleitung Hier wird keine Einführung in die Verwendung und Syntax von make- und config-Tools geboten, sondern nur kurz auf einige Spezialitäten hingewiesen, die bei den ersten Einsatzversuchen derartiger Werkzeuge im Zusammenhang mit Fortran zu beachten sind. Grundsätzlich kann bei der Erstellung von Makefiles und Konsorten eine ähnliche Vorgehensweise wie bei konventionellen CProgrammen gewählt werden. Es ist bei Fortran-Programmen jedoch zu bedenken, dass bei Verwendung von Modulen modDateien generiert werden (ab Fortran 90). Diese mod-Dateien sind in weiterer Folge für das Kompilieren von moduleinbindenden Quellcodedateien und den Linkvorgang von entscheidender Bedeutung. Somit ist bei hierarchisch verzweigten Quellcodeverzeichnisbäumen Obacht zu geben, dass jeweils auch Zugriff zu diesen mod-Dateien gegeben ist. Dies kann geschehen durch • geeigneten Aufbau der Makefiles, • durch Verwendung von Tools, die solche Abhängkeiten automatisch auflösen • oder auch durch explizite Bekanntgabe der entsprechenden Pfade an Compiler und Linker.

97.2. Explizite Bekanntgabe von Modulpfaden 97.2.1. gfortran Standardmäßig werden include- und mod-Dateien im aktuellen Verzeichnis gesucht. Die Suche kann aber mit folgendem Compilerschalter auf andere Pfade ausgedehnt werden:

612

Explizite Bekanntgabe von Modulpfaden

• -I...: Suchpfad für • include-Dateien • mod-Dateien

erweitern. Standardmäßig werden mod-Dateien in das aktuelle Verzeichnis geschrieben. Dieses Verhalten kann mit folgendem Schalter geändert werden: • -J...: Legt Verzeichnis fest, in das die mod-Dateien geschrieben werden, gleichzeitig auch Suchpfad für modDateien. (Alias für -M... um Konflikte mit bisherigen GCCOptionen zu vermeiden)

97.2.2. g95 Standardmäßig werden include- und mod-Dateien im aktuellen Verzeichnis gesucht. Die Suche kann aber mit folgendem Compilerschalter auf andere Pfade ausgedehnt werden: • -I...: Suchpfad für • include-Dateien • mod-Dateien

erweitern. Auch der g95-Compiler kennt einen -M-Schalter. Dieser hat aber eine komplett andere Bedeutung als beim gfortran-Compiler. Stattdessen gibt es beim g95-Compiler den Schalter:

613

Make & Co.

• -fmod=...: Legt Verzeichnis fest, in das die mod-Dateien geschrieben werden, gleichzeitig auch Suchpfad für modDateien.

97.2.3. ifort • -I...: Suchpfad für • include-Dateien • mod-Dateien

erweitern. • -module ..: Legt Verzeichnis fest, in das die mod-Dateien geschrieben werden, gleichzeitig auch Suchpfad für modDateien.

97.2.4. Sun f90/f95 • -M...: Fügt den angegebenen Pfad zum Modulsuchpfad hinzu. • -moddir=...: mod-Dateien werden in das angegebene Verzeichnis geschrieben, gleichzeitig auch Suchpfad für modDateien.

97.3. GNU Make GNU Make erkennt derzeit leider nur FORTRAN 77-Dateien mit der Endung .f automatisch. Für "free source form"-FortranProgramme sind daher einige vorbereitende Arbeiten nötig, um dann auch die Vorteile (und Nachteile) der impliziten Anwendung von "Pattern Rules" genießen zu dürfen. Werden alle Makeschritte

614

GNU Make

für Fortran-Dateien explit vorgegeben, dann kann man sich dies natürlich sparen.

97.3.1. Ein einfaches Beispiel Es sei ein einfaches Beispiel gegeben, das eine FORTRAN 77-, eine Fortran 2003- und eine C-Datei enthält. Diese Dateien liegen im selben Verzeichnis.

Quellcode-Dateien main.f03: Fortran 2003-Code ! Das Hauptprogramm program main implicit none interface function addition( a, b ) bind( c ) use, intrinsic :: iso_c_binding real( kind = c_float ), value :: a real( kind = c_float ), value :: b real( kind = c_float ) :: addition end function addition subroutine sub() end subroutine sub end interface call sub() write (*,*) addition( 2.5, 3.3 ) ! Ausgabe: ! Summe = ! 5.8 end program main

func.c: Programmcode /* Addiere zwei Zahlen */ float addition(float a, float b) { return (a + b);

615

Make & Co.

}

sub.f: 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 C

Eine einfache FORTRAN 77-Subroutine SUBROUTINE SUB WRITE( *, * ) ’Summe =’ END

12345678901234567890123456789012345678901234567890123456789012345678901234567890 0

. |

1

.

2

.

3

.

4

Explizite Vorgabe der Makeschritte Makefile: FC = gfortran

# oder g95, ifort, ...

prog: main.o func.o sub.o $(FC) -o [email protected] $ˆ main.o: main.f03 $(FC) -c $ˆ func.o: func.c $(CC) -c $ˆ

sub.o: sub.f $(FC) -c $ˆ

Nutzung von "Pattern Rules" Makefile: FC

616

= gfortran

# oder g95, ifort, ...

.

5

.

6

.

7 |

.

8

GNU Make

%.o: %.f03 $(FC) -c $< prog: main.o func.o sub.o $(FC) -o [email protected]

Die Generierung der Objektdateien aus den Quellcodedateien geschieht hier implizit. Für C- und FORTRAN 77-Dateien sucht sich GNU Make die entsprechenden Regeln aus seiner internen Regel-Datenbank. Für .f03-Dateien wurde der entsprechende Befehl hier von uns explizit durch eine "Pattern Rule" vorgegeben. Die make-Ausgabe sieht so aus: gfortran -c main.f03 cc

-c -o func.o func.c

gfortran

-c -o sub.o sub.f

gfortran -o prog main.o func.o sub.o

Solange die Quelldateien im selben Verzeichnis liegen, ist die Erstellung eines Makefiles ziemlich einfach. Wenn aber die Quelldateien gestaffelt in Unterverzeichnissen gespeichert sind und womöglich noch Abhängigkeiten von einem Unterverzeichis zum anderen gegeben sind, dann kann die ganze Sache ziemlich kompliziert werden. Im Anschluss wird eine einfache nichtrekursive Make-Variante gezeigt.

97.3.2. Nichtrekursive Make-Variante Vor der Programmerstellung: -- (D) projektverzeichnis |-- (F) Makefile |-- (F) module.mk

617

Make & Co.

|-- (F) main.f90 | |-- (D) kreis | |-- (F) module.mk | |-- (F) kreis.f90 | |-- (F) kreissegment.f90 | |-- (D) quadrat | |-- (F) module.mk | |-- (F) quadrat.f90 (D) ... directory (F) ... file

Nach der Programmerstellung durch Aufruf von make: -- (D) projektverzeichnis |-- (F) Makefile |-- (F) module.mk |-- (F) main.f90 |-- (F) main.o |-- (F) prog |-- (F) kreis.mod |-- (F) kreissegment.mod |-- (F) quadrat.mod | |-- (D) kreis | |-- (F) module.mk | |-- (F) kreis.f90 | |-- (F) kreissegment.f90 | |-- (F) kreis.o | |-- (F) kreissegment.o | |-- (D) quadrat | |-- (F) module.mk | |-- (F) quadrat.f90 | |-- (F) quadrat.o

618

GNU Make

Quellcode-Dateien main.f90: Fortran 90/95-Code (free source form) program main use kreis use kreissegment use quadrat implicit none call k() call q() call ks() end program main

kreis/kreis.f90: Fortran 90/95-Code (free source form) module kreis implicit none private public :: k contains subroutine k() print *, "Ich bin ein Kreis!" end subroutine k end module kreis

kreis/kreissegment.f90: Fortran 90/95-Code (free source form) module kreissegment use kreis implicit none private public :: ks contains subroutine ks() call k() print *, "Hihi, war nur ein Scherz. Ich bin ein Kreissegment!" end subroutine ks end module kreissegment

619

Make & Co.

quadrat/quadrat.f90: Fortran 90/95-Code (free source form) module quadrat implicit none private public :: q contains subroutine q() print *, "Ich bin ein Quadrat!" end subroutine q end module quadrat

Makefile, Include-Dateien Makefile: FC

:= g95

SRC

:=

OBJ

= $(subst .f90,.o,$(SRC))

%.o: %.f90 $(FC) -c -o [email protected] $< include kreis/module.mk include quadrat/module.mk include module.mk prog: $(OBJ) $(FC) -o [email protected]

module.mk: SRC += main.f90

kreis/module.mk: SRC += kreis/kreis.f90 kreis/kreissegment.f90

620

CMake

quadrat/module.mk: SRC += quadrat/quadrat.f90

Es gibt nur ein Makefile im Projekthauptverzeichnis. Sämtliche unterverzeichnisspezifischen Details (hier nur die Bekanntgabe der Quellcodedateien) werden in den jeweiligen Unterverzeichnissen in eigenen Include-Dateien (.mk) festgelegt und in das Makefile eingebunden. Da, anders als beim rekursiven Make, nicht in die einzelnen Unterverzeichnisse gewechselt wird, werden allfällige mod-Dateien auch nur in das Projekthauptverzeichnis (= das aktuelle Verzeichnis) geschrieben.

97.3.3. Weiterführende Make-Infos • GNU M AKE M ANUAL1 • R OBERT M ECKLENBURG : M ANAGING P ROJECTS WITH GNU M AKE , O’R EILLY O PENBOOK , 20042 • P ETER M ILLER : R ECURSIVE M AKE C ONSIDERED H ARMFUL , 19973

97.4. CMake CMake ist kein Make-Klon, sondern ein moderner AutotoolsErsatz. Gleiches Beispiel wie bei HTTP :// MW / INDEX . PHP 5/M AKE N ICHTREKURSIVE _M AKE -VARIANTE4 , es muss in diesem Fall nur eine 1 2 3 4

H T T P :// W W W . G N U . O R G / S O F T W A R E / M A K E / M A N U A L / H T T P :// W W W . O R E I L L Y . C O M / C A T A L O G / M A K E 3/ B O O K / I N D E X . C S P H T T P :// M I L L E R . E M U . I D . A U / P M I L L E R / B O O K S / R M C H / H T T P :// M W / I N D E X . P H P 5/M A K E #N I C H T R E K U R S I V E _ M A K E -{}V A R I A N T E

621

Make & Co.

CMakeLists.txt-Datei im Projekthauptverzeichnis erstellt werden. Makefile und dazugehörende Dateien werden automatisch beim cmake-Aufruf erstellt. CMakeLists.txt: PROJECT(bsp Fortran) SET(src main.f90 kreis/kreis.f90 kreis/kreissegment.f90 quadrat/quadrat.f90 ) ADD_EXECUTABLE(prog ${src})

Generieren der Makefiles, etc.: • FC=g95 cmake .

-- Check for working Fortran compiler: /xyz/bin/g95 -- Check for working Fortran compiler: /xyz/bin/g95 -- works -- Checking whether /xyz/bin/g95 supports Fortran 90 -- Checking whether /xyz/bin/g95 supports Fortran 90 -- yes -- Configuring done -- Generating done -- Build files have been written to: /abc/projektverzeichnis

Mittels FC=... wird der zu verwendende Fortran-Compiler festgelegt. Wenn irgendein auf dem System installierter FortranCompiler verwendet werden soll, kann diese Vorgabe auch entfallen. In der CMakeLists.txt muss die Programmiersprache Fortran ausdrücklich aktiviert werden. Entweder wie hier im PROJECT-Statement oder alternativ auch über die ENABLE_LANGUAGE-Anweisung.

622

SCons

Programmerstellung: • make

Scanning dependencies of target prog [ 25%] Building Fortran object CMakeFiles/prog.dir/kreis/kreis.o [ 50%] Building Fortran object CMakeFiles/prog.dir/kreis/kreissegment.o [ 75%] Building Fortran object CMakeFiles/prog.dir/quadrat/quadrat.o [100%] Building Fortran object CMakeFiles/prog.dir/main.o Linking Fortran executable prog

CMake (2.4-patch 7) erkennt nur Dateien mit den Endungen f, F, ,f77, F77, f90, F90, for, f95 und F95, jedoch keine mit f03 oder F03. CMake-Homepage: • CM AKE C ROSS - PLATFORM M AKE5

97.5. SCons • SC ONS6 • SC ONS -H OMEPAGE7 • SC ONS W IKI - M ULTIPLE D IRECTORY F ORTRAN B UILD8

5 6 7 8

H T T P :// W W W . C M A K E . O R G /HTML/I N D E X . H T M L H T T P :// D E . W I K I P E D I A . O R G / W I K I /SC O N S H T T P :// W W W . S C O N S . O R G / H T T P :// W W W . S C O N S . O R G / W I K I /M U L T I P L E D I R E C T O R Y F O R T R A N B U I L D ? H I G H L I G H T =%28M U L T I P L E D I R E C T O R Y F O R T R A N B U I L D %29

623

98. Photran - Eine IDE für Fortran basierend auf Eclipse

Für Fortran existieren bei weitem nicht so viele freie IDEs wie für C/C++. Eines der wenigen, wenn nicht sogar derzeit das einzige plattformübergreifende Werkzeug dieser Art ist Photran. Es basiert auf der bekannten Eclipse-IDE und deren C/C++-Erweiterung CDT. Photran weist aber noch nicht den Reife- und Fertigstellungsgrad seiner Java- oder C/C++-Pendants auf.

Leider existiert kein offizielles ausführliches Benutzerhandbuch für Photran und auch in diesem Buch wird momentan keine Photran-Kurzanleitung geboten. Grund ist, dass sich die PhotranBenutzerschnittstelle von Version zu Version noch sehr stark ändert. Es sollen hier also nur kurz einige Photran-Begriffe angerissen werden. Für weitere Informationen zu Photran wird auf die ehe spärliche offizielle Photran-Dokumentation verwiesen. Vieles in Photran ist ohnehin sehr ähnlich der Eclipse-IDE mit CDTErweiterung.

625

Photran - Eine IDE für Fortran basierend auf Eclipse

Abb. 71

Download-Varianten: • Full Photran: Ein abgespecktes Eclipse mit den erforderlichen CDT- und Photran-Packages. Sofern auf dem Rechner eine installierte JRE oder ein JDK vorhanden ist, kann nach dem Download und Entpacken dieses Softwarepakets mit der Photran-IDE gearbeitet werden. • Photran Feature: In dieser Download-Variante ist nur die Fortran-Erweiterung für Eclipse enthalten. Dieses Paket muss also in eine schon vorhandene Eclipse-Installation eingespielt werden. Auch das CDT ist in diesem Paket nicht inkludiert. In älteren Photran-Versionen konnte die gewünschte Projektart ("Standard Make" oder "Managed Make") noch direkt bei der

626

Weblinks

Erstellung eines Photran-Projektes über Menüpunkte angewählt werden. Diese Möglichkeit ist in der Version 4.0 beta 2 entfallen. Die aktuell erforderlichen Schritte hin zu einem "Standard Make"oder "Managed Make"-Projekt sind auf der Photran-Seite "Documentation for Photran" beschrieben. • "Standard Make": Der Programmierer muss sich selbst um die Erstellung der für das Programm erforderlichen Makefiles kümmern. • "Managed Make": Photran erstellt eigenständig die erforderlichen Makefiles. Dieser Projekttyp ist derzeit noch mit Vorsicht zu geniessen.

98.1. Weblinks • P HOTRAN -W EBSITE1 • "D OCUMENTATION W EBSITE2

1 2

FOR

P HOTRAN "

AUF

DER

P HOTRAN -

H T T P :// W W W . E C L I P S E . O R G / P H O T R A N H T T P :// W W W . E C L I P S E . O R G / P H O T R A N / D O C U M E N T A T I O N . P H P

627

Teil XI.

Weblinks

629

Wikis

98.2. Wikis • W IKIPEDIA ZUM T HEMA F ORTRAN3 • D AS ENGLISCHSPRACHIGE F ORTRAN -W IKIBOOK4

98.3. Standards • • • • • • •

3 4 5 6 7

ISO/IEC JTC1/SC22/WG5 O FFIZIELLE H OMEPAGE FÜR F ORTRAN -S TANDARDS5 J3 F ORTRAN S TANDARDS T ECHNICAL C OMMITTEE6 D ER FORTRAN 66-S TANDARD, ANSI USAS X3.9-19667 D ER FORTRAN 77-S TANDARD X3J3/90.4, ANSI X3.9-19788 D ER F ORTRAN 95-S TANDARD J3/97-007, ISO/IEC 1539-1 : 1997 ( W ORKING D RAFT )9 D ER F ORTRAN 2003-S TANDARD J3/04-007, ISO/IEC 1539-1 : 2004 ( W ORKING D RAFT )10 (D ER F ORTRAN 2008-S TANDARD J3/07-007, R EV.3 VOM 27. S EPTEMBER 2007 ( W ORKING D RAFT ))11

H T T P :// D E . W I K I P E D I A . O R G / W I K I /F O R T R A N H T T P :// E N . W I K I B O O K S . O R G / W I K I /F O R T R A N H T T P :// W W W . N A G . C O . U K / S C 22 W G 5/ H T T P :// W W W . J 3-{} F O R T R A N . O R G / H T T P :// W W W . F H -{} J E N A . D E /~{} K L E I N E / H I S T O R Y / L A N G U A G E S / A N S I -{} X 3 D O T 9-{}1966-{}F O R T R A N 66. P D F

8 9

H T T P :// J 3-{} F O R T R A N . O R G / D O C / S T A N D I N G / A R C H I V E /007/

10

97-{}007 R 2/ P D F /97-{}007 R 2. P D F H T T P :// W W W . J 3-{} F O R T R A N . O R G / D O C / Y E A R /04/04-{}007.

H T T P :// W W W . F O R T R A N . C O M /F77_ S T D / R J C N F . H T M L

PDF

11

H T T P :// J 3-{} F O R T R A N . O R G / D O C / S T A N D I N G / L I N K S /007. P D F

631

Photran - Eine IDE für Fortran basierend auf Eclipse

98.4. Skripten, Tutorials, Bücher 98.4.1. Fortran 2003/2008 • T HE N EW F EATURES OF F ORTRAN 2003 ( J OHN R EID )12

98.4.2. Fortran 90/95 • • • • •

P ROGRAMMIEREN

F ORTRAN 90/95 (G ERD G ROTEN , F ORSCHUNGSZENTRUM J ÜLICH G MB H)13 P ROGRAMMIEREN IN F ORTRAN 90/95 (D R . H EIDRUN KOLINSKY, R ECHENZENTRUM DER U NIVERSITÄT B AYREUTH )14 DMOZ -L INKSAMMLUNG FÜR F ORTRAN 90/95-T UTORIALS IN EN GLISCHER S PRACHE 15 N UMERICAL R ECIPES IN F ORTRAN 9016 F ORTRAN 95-FACHWÖRTERLISTE E NGLISCH -D EUTSCH (RRZN R EGIONALES R ECHENZENTRUM FÜR N IEDERSACHSEN )17 IN

98.4.3. FORTRAN 77 • P ROFESSIONAL P ROGRAMMER ’ S G UIDE G. PAGE , U NIVERSITY OF L EICESTER )18 12

TO

F ORTRAN 77 (C LIVE

H T T P :// W W W . F O R T R A N P L U S . C O . U K / R E S O U R C E S / J O H N _ R E I D _ N E W _2003. P D F

13

H T T P :// W W W . K F A -{} J U E L I C H . D E / Z A M / D O C S / B H B / B H B _ H T M L / D 0124/ D 0124. H T M L

14

H T T P :// W W W . R Z . U N I -{} B A Y R E U T H . D E / L E H R E / F O R T R A N 90/ V O R L E S U N G/I N D E X.H T M L

15

H T T P :// D M O Z . O R G /C O M P U T E R S /P R O G R A M M I N G /L A N G U A G E S / F O R T R A N /T U T O R I A L S /F O R T R A N _90_ A N D _95/ 16 H T T P :// W W W . N R B O O K . C O M / B / B O O K F 90 P D F . P H P 17 H T T P :// W W W . R R Z N . U N I -{} H A N N O V E R . D E / F I L E A D M I N / B U E C H E R / U M D R U C K E /SPR.F95.2. P D F 18 H T T P :// W W W . S T A R . L E . A C . U K /~{} C G P / P R O F 77. H T M L

632

Compiler • S KRIPTUM ZU FORTRAN77 (S. V ETTER , URZ H EIDELBERG )19 • E INFÜHRUNG IN DIE FORTRAN P ROGRAMMIERUNG (E LSNER , U NIVERSITÄT O SNABRÜCK )20 • DMOZ -L INKSAMMLUNG FÜR FORTRAN 77-T UTORIALS IN EN GLISCHER S PRACHE 21 • N UMERICAL R ECIPES IN F ORTRAN 7722 • S PRACHELEMENTE IN FORTRAN (M ANFRED FABER U . G ERHARD K AHL , TU W IEN ) 23

98.5. Compiler • • • • • • 19 20

21 22 23 24 25 26 27 28 29

G9524 GNU F ORTRAN 9525 I NTEL F ORTRAN C OMPILER FOR L INUX26 O PEN 64, T HE O PEN R ESEARCH C OMPILER27 O PEN WATCOM28 S ILVERFROST /S ALFORD FTN95 C OMPILER 29 H T T P :// W E B . U R Z . U N I -{} H E I D E L B E R G . D E /D O K U M E N T A T I O N / FORTRAN77. H T M L H T T P :// W W W . R Z . U N I -{} O S N A B R U E C K . D E /Z U M _N A C H L E S E N / S K R I P T E _T U T O R I A L S /P R O G R A M M I E R E N _I N _F O R T R A N _77/ P D F / F O R T R A N 1. P D F H T T P :// D M O Z . O R G /C O M P U T E R S /P R O G R A M M I N G /L A N G U A G E S / F O R T R A N /T U T O R I A L S /F O R T R A N _77/ H T T P :// W W W . N R B O O K . C O M / B / B O O K F P D F . P H P H T T P :// D O L L Y W O O D . I T P . T U W I E N . A C . A T /~{} E D V 2/S K R I P T E N / F T N.P D F H T T P :// W W W . G 95. O R G H T T P :// G C C . G N U . O R G / F O R T R A N / H T T P :// W W W . I N T E L . C O M / C D / S O F T W A R E / P R O D U C T S / A S M O -{} N A / E N G / C O M P I L E R S / F L I N / I N D E X . H T M H T T P :// W W W . O P E N 64. N E T H T T P :// W W W . O P E N W A T C O M . O R G H T T P :// W W W . S I L V E R F R O S T . C O M /11/ F T N 95/ O V E R V I E W . A S P

633

Photran - Eine IDE für Fortran basierend auf Eclipse • S UN S TUDIO E XPRESS30

98.6. Debugger • D ER GNU D EBUGGER31

98.7. IDEs • P HOTRAN32

98.8. Amüsantes • T ESTEN S IE I HREN P ROGRAMMIERSTIL33 • R EAL P ROGRAMMERS D ON ’ T U SE PASCAL34

30

H T T P :// D E V E L O P E R S . S U N . C O M / S U N S T U D I O / D O W N L O A D S / E X P R E S S/I N D E X.J S P

31 32 33 34

634

H T T P :// D I R E C T O R Y . F S F . O R G / G D B . H T M L H T T P :// W W W . E C L I P S E . O R G / P H O T R A N / H T T P :// W W W . P D B M . D E / H U M O R / P R O G R A M M I E R S T I L . H T M L H T T P :// W W W . E E . R Y E R S O N . C A /~{} E L F / H A C K / R E A L M E N . H T M L

Teil XII.

Stichwortverzeichnis

635

A

• • • • • •

** (P OTENZ -O PERATOR )35 +, -, *, /, ** (A RITHMETISCHE O PERATOREN , FORTRAN 77)36 +, -, *, /, ** (A RITHMETISCHE O PERATOREN , F ORTRAN 95)37 = ( W ERTZUWEISUNG , FORTRAN 77)38 = ( W ERTZUWEISUNG , F ORTRAN 95)39 <, <=, >, >=, ==, /= ( V ERGLEICHSOPERATOREN , F ORTRAN 95)40

98.9. A • • • • • 35 36 37 38 39 40 41 42 43 44 45

(F ORTRAN 95)41 ABS (FORTRAN 77)42 A BSOLUTWERT (FORTRAN 77)43 A BSOLUTWERT (F ORTRAN 95)44 ACOS (FORTRAN 77)45 ABS

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G % 23E I G E N S C H A F T E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77% 23A R I T H M E T I S C H E %20O P E R A T O R E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95% 23A R I T H M E T I S C H E %20O P E R A T O R E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77% 23W E R T Z U W E I S U N G %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95% 23W E R T Z U W E I S U N G %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95% 23V E R G L E I C H S O P E R A T O R E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23A B S O L U T W E R T %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23A B S O L U T W E R T %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23A B S O L U T W E R T %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23A B S O L U T W E R T %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23A R K U S F U N K T I O N E N %20

637

Photran - Eine IDE für Fortran basierend auf Eclipse

• • • • • • • • • • • •

(F ORTRAN 95)46 ADJUSTR (F ORTRAN 95) 47 AIMAG (F ORTRAN 95) 48 AIMAG (FORTRAN 77)49 AINT (F ORTRAN 95) 50 AINT (FORTRAN 77)51 ALLOCATE (F ORTRAN 95) 52 ALLOCATED (F ORTRAN 95) 53 ALOG (FORTRAN 77)54 ALOG10 (FORTRAN 77)55 AMAX 0 (F ORTRAN 95) 56 AMAX0 (FORTRAN 77)57 ADJUSTL

46 47 48 49 50 51 52

53 54 55 56 57

638

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23S O N S T I G E %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23S O N S T I G E %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23K O M P L E X E %20Z A H L E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77% 23K O M P L E X E %20Z A H L E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23R U N D U N G %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23R U N D U N G %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23S P E I C H E R P L A T Z %20 D Y N A M I S C H %20 R E S E R V I E R E N % 20 U N D %20 F R E I G E B E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23F E L D F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23L O G A R I T H M U S %20 N A T U R A L I S %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23D E K A D I S C H E R %20L O G A R I T H M U S %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23M A X I M U M %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77% 23M A X I M U M %20

A

• • • • • • • • • • • •

58 59 60 61 62 63 64 65 66 67 68 69

(F ORTRAN 95)58 AMAX1 (FORTRAN 77)59 AMIN 0 (F ORTRAN 95) 60 AMIN0 (FORTRAN 77)61 AMIN 1 (F ORTRAN 95) 62 AMIN1 (FORTRAN 77)63 AMOD (F ORTRAN 95) 64 AMOD (FORTRAN 77)65 .AND. (FORTRAN 77)66 .AND. (F ORTRAN 95)67 ANINT (F ORTRAN 95) 68 ANINT (FORTRAN 77)69 AMAX 1

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23M A X I M U M %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77% 23M A X I M U M %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23M I N I M U M %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77% 23M I N I M U M %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23M I N I M U M %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77% 23M I N I M U M %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23M O D U L O %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23M O D U L O %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23L O G I S C H E %20O P E R A T O R E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23L O G I S C H E %20O P E R A T O R E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23R U N D U N G %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23R U N D U N G %20

639

Photran - Eine IDE für Fortran basierend auf Eclipse

• • • • • • • • • • • •

(F ORTRAN 95)70 A RITHMETISCHES IF (FORTRAN 77)71 A RKUSFUNKTIONEN (FORTRAN 77)72 A RKUSFUNKTIONEN (F ORTRAN 95)73 A RRAY CONSTRUCTOR (F ORTRAN 95)74 ASIN (F ORTRAN 95) 75 ASIN (FORTRAN 77)76 ASSIGN (FORTRAN 77)77 A SSIGNED GOTO (FORTRAN 77)78 ASSOCIATED (Z EIGERFUNKTION , F ORTRAN 95) 79 ASSOCIATED (A SSOZIATIONSSTATUS , F ORTRAN 95) 80 A SSOZIATIONSSTATUS (F ORTRAN 95)81 ANY

70 71 72 73 74

75 76 77 78 79 80 81

640

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23F E L D F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23A R I T H M E T I S C H E S %20IF%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23A R K U S F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23A R K U S F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _ 95%23E I N D I M E N S I O N A L E %20F E L D E R %20%28 A R R A Y % 20 C O N S T R U C T O R %29%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23A R K U S F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23A R K U S F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23ASSIGN%20 U N D %20A S S I G N E D %20GOTO%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23ASSIGN%20 U N D %20A S S I G N E D %20GOTO%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23Z E I G E R F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23A S S O Z I A T I O N S S T A T U S %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23A S S O Z I A T I O N S S T A T U S %20

B • ATAN (F ORTRAN 95)82 • ATAN (FORTRAN 77)83 • ATAN 2 (F ORTRAN 95)84 • ATAN2 (FORTRAN 77)85 • ATLAS, AUTOMATICALLY T UNED L INEAR A LGEBRA S OFTWARE86

98.10. B • • • • • • 82 83 84 85 86 87 88 89 90 91 92

B EDINGTES GOTO (FORTRAN 77)87 B ENANNTE KONSTANTEN (FORTRAN 77)88 B ENANNTE KONSTANTEN (F ORTRAN 95)89 B INÄRZAHL (F ORTRAN 95)90 BIT _ SIZE (F ORTRAN 95) 91 B ITFUNKTIONEN (F ORTRAN 95)92 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23A R K U S F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23A R K U S F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23A R K U S F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23A R K U S F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_BLAS_ATLAS% 20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23B E D I N G T E S %20GOTO%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77% 23B E N A N N T E %20K O N S T A N T E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95% 23B E N A N N T E %20K O N S T A N T E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95% 23D A T E N T Y P E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23B I T F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23B I T F U N K T I O N E N %20

641

Photran - Eine IDE für Fortran basierend auf Eclipse • BLAS, B ASIC L INEAR A LGEBRA S UBPROGRAMS93 • BTEST (F ORTRAN 95)94

98.11. C • • • • • • • • •

C95 C (A NHANG A)96 C (F ORTRAN UND C)97 CABS (F ORTRAN 95) 98 CABS (FORTRAN 77)99 CALL (F ORTRAN 95) 100 CALL (FORTRAN 77)101 CCOS (FORTRAN 77)102 CEILING (F ORTRAN 95) 103

93

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_BLAS_ATLAS%

20 94 95 96 97 98 99 100 101 102 103

642

H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23B I T F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G % 23E I G E N S C H A F T E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_A N H A N G _A%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _ U N D _C%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23A B S O L U T W E R T %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23A B S O L U T W E R T %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23 S U B R O U T I N E %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23SUBROUTINE%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23W I N K E L F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23R U N D U N G %20

C

• • • • • • • • • • • •

(F ORTRAN 95)104 CEXP (FORTRAN 77)105 CHAR (F ORTRAN 95) 106 CHAR (FORTRAN 77)107 CHARACTER (F ORTRAN 95) 108 CHARACTER (FORTRAN 77)109 CLOG (FORTRAN 77)110 CLOSE (F ORTRAN 95) 111 CLOSE (FORTRAN 77)112 CMPLX (F ORTRAN 95) 113 CMPLX (FORTRAN 77)114 COMMON (FORTRAN 77)115 CEXP

104 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23E X P O N E N T I A L F U N K T I O N %20 105 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23E X P O N E N T I A L F U N K T I O N %20 106 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23U M W A N D L U N G %20 I N %20CHARACTER%20 107 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23U M W A N D L U N G %20 I N %20CHARACTER%20 108 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23Z E I C H E N K E T T E N %20 109 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23Z E I C H E N K E T T E N %20 110 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23L O G A R I T H M U S %20 N A T U R A L I S %20 111 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 C L O S E %20 112 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23CLOSE%20 113 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23U M W A N D L U N G %20 I N %20COMPLEX%20 114 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23U M W A N D L U N G %20 I N %20COMPLEX%20 115 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23COMMON%20

643

Photran - Eine IDE für Fortran basierend auf Eclipse

• • • • • • • • • • • •

C OMPILER116 COMPLEX (F ORTRAN 95) 117 COMPLEX (FORTRAN 77)118 CONJ (F ORTRAN 95) 119 CONJ (FORTRAN 77)120 CONTINUE (FORTRAN 77)121 COS (F ORTRAN 95) 122 COS (FORTRAN 77)123 COSH (F ORTRAN 95) 124 COSH (FORTRAN 77)125 CSHIFT (F ORTRAN 95) 126 CSIN (FORTRAN 77)127

116 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

23C O M P I L E R %20 117 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23D A T E N T Y P E N %20 118 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23A R I T H M E T I S C H E %20D A T E N T Y P E N %20 119 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23K O M P L E X E %20Z A H L E N %20 120 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23K O M P L E X E %20Z A H L E N %20 121 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23CONTINUE%20 122 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23W I N K E L F U N K T I O N %20 123 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23W I N K E L F U N K T I O N E N %20 124 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23H Y P E R B E L F U N K T I O N E N %20 125 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23H Y P E R B E L F U N K T I O N E N %20 126 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23F E L D F U N K T I O N E N %20 127 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23W I N K E L F U N K T I O N E N %20

644

D • CSQRT (F ORTRAN 95)128 • CSQRT (FORTRAN 77)129 • CYCLE (F ORTRAN 95)130 • C YGWIN131

98.12. D • • • • • • •

(F ORTRAN 95)132 DABS (FORTRAN 77)133 DACOS (FORTRAN 77)134 DASIN (FORTRAN 77)135 DATA (FORTRAN 77)136 DATAN (FORTRAN 77)137 DATAN2 (FORTRAN 77)138 DABS

128 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23Q U A D R A T W U R Z E L %20 129 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23Q U A D R A T W U R Z E L %20 130 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 C Y C L E %20 131 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_G95%

23U N I X -{} A R T I G E %20 I N K L .%20C Y G W I N %20 U N D %20M A C OSX%20 132 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23A B S O L U T W E R T %20 133 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23A B S O L U T W E R T %20 134 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23A R K U S F U N K T I O N E N %20 135 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23A R K U S F U N K T I O N E N %20 136 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23DATA%20 137 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23A R K U S F U N K T I O N E N %20 138 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23A R K U S F U N K T I O N E N %20

645

Photran - Eine IDE für Fortran basierend auf Eclipse

• • • • • • • • • • • •

D ATEI (FORTRAN 77)139 D ATEI (F ORTRAN 95)140 D ATENSATZ (FORTRAN 77)141 D ATENTYP (FORTRAN 77)142 D ATENTYP (F ORTRAN 95)143 D ATENTYP HÖHERER G ENAUIGKEIT (F ORTRAN 95)144 D ATENTYPUMWANDLUNG (FORTRAN 77)145 D ATENVERBUND (F ORTRAN 95)146 DBLE (FORTRAN 77)147 DCOS (FORTRAN 77)148 DCOSH (FORTRAN 77)149 DDIM (F ORTRAN 95) 150

139 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23D A T E I %20 140 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23D A T E I %20 141 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23D A T E N S A T Z %20 142 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23D A T E N T Y P E N %20 143 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23D A T E N T Y P E N %20 144 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23D A T E N T Y P E N %20 H %F6 H E R E R %20G E N A U I G K E I T %20 145 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23D A T E N T Y P U M W A N D L U N G %20 146 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23D A T E N V E R B U N D %20 147 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23U M W A N D L U N G %20 I N %20DOUBLE%20 148 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23W I N K E L F U N K T I O N E N %20 149 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23H Y P E R B E L F U N K T I O N E N %20 150 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23P O S I T I V E %20D I F F E R E N Z %20

646

D

• • • • • • • • • • • •

DDIM (FORTRAN 77)151 DEALLOCATE (F ORTRAN 95) 152 D EBUGGER (A NHANG C)153 DEXP (F ORTRAN 95) 154 DEXP (FORTRAN 77)155 DIM (F ORTRAN 95) 156 DIM (FORTRAN 77)157 DINT (F ORTRAN 95) 158 DINT (FORTRAN 77)159 DLOG (FORTRAN 77)160 DISLIN161 DLOG10 (FORTRAN 77)162

151 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23P O S I T I V E %20D I F F E R E N Z %20 152 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

153 154 155 156 157 158 159 160 161 162

2095%23S P E I C H E R P L A T Z %20 D Y N A M I S C H %20 R E S E R V I E R E N % 20 U N D %20 F R E I G E B E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_A N H A N G _C%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23E X P O N E N T I A L F U N K T I O N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23E X P O N E N T I A L F U N K T I O N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23P O S I T I V E %20D I F F E R E N Z %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23P O S I T I V E %20D I F F E R E N Z %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23R U N D U N G %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23R U N D U N G %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23L O G A R I T H M U S %20 N A T U R A L I S %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_DISLIN%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23D E K A D I S C H E R %20L O G A R I T H M U S %20

647

Photran - Eine IDE für Fortran basierend auf Eclipse

• • • • • • • • • • • •

(F ORTRAN 95)163 DMAX1 (FORTRAN 77)164 DMIN 1 (F ORTRAN 95) 165 DMIN1 (FORTRAN 77)166 DMOD (F ORTRAN 95) 167 DMOD (FORTRAN 77)168 DNINT (F ORTRAN 95) 169 DNINT (FORTRAN 77)170 DO - IF - EXIT (F ORTRAN 95) 171 DO -L ISTE (F ORTRAN 95) 172 DO-L ISTE (FORTRAN 77)173 DO-S CHLEIFE (FORTRAN 77)174 DMAX 1

163 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M A X I M U M %20 164 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23M A X I M U M %20 165 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M I N I M U M %20 166 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23M I N I M U M %20 167 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M O D U L O %20 168 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23M O D U L O %20 169 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23R U N D U N G %20 170 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23R U N D U N G %20 171 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 D O -{} I F -{} E X I T %20 172 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23I M P L I Z I T E %20 D O -{}L I S T E %20 173 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23I M P L I Z I T E %20DO-{}L I S T E %20 174 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23DO-{}S C H L E I F E N %20

648

D

• • • • • • • • • • • •

(F ORTRAN 95)175 DOUBLE PRECISION (F ORTRAN 95) 176 DOUBLE PRECISION (FORTRAN 77)177 DO WHILE (F ORTRAN 95) 178 DO -Z ÄHLSCHLEIFE (F ORTRAN 95) 179 DPROD (FORTRAN 77)180 DSIGN (F ORTRAN 95) 181 DSIGN (FORTRAN 77)182 DSIN (FORTRAN 77)183 DSINH (FORTRAN 77)184 DSQRT (F ORTRAN 95) 185 DSQRT (FORTRAN 77)186 DOT _ PRODUCT

175 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23F E L D F U N K T I O N E N %20 176 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23D A T E N T Y P E N %20 177 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23A R I T H M E T I S C H E %20D A T E N T Y P E N %20 178 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 D O %20 W H I L E %20 179 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23D I E %20 D O -{}Z%E4 H L S C H L E I F E %20 180 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23D O U B L E %20P R E C I S I O N -{}P R O D U K T %20 181 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23V O R Z E I C H E N T R A N S F E R %20 182 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23V O R Z E I C H E N T R A N S F E R %20 183 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23W I N K E L F U N K T I O N E N %20 184 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23H Y P E R B E L F U N K T I O N E N %20 185 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23Q U A D R A T W U R Z E L %20 186 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23Q U A D R A T W U R Z E L %20

649

Photran - Eine IDE für Fortran basierend auf Eclipse • DTAN (FORTRAN 77)187 • DTANH (FORTRAN 77)188 • DYNAMISCHE S PEICHERALLOKATION (F ORTRAN 95)189

98.13. E • • • • • • • •

E IN - UND AUSGABE (FORTRAN 77)190 E IN - UND AUSGABE (F ORTRAN 95)191 ELSE - IF (F ORTRAN 95) 192 ENTRY (FORTRAN 77)193 EPSILON (F ORTRAN 95) 194 .EQ. (FORTRAN 77)195 .EQV. (FORTRAN 77)196 .EQV. (F ORTRAN 95)197

187 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23W I N K E L F U N K T I O N E N %20 188 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23H Y P E R B E L F U N K T I O N E N %20 189 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23D Y N A M I S C H E %20S P E I C H E R A L L O K A T I O N %20 190 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23E I N -{}%20 U N D %20A U S G A B E %20 191 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23E I N -{}%20 U N D %20A U S G A B E %20 192 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 E L S E -{} I F %20 193 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23ENTRY%20 194 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23W E I T E R E %20F U N K T I O N E N %20 195 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23V E R G L E I C H S O P E R A T O R E N %20 196 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23L O G I S C H E %20O P E R A T O R E N %20 197 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23L O G I S C H E %20O P E R A T O R E N %20

650

E

• • • • • • • • • • • •

E RGEBNISDATENTYP (FORTRAN 77)198 E RGEBNISDATENTYP (F ORTRAN 95)199 EXIT (F ORTRAN 95) 200 EXP (F ORTRAN 95) 201 EXP (FORTRAN 77)202 E XPLIZITE T YPZUWEISUNG (FORTRAN 77)203 E XPLIZITE T YPZUWEISUNG (F ORTRAN 95)204 E XPLIZITE T YPUMWANDLUNG (FORTRAN 77)205 E XPLIZITE T YPUMWANDLUNG (F ORTRAN 95)206 EXPONENT (F ORTRAN 95) 207 E XPONENTIALFUNKTION (FORTRAN 77)208 E XPONENTIALFUNKTION (F ORTRAN 95)209

198 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23E R G E B N I S D A T E N T Y P %20 199 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23E R G E B N I S D A T E N T Y P %20 200 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 E X I T %20 201 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23E X P O N E N T I A L F U N K T I O N %20 202 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23E X P O N E N T I A L F U N K T I O N %20 203 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23E X P L I Z I T E %20T Y P A N W E I S U N G %20 204 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23E X P L I Z I T E %20T Y P A N W E I S U N G %20 205 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23E X P L I Z I T E %20T Y P U M W A N D L U N G %20 206 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23E X P L I Z I T E %20T Y P U M W A N D L U N G %20 207 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23W E I T E R E %20F U N K T I O N E N %20 208 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23E X P O N E N T I A L F U N K T I O N %20 209 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23E X P O N E N T I A L F U N K T I O N %20

651

Photran - Eine IDE für Fortran basierend auf Eclipse • EXTERNAL (F ORTRAN 95)210 • EXTERNAL (FORTRAN 77)211

98.14. F • • • • • • • • •

F212 F 2 C 213 F ELD (FORTRAN 77)214 F ELD (F ORTRAN 95)215 F ELD (PARAMETER , F ORTRAN 95)216 F ELD (PARAMETER , FORTRAN 77)217 F ELDFUNKTION (F ORTRAN 95)218 F ELDINITIALISIERUNG (F ORTRAN 95)219 FLOAT (F ORTRAN 95) 220

210 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23P R O Z E D U R E N %20 A L S %20P A R A M E T E R %20 211 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23P R O Z E D U R E N %20 A L S %20P A R A M E T E R %20 212 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

23V A R I A N T E N %20 213 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

23%DC B E R S E T Z E R %20 214 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23F E L D E R %20 215 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23F E L D E R %20 216 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23F E L D E R %20 A L S %20P A R A M E T E R %20 217 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23F E L D E R %20 A L S %20P A R A M E T E R %20 218 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23F E L D F U N K T I O N E N %20 219 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23F E L D I N I T I A L I S I E R U N G %20 220 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23U M W A N D L U N G %20 I N %20REAL%20

652

F

• • • • • • • • • • • •

FLOAT (FORTRAN 77)221 FLOOR (F ORTRAN 95) 222 FORALL -S CHLEIFE (F ORTRAN 95) 223 FORMAT (F ORTRAN 95) 224 FORMAT (FORTRAN 77)225 F ORMATIERUNG (FORTRAN 77)226 F ORMATIERUNG (F ORTRAN 95)227 F ORTRAN228 FORTRAN I229 FORTRAN II230 FORTRAN IV231 FORTRAN 66232

221 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23U M W A N D L U N G %20 I N %20REAL%20 222 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23R U N D U N G %20 223 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 F O R A L L -{}S C H L E I F E %20 224 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23 F O R M A T %20 225 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23FORMAT%20 226 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23FORMAT%20 227 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23 F O R M A T %20 228 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

20 229 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

23V E R S I O N E N %20 230 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

23V E R S I O N E N %20 231 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

23V E R S I O N E N %20 232 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

23V E R S I O N E N %20

653

Photran - Eine IDE für Fortran basierend auf Eclipse

• • • • • • • • • • • •

FORTRAN 77233 FORTRAN 77 (E INLEITUNG )234 F ORTRAN 90235 F ORTRAN 95236 F ORTRAN 95 (E INLEITUNG )237 F ORTRAN 2003 (E INLEITUNG )238 F ORTSETZUNGSZEILE (FORTRAN 77)239 F REE SOURCE FORM (F ORTRAN 95)240 F REIES Z EILENFORMAT (F ORTRAN 95)241 FUNCTION (F ORTRAN 95) 242 FUNCTION (FORTRAN 77)243 F UNKTIONSANWEISUNG (FORTRAN 77)244

233 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

20 234 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

23V E R S I O N E N %20 235 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

23V E R S I O N E N %20 236 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

20 237 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

23V E R S I O N E N %20 238 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

23V E R S I O N E N %20 239 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23D A S %20Z E I L E N F O R M A T %20 240 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23B E I S P I E L %3A%20H A L L O %20W E L T %20 241 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23D A S %20Z E I L E N F O R M A T %20 242 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 F U N C T I O N %20 243 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23FUNCTION%20 244 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23F U N K T I O N S A N W E I S U N G %20

654

G

98.15. G • • • • • • • • • • • •

G95245 .GE. (FORTRAN 77)246 GETARG (F ORTRAN 95) 247 GNU F ORTRAN 95 ( GFORTRAN )248 GOTO (FORTRAN 77)249 GOTO (A SSIGNED, FORTRAN 77)250 GOTO (B EDINGT, FORTRAN 77)251 G RAPHICAL U SER I NTERFACE (DISLIN)252 G RAPHICAL U SER I NTERFACE ( JAPI )253 G RAPHICAL U SER I NTERFACE ( PILIB )254 .GT. (FORTRAN 77)255 GTK+ ( PILIB )256

245 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_G95%20 246 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23V E R G L E I C H S O P E R A T O R E N %20 247 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23K O M M A N D O Z E I L E N A R G U M E N T E %20 248 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_G F O R T R A N %20 249 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23GOTO%20 250 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23ASSIGN%20 U N D %20A S S I G N E D %20GOTO%20 251 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23B E D I N G T E S %20GOTO%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_DISLIN%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_J A P I %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_P I L I B %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23V E R G L E I C H S O P E R A T O R E N %20 256 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_P I L I B %20

252 253 254 255

655

Photran - Eine IDE für Fortran basierend auf Eclipse

98.16. H • • • • • • •

H AUPTPROGRAMM (FORTRAN 77)257 H AUPTPROGRAMM (F ORTRAN 95)258 H EXADEZIMALZAHL (F ORTRAN 95)259 H OLLERITH (FORTRAN 77)260 HPF, H IGH P ERFORMANCE F ORTRAN261 H YPERBELFUNKTION (FORTRAN 77)262 H YPERBELFUNKTIONEN (F ORTRAN 95)263

98.17. I • IABS (F ORTRAN 95)264 • IABS (FORTRAN 77)265

257 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_

258

259 260 261 262 263 264 265

656

77%23D I E %20P R O G R A M M S T R U K T U R %20 F %FC R %20 D A S % 20H A U P T P R O G R A M M %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _ 95%23D I E %20P R O G R A M M S T R U K T U R %20 F %FC R %20 D A S % 20H A U P T P R O G R A M M %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95% 23D A T E N T Y P E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23H O L L E R I T H -{}K O N S T A N T E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G % 23V A R I A N T E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77% 23H Y P E R B E L F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23H Y P E R B E L F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23A B S O L U T W E R T %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23A B S O L U T W E R T %20

I

• • • • • • • • • • • •

(F ORTRAN 95)266 IARGC (F ORTRAN 95) 267 IBCLR (F ORTRAN 95) 268 IBSET (F ORTRAN 95) 269 ICHAR (F ORTRAN 95) 270 ICHAR (FORTRAN 77)271 IDIM (F ORTRAN 95) 272 IDIM (FORTRAN 77)273 IDINT (FORTRAN 77)274 IDNINT (F ORTRAN 95) 275 IDNINT (FORTRAN 77)276 IEOR (F ORTRAN 95) 277 IAND

266 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23B I T F U N K T I O N E N %20 267 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23K O M M A N D O Z E I L E N A R G U M E N T E %20 268 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23B I T F U N K T I O N E N %20 269 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23B I T F U N K T I O N E N %20 270 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23U M W A N D L U N G %20 I N %20INTEGER%20 271 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23U M W A N D L U N G %20 I N %20INTEGER%20 272 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23P O S I T I V E %20D I F F E R E N Z %20 273 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23P O S I T I V E %20D I F F E R E N Z %20 274 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23U M W A N D L U N G %20 I N %20INTEGER%20 275 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23R U N D U N G %20 276 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23R U N D U N G %20 277 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23B I T F U N K T I O N E N %20

657

Photran - Eine IDE für Fortran basierend auf Eclipse

• • • • • • • • • • •

IF (A RITHMETISCH , FORTRAN 77)278 IF-V ERWEIGUNG (FORTRAN 77)279 IF -E INZEILER (F ORTRAN 95) 280 IF - THEN (F ORTRAN 95) 281 IF - THEN - ELSE (F ORTRAN 95) 282 IFIX (F ORTRAN 95) 283 IFIX (FORTRAN 77)284 IMPLICIT (F ORTRAN 95) 285 IMPLICIT (FORTRAN 77)286 I MPLIZITE T YPUMWANDLUNG (FORTRAN 77)287 I MPLIZITE T YPUMWANDLUNG (F ORTRAN 95)288

278 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23A R I T H M E T I S C H E S %20IF%20 279 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23IF-{}V E R Z W E I G U N G E N %20 280 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23D E R %20 I F -{}E I N Z E I L E R %20 281 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 I F -{} T H E N %20 282 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 I F -{} T H E N -{} E L S E %20 283 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23U M W A N D L U N G %20 I N %20INTEGER%20 284 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23U M W A N D L U N G %20 I N %20INTEGER%20 285 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23I M P L I Z I T E %20T Y P A N W E I S U N G %20 286 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23I M P L I Z I T E %20T Y P A N W E I S U N G %20 287 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_

77%23I M P L I Z I T E %20T Y P U M W A N D L U N G %20 B E I %20O P E R A N D E N % 20 G E M I S C H T E N %20D A T E N T Y P S %20 288 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _ 95%23I M P L I Z I T E %20T Y P U M W A N D L U N G %20 B E I %20O P E R A N D E N % 20 G E M I S C H T E N %20D A T E N T Y P S %20

658

I

• • • • • • • • • • • •

INCLUDE (FORTRAN 77)289 INDEX (F ORTRAN 95) 290 INDEX (FORTRAN 77)291 INT (F ORTRAN 95) 292 INT (FORTRAN 77)293 INTEGER (F ORTRAN 95) 294 INTEGER (FORTRAN 77)295 I NTEL F ORTRAN C OMPILER296 INTENT (F ORTRAN 95) 297 INTERFACE (F ORTRAN UND C)298 INTRINSIC (F ORTRAN 95) 299 INTRINSIC (FORTRAN 77)300

289 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23INCLUDE%20 290 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23I N D E X %20 E I N E S %20T E I L S T R I N G S %20 291 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23I N D E X %20 E I N E S %20T E I L S T R I N G S %20 292 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23U M W A N D L U N G %20 I N %20INTEGER%20 293 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

3A_S T A N D A R D F U N K T I O N E N %23U M W A N D L U N G _ I N _INTEGER%20 294 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23D A T E N T Y P E N %20 295 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23A R I T H M E T I S C H E %20D A T E N T Y P E N %20 296 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_I F O R T %20 297 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 S U B R O U T I N E %20 298 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _ U N D _C%23I N T E R F A C E %20

299 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23P R O Z E D U R E N %20 A L S %20P A R A M E T E R %20 300 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23P R O Z E D U R E N %20 A L S %20P A R A M E T E R %20

659

Photran - Eine IDE für Fortran basierend auf Eclipse • I NTRINSIC FUNCTION (FORTRAN 77)301 • I NTRINSIC FUNCTION (F ORTRAN 95)302 • IOR (F ORTRAN 95)303 • ISHFT (F ORTRAN 95)304 • ISHFTC (F ORTRAN 95)305 • ISIGN (F ORTRAN 95)306 • ISIGN (FORTRAN 77)307

98.18. J • JAPI308 • J AVA AWT ( JAPI )309

301 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

302

303 304 305 306 307 308 309

660

2077%23S T A N D A R D F U N K T I O N E N %20%28 I N T R I N S I C % 20 F U N C T I O N S %29%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23S T A N D A R D F U N K T I O N E N %20%28 I N T R I N S I C % 20 F U N C T I O N S %29%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23B I T F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23B I T F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23B I T F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23V O R Z E I C H E N T R A N S F E R %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23V O R Z E I C H E N T R A N S F E R %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_J A P I %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_J A P I %20

K

98.19. K • • • • • •

(F ORTRAN 95)310 KIND (F UNKTION , F ORTRAN 95) 311 KOMMANDOZEILENARGUMENT (F ORTRAN 95)312 KOMMENTARZEILE (FORTRAN 77)313 KOMPLEXE Z AHLEN (FORTRAN 77)314 KOMPLEXE Z AHLEN (F ORTRAN 95)315 KIND

98.20. L • LAPACK, L INEAR A LGEBRA PACKAGE316 • LBOUND (F ORTRAN 95)317 • .LE. (FORTRAN 77)318 • LEN (F ORTRAN 95)319

310 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23E I N F A C H E %20V A R I A N T E %20 311 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 K I N D -{}P A R A M E T E R %20 312 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23K O M M A N D O Z E I L E N A R G U M E N T E %20 313 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23D A S %20Z E I L E N F O R M A T %20 314 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23K O M P L E X E %20Z A H L E N %20 315 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23K O M P L E X E %20Z A H L E N %20 316 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_LAPACK%20 317 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23F E L D F U N K T I O N E N %20 318 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23V E R G L E I C H S O P E R A T O R E N %20 319 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23S T R I N G L %E4 N G E %20

661

Photran - Eine IDE für Fortran basierend auf Eclipse

• • • • • • • • • • • •

LEN (FORTRAN 77)320 LEN _ TRIM (F ORTRAN 95) 321 L EXIKALISCHE F UNKTIONEN (FORTRAN 77)322 L EXIKALISCHE F UNKTIONEN (F ORTRAN 95)323 LGE (F ORTRAN 95) 324 LGE (FORTRAN 77)325 LGT (F ORTRAN 95) 326 * LGT (FORTRAN 77) 327 L INEARES G LEICHUNGSSYSTEM (LAPACK)328 LLE (F ORTRAN 95) 329 LLE (FORTRAN 77)330 LLT (F ORTRAN 95) 331 LLT (FORTRAN 77)332

320 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23S T R I N G L %E4 N G E %20 321 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23S O N S T I G E %20 322 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23L E X I K A L I S C H E %20F U N K T I O N E N %20 323 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23L E X I K A L I S C H E %20F U N K T I O N E N %20 324 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23L E X I K A L I S C H E %20F U N K T I O N E N %20 325 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23L E X I K A L I S C H E %20F U N K T I O N E N %20 326 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23L E X I K A L I S C H E %20F U N K T I O N E N %20 327 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23L E X I K A L I S C H E %20F U N K T I O N E N %20 328 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_LAPACK%20 329 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23L E X I K A L I S C H E %20F U N K T I O N E N %20 330 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23L E X I K A L I S C H E %20F U N K T I O N E N %20 331 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23L E X I K A L I S C H E %20F U N K T I O N E N %20 332 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23L E X I K A L I S C H E %20F U N K T I O N E N %20

662

M

• • • • • •

L OGARITHMUS (F ORTRAN 95)333 L OGARITHMUS (FORTRAN 77)334 LOGICAL (F ORTRAN 95) 335 LOGICAL (FORTRAN 77)336 L OGISCHE O PERATOREN (FORTRAN 77)337 .LT. (FORTRAN 77)338

98.21. M • • • • •

M AC OSX339 M ATRIXOPERATION340 M ATRIZENRECHNUNG (BLAS UND ATLAS)341 M ATRIZENRECHNUNG (F ORTRAN 95)342 MAX (F ORTRAN 95) 343

333 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23L O G A R I T H M U S %20 N A T U R A L I S %20 334 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23L O G A R I T H M U S %20 N A T U R A L I S %20 335 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23L O G I S C H E R %20D A T E N T Y P %20 336 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23L O G I S C H E R %20D A T E N T Y P %20 337 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23L O G I S C H E %20O P E R A T O R E N %20 338 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23V E R G L E I C H S O P E R A T O R E N %20 339 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_G95%

23U N I X -{} A R T I G E %20 I N K L .%20C Y G W I N %20 U N D %20M A C OSX%20 340 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

23E I G E N S C H A F T E N %20 341 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_BLAS_ATLAS%

20 342 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23V E K T O R E N -{}%20 U N D %20M A T R I Z E N R E C H N U N G %20 343 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M A X I M U M %20

663

Photran - Eine IDE für Fortran basierend auf Eclipse

• • • • • • • • • • • •

(F ORTRAN 95)344 MAX0 (FORTRAN 77)345 MAX 1 (F ORTRAN 95) 346 MAX1 (FORTRAN 77)347 M AXIMUM (FORTRAN 77)348 M AXIMUM (F ORTRAN 95)349 M EHRDIMENSIONALES F ELD (FORTRAN 77)350 M EHRDIMENSIONALES F ELD (F ORTRAN 95)351 MIN (F ORTRAN 95) 352 MIN 0 (F ORTRAN 95) 353 MIN0 (FORTRAN 77)354 MIN 1 (F ORTRAN 95) 355 MAX 0

344 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M A X I M U M %20 345 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23M A X I M U M %20 346 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M A X I M U M %20 347 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23M A X I M U M %20 348 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23M A X I M U M %20 349 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M A X I M U M %20 350 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23M E H R D I M E N S I O N A L E %20F E L D E R %20 351 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23M E H R D I M E N S I O N A L E %20F E L D E R %20 352 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M I N I M U M %20 353 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M I N I M U M %20 354 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23M I N I M U M %20 355 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M I N I M U M %20

664

N

• • • • • • • • •

MIN1 (FORTRAN 77)356 M INIMUM (F ORTRAN 95)357 M INIMUM (FORTRAN 77)358 MOD (F ORTRAN 95) 359 MOD (FORTRAN 77)360 M ODUL (F ORTRAN 95)361 M ODULO (FORTRAN 77)362 M ODULO (F ORTRAN 95)363 MODULE (F ORTRAN 95) 364

98.22. N • .NE. (FORTRAN 77)365 • .NEQV. (FORTRAN 77)366 356 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23M I N I M U M %20 357 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M I N I M U M %20 358 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23M I N I M U M %20 359 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M O D U L O %20 360 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23M O D U L O %20 361 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M O D U L E %20 362 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23M O D U L O %20 363 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M O D U L O %20 364 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M O D U L E %20 365 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23V E R G L E I C H S O P E R A T O R E N %20 366 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23L O G I S C H E %20O P E R A T O R E N %20

665

Photran - Eine IDE für Fortran basierend auf Eclipse

• • • • • • • •

.NEQV. (F ORTRAN 95)367 NINT (F ORTRAN 95) 368 NINT (FORTRAN 77)369 .NOT. (FORTRAN 77)370 .NOT. (F ORTRAN 95)371 NOT (F ORTRAN 95) 372 NULL (F ORTRAN 95) 373 NULLIFY (F ORTRAN 95) 374

98.23. O • O KTALZAHL (F ORTRAN 95)375 • OPEN (F ORTRAN 95)376 • OPEN (FORTRAN 77)377 367 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23L O G I S C H E %20O P E R A T O R E N %20 368 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23R U N D U N G %20 369 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23R U N D U N G %20 370 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23L O G I S C H E %20O P E R A T O R E N %20 371 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23L O G I S C H E %20O P E R A T O R E N %20 372 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23B I T F U N K T I O N E N %20 373 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23A S S O Z I A T I O N S S T A T U S %20 374 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23A S S O Z I A T I O N S S T A T U S %20 375 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23D A T E N T Y P E N %20 376 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 O P E N %20 377 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23OPEN%20

666

P

• • • •

O PERATORENPRIORITÄT (FORTRAN 77)378 O PERATORENPRIORITÄT (F ORTRAN 95)379 .OR. (FORTRAN 77)380 .OR. (F ORTRAN 95)381

98.24. P • • • • • • •

(F ORTRAN 95)382 PARAMETER (FORTRAN 77)383 PAUSE (FORTRAN 77)384 PARAMETER

PILIB 385

(F ORTRAN 95)386 P OSITIVE D IFFERENZ (FORTRAN 77)387 P ROZEDUR (PARAMETER , FORTRAN 77)388 POINTER

378 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23O P E R A T O R E N P R I O R I T %E4 T %20 379 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23O P E R A T O R E N P R I O R I T %E4 T %20 380 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23L O G I S C H E %20O P E R A T O R E N %20 381 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23L O G I S C H E %20O P E R A T O R E N %20 382 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23B E N A N N T E %20K O N S T A N T E N %20 383 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23B E N A N N T E %20K O N S T A N T E N %20 384 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23PAUSE%20 385 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_P I L I B %20 386 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23Z E I G E R %20 I N %20F O R T R A N %2095%20 387 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23P O S I T I V E %20D I F F E R E N Z %20 388 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23P R O Z E D U R E N %20 A L S %20P A R A M E T E R %20

667

Photran - Eine IDE für Fortran basierend auf Eclipse • P ROZEDUR (PARAMETER , F ORTRAN 95)389

98.25. Q • QUADRATWURZEL (FORTRAN 77)390

98.26. R • • • • • • •

R ATFOR391 READ (F ORTRAN 95) 392 READ (FORTRAN 77)393 REAL (F ORTRAN 95) 394 REAL (F UNKTION , F ORTRAN 95) 395 REAL (FORTRAN 77)396 REAL (F UNKTION , FORTRAN 77)397

389 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23P R O Z E D U R E N %20 A L S %20P A R A M E T E R %20 390 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23Q U A D R A T W U R Z E L %20 391 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

23V A R I A N T E N %20 392 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23 R E A D %20 393 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23READ%20 394 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23D A T E N T Y P E N %20 395 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23U M W A N D L U N G %20 I N %20REAL%20 396 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23A R I T H M E T I S C H E %20D A T E N T Y P E N %20 397 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23U M W A N D L U N G %20 I N %20REAL%20

668

S

• • • • • • • •

R EKURSIVER U NTERPROGRAMMAUFRUF (F ORTRAN 95)398 REPEAT (F ORTRAN 95) 399 "R EPEAT U NTIL "-S CHLEIFE (FORTRAN 77)400 RESHAPE (F ORTRAN 95) 401 RETURN (F ORTRAN 95) 402 RETURN (FORTRAN 77)403 RUNDUNG (FORTRAN 77)404 RUNDUNG (F ORTRAN 95)405

98.27. S • SAVE (FORTRAN 77)406 • SCAN (F ORTRAN 95)407 • S CHLEIFE (FORTRAN 77)408 398 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23R E K U R S I V E R %20U N T E R P R O G R A M M A U F R U F %20 399 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23S O N S T I G E %20 400 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23%22R E P E A T %20U N T I L %22-{}S C H L E I F E %20 401 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23M E H R D I M E N S I O N A L E %20F E L D E R %20%28 R E S H A P E %29%20 402 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 F U N C T I O N %20 403 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23FUNCTION%20 404 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23R U N D U N G %20 405 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23R U N D U N G %20 406 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23SAVE%20 407 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23S O N S T I G E %20 408 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23V E R Z W E I G U N G E N %20 U N D %20S C H L E I F E N %20

669

Photran - Eine IDE für Fortran basierend auf Eclipse

• • • • • • • • • • •

S CHLEIFE (F ORTRAN 95)409 SELECT CASE (F ORTRAN 95) 410 SELECTED _ REAL _ KIND (F ORTRAN 95) 411 S EQUENTIELLE D ATEI (FORTRAN 77)412 S EQUENTIELLE D ATEI (F ORTRAN 95)413 SIGN (F ORTRAN 95) 414 SIGN (FORTRAN 77)415 SIN (F ORTRAN 95) 416 SIN (FORTRAN 77)417 SINH (F ORTRAN 95) 418 SINH (FORTRAN 77)419

409 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23V E R Z W E I G U N G E N %20 U N D %20S C H L E I F E N %20 410 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 S E L E C T %20 C A S E -{}V E R Z W E I G U N G %20 411 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 S E L E C T E D _ R E A L _ K I N D %20 412 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

413

414 415 416 417 418 419

670

2077%23P O S I T I O N I E R E N %20 B E I %20 S E Q U E N T I E L L E N % 20D A T E I E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23P O S I T I O N I E R E N %20 B E I %20 S E Q U E N T I E L L E N % 20D A T E I E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23V O R Z E I C H E N T R A N S F E R %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23V O R Z E I C H E N T R A N S F E R %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23W I N K E L F U N K T I O N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23W I N K E L F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23H Y P E R B E L F U N K T I O N E N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77% 23H Y P E R B E L F U N K T I O N E N %20

S

• • • • • • • • • • •

(F ORTRAN 95)420 SNGL (F ORTRAN 95) 421 SNGL (FORTRAN 77)422 S PALTENORGANISATION423 SQRT (F ORTRAN 95) 424 SQRT (FORTRAN 77)425 S TANDARDFUNKTION (FORTRAN 77)426 S TANDARDFUNKTION (F ORTRAN 95)427 S TATISCHE S PEICHERALLOKATION (F ORTRAN 95)428 STOP (F ORTRAN 95) 429 STOP (FORTRAN 77)430 SIZE

420 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23F E L D F U N K T I O N E N %20 421 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23U M W A N D L U N G %20 I N %20REAL%20 422 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23U M W A N D L U N G %20 I N %20REAL%20 423 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23D A S %20Z E I L E N F O R M A T %20 424 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23Q U A D R A T W U R Z E L %20 425 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23Q U A D R A T W U R Z E L %20 426 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

427

428 429 430

2077%23S T A N D A R D F U N K T I O N E N %20%28 I N T R I N S I C % 20 F U N C T I O N S %29%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23S T A N D A R D F U N K T I O N E N %20%28 I N T R I N S I C % 20 F U N C T I O N S %29%20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95% 23S T A T I S C H E %20S P E I C H E R A L L O K A T I O N %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N % 2095%23 S T O P %20 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN% 2077%23STOP%20

671

Photran - Eine IDE für Fortran basierend auf Eclipse

• • • • • • • •

S TRINGVERKNÜPFUNG (FORTRAN 77)431 S TRINGVERKNÜPFUNG (F ORTRAN 95)432 S TRINGFUNKTIONEN (FORTRAN 77)433 S TRINGFUNKTIONEN (F ORTRAN 95)434 SUBROUTINE (F ORTRAN 95) 435 SUBROUTINE (FORTRAN 77)436 S YMBOLISCHE N AMEN (FORTRAN 77)437 S YMBOLISCHE N AMEN (F ORTRAN 95)438

98.28. T • TAN (F ORTRAN 95)439 • TAN (FORTRAN 77)440 • TANH (F ORTRAN 95)441 431 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23V E R K N %FC P F U N G S O P E R A T O R %20 432 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23V E R K N %FC P F U N G S O P E R A T O R %20 433 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23S T R I N G F U N K T I O N E N %20 434 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23S T R I N G F U N K T I O N E N %20 435 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 S U B R O U T I N E %20 436 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23SUBROUTINE%20 437 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23S Y M B O L I S C H E %20N A M E N %20 438 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23S Y M B O L I S C H E %20N A M E N %20 439 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23W I N K E L F U N K T I O N %20 440 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23W I N K E L F U N K T I O N E N %20 441 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23H Y P E R B E L F U N K T I O N E N %20

672

U

• • • • • • • • •

TANH (FORTRAN 77)442 TARGET (F ORTRAN 95) 443 T CL /T K (F ORTRAN UND T CL )444 T EILFELD (F ORTRAN 95)445 T EILKETTE (FORTRAN 77)446 T EILKETTE (F ORTRAN 95)447 TRANSPOSE (F ORTRAN 95) 448 TRIM (F ORTRAN 95) 449 TYPE (F ORTRAN 95) 450

98.29. U • UBOUND (F ORTRAN 95)451 • UNIT (FORTRAN 77)452 442 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23H Y P E R B E L F U N K T I O N E N %20 443 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23Z E I G E R %20 I N %20F O R T R A N %2095%20 444 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _ U N D _T C L %20

445 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23T E I L F E L D E R %20 446 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23T E I L K E T T E N %20 447 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23T E I L K E T T E N %20 448 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23V E K T O R E N -{}%20 U N D %20M A T R I Z E N R E C H N U N G %20 449 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23S O N S T I G E %20 450 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23D A T E N V E R B U N D %20 451 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23F E L D F U N K T I O N E N %20 452 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23UNIT%20

673

Photran - Eine IDE für Fortran basierend auf Eclipse • U NTERPROGRAMM (FORTRAN 77)453 • U NTERPROGRAMM (F ORTRAN 95)454 • USE (F ORTRAN 95)455

98.30. V • • • • • • • •

VARIABLE (FORTRAN 77)456 VARIABLE (F ORTRAN 95)457 V EKTOROPERATION458 V EKTORRECHNUNG (BLAS UND ATLAS)459 V EKTORRECHNUNG (F ORTRAN 95)460 V ERGLEICHSOPERATOR (FORTRAN 77)461 V ERGLEICHSOPERATOR (F ORTRAN 95)462 VERIFY (F ORTRAN 95) 463

453 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23U N T E R P R O G R A M M E %20 454 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23U N T E R P R O G R A M M E %20 455 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23M O D U L E %20 456 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23V A R I A B L E N %20 457 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23V A R I A B L E N %20 458 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

23E I G E N S C H A F T E N %20 459 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_BLAS_ATLAS%

20 460 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23V E K T O R E N -{}%20 U N D %20M A T R I Z E N R E C H N U N G %20 461 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23V E R G L E I C H S O P E R A T O R E N %20 462 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23V E R G L E I C H S O P E R A T O R E N %20 463 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23S O N S T I G E %20

674

W

• • • • •

V ERKETTETE L ISTE (F ORTRAN 95)464 V ERZWEIGUNG (FORTRAN 77)465 V ERZWEIGUNG (F ORTRAN 95)466 V ORZEICHENTRANSFER (FORTRAN 77)467 V ORZEICHENTRANSFER (F ORTRAN 95)468

98.31. W • WHERE - ELSEWHERE -S CHLEIFE (F ORTRAN 95)469 • WHERE -S CHLEIFE (F ORTRAN 95)470 • "W HILE "-S CHLEIFE (FORTRAN 77)471 • W INKELFUNKTION (FORTRAN 77)472 • W INKELFUNKTION (F ORTRAN 95)473 • WRITE (F ORTRAN 95)474 464 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23V E R K E T T E T E %20L I S T E N %20 465 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23V E R Z W E I G U N G E N %20 U N D %20S C H L E I F E N %20 466 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23V E R Z W E I G U N G E N %20 U N D %20S C H L E I F E N %20 467 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23V O R Z E I C H E N T R A N S F E R %20 468 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23V O R Z E I C H E N T R A N S F E R %20 469 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 W H E R E -{} E L S E W H E R E %20 470 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23 W H E R E -{}S C H L E I F E %20 471 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23%22W H I L E %22-{}S C H L E I F E %20 472 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN%

2077%23W I N K E L F U N K T I O N E N %20 473 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23W I N K E L F U N K T I O N %20 474 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23 W R I T E %20

675

Photran - Eine IDE für Fortran basierend auf Eclipse • WRITE (FORTRAN 77)475

98.32. X 98.33. Y 98.34. Z • • • • • • •

Z EICHENVORRAT (FORTRAN 77)476 Z EICHENVORRAT (F ORTRAN 95)477 Z EIGER (F ORTRAN 95)478 Z EIGERFUNKTIONEN (F ORTRAN 95)479 Z EILENFORMAT (E INLEITUNG )480 Z EILENFORMAT (FORTRAN 77)481 Z EILENFORMAT (F ORTRAN 95)482

475 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23WRITE%20 476 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23D E R %20FORTRAN-{}Z E I C H E N V O R R A T %20 477 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23D E R %20F O R T R A N -{}Z E I C H E N V O R R A T %20 478 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23Z E I G E R %20 479 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N %

2095%23Z E I G E R F U N K T I O N E N %20 480 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_E I N L E I T U N G %

23V E R S I O N E N %20 481 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_FORTRAN_77%

23D A S %20Z E I L E N F O R M A T %20 482 H T T P :// D E . W I K I B O O K S . O R G / W I K I /F O R T R A N %3A_F O R T R A N _95%

23D A S %20Z E I L E N F O R M A T %20

676

99. Autoren Edits 7 2 31 1 1 1 3 391 3 1 2 3 4 5 6 7 8 9

User A KKORDEON1 C OMMONS D ELINKER2 D IRK H UENNIGER3 F ILE P ETER4 F ORTRANPLUS5 H EFTIGINDENAFTER6 H EULER 067 I NTRUDER8 J UETHO9

H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : AK K O R D E O N H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : CO M M O N SDE L I N K E R H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : D I R K _H U E N N I G E R H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : FI L EPE T E R H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : FO R T R A N P L U S H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : HE F T I G I N D E N A F T E R H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : H E U L E R 06 H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : IN T R U D E R H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : JU E T H O

677

Autoren

2 1 46 1 1 5 19

10 11 12 13 14 15 16

678

K LAUS E IFERT10 L OEHDEN11 M ICHAEL F REY12 P HILIPENDULA13 S ALATGURKE14 T HE PACKER15 T HORNARD16

H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : K L A U S _E I F E R T H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : LO E H D E N H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : MI C H A E LFR E Y H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : PH I L I P E N D U L A H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : SA L A T G U R K E H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : TH EPA C K E R H T T P :// D E . W I K I B O O K S . O R G / W / I N D E X . P H P ? T I T L E =B E N U T Z E R : TH O R N A R D

100. Bildnachweis In der nachfolgenden Tabelle sind alle Bilder mit ihren Autoren und Lizenen aufgelistet. Für die Namen der Lizenzen wurden folgende Abkürzungen verwendet: • GFDL: Gnu Free Documentation License. Der Text dieser Lizenz ist in einem Kapitel diese Buches vollständig angegeben. • cc-by-sa-3.0: Creative Commons Attribution ShareAlike 3.0 License. Der Text dieser Lizenz kann auf der Webseite http://creativecommons.org/licenses/by-sa/3.0/ nachgelesen werden. • cc-by-sa-2.5: Creative Commons Attribution ShareAlike 2.5 License. Der Text dieser Lizenz kann auf der Webseite http://creativecommons.org/licenses/by-sa/2.5/ nachgelesen werden. • cc-by-sa-2.0: Creative Commons Attribution ShareAlike 2.0 License. Der Text der englischen Version dieser Lizenz kann auf der Webseite http://creativecommons.org/licenses/bysa/2.0/ nachgelesen werden. Mit dieser Abkürzung sind jedoch auch die Versionen dieser Lizenz für andere Sprachen bezeichnet. Den an diesen Details interessierten Leser verweisen wir auf die Onlineversion dieses Buches.

679

Bildnachweis

• cc-by-sa-1.0: Creative Commons Attribution ShareAlike 1.0 License. Der Text dieser Lizenz kann auf der Webseite http://creativecommons.org/licenses/by-sa/1.0/ nachgelesen werden. • cc-by-2.0: Creative Commons Attribution 2.0 License. Der Text der englischen Version dieser Lizenz kann auf der Webseite http://creativecommons.org/licenses/by/2.0/ nachgelesen werden. Mit dieser Abkürzung sind jedoch auch die Versionen dieser Lizenz für andere Sprachen bezeichnet. Den an diesen Details interessierten Leser verweisen wir auf die Onlineversion dieses Buches. • cc-by-2.0: Creative Commons Attribution 2.0 License. Der Text dieser Lizenz kann auf der Webseite http://creativecommons.org/licenses/by/2.0/deed.en nachgelesen werden. • cc-by-2.5: Creative Commons Attribution 2.5 License. Der Text dieser Lizenz kann auf der Webseite http://creativecommons.org/licenses/by/2.5/deed.en nachgelesen werden. Mit dieser Abkürzung sind jedoch auch die Versionen dieser Lizenz für andere Sprachen bezeichnet. Den an diesen Details interessierten Leser verweisen wir auf die Onlineversion dieses Buches. • cc-by-3.0: Creative Commons Attribution 3.0 License. Der Text dieser Lizenz kann auf der Webseite http://creativecommons.org/licenses/by/3.0/deed.en nachgelesen werden. Mit dieser Abkürzung sind jedoch auch die Versionen dieser Lizenz für andere Sprachen bezeichnet. Den an diesen Details interessierten Leser verweisen wir auf die Onlineversion dieses Buches. • GPL: GNU General Public License Version 2. Der Text dieser Lizenz kann auf der Webseite

680

Z

http://www.gnu.org/licenses/gpl-2.0.txt werden.

nachgelesen

• PD: This image is in the public domain. Dieses Bild ist gemeinfrei.

• ATTR: The copyright holder of this file allows anyone to use it for any purpose, provided that the copyright holder is properly attributed. Redistribution, derivative work, commercial use, and all other use is permitted.

• EURO: This is the common (reverse) face of a euro coin. The copyright on the design of the common face of the euro coins belongs to the European Commission. Authorised is reproduction in a format without relief (drawings, paintings, films) provided they are not detrimental to the image of the euro.

• LFK: Lizenz Freie Kunst. Der Text dieser Lizenz kann auf der Webseite http://artlibre.org/licence/lal/de nachgelesen werden.

• CFR: Copyright free use. Der Urheberrechtsinhaber erlaubt es jedem, dieses Bild für jeglichen Zweck, inklusive uneingeschränkter Weiterveröffentlichung, kommerziellem Gebrauch und Modifizierung, zu nutzen.

• EPL: Eclipse Public License. Der Text dieser Lizenz kann auf der Webseite http://www.eclipse.org/org/documents/eplv10.php nachgelesen werden.

681

Bildnachweis

Bild 1 2

3 4 5 6 7 8 9 10 11 12 13 14 15 16

1 2 3 4 5 6 7 8

682

Autor = • SVG: • commons: S HAZZ1 • pl.wiki: S HAZZ2 • Bitmap project by: • pl.wiki B ORKOWSK3 - W. Borkowski == {{int:filedesc S URACHIT4

Courtesy of the Naval Surface Warfare Center, Dahlgren, VA., 1988. S IRIUS B5 Arnold Reinhold

A RT. L EBEDEV S TUDIO6 Original uploader was O RIGINAL G AMER7 at EN . WIKIPEDIA 8

Lizenz PD GFDL

GFDL PD PD PD PD PD PD PD PD GFDL cc-by-sa2.5 PD PD PD

H T T P :// D E . W I K I B O O K S . O R G / W I K I / U S E R %3AS H A Z Z H T T P :// D E . W I K I P E D I A . O R G / W I K I / P L %3A U S E R %3AS H A Z Z H T T P :// D E . W I K I P E D I A . O R G / W I K I / P L %3A U S E R %3AB O R K O W S K H T T P :// D E . W I K I B O O K S . O R G / W I K I /U S E R %3AS U R A C H I T H T T P :// D E . W I K I B O O K S . O R G / W I K I /U S E R %3AS I R I U S B H T T P :// W W W . A R T L E B E D E V . C O M / H T T P :// D E . W I K I B O O K S . O R G / W I K I /%3A E N %3AU S E R % 3AO R I G I N A L G A M E R H T T P :// E N . W I K I P E D I A . O R G

Z

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

9 10 11 12 13 14 15

R ATOPI9 User A RPINGSTONE10 on EN . WIKIPEDIA11 J AILBIRD12

S TEPHAN B AUM13 (recolored by M ZAJAC14 , converted to SVG by B OOYABAZOOKA15 )

Leipnizkeks User:Petwoe on German Wikipedia Intruder Intruder

GFDL PD cc-by-sa2.0 PD GFDL PD PD PD PD PD PD PD PD PD PD GFDL PD GFDL GFDL PD GFDL PD PD PD PD

H T T P :// D E . W I K I B O O K S . O R G / W I K I /%3A D E %3AU S E R %3AR A T O P I H T T P :// D E . W I K I B O O K S . O R G / W I K I /%3A E N %3AU S E R % 3AA R P I N G S T O N E H T T P :// E N . W I K I P E D I A . O R G H T T P :// D E . W I K I B O O K S . O R G / W I K I /U S E R %3AJ A I L B I R D H T T P :// D E . W I K I B O O K S . O R G / W I K I /U S E R %3AB A U M S T H T T P :// D E . W I K I B O O K S . O R G / W I K I /%3A E N %3AU S E R %3AM Z A J A C H T T P :// D E . W I K I B O O K S . O R G / W I K I /U S E R %3AB O O Y A B A Z O O K A

683

Bildnachweis

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71

16

684

M ESSER W OLAND16 Intruder Intruder Intruder

Intruder

MASA Thunderbolt No.999

PD PD PD PD PD GFDL GFDL GFDL GFDL PD PD GFDL PD PD PD PD PD PD PD PD PD PD PD PD PD PD PD PD GFDL EPL

H T T P :// D E . W I K I B O O K S . O R G / W I K I / U S E R %3AM E S S E R W O L A N D