You are on page 1of 197

Universit Pierre et Marie Curie

Paris VI

Master de Sciences et Technologies :


Mention Physique et Applications
Mention Sciences de lUnivers,
Environnement, cologie
Mthodes numriques et informatiques :
programmation

Introduction
au fortran
90/95/2003

Avertissement
Ce document est diffus dans une version en volution, qui reste encore trs inacheve, notamment
concernant les apports du fortran 2003. Plusieurs chapitres ne sont que des bauches, en particulier
ceux sur les structures, les pointeurs et linteroprabilit avec le C ; dautres questions sont peine
abordes. Lobjectif reste de complter progressivement le document.
Dans ce contexte, je vous remercie par avance de me signaler les erreurs aussi bien que les formulations
obscures. Vos commentaires et suggestions seront les bienvenus.
Jacques.Lefrere@upmc.fr

10 novembre 2015

ii

Remerciements
Je tiens remercier mes collgues enseignants de la Matrise de Physique et Applications
de lUniversit Pierre et Marie Curie, Paris VI, Marie-Claude et Jean-Claude Justice, Michel
Karatchenzeff, Ma Pham, ainsi que mes collgues du M1 du Master de lUPMC, Albert
Hertzog, Philippe Sindzingre et Franois Ravetta, pour leurs encouragements et leurs conseils
au cours de la rdaction de ce document.
Je remercie aussi Marie-Alice Foujols de lInstitut Pierre Simon Laplace pour ses sminaires
enthousiastes qui nous ont sensibiliss au fortran 90.
Merci aussi aux collgues du Service daronomie pour les nombreuses discussions au sujet
du fortran au sein du laboratoire, et en particulier Franoise Pinsard, Francis Dalaudier et
Stphane Marchand pour leurs patientes relectures critiques.
Je remercie aussi Frdric Bernardo sans lequel le chapitre sur linter-oprabilit avec le
langage C naurait pas vu le jour.
Merci enfin tous ceux qui ont contribu de prs ou de loin llaboration de ce document, et
surtout aux tudiants de la Matrise de Physique et Applications de Paris VI, puis ceux du M1
du Master (mentions P&A et SDUEE) de lUPMC, car cest avant tout pour eux mais aussi grce
eux quil a t rdig.

Ce document a t mis en page grce au traitement de texte LATEX.

iii

Notations
La police machine crire , espacement fixe, est utilise pour indiquer les lments du
code source du fortran.
Les crochets [. . . ] dlimitent les lments optionnels de la syntaxe ou les arguments optionnels des procdures ; ces symboles ne font pas partie de la syntaxe.
Lors de la description de la syntaxe, les symboles < et > indiquent o lutilisateur doit substituer les identificateurs, expressions, ou valeurs quil a choisis ; ces symboles ne font pas partie
de la syntaxe.
Exemple
La syntaxe dcrite comme suit :

[<nom > :] IF (<expression logique >) THEN


<bloc d'instructions >
END IF [<nom >]
peut tre utilise comme dans lexemple suivant, o lidentificateur chiffre est optionnel :
chiffre: IF (i < 10) THEN
WRITE(*,*) 'i est infrieur 10'
END IF chiffre

Indications de lecture

0.0.0 Sous-section facultative


Les sections (ou sous-sections) qui peuvent tre omises en premire lecture sont indiques par
le symbole plac gauche du titre de la section comme ci-dessus.

f95

0.0.0 Sous-section nouveaut f95


Les sections (ou sous-sections) qui font intervenir des nouveauts des standards 95, 2003 ou
2008 du fortran sont indiques par le symbole f95, f2003 ou f2008 plac gauche du titre de la
section comme ci-dessus.
Sil sagit de quelques points spcifiques dun standard, par exemple le standard 2008, le para- f2008
graphe est identifi par le symbole f2008 plac dans la marge extrieure du texte, comme pour ce
paragraphe.

Conseils pratiques
Les rgles de bon usage du langage, qui, au del de la norme, sont motives par des objectifs
de lisibilit, de portabilit ou de robustesse du code source, sont repres par le symbole dans la
marge extrieure du texte, comme pour ce paragraphe.

Difficults
Les points prsentant des difficults particulires ou des risques derreur sont indiqus par le B
symbole B dans la marge extrieure du texte, comme pour ce paragraphe.

iv

Avertissement
Ce document nest pas un manuel de rfrence du fortran 90/95/2003 dcrivant exhaustivement la norme du langage. Il sagit dun document largement inspir des rfrences cites dans
la bibliographie, rfrences auxquelles il est vivement conseill de se reporter pour une tude plus
approfondie ou plus systmatique. Incomplet, notamment sur certains aspects les plus rcents du
fortran, il sapparente plus un guide de lutilisateur du fortran pour le calcul scientifique. Il
sadresse essentiellement des tudiants ayant dj une exprience de la programmation dans un
langage structur (fortran ou C) souhaitant sinitier aux nouvelles fonctionnalits du langage
partir du fortran 90, notamment :
la notation tableaux, les oprateurs et fonctions manipulant globalement des tableaux multidimensionnels,
lallocation dynamique, les types drivs et les pointeurs,
le contrle des passages darguments entre procdures via les modules.

Prsentation
Aprs un chapitre 1 introductif (p. 1) prsentant lvolution du fortran, les tapes de mise au
point des programmes et les lments du langage, le chapitre 2 (p. 10) dcrit les types dobjets
du langage et leurs attributs, en particulier numriques, avant daborder au chapitre 3 (p. 21) les
oprateurs qui permettent de les manipuler.
Le chapitre 4 (p. 26) est entirement consacr aux structures de contrle du fortran : cest un
chapitre essentiel et facile qui doit tre tudi ds la premire lecture.
Le chapitre 5 entres-sorties (p. 35) aborde les instructions de lecture et dcriture et les formats
de conversion des donnes : il est conseill de commencer par les sections dintroduction et de
terminologie, quitte revenir ensuite sur la description dtaille des instructions et surtout des
formats, pour laquelle des allers et retours avec les sections dexemples ainsi quavec le chapitre 8
(p. 94) sur les chanes de caractres sont ncessaires.
Le chapitre 6 intitul procdures (p. 57) constitue le deuxime thme majeur du document : il
prsente les fonctions et les sous-programmes en partant de la notion de procdure interne attache
un programme pour aboutir aux procdures de module rutilisables grce la compilation spare.
La dernire section (6.5) abordant les fonctionnalits avances peut tre passe en premire lecture.
Le troisime thme majeur du fortran, les tableaux, fait lobjet du chapitre 7 (p. 79) : il constitue latout principal du fortran 90 pour le calcul scientifique avec lintroduction des notations
matricielles et des fonctions intrinsques manipulant les tableaux multidimensionnels. Ce chapitre
essentiel peut tre abord en deux tapes : la premire lecture doit inclure lallocation dynamique
ainsi que le lien entre procdures et tableaux, mais on peut garder pour une deuxime lecture les
notions de sections non-rgulires, les masques et la structure FORALL.
Le chapitre 8 (p. 94) prsente la manipulation des chanes de caractres et les fonctions associes : cest un chapitre facile, mme sil nest pas central pour les applications au calcul scientifique.
Les chapitres 9 sur les types drivs (p. 102), 10 sur la gnricit (p. 111) et 11 sur les pointeurs
(p. 118) prsentent des fonctionnalits orientes objet du fortran, et peuvent tre rservs une
deuxime lecture. Quant au chapitre 12 (p. 129), qui prsente les techniques dappel de fonctions
crites en C depuis le fortran et rciproquement, il peut intresser des non-spcialistes du fortran
pour linterfacer avec le langage C.
Enfin, les annexes ont plus vocation servir de rfrence qu tre lues de faon linaire, mme
sil est utile de les parcourir pour connatre leur existence. Cela vaut par exemple pour la liste
des fonctions intrinsques du fortran (A, p. 138) quitte revenir au document ponctuellement
pour vrifier une syntaxe dappel. De la mme faon, parcourir lannexe C, p. 154 sur la norme
IEEE de reprsentation des nombres rels permet de visualiser concrtement les approximations
des calculs en machine. Par ailleurs, les utilisateurs du langage C pourront trouver dans lannexe D,
p. 160, un aide-mmoire prsentant une comparaison approximative des syntaxes et fonctions des
deux langages. Pour terminer, lannexe E, p. 165 fournit de brves indications sur lutilisation de
quelques compilateurs.

Table des matires


Notations . .
Indications de
Avertissement
Prsentation .

. . . . .
lecture
. . . . .
. . . . .

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

Table des matires

iii
iii
iv
iv
v

1 Introduction
1.1 Historique du fortran . . . . . . . . . . . . . .
1.2 Les tapes de mise en uvre dun programme
1.2.1 dition du fichier source . . . . . . . .
1.2.2 Compilation et dition de liens . . . .
1.2.3 Excution . . . . . . . . . . . . . . . .
1.2.4 Cas des fichiers sources multiples . . .
1.3 Les lments du langage . . . . . . . . . . . .
1.3.1 Les caractres du fortran . . . . . . .
1.3.2 Les identificateurs des objets . . . . .
1.4 Les formats du code source fortran . . . . . .
1.4.1 Format fixe . . . . . . . . . . . . . . .
1.4.2 Format libre du fortran 90 . . . . . . .

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

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

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

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

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

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

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

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

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

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

2 Types, constantes et variables


2.1 Les types intrinsques . . . . . . . . . . . . . . . . . . . . . . .
2.2 La reprsentation des types numriques . . . . . . . . . . . . .
2.2.1 Reprsentation des entiers . . . . . . . . . . . . . . . . .
2.2.2 Reprsentation des rels en virgule flottante . . . . . . .
2.2.3 Domaine et prcision des types numriques . . . . . . .
2.3 Dclaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.4 Les constantes . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5 Initialisation . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5.1 Les constantes nommes (ou symboliques), . . . . . . .
2.5.2 Variantes des types prdfinis . . . . . . . . . . . . . . .
2.5.3 Exemples de constantes nommes spcifiant les variantes
2.5.4 Une mthode modulaire pour fixer la prcision des rels
2.6 Fonctions de conversion de type . . . . . . . . . . . . . . . . . .

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

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

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

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

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

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

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

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

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

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

. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
des types prdfinis
. . . . . . . . . . .
. . . . . . . . . . .

3 Oprateurs et expressions
3.1 Les oprateurs numriques . . . . . . . . . . . . . . . . . . . . . . .
3.1.1 Rgles de priorit entre les oprateurs numriques binaires .
3.1.2 Imperfections numriques des oprations lies aux types . .
3.1.3 Conversions implicites . . . . . . . . . . . . . . . . . . . . .
3.2 Les oprateurs de comparaison . . . . . . . . . . . . . . . . . . . .
3.3 Les oprateurs boolens . . . . . . . . . . . . . . . . . . . . . . . .
3.4 Oprateur de concatnation des chanes de caractres . . . . . . . .
3.5 Priorits entre les oprateurs . . . . . . . . . . . . . . . . . . . . .
v

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

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

1
1
2
3
3
5
5
6
6
7
7
7
8
10
10
10
10
12
14
16
17
17
18
18
19
19
20
21
21
21
21
22
23
24
25
25

vi

TABLE DES MATIRES

4 Structures de contrle
4.1 Structures IF . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.1.1 Linstruction IF . . . . . . . . . . . . . . . . . . . . .
4.1.2 La structure IF ... END IF . . . . . . . . . . . . . .
4.1.3 Utilisation du ELSE IF . . . . . . . . . . . . . . . . . .
4.2 Structure SELECT CASE . . . . . . . . . . . . . . . . . . . . .
4.3 Structures de boucles . . . . . . . . . . . . . . . . . . . . . . .
4.3.1 Boucles DO avec compteur . . . . . . . . . . . . . . . .
4.3.2 Boucles DO WHILE . . . . . . . . . . . . . . . . . . . .
4.3.3 Ruptures de squence dans les boucles : EXIT et CYCLE
4.3.4 Boucles DO sans compteur . . . . . . . . . . . . . . . .
4.4 La structure BLOCK . . . . . . . . . . . . . . . . . . . . . . . .
4.5 Sortie de structure quelconque avec linstruction EXIT nomm
4.6 Autres instructions de contrle . . . . . . . . . . . . . . . . .
4.6.1 Instruction CONTINUE . . . . . . . . . . . . . . . . . .
4.6.2 Branchement par GO TO . . . . . . . . . . . . . . . . .
4.6.3 Instruction STOP . . . . . . . . . . . . . . . . . . . . .
4.6.4 Instruction RETURN . . . . . . . . . . . . . . . . . . . .
4.6.5 Remarques sur les instructions STOP et RETURN . . . .
4.6.6 Branchements dans les entres-sorties . . . . . . . . .

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

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

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

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

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

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

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

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

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

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

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

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

26
26
26
26
27
27
29
29
29
30
31
31
32
32
32
32
33
33
34
34

5 Entressorties, fichiers
5.1 Introduction : entres et sorties standard . . . . . . . .
5.1.1 Une instruction dE/S = un enregistrement . .
5.1.2 Saisie de donnes au clavier . . . . . . . . . . .
5.2 Gnralits et terminologie . . . . . . . . . . . . . . .
5.2.1 Fichiers externes et fichiers internes . . . . . .
5.2.2 Notion denregistrement . . . . . . . . . . . . .
5.2.3 Fichiers formats et fichiers non formats . . .
5.2.4 Mthodes daccs aux donnes . . . . . . . . .
5.2.5 Notion de liste dentre-sortie . . . . . . . . . .
5.3 Instructions dentres-sorties . . . . . . . . . . . . . .
5.3.1 Le module intrinsque ISO_FORTRAN_ENV . . .
5.3.2 OPEN . . . . . . . . . . . . . . . . . . . . . . . .
5.3.3 CLOSE . . . . . . . . . . . . . . . . . . . . . . .
5.3.4 READ . . . . . . . . . . . . . . . . . . . . . . . .
5.3.5 WRITE . . . . . . . . . . . . . . . . . . . . . . .
5.3.6 PRINT . . . . . . . . . . . . . . . . . . . . . . .
5.3.7 INQUIRE . . . . . . . . . . . . . . . . . . . . . .
5.3.8 Instructions de positionnement dans les fichiers
5.3.9 Entres-sorties sans avancement automatique .
5.4 Descripteurs de format . . . . . . . . . . . . . . . . . .
5.4.1 Descripteurs actifs . . . . . . . . . . . . . . . .
5.4.2 Descripteurs de contrle . . . . . . . . . . . . .
5.4.3 Syntaxe des formats et rgles dexploration . .
5.4.4 Boucles et changements denregistrement . . .
5.4.5 Format variable . . . . . . . . . . . . . . . . . .
5.5 Exemples dentres-sorties formates . . . . . . . . . .
5.5.1 Descripteurs de donnes numriques en criture
5.5.2 Descripteurs de contrle en criture . . . . . .
5.6 Exemples de fichiers en accs direct . . . . . . . . . . .
5.6.1 Exemple de fichier format en accs direct . .
5.6.2 Exemple de fichier non-format en accs direct

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

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

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

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

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

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

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

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

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

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

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

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

35
35
35
36
37
37
38
38
39
40
41
41
42
44
44
45
45
45
46
47
47
48
49
50
50
51
52
52
53
54
54
55

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

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

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

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

vii

TABLE DES MATIRES

6 Procdures
6.1 Introduction . . . . . . . . . . . . . . . . . . . . . .
6.1.1 Intrt des procdures . . . . . . . . . . . .
6.1.2 Variables locales, automatiques et statiques
6.1.3 Arguments des procdures . . . . . . . . . .
6.1.4 Lattribut INTENT des arguments . . . . . .
6.2 Sous-programmes et fonctions . . . . . . . . . . . .
6.2.1 Sous-programmes . . . . . . . . . . . . . . .
6.2.2 Fonctions . . . . . . . . . . . . . . . . . . .
6.3 Procdures internes et procdures externes . . . . .
6.3.1 Procdures internes : CONTAINS . . . . . . .
6.3.2 Procdures externes . . . . . . . . . . . . .
6.3.3 La notion dinterface . . . . . . . . . . . . .
6.4 Les modules . . . . . . . . . . . . . . . . . . . . . .
6.4.1 Exemple de procdure de module . . . . . .
6.4.2 Partage de donnes via des modules . . . .
6.4.3 lments dencapsulation . . . . . . . . . .
6.4.4 Linstruction IMPORT dans les interfaces . .
6.4.5 Modules intrinsques . . . . . . . . . . . . .
6.5 Fonctionnalits avances . . . . . . . . . . . . . . .
6.5.1 Arguments optionnels . . . . . . . . . . . .
6.5.2 Transmission darguments par mot-clef . . .
6.5.3 Noms de procdures passs en argument . .
6.5.4 La dclaration PROCEDURE . . . . . . . . . .
6.5.5 Interfaces abstraites . . . . . . . . . . . . .
6.5.6 Procdures rcursives . . . . . . . . . . . .
6.5.7 Procdures pures . . . . . . . . . . . . . . .
6.5.8 Procdures lmentaires . . . . . . . . . . .

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

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

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

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

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

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

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

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

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

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

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

57
57
57
58
58
59
59
60
61
61
62
63
63
64
64
65
67
69
69
69
69
70
71
74
74
76
78
78

7 Tableaux
7.1 Gnralits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.1 Terminologie des tableaux . . . . . . . . . . . . . . . . . .
7.1.2 Ordre des lments dans un tableau multidimensionnel . .
7.1.3 Constructeurs de tableaux . . . . . . . . . . . . . . . . . .
7.2 Sections de tableaux . . . . . . . . . . . . . . . . . . . . . . . . .
7.2.1 Sections rgulires . . . . . . . . . . . . . . . . . . . . . .
7.2.2 Sections non-rgulires . . . . . . . . . . . . . . . . . . . .
7.3 Oprations sur les tableaux . . . . . . . . . . . . . . . . . . . . .
7.3.1 Extension des oprations lmentaires aux tableaux . . .
7.3.2 Instruction et structure WHERE . . . . . . . . . . . . . . .
7.3.3 Affectation dune section non-rgulire . . . . . . . . . . .
7.4 Fonctions intrinsques particulires aux tableaux . . . . . . . . .
7.4.1 Fonctions dinterrogation . . . . . . . . . . . . . . . . . .
7.4.2 Fonctions de rduction . . . . . . . . . . . . . . . . . . . .
7.4.3 Fonctions de transformation . . . . . . . . . . . . . . . . .
7.4.4 Notion de masque . . . . . . . . . . . . . . . . . . . . . .
7.4.5 ALL, ANY, COUNT . . . . . . . . . . . . . . . . . . . . . . . .
7.4.6 Instruction et structure FORALL . . . . . . . . . . . . . . .
7.5 Tableaux, procdures et allocation dynamique . . . . . . . . . . .
7.5.1 Les trois mthodes dallocation des tableaux . . . . . . .
7.5.2 Tableaux en arguments muets des procdures . . . . . . .
7.5.3 Tableaux dynamiques allouables . . . . . . . . . . . . . .
7.5.4 Allocation au vol de tableaux dynamiques par affectation

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

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

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

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

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

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

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

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

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

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

79
79
79
80
81
81
82
82
83
83
84
84
85
85
85
86
88
88
88
89
89
90
91
93

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

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

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

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

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

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

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

viii

TABLE DES MATIRES

8 Chanes de caractres
8.1 Le type chane de caractres . . . . . . . . . . . . . . . . . . . . . . . . .
8.1.1 Les constantes chanes de caractres . . . . . . . . . . . . . . . .
8.1.2 Les dclarations de chanes de caractres . . . . . . . . . . . . . .
8.1.3 Les variantes du type chanes de caractres . . . . . . . . . . . .
8.2 Expressions de type chane de caractres . . . . . . . . . . . . . . . . . .
8.2.1 Concatnation de chanes . . . . . . . . . . . . . . . . . . . . . .
8.2.2 Sous-chanes . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.2.3 Affectation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.3 Les fonctions oprant sur les chanes de caractres . . . . . . . . . . . .
8.3.1 Suppression des espaces terminaux avec TRIM . . . . . . . . . . .
8.3.2 Justification gauche avec ADJUSTL . . . . . . . . . . . . . . . .
8.3.3 Justification droite avec ADJUSTR . . . . . . . . . . . . . . . . .
8.3.4 Les fonctions LEN et LEN_TRIM . . . . . . . . . . . . . . . . . . .
8.3.5 Recherche de sous-chane avec INDEX . . . . . . . . . . . . . . . .
8.3.6 Recherche des caractres dun ensemble avec SCAN . . . . . . . .
8.3.7 Recherche des caractres hors dun ensemble avec VERIFY . . . .
8.3.8 Duplication de chanes avec REPEAT . . . . . . . . . . . . . . . .
8.3.9 Conversion de caractre en entier . . . . . . . . . . . . . . . . . .
8.3.10 Conversion dentier en caractre . . . . . . . . . . . . . . . . . .
8.3.11 Comparaison de chanes de caractres . . . . . . . . . . . . . . .
8.3.12 Le caractre de fin de ligne NEW_LINE . . . . . . . . . . . . . . .
8.4 Les entres-sorties de chanes de caractres . . . . . . . . . . . . . . . .
8.4.1 Les entres-sorties de chanes formates . . . . . . . . . . . . . .
8.4.2 Les entres de chanes en format libre . . . . . . . . . . . . . . .
8.4.3 Les fichiers internes : codage en chane de caractres et dcodage
8.5 Les tableaux de chanes de caractres . . . . . . . . . . . . . . . . . . . .
8.6 Chanes et procdures . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

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

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

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

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

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

94
94
94
94
95
95
95
95
96
96
96
96
97
97
97
97
97
98
98
98
98
98
98
98
99
99
99
100

9 Types drivs ou structures


9.1 Dfinition dun type driv . . . . . . . . . . . . . . . .
9.1.1 Lattribut SEQUENCE . . . . . . . . . . . . . . . .
9.2 Rfrence et affectation des structures . . . . . . . . . .
9.2.1 Constructeur de type driv . . . . . . . . . . . .
9.2.2 Slecteur de champ % . . . . . . . . . . . . . . .
9.3 Imbrication et extension de structures . . . . . . . . . .
9.3.1 Imbrication de structures . . . . . . . . . . . . .
9.3.2 Extension dun type driv . . . . . . . . . . . .
9.4 Structures et tableaux . . . . . . . . . . . . . . . . . . .
9.5 Types drivs composantes allouables dynamiquement
9.6 Procdures agissant sur les structures . . . . . . . . . .
9.7 Procdures attaches un type driv . . . . . . . . . .
9.7.1 Un exemple lmentaire dhritage . . . . . . . .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

102
102
103
103
103
103
104
104
105
105
106
106
107
109

10 Gnricit, surcharge doprateurs


10.1 Procdures gnriques et spcifiques
10.2 Linterface-oprateur . . . . . . . . .
10.2.1 Surcharge doprateurs . . . .
10.2.2 Cration doprateurs . . . .
10.3 Linterface-affectation . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

111
111
112
113
114
114

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

ix

TABLE DES MATIRES

11 Pointeurs
11.1 Pointeurs, cibles et association . . . . . . . . . . . .
11.1.1 Association une cible nomme . . . . . . .
11.1.2 Association une cible dynamique anonyme .
11.2 Pointeurs sur des tableaux . . . . . . . . . . . . . . .
11.3 Tableaux de types drivs contenant des pointeurs .
11.4 Pointeurs de procdures . . . . . . . . . . . . . . . .
11.5 Manipulation de listes chanes . . . . . . . . . . . .

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

118
118
119
120
121
123
126
126

12 Inter-oprabilit avec le C
12.1 Interoprabilit des types intrinsques . . . . . . . . . . . . . . . . . . . . .
12.2 Inter-oprabilit des types drivs . . . . . . . . . . . . . . . . . . . . . . . .
12.3 Inter-oprabilit avec les pointeurs du C . . . . . . . . . . . . . . . . . . . .
12.4 Inter-oprabilit des procdures . . . . . . . . . . . . . . . . . . . . . . . . .
12.4.1 Le passage par copie de valeur (value) . . . . . . . . . . . . . . . . .
12.4.2 Exemple : appel de fonctions C depuis le fortran . . . . . . . . . . .
12.4.3 Exemple : appel de sous-programmes fortran depuis le C . . . . . . .
12.5 Inter-oprabilit des tableaux . . . . . . . . . . . . . . . . . . . . . . . . . .
12.5.1 Exemple : fonctions C manipulant des tableaux dfinis en fortran . .
12.5.2 Exemple : fortran manipulant des tableaux dynamiques allous en C

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

129
129
130
130
130
131
131
132
133
133
135

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

138
138
140
140
142
143
144
144
145
145
146
147
148
149

A Procdures intrinsques
A.1 Fonctions numriques de base . . . .
A.2 Conversion, arrondi et troncature . .
A.3 Gnrateur pseudo-alatoire . . . . .
A.4 Reprsentation des nombres . . . . .
A.5 Fonctions oprant sur des tableaux .
A.6 Manipulation de bits . . . . . . . . .
A.7 Divers . . . . . . . . . . . . . . . . .
A.8 Pointeurs . . . . . . . . . . . . . . .
A.9 Accs lenvironnement fortran . . .
A.10 Accs lenvironnement systme . .
A.11 Excution dune commande systme
A.12 Gestion du temps . . . . . . . . . . .
A.13 Caractres et chanes de caractres .

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

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

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

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

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

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

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

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

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

.
.
.
.
.
.
.

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

.
.
.
.
.
.
.

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

.
.
.
.
.
.
.

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

.
.
.
.
.
.
.

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

.
.
.
.
.
.
.

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

.
.
.
.
.
.
.

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

.
.
.
.
.
.
.

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

.
.
.
.
.
.
.

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

.
.
.
.
.
.
.

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

.
.
.
.
.
.
.

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

.
.
.
.
.
.
.

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

.
.
.
.
.
.
.

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

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

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

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

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

B Ordre des instructions

153

C La norme IEEE 754


C.1 Introduction . . . . . . . . . . . . . . . . . . . . . . .
C.1.1 Reprsentation des rels en virgules flottante
C.1.2 Arithmtique tendue . . . . . . . . . . . . .
C.2 Les codes normaux . . . . . . . . . . . . . . . . . . .
C.2.1 Les nombres normaliss . . . . . . . . . . . .
C.2.2 Les nombres dnormaliss . . . . . . . . . . .
C.3 Les codes spciaux . . . . . . . . . . . . . . . . . . .
C.3.1 Arithmtique IEEE et options de compilation
C.4 Le codage IEEE des flottants sur 32 bits et 64 bits .
C.4.1 Le codage IEEE des flottants sur 32 bits . . .
C.4.2 Le codage IEEE des flottants sur 64 bits . . .

154
154
154
155
155
155
155
156
156
157
157
158

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

D Correspondance entre les syntaxes du fortran et du C


D.1 Dclarations des types de base . . . . . . . . . . . . . .
D.2 Oprateurs algbriques . . . . . . . . . . . . . . . . . . .
D.3 Oprateurs de comparaison . . . . . . . . . . . . . . . .
D.4 Oprateurs logiques . . . . . . . . . . . . . . . . . . . .
D.5 Oprations sur les bits . . . . . . . . . . . . . . . . . . .
D.6 Structures de contrle . . . . . . . . . . . . . . . . . . .
D.7 Pointeurs . . . . . . . . . . . . . . . . . . . . . . . . . .
D.8 Fonctions mathmatiques . . . . . . . . . . . . . . . . .
D.9 Formats . . . . . . . . . . . . . . . . . . . . . . . . . . .
D.10 Codage des valeurs numriques : domaine et prcision .
D.10.1 Domaine des entiers . . . . . . . . . . . . . . . .
D.10.2 Domaine et prcision des flottants . . . . . . . .

TABLE DES MATIRES

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

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

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

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

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

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

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

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

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

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

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

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

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

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

160
160
160
161
161
161
162
162
163
164
164
164
164

E Compilateurs et options de compilation


E.1 Compilateur xlf sous ibm-aix . . . . . . . . . . . . . . . . .
E.1.1 Options du compilateur xlf conseilles . . . . . . . .
E.2 Compilateur f95 ou nagfor de NAG . . . . . . . . . . . . .
E.2.1 Options du compilateur nagfor conseilles . . . . .
E.3 Compilateur pgf95 de Portland . . . . . . . . . . . . . .
E.3.1 Options du compilateur pgf95 conseilles . . . . . .
E.4 Compilateur ifort dIntel . . . . . . . . . . . . . . . . . .
E.4.1 Options du compilateur ifort conseilles . . . . . .
E.5 Compilateur g95 . . . . . . . . . . . . . . . . . . . . . . . .
E.5.1 Options du compilateur g95 conseilles . . . . . . . .
E.6 Compilateur gfortran . . . . . . . . . . . . . . . . . . . . .
E.6.1 Options du compilateur gfortran conseilles . . . . .
E.7 Options contrlant le nombre doctets des types numriques
E.7.1 Options passant sur 64 bits les entiers par dfaut . .
E.7.2 Options passant sur 64 bits les rels par dfaut . . .
E.8 quivalences des options entre les compilateurs . . . . . . .

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

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

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

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

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

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

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

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

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

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

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

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

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

165
165
165
166
167
167
167
168
168
169
170
171
171
172
172
173
173

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

Bibliographie

174

Index

179

Chapitre 1

Introduction
1.1

Historique du fortran

Le fortran (FORMULA TRANSLATION) est le premier langage informatique de haut niveau.


N la fin des annes 1950 sous limpulsion de John Backus 1 , il a t standardis en 1972 sous
la forme du fortran 66 et son efficacit dans le calcul scientifique en a fait le langage le plus
utilis dans les applications non commerciales. La mise jour du standard la fin des annes 1970
a apport dnormes amliorations en particulier dans le traitement des chanes de caractres avec
le fortran 77.
Mais cest avec fortran 90, dont la norme fut particulirement longue ngocier, quest
intervenue une vritable modernisation du langage fortran. Cette nouvelle version a permis un
nettoyage des lments les plus obsoltes du fortran (format fixe par exemple, li lutilisation
des cartes perfores). Elle a aussi introduit des fonctionnalits nouvelles parfois prsentes dans
des langages plus rcents, parmi lesquelles nous ne soulignerons que les plus attendues dans notre
domaine dapplications :
langage de programmation structur ;
outils de manipulation des tableaux (multidimensionnels) puissants, concis et adapts au
calcul vectoriel et parallle ;
gestion dynamique, pointeurs ;
cration de types drivs (structures), surcharge doprateurs, gnricit, ...
fiabilisation des passages darguments entre procdures.
Enfin, lvolution du langage fortran a continu avec le fortran 95, qui constitue une rvision
mineure, mais surtout le fortran 2003, dont le standard a t publi en novembre 2004 2 . Il
apporte notamment :
une interoprabilit normalise avec le langage C ;
de nouvelles possibilits concernant les tableaux dynamiques et les types drivs ;
des fonctionnalits de programmation oriente objet, notamment lextension des types drivs
et lhritage, la notion de procdure attache (bound) un type ;
une meilleure intgration dans le systme dexploitation.
Une partie de ces fonctionnalits taient dj intgres dans certains compilateurs fortran 95
sous forme dextensions, mais la publication de la norme va acclrer leur intgration 3 et garantir
leur portabilit.
Dans ce contexte, nous ne documenterons pas en gnral les aspects qualifis dobsolescents en
fortran 90/95, donc destins disparatre des prochaines versions.
1. John Backus, mort en 2007, a reu le prix Turing en 1977, notamment pour ses travaux sur Fortran.
2. Consulter http://j3-fortran.org/doc/.
3. Voir la disponibilit sur les diffrents compilateurs : http://fortranwiki.org/fortran/show/Fortran+2003+
status

CHAPITRE 1. INTRODUCTION

La nouvelle norme fortran 2008 constitue une volution mineure 4 par rapport au fortran 2003
avec notamment la notion de sous-module, des outils de programmation parallle (en particulier
les tableaux distribus, ou coarrays 5 ), la notion de bloc avec ses variables locales, de nouvelles
fonctions mathmatiques intrinsques... Le document final du standard fortran 2008 (Metcalf
et al. (2011)) a t approuv 6 en septembre 2010. Les discussions sur le prochain standard (fortran
2015) sont en cours 7 .

1.2

Les tapes de mise en uvre dun programme

Outre lanalyse de lalgorithme, la mise en uvre dun programme en fortran comporte essentiellement quatre phases, schmatises ci-contre dans le cas dun seul fichier source 8 :

(1) dition

vi essai.f90
?

fichier source
essai.f90
(2) compilation

gfortran essai.f90 -o essai.x

gfortran -c essai.f90

?
fichier objet
essai.o

(3) dition de liens

gfortran essai.o -o essai.x


?

fichier excutable 
essai.x
(4) excution

essai.x
?

1. rdaction des units de programme


source laide dun diteur de texte
2. compilation (proprement dite) des
fichiers source pour produire des fichiers objets
3. lien entre les objets et les bibliothques produisant un excutable
(grce lditeur de liens ld, luimme appel par le compilateur)
4. excution
Par dfaut, les phases de compilation (2)
et ddition de liens (3) sont inities par
un seul appel au compilateur et le fichier objet (cr dans un rpertoire temporaire) nest pas conserv. Il est ncessaire de passer loption -c au compilateur
pour ne pas enchaner automatiquement
ldition de liens.
Sans cette option, le compilateur dtermine la nature du fichier (source ou objet)
qui lui est fourni au vu du suffixe de son
nom et lance la compilation des fichiers
sources ventuels (suffixe .f90) puis ldition de liens des objets (suffixe .o).

Seul le fichier source est portable dune machine une autre, condition quil respecte un
standard du langage. Le fichier objet est une traduction en langage machine de bas niveau des
instructions du fichier source. Pour constituer le fichier excutable, il faut rsoudre les appels
des fonctions intrinsques du langage et ventuellement dautres bibliothques : cest le rle de
lditeur de liens, ld, daller extraire des bibliothques les codes objets des procdures appeles
pour les agrger au fichier objet compil, de faon constituer le fichier excutable, en principe
autonome. Les fichiers objets et le fichier excutable sont des fichiers binaires spcifiques de la
machine et du compilateur utilis.
4. Voir la prsentation des apports de fortran 2008 ftp://ftp.nag.co.uk/sc22wg5/N1851-N1900/N1891.pdf par
John Reid.
5. Les coarrays sont dj implments sous le compilateur g95.
6. La dernire version en discussion : ftp://ftp.nag.co.uk/sc22wg5/N1801-N1850/N1830.pdf du standard 2008
ntant plus disponible, on peut consulter celle daot 2009 : ftp://ftp.nag.co.uk/sc22wg5/N1751-N1800/N1791.pdf
7. Voir le projet de norme fortran 2015 publi en mai 2014 : ftp://ftp.nag.co.uk/sc22wg5/N2001-N2050/N2014.
pdf
8. Le cas plus raliste de plusieurs fichiers sources est abord en 1.2.4, p. 5 et dtaill dans le contexte des modules
en 6.4, p 64 avec notamment la Fig. 6.1, p. 66.

1.2. LES TAPES DE MISE EN UVRE DUN PROGRAMME

Les erreurs...
Si certaines erreurs peuvent tre dtectes lors de la compilation (essentiellement les erreurs
de syntaxe), voire lors de ldition de liens, dautres peuvent ne se manifester que dans la phase
dexcution (run-time errors) : elles devront tre corriges en reprenant le processus la phase (1),
ldition des programmes source.
N.-B. : il est vivement conseill de corriger les erreurs diagnostiques par le compilateur dans
lordre dapparition, car une premire erreur 9 peut en induire une quantit dautres 10 dans la suite
du programme (par exemple quand elle porte sur une dclaration de variable).

1.2.1

dition du fichier source

Nimporte quel diteur de texte peut permettre la saisie des programmes sources, qui sont des
fichiers texte. Mais certaines fonctions de lditeur seront particulirement utiles pour diter un
langage structur comme le fortran. Par exemple, sous lditeur vi, la cohrence des parenthses
ventuellement embotes peut tre vrifie par la simple frappe de la touche % qui, si le curseur est
plac sur un dlimiteur ouvrant, le dplace sur le dlimiteur fermant associ, et rciproquement.
Certains diteurs de texte sont dits sensibles au langage , dont la syntaxe est dcrite par
lintermdiaire de fichiers spcifiques. Parmi ces diteurs intelligents , citons emacs et xemacs,
gedit, kedit et la version vim 11 (vi improved) de lditeur vi disponible sous linux.
Ils sont alors capables de reprer les commentaires, les chanes de caractres, de reconnatre
les mots-clefs du langage, ses structures de contrle, ses fonctions intrinsques, et dautoriser leur
saisie abrge. La structure syntaxique du fichier source peut alors tre mise en vidence par lusage
de couleurs spcifiques, ce qui constitue une aide prcieuse pour contrler la syntaxe ds la phase
ddition.
Les diteurs emacs et xemacs possdent un mode fortran 90 12 activ automatiquement au
vu du suffixe (extension) du fichier dit. Dans ce mode, il est possible de lancer une compilation
depuis lditeur, dindenter automatiquement les structures... La prsentation syntaxique du fichier
source est elle-mme configurable : par exemple, le degr de marquage syntaxique est ajustable
sur 4 niveaux et laffichage des mots-clefs peut tre bascul de minuscules en majuscules, ou en
minuscules avec linitiale en capitale.
Un fichier source lmentaire ne comportant quun programme principal dbute par linstruction
PROGRAM, suivie du nom du programme et se termine par END PROGRAM, suivi du mme nom. Par
exemple, le programme suivant nomm bienvenue permet dafficher le message Bonjour.
PROGRAM bienvenue
WRITE(*,*) "Bonjour"
END PROGRAM bienvenue

1.2.2

Compilation et dition de liens

De nombreux compilateurs fortran sont disponibles, propritaires ou libres : on pourra consulter


ce propos lannexe E, p 165. Dans ce document, nous dcrirons essentiellement les possibilits
des deux compilateurs libres g95 (cf. E.5, p. 169 et surtout gfortran (cf. E.6, p. 171 avec lesquels
les codes proposs sont tests.
La syntaxe des commandes de compilation est spcifique de chaque compilateur, mais, au moins
sous unix, certaines options importantes respectent une syntaxe gnrale :
loption -c qui permet de crer un fichier objet sans lancer ldition de liens.
9. Certains compilateurs possdent une option (-fone-error pour g95, cf. E.5.1, -fmax-errors=1 pour gfortran
cf. E.6.1, -diag-error-limit1 pour ifort, cf. E.4.1) permettant darrter la compilation ds la premire erreur.
10. Sous unix, les messages derreur sont envoys sur la sortie derreur standard. Cest donc celle-ci quil faut
rediriger pour matriser le dfilement des messages soit dans un fichier par 2> fichier_erreurs, soit dans un tube
aprs fusion avec la sortie standard par 2>&1 | less par exemple.
11. Pour vim, la syntaxe du fortran 90 est dcrite dans le fichier /usr/share/vim/syntax/fortran.vim.
12. Le mode fortran de emacs et xemacs est dcrit dans le fichier lisp f90.el, dont la version compile est f90.elc.

CHAPITRE 1. INTRODUCTION

loption -o suivie dun nom de fichier permet de spcifier le nom du fichier produit par le
compilateur 13 , que ce soit un fichier objet (dans le cas o lon utilise aussi loption -c) ou
un fichier excutable si ldition de liens est lance.
B

loption -l suivie du nom (dpouill de lib en tte et de .a en fin) dune bibliothque


laquelle on fait appel lors de ldition de liens. Cette option doit tre place aprs les fichiers
qui appellent des procdures de la bibliothque. Pour utiliser par exemple la bibliothque
libnrecip.a avec gfortran, on lancera 14 :
gfortran

<essai >.f90

-lnrecip

les options de type -O<n >, o <n > est un entier, contrlent loptimisation du code. Plus <n >
est lev, plus le code peut sexcuter rapidement, mais les optimisations fortes ne sont pas
forcment sres. Il est conseill de commencer la mise au point dun code avec loption -O0.

Dans la mise au point des programmes, il est recommand dutiliser toute la puissance du
compilateur pour dtecter ds la compilation les erreurs ou les fragilits dun code. En choisissant
les options adquates, on lui demandera la plus grande svrit et le maximum de diagnostics.
On exploitera en particulier les avertissements (warnings) qui bien souvent dtectent des sources
derreur potentielles qui ne se manifestent quau moment de ldition de liens ou, pire, de lexcution
(les messages derreur produits sont alors plus difficiles interprter).
Bibliothques et excutables statiques ou dynamiques
On doit aujourdhui distinguer deux sortes de bibliothques et deux sortes dexcutables :
Les bibliothques statiques, de suffixe .a, sont des archives de fichiers objets, cres avec la
commande ar 15 .
Elles permettent deffectuer une dition de liens statique, avec loption -static du compilateur et de lditeur de liens, afin de crer des excutables autonomes 16 .
Les bibliothques dynamiques partageables, de plus en plus souvent adoptes, de suffixe .so
(shared object).
Elles permettent deffectuer (par dfaut) une dition de liens dynamique, et de crer des
excutables beaucoup moins volumineux, pour lesquels lagrgation des objets est diffre
au moment de lexcution. Les excutables dynamiques ne sont donc plus autonomes et
ncessitent la prsence des bibliothques dynamiques 17 lors de lexcution.
En pratique, fortran dispose dune bibliothque intrinsque, dont lemplacement est connu du
compilateur : cest pourquoi on charge gnralement le compilateur dappeler lditeur de liens ld
en lui indiquant le chemin de la bibliothque fortran 18 .
13. En labsence de loption -o, le fichier objet est nomm en substituant le suffixe .o au suffixe du fichier source
et le fichier excutable est nomm a.out
14. On insrera si ncessaire, avant loption -l, le chemin daccs la bibliothque, -L<rep > si elle nest pas place
dans un des rpertoires scruts par dfaut lors de sa recherche.
15. La commande ar est similaire tar : elle permet de crer des archives de codes objets, de les mettre jour,
dextraire les objets des bibliothques, den afficher la liste.... Par exemple, on peut afficher la liste des objets dans
la bibliothque intrinsque de gfortran par la commande :
ar -t /usr/lib/gcc/x86_64-redhat-linux/4.4.4/libgfortran.a dans laquelle on va trouver par exemple les diffrentes fonctions mathmatiques spcifiques des rels sur 4, 8, 10 et 16 octets de la fonction gnrique sin :
_sin_r4.o,_sin_r8.o, _sin_r10.o,_sin_r16.o.
16. Ldition de liens statique est en particulier ncessaire sil on souhaite gnrer un excutable destin une
machine (de mme architecture) o fortran nest pas install.
17. On peut afficher la liste des bibliothques dynamiques dont dpend un excutable via la commande ldd.
18. De plus, comme les fonctions mathmatiques usuelles sont dans la bibliothque intrinsque du fortran, il nest
pas ncessaire de la mentionner avec loption -l si ldition de liens est lance par le compilateur fortran. Il faudrait
au contraire la rfrencer explicitement si on faisait ldition de liens avec un compilateur C, par exemple dans le
cas des codes mixtes en C et fortran (cf. chap. 12, p. 129).

1.2. LES TAPES DE MISE EN UVRE DUN PROGRAMME

1.2.3

Excution

Le fichier excutable 19 sappelle par dfaut a.out. On peut aussi spcifier son nom lors de la
compilation par loption -o <fichier_excutable >. Ce fichier excutable se comporte comme
une commande du systme dexploitation, lance en tapant a.out 20 par exemple. En particulier,
sous unix, ses flux dentre, de sortie et derreur standard (cf. 5.2.1, p. 38) peuvent tre redirigs
vers des fichiers ou dautres commandes. De mme, comme pour les autres processus, linterruption
en cours dexcution est possible en frappant ^C.
Dbogueur
Dans la phase de mise au point et de recherche derreurs, on peut tre amen excuter le
programme sous le contrle dun dbogueur (debugger) pour analyser en dtail son comportement,
notamment le contenu des mmoires o sont stockes les variables et le cheminement dans les
instructions. Pour cela, il est ncessaire de compiler le programme avec loption -g pour produire
un excutable spcifique que pourra lancer le dbogueur.
Par exemple, sur les systmes o le compilateur gcc est install, le dbogueur gdb est disponible
et peut analyser des codes compils avec gfortran ou g95. Aprs avoir lanc le dbogueur, on peut
placer des points darrt (breakpoints) dans le programme source avant de le lancer sous son contrle.
Il est alors possible dexaminer des variables et mme de les modifier avant de relancer lexcution
pas pas ou jusquau prochain point darrt... Des interfaces graphiques de gdb sont disponibles,
notamment ddd.

1.2.4

Cas des fichiers sources multiples

Ds quune application est un peu importante, elle fait appel plusieurs procdures (sousprogrammes ou fonctions) quil est souvent prfrable de stocker dans des fichiers distincts,
condition quil sagisse de procdures externes (cf. 6.3.2, p. 63). Dans ce cas, on peut procder
la compilation spare des sous-programmes et fonctions, produisant ainsi des fichiers objets (que
lon pourra ventuellement rassembler dans une bibliothque personnelle).
gfortran -c <subpr1 >.f90

<subpr2 >.f90

Puis on lance la compilation du programme principal et ldition de liens en fournissant au compilateur le fichier source du programme principal et la liste des fichiers objets produits par la
compilation prcdente.
gfortran <principal >.f90

<subpr1 >.o

<subpr2 >.o

Mais on verra (cf. 6.4, p. 64) quil est prfrable dintgrer les procdures dans des modules :
la compilation dun module produit, en plus du fichier objet, un fichier de module dextension
.mod permettant de stocker des informations (notamment les interfaces des procdures compiles 21 )
utiles pour compiler ultrieurement dautres procdures qui leur font appel : grce linstruction
USE portant sur ce module, elles pourront acqurir la visibilit sur linterface des procdures du
module (cf. Figure 6.1, p. 66). On notera que ces fichiers de module ne sont pas portables : ils
dpendent du compilateur et ventuellement de sa version.
Enfin, dans le cas o on fait appel une bibliothque constitue de modules pr-compils, il
faut ventuellement indiquer au compilateur dans quel rpertoire trouver les fichiers de module
associs la bibliothque grce loption -I<mod_rep > 22 .
19. Sous unix, lattribut excutable est automatiquement positionn par lditeur de liens lors de la cration de
ce fichier. Lappel la commande chmod nest donc pas ncessaire.
20. Cela suppose que le rpertoire o se situe lexcutable fasse partie des chemins contenus dans la variable denvironnement PATH sous unix. Sinon, il faut prciser le chemin daccs, en lanant par exemple ./a.out si lexcutable
est dans le rpertoire courant.
21. Ces fichiers jouent un rle comparable aux fichiers dentte du langage C.
22. Comme pour les fichiers inclure par le prprocesseur.

CHAPITRE 1. INTRODUCTION

Loutil make
La maintenance (gnration et mise jour) dapplications sappuyant sur plusieurs fichiers
source et ventuellement des bibliothques peut tre automatise par des outils comme lutilitaire
make sous unix.
La commande make permet dautomatiser la gnration et la mise jour de cibles (target), en
gnral un fichier excutable, qui dpendent dautres fichiers, par exemple les fichiers sources, en
mettant en uvre certaines rgles (rules) de construction, constitues de commandes unix.
Elle sappuie sur un fichier makefile qui liste les cibles, dcrit larbre des dpendances et les
rgles de production des cibles. Pour plus dtails, on pourra consulter la documentation en ligne
de gnumake : http://www.gnu.org/software/make/manual/make.html.
Les compilateurs g95 et gfortran 23 possdent une option permettant daider lcriture des
dpendances aprs une compilation effectue la main :
gfortran -M <fichier.f90 > affiche les dpendances du fichier <fichier.o >.

1.3
1.3.1

Les lments du langage


Les caractres du fortran

Les caractres du fortran 90


Lensemble des caractres du fortran 90 est constitu des caractres alphanumriques, de signes
de ponctuation et de quelques symboles spciaux. Il comprend :
les minuscules (lettres de a z),
les majuscules (lettres de A Z),
les chiffres arabes de 0 9,
le caractre soulign : _ ,
et les symboles suivants 24 , parmi lesquels $ et ? nont pas de signification particulire dans
le langage :

,
<

+
.
>

:
%

=
;
!

*
'
&

(
"
$

)
/
?

Noter que le caractre de tabulation (qui pourrait faciliter lindentation du code) nest pas autoris
dans les fichiers source fortran, mme si plusieurs compilateurs se contentent de produire un avertissement en rencontrant une tabulation. Il est donc prudent de configurer les diteurs de faon
traduire chaque tabulation en un nombre despaces adquat ; si ncessaire, on peut utiliser le filtre
unix expand pour effectuer cette conversion a posteriori.

f2003

Les caractres du fortran 2003


La norme 2003 a complt le jeu de caractres du fortran par les caractres spciaux suivants :
~

Les crochets carrs [ et ] peuvent tre utiliss comme dlimiteurs dans les constructeurs de tableaux
monodimensionnels (cf. 7.1.3, p. 81).
23. Sous gfortran, loption -M nest disponible qu partir de la version 4.6.
24. Le langage C comporte plus de caractres avec les dlimiteurs (accolades {}, crochets []), la contre-oblique \,
les oprateurs %, ~, ^ et |. Le caractre # est en fait interprt par le prprocesseur qui peut agir aussi bien sur un
programme en C que sur un programme en fortran.

1.4. LES FORMATS DU CODE SOURCE FORTRAN

1.3.2

Les identificateurs des objets

Les objets (variables, procdures et units de programme) sont identifis laide de mots commenant par une lettre et constitus en fortran 95 dau plus 31 caractres alphanumriques 25 (plus
le soulign _ qui permet un pseudo-dcoupage des noms en mots). Le nombre de caractres f2003
des identificateurs est port 63 en fortran 2003. Noter quil nexiste quun seul espace de noms
en fortran : il est en particulier interdit dutiliser le mme identifiant pour une variable et un programme ou une procdure et un module. Contrairement dautres langages (notamment le C et
unix), le fortran ne distingue pas majuscules et minuscules en dehors des chanes de caractres.
N.-B. : pour des raisons de lisibilit, il est videmment dconseill den profiter pour introduire
des variantes dans lorthographe des identificateurs, nommant successivement par exemple une
mme variable TOTAL, puis total quelques lignes plus loin. On prconise linverse de rserver les
capitales pour les mots clefs du langage 26 et dcrire les identificateurs dfinis par lutilisateur en
minuscules, ou ventuellement avec les initiales en majuscules pour mettre en vidence les mots
dans les noms des objets, comme par exemple dans TotalPartiel.
Dautres conventions sont possibles, (consulter par exemple Clerman et Spector (2011) pour
les questions de style) sachant que les mots-clefs du langage seront mis en vidence par colorisation
lors de ldition. Lessentiel est de se tenir une rgle prcise tout au long du programme.

1.4

Les formats du code source fortran

Pour des raisons de compatiblit ascendante, les compilateurs fortran 90 acceptent deux formats
pour les fichiers sources :
le format fixe (fixed format) qui est celui du fortran 77 (lui-mme hrit des contraintes
imposes par les cartes perfores), avec deux extensions ;
le format libre (free format), qui permet une criture plus souple du code source, et est
fortement prconis 27 pour les programmes nouveaux.
Ces deux formats sont incompatibles et le compilateur doit tre inform (soit au vu du suffixe du
nom de fichier, soit grce une option, cf. annexe E) du format choisi dans les fichiers sources
qui lui sont soumis. Lutilisation conjointe de sources aux deux formats est possible en compilant
sparment (cf. 1.2.4, p. 5) les fichiers sources au format fixe, puis ceux au format libre, et en
assemblant ensuite les objets.

1.4.1

Format fixe

En format fixe, les instructions peuvent stendre de la colonne 7 jusqu la colonne 72.
Au-del de la colonne 72, les caractres ne sont pas pris en compte comme instruction par B
un compilateur standard 28 ;
Une ligne de commentaire peut tre introduite grce au caractre C plac en premire colonne.
Une ligne ne peut contenir quune instruction, mais une instruction peut stendre sur plusieurs lignes en plaant un caractre quelconque, mais diffrent de 0 et dun blanc en colonne 6
des lignes de continuation. Toutefois, la coupure de ligne ne peut pas se faire lintrieur
dune chane de caractres dlimite par des "..." ou des '...'.
En dehors dune ligne de commentaires, les colonnes 2 5 sont destines des tiquettes
numriques permettant de reprer certaines instructions (pour les formats, les branchements
ou les boucles).
25. En fortran 66 standard, la norme ne diffrenciait que les six premiers caractres. Heureusement, la plupart des
compilateurs sont plus tolrants ce qui permet de choisir des identificateurs plus vocateurs.
26. Rappelons que certains diteurs (Language Sensitive Editors), tels quemacs (cf. 1.2.1, p. 3), permettent de
basculer globalement la prsentation des mots-clefs du fortran entre minuscules, majuscules ou capitalisation des
initiales.
27. Le format fixe est dj obsolescent en fortran 95.
28. Sur les cartes perfores, o chaque carte reprsentait une ligne de code, ces colonnes permettaient dindiquer
des commentaires, voire de numroter les cartes pour pouvoir les reclasser en cas de chute du paquet de cartes qui
constitue maintenant un fichier. Cependant, en utilisant certaines options des compilateurs (parfois actives par
dfaut), les colonnes de 73 80 (ou 132) peuvent tre interprtes comme des instructions.

CHAPITRE 1. INTRODUCTION

Dans la partie instruction de la ligne et hors chane de caractres, les blancs ne sont pas
significatifs : dune part, ils ne sont pas ncessaires pour sparer les mots-clefs entre eux ou
des identifiants, mais on peut aussi insrer des blancs lintrieur des mots-clefs, des noms
de variables et des constantes numriques. Utiliser ces facilits est fortement dconseill,
dautant que les blancs sont significatifs en format libre ; mais il est bon de les connatre pour
dcrypter certains codes en format fixe qui les exploitaient 29 .
Les deux extensions suivantes au format du fortran 77 dfinissent le format fixe du fortran 90 :
en plus de C, les caractres c, * et ! placs en premire colonne sont considrs comme
introducteurs de commentaire.
une ligne peut contenir plusieurs instructions, condition quelles soient spares par des
; (points-virgules).
C
exemple d'extrait de fichier source fortran au format fixe
C
C2345678901234567890123456789012345678901234567890123456789012345678901234567890
C
1
2
3
4
5
6
7
8
C
||||||||
SOMME = TERME_1 +
1
TERME_2 +
1
TERME_3
C
dbut de la boucle
DO 100 I = 1, N
DEBUT
K = K + I
100 CONTINUE
FIN
C
fin de la boucle

1.4.2

Format libre du fortran 90

En format libre, les instructions peuvent stendre de la colonne 1 la colonne 132.


Le caractre ! 30 , hors chane de caractre, permet dintroduire un commentaire nimporte
o dans la ligne ; ce commentaire se termine la fin de la ligne 31 .

Une ligne peut contenir plusieurs instructions, spares par un point-virgule ; 32 .


Pour des raisons de lisibilit, il est cependant dconseill de grouper plusieurs instructions
sur une mme ligne.
Terminer une ligne dinstruction par le caractre de suite & indique que linstruction se
continue sur la ligne suivante 33 . Dans le cas o la coupure de ligne intervient au sein dune
chane de caractres, il faut insrer un & comme premier caractre non-blanc de la ligne de
continuation pour indiquer o reprend la chane.
29. Les blancs taient utiliss par exemple afin de sparer les groupes de 3 chiffres, ou les mots constitutifs dun
identifiant. linverse, on pouvait les supprimer entre type et nom de variable pour obtenir un code plus concis.
C format fixe: partir de la colonne 7
IMPLICITNONE
REALx, sx
INTEGER :: old j
oldj = 2 000
x = . 314 159 e 1
s x = S I N (x)
W R I T E (*,*) old j, x, s x

prfrer =

C format fixe: partir de la colonne 7


IMPLICIT NONE
REAL x,sx
INTEGER :: oldj
oldj = 2000
x = .314159e1
sx = SIN(x)
WRITE(*,*) oldj, x, sx

30. En fortran 90, cest le seul introducteur de commentaire ; en particulier, C , c et * ne permettent


plus dintroduire un commentaire dans le source.
31. Le caractre ! , introducteur de commentaire nest pas un dlimiteur, contrairement ce qui se passe en C
avec le couple /* ... */. Il est comparer avec le couple // introducteur de commentaires du C99 et du C++.
32. Mais, contrairement ce qui se passe en C, une ligne dinstruction ne se termine pas par un ; .
33. Cette technique ne peut pas tre employe pour des lignes de commentaire. linverse, et bien que cette
pratique soit dconseille pour manque de lisibilit, on peut insrer une ou plusieurs lignes de commentaires (chacune
introduite par un !) entre les diffrentes lignes (termines, sauf la dernire, par un &) constituant une instruction.

1.4. LES FORMATS DU CODE SOURCE FORTRAN

Les caractres ! et & perdent leur interprtation spciale lorsquils sont situs lintrieur
dune chane de caractres (entre "..." ou entre '...'). Mais, dans le cas o la chane nest
pas ferme en fin de ligne, un & en dernier caractre non blanc est interprt comme indiquant
que la fin de ligne ne termine pas linstruction. Le nombre maximum de lignes sur lesquelles
peut stendre une instruction est limit 40 en fortran 95 (39 lignes de suite), et 256 en f2003
fortran 2003 (255 lignes de suite).
1
2
3
4
5
6
7
8
9
10
11
12
13
14

PROGRAM essai
!
exemple de source fortran 90 au format libre
IMPLICIT NONE
REAL :: somme, terme_1 = 1., terme_2 = 2., terme_3 = 3.
!
! une instruction longue scinde en plusieurs lignes
somme = terme_1 + &
! description du premier terme
terme_2 + &
! description du deuxime terme
terme_3
! description du troisime terme
! cas o la coupure se fait au sein d'une chane de caractres
WRITE (*,*) ' chane de caractres comportant plusieurs lignes dans &
&le programme source'
!
ce & est obligatoire pour marquer la continuation de la chane
END PROGRAM essai
Lordre dcriture suivant
WRITE (*,*) 'chane avec des & et des ! normaux et deux &&
& spciaux' ! suivie d'un commentaire
affichera sur une seule ligne :
chane avec des & et des ! normaux et deux & spciaux
Les blancs Noter que les espaces sont significatifs en format libre. En particulier, en labsence
de sparateur (virgule, parenthse...), un blanc est obligatoire pour dlimiter deux mots-clefs. Mais
lespace est facultatif dans certains cas, comme ELSEIF, DOUBLEPRECISION, INOUT, SELECTCASE,
ainsi que pour toutes les fins de structures introduites par END : ENDIF, ENDDO, ...
Interposer des espaces permet damliorer la lisibilit du code, avec par exemple les rgles
suivantes (cf. Clerman et Spector (2011)), en veillant maintenir une prsentation homogne
dans tout le code :
mettre en retrait (indent) les blocs (structures de contrle, dclaration de types drivs,
interfaces, ...), sans utiliser de tabulation (cf. 1.3.1, p. 6) et avec toujours le mme nombre
despaces (2 ou 4 suffisent, mais choisir 8 espaces provoquerait des retraits trop importants
pour les structures imbriques) ;
entourer dune espace le signe = daffectation dans les expressions ;
entourer dune espace les oprateurs de lopration principale des expressions ;
ajouter une espace aprs la virgule, et seulement aprs, dans les listes (attributs, arguments
des procdures, objets lors de la dclaration, ...).

Chapitre 2

Types, constantes et variables


2.1

Les types intrinsques

Le langage fortran 90 possde les types intrinsques ou prdfinis suivants :


CHARACTER : chane de caractres 1
LOGICAL : boolen
types numriques :
type numrique reprsent exactement :
INTEGER : entier
types numriques reprsents approximativement :
REAL : rel en virgule flottante
DOUBLE PRECISION : flottant en prcision tendue ( viter : lui prfrer une variante
de type dtermine de faon plus portable, grce lattribut KIND, cf. 2.5.2, p. 18)
COMPLEX : nombre complexe flottant
Notons que les types intrinsques sont dclins en diffrentes variantes ou sous-types (cf. 2.5.2,
p. 18), dont la liste prcdente prsente les sous-types par dfaut. Enfin, on verra au chapitre. 9,
p.102, quil est possible dtendre la liste des types disponibles en dfinissant des types drivs pour
reprsenter plus efficacement certaines structures de donnes.

2.2

La reprsentation des types numriques

Les entiers sont reprsents en mmoire de faon exacte, donc sans perte de prcision, mais leur
domaine est limit par le nombre de bits choisi pour les reprsenter.
Au contraire, les rels ne peuvent pas, en gnral, tre reprsents exactement en mmoire :
cest pourquoi on vitera les tests dgalit sur les rels ; cest aussi ce qui explique limpossibilit
dappliquer des expressions relles des tests de type numration de valeurs 2 .
On verra en particulier que lcart entre deux rels successifs assez grands ( 107 ) peut dpasser
1 : il est donc extrmement dconseill de compter en utilisant des variables de type rel.
Pour plus de dtail sur la reprsentation des nombres et limplmentation des oprations arithmtiques, on consultera le chapitre 9 Arithmtique des ordinateurs de Stallings (2003).

2.2.1

Reprsentation des entiers

Si la reprsentation la plus connue des entiers positifs est celle de la base 10 (qui utilise 10
symboles de 0 9), la plupart des ordinateurs utilisent une reprsentation en base 2 ne ncessitant
que 2 symboles (0 et 1) ; en reprsentation binaire, lquivalent du chiffre de la reprsentation
1. En fortran, un caractre est stock dans une chane de type CHARACTER et de longueur 1, contrairement ce
qui se passe en langage C, o seul le type caractre est natif et les chanes ne sont que des tableaux de caractres.
2. select case en fortran ou switch ... case en C.

10

11

2.2. LA REPRSENTATION DES TYPES NUMRIQUES

dcimale est le bit. La reprsentation en octal (base 8) utilise les 8 symboles de 0 7 alors que la
reprsentation hexadcimale 3 (base 16) utilise 16 symboles : 0,1, ..., 9, A, B, ...F.
Reprsentation des entiers positifs
La reprsentation des entiers positifs utilise des codes poids, dont les poids sont les puissances
successives de la base b ; soit, avec q coefficients :
n=

q1
X

p i bi

o 0 6 pi < b

(2.1)

i=0

Rciproquement, les coefficients pi peuvent tre obtenus par des divisions entires successives par b :
p0 , coefficient de plus faible poids, est le reste de la division de n par b ;
p1 le reste dans la division par b2 ; ...
Dans le cas o b = 2, chaque coefficient pi peut tre reprsent par un bit. Par exemple, pour
lentier 13 :
13 = 1 101 + 3 100

not 1310 en base 10

13 = 1 2 + 1 2 + 0 21 + 1 20
3

not 11012 en base 2

Si on consacre q bits la reprsentation dun entier positif, on peut couvrir le domaine [0, 2q 1].
Reprsentation des entiers ngatifs
Les entiers ngatifs sont reprsents habituellement avec le symbole complmentaire quil
va falloir traduire en codage binaire par un bit complmentaire appel bit de signe.
En binaire, un entier relatif est donc reprsent sur q + 1 bits. On choisit de coder le signe sur
le bit de plus fort poids avec 0 pour les entiers positifs et 1 pour les ngatifs. Mais si on codait
simplement la valeur absolue en binaire de n sur les q bits restants, une opration arithmtique
lmentaire comme laddition entre entiers de signes diffrents ne seffectuerait pas comme celle de
deux entiers de mme signe.
On choisit au contraire de reprsenter lentier n ngatif par un bit de signe 1 suivi des bits du
complment 2q+1 de |n|, cest--dire ceux de lentier positif 2q+1 |n|. On parle alors (abusivement)
de complment deux, obtenu en inversant tous les bits puis en ajoutant 1 avec perte de la retenue.
Larithmtique entire ainsi mise en uvre fonctionne modulo 2q+1 . Le domaine couvert va donc
de 2q 2q 1 (voir par exemple 2.2.3, p. 15). Par exemple, les entiers cods sur 8 bits, soit 1 octet
(q = 7) couvrent le domaine 27 = 128 27 1 = +127 (cf. Fig 2.1 et Table 2.1) :
+28 1

+0

+1

+0

+1

28
n<0
+26

+27 + 1
+27 1
+27
+127
+129
+128

n>0
+26

27 + 1
+27 1
27
+127
127
128

Figure 2.1 Entiers positifs ( gauche) et entiers relatifs ( droite) sur 8 bits : pour passer des
positifs aux relatifs, on soustrait 28 dans la partie gauche (pointille) du cercle. La discontinuit
initialement en haut gauche de 0 pour les positifs, se retrouve en bas entre +127 et 128.
3. La base 16 a t utilise sur certains calculateurs ibm.

12

CHAPITRE 2. TYPES, CONSTANTES ET VARIABLES

n
128
127
...
1
0
+1
...
+127

signe

26

25

24

23

22

21

20

1
1
...
1
0
0
...
0

0
0
...
1
0
0
...
1

0
0
...
1
0
0
...
1

0
0
...
1
0
0
...
1

0
0
...
1
0
0
...
1

0
0
...
1
0
0
...
1

0
0
...
1
0
0
...
1

0
1
...
1
0
1
...
1

Table 2.1 Reprsentation des entiers relatifs sur 8 bits.


Affichage des entiers en binaire En utilisant le format binaire de sortie not B (cf. 5.4.1, p. 48)
comme convertisseur binaire-dcimal, on peut vrifier simplement la reprsentation des entiers, par
exemple sur 32 bits et sur 8 bits.
PROGRAM entier_binaire
IMPLICIT NONE
INTEGER :: i0 ! entier par dfaut (32 bits)
! entiers pour stocker au moins 100 => 8 bits
INTEGER, PARAMETER :: k1=SELECTED_INT_KIND(2)
INTEGER(kind=k1) :: i1
WRITE(*, *) "entiers sur",DIGITS(i0),"bits + signe"
WRITE(*, *) "soit ",BIT_SIZE(i0), "bits avec signe"
WRITE(*, "(i11)") HUGE(i0)
WRITE(*, "(b32.32)") HUGE(i0)
WRITE(*, "(i11)") -HUGE(i0)-1
WRITE(*, "(b32.32, /)") -HUGE(i0)-1
WRITE(*, *) "entiers sur",DIGITS(i1),"bits + signe"
WRITE(*, *) "soit ",BIT_SIZE(i1), "bits avec signe"
WRITE(*, "(i4, 1x, b8.8)") HUGE(i1), HUGE(i1)
WRITE(*, "(i4, 1x, b8.8)") -HUGE(i1)-1_k1, &
-HUGE(i1)-1_k1
END PROGRAM entier_binaire

entiers sur 31 bits + signe


soit 32 bits avec signe
2147483647
01111111111111111111111111111111
-2147483648
10000000000000000000000000000000
entiers sur 7 bits + signe
soit 8 bits avec signe
127 01111111
-128 10000000

Traditionnellement, comme en dcimal, on range les bits par poids dcroissant, le plus fort poids
gauche. Mais des variantes dans lordre de stockage 4 des octets ou des groupes de deux octets
existent : on distingue les conventions little-endian o les octets de poids fort sont stocks en fin et
big-endian o les octets de poids fort sont stocks en tte.

2.2.2

Reprsentation des rels en virgule flottante

Si on codait les rels en virgule fixe 5 , la prcision absolue de la reprsentation serait fixe ; mais
la prcision relative dpendrait de lordre de grandeur. Pour conserver une prcision relative plus
indpendante de lordre de grandeur, cest--dire pour travailler avec un nombre fixe de chiffres
significatifs, on prfre une reprsentation en virgule flottante 6 , avec une mantisse, reprsentant la
partie fractionnaire et un exposant qui fixe lordre de grandeur (cf qu. 2.2, p. 13).
Par exemple en base 10, avec 4 chiffres aprs la virgule, on peut comparer dans la table 2.2,
p. 13, les deux reprsentations approches (obtenues, pour simplifier, par troncature et non par
arrondi) : on constate quen virgule fixe, plus les valeurs sont petites, moins on conserve de chiffres.
4. On peut faire lanalogie avec les modes dcriture de la date suivant les pays qui diffrent notamment par
lordre entre le jour, le mois et lanne.
5. On peut, pour simplifier, envisager le cas de la base dcimale, et faire lanalogie avec le format F en fortran ou
%f en C, avec un nombre fixe de chiffres aprs la virgule.
6. Pour poursuivre la comparaison, cela correspond la notation exponentielle en format E en fortran ou %e en C

13

2.2. LA REPRSENTATION DES TYPES NUMRIQUES

nombre exact

virgule fixe virgule flottante


par troncature

0.0000123456789
0.000123456789
0.00123456789
0.0123456789
0.123456789
1.23456789
12.3456789
123.456789
1234.56789

0.1234
0.1234
0.1234
0.1234
0.1234
0.1234
0.1234
0.1234
0.1234

.0000
.0001
.0012
.0123
.1234
1.2345
12.3456
123.4567
1234.5678

104
103
102
101
100
101
102
103
104

Table 2.2 Reprsentation en virgule fixe et virgule flottante en base 10


Reprsenter un rel (non nul) en virgule flottante, cest en donner une approximation finie en
le dveloppant dans une base b sous la forme :
r = s be m = s be

q
X

(2.2)

pi bi

i=1

o
s = 1 est le signe ;
e est un entier qualifi dexposant ;
la partie fractionnaire m est la mantisse.
Mais cette reprsentation nest pas unique. Afin de choisir parmi les combinaisons de mantisse et
dexposant, on impose que la mantisse soit comprise entre 1/b inclus 7 et 1 exclus soit p1 6= 0. Par
exemple en dcimal, 1,234 101 peut scrire 0,1234 100 ou 0,01234 101 : on exclut donc la
deuxime combinaison.
Chaque variante du type rel (dtermine via le paramtre KIND) est caractrise par :
un nombre q de symboles (chiffres dcimaux en base 10 et bits en base 2) de la mantisse qui
fixe la prcision relative des rels ;
un nombre de symboles pour lexposant qui fixe le domaine de valeurs couvert.
Dans cette reprsentation, en dcimal, les rels en virgule flottante sont rpartis en progression
arithmtique dans chaque dcade avec un nombre fixe de valeurs par dcade et un pas multipli
par 10 chaque changement de dcade. En binaire, cest dans chaque octave (intervalle de type
[2p , 2p+1 [) quils sont en progression arithmtique avec un nombre n = 2q1 de valeurs par octave ;
le pas double chaque changement doctave (cf. Annexe C, p. 154 sur le codage ieee).
2
+0

1/4

MIN

chelle log

1/2

+1

+2

+4

MAX
une octave (n valeurs)
chelle linaire ( exposant fix)

Figure 2.2 Reprsentation des rels positifs en virgule flottante base 2 : domaine en chelle log.
Seules sont reprsentes ici les puissances exactes de 2 lorsque lexposant est incrment mantisse
fixe. Le nombre de bits de lexposant dtermine le domaine couvert. Le zoom sur une octave,
exposant fix, est, lui, en chelle linaire (cf. Fig. 2.3, p. 14).
7. Si la mantisse est infrieure 1/b, on perd des chiffres significatifs, mais, exposant fix, cela permet de
reprsenter des nombres plus petits qualifis de dnormaliss (cf. C.2.2, p. 155).

14

CHAPITRE 2. TYPES, CONSTANTES ET VARIABLES

X(1 + (n 1))

X = 2p
X(1 + 2)
X(1 + )

X/2

X/2
X/2 = nX/2

X = X/n = X

2X

chelle linaire
X = nX

Figure 2.3 Reprsentation en virgule flottante base 2 : deux octaves en chelle linaire. X =
X est le pas dans loctave [X, 2X[ qui comporte n = 2q1 intervalles, o q est le nombre de bits
de la mantisse (avec le 1er bit 1), qui dtermine la prcision relative de la reprsentation.

2.2.3

Domaine et prcision des types numriques

Les nombres tant stocks sur un nombre de bits fixe, ne sont reprsents que dans un domaine
fini. De plus, seul le type entier permet une reprsentation exacte des valeurs numriques, alors
que les nombres rels ne sont en gnral reprsents en virgule flottante quapproximativement 8 .
Fonctions dinterrogation sur le codage des types numriques
Plusieurs fonctions intrinsques permettent de caractriser globalement 9 la reprsentation du
type numrique de leur argument du point de vue :
de la base b (en gnral 2) employe dans la reprsentation (2.1) pour les entiers ou (2.2)
pour les rels du type de x : RADIX(x) ;
du nombre de digits utiliss pour le reprsenter : DIGITS(x) donne le nombre de symboles
(cest--dire de bits dans le cas usuel de la base 2) consacrs au stockage de la mantisse de x
dans le type de x. Plus prcisment :
si x est un entier, DIGITS(x) est le nombre q de bits sur lesquels lentier est stock
hors bit de signe. Il dtermine donc le domaine couvert par ce type. Dans le cas entier,
BIT_SIZE(x) rend le nombre total de bits utiliss pour le stocker (bit de signe inclus).
si x est un rel en virgule flottante, DIGITS(x) est le nombre de bits (ici q) 10 sur lesquels
est stocke sa mantisse. Il dtermine alors la prcision relative de la reprsentation de x.
du domaine couvert par un type donn :
HUGE(x), la plus grande valeur (entire ou relle) reprsentable dans le type de x.
TINY(x), la plus petite valeur absolue flottante reprsentable 11 dans le type de x.
RANGE(x) qui donne :
la puissance de 10 du plus grand entier dfini dans le type de x sil sagit dun entier :
ainsi tout entier x tel que |x| 6 10r o r est la valeur de RANGE est reprsentable
dans ce type et RANGE(x) = INT(LOG10(HUGE(x))
la plus petite des valeurs absolues des puissances de 10 du plus petit et du plus
grand des rels dans le type de x, si x est un flottant :
RANGE(x) = INT(MIN(LOG10(HUGE(x)), -LOG10(TINY(x))))
ainsi tout rel x scrivant sous la forme x= 0.????? 10k avec k entier et |k| 6 r
o r est la valeur de RANGE, est reprsentable dans ce type ;
8. Plus prcisment, ne peuvent ventuellement tre exactement reprsents que les rationnels dont le dnominateur est une puissance de la base, donc en pratique du type n/2p avec des contraintes sur n et p. Ainsi les entiers de
valeur absolue assez faible, et certains nombres rationnels de dnominateur 2p sont reprsents exactement en virgule
flottante. En revanche la majorit des nombres dcimaux, 0.1 par exemple, ne sont pas reprsentables exactement.
9. Seul le type et non la valeur de largument de ces fonctions dinterrogation a une importance.
10. Dans le cas dune mantisse normalise, son premier bit, toujours gal 1, nest pas stock (cf. C.2.1, p. 155).
Cela permet de gagner un bit, mais ce bit cach est pris en compte dans la fonction DIGITS.
11. On se limite ici aux reprsentations normalises, cf. annexe C, p. 154, sachant quil est possible de reprsenter
des valeurs absolues plus petites au prix dune perte de prcision.

15

2.2. LA REPRSENTATION DES TYPES NUMRIQUES

de la prcision de la reprsentation en virgule flottante :


PRECISION(x) donne le nombre de chiffres dcimaux significatifs dun rel du type de x.
EPSILON(x) donne la plus petite valeur relle positive qui nest pas ngligeable devant
1. dans le type de x. Cest la plus petite valeur positive qui, ajoute 1., donne le
flottant successeur de 1. (le plus proche de 1. par excs, dans la reprsentation de x).
Si un entier i est stock sur q+1 bits, BIT_SIZE(i) vaut q+1, DIGITS(i) vaut q et HUGE(i)
vaut 2q 1.
Dautres fonctions intrinsques dinterrogation permettent de prciser localement la reprsentation des types numriques ; leur rsultat dpend la fois du type et de la valeur de x :
EXPONENT(x) rend un entier donnant lexposant e de x de la reprsentation (2.2) ;
FRACTION(x) rend un rel donnant la mantisse m de x de la reprsentation (2.2) ;
NEAREST(x, s) rend le rel le plus proche de x mais distinct de x dans la reprsentation (2.2)
selon la direction fixe par le signe du rel s (successeur ou prdcesseur de x) ; successeur ou
prdcesseur sont en gnral gale distance qui est le pas de la progression arithmtique des
rels dans une octave, sauf si x est une puissance entire de 2 ; par exemple, NEAREST(1.,+1.)
vaut 1. + EPSILON(1.) alors que NEAREST(1.,-1.) vaut 1. - EPSILON(1.)/2. ;
SPACING(x) rend la distance entre x et son voisin le plus proche en sloignant de 0, soit la
distance entre |x| et son successeur ; un multiple de cette distance peut tre utilis comme
critre de convergence dans un algorithme itratif. EPSILON(x) est donc gal SPACING(1.).

Caractristiques des types numriques prdfinis


Les caractristiques des types numriques prdfinis dpendent la fois du processeur et des
compilateurs (souvent au travers doptions spcifiques).
Types entiers par dfaut Sur un processeur 32 bits, les entiers par dfaut sont stocks sur
4 octets donc 31 bits pour la valeur absolue plus un bit de signe. La variante de type (KIND) des
entiers reprsente gnralement le nombre doctets sur lesquels est cod cet entier 12 .
Sur un processeur de type PC 64 bits, les entiers par dfaut peuvent tre stocks sur 8 octets,
(mme si ce nest pas forcment la rgle), donc 63 bits pour la valeur absolue plus un bit de signe.
Des options de compilation permettent dimposer les entiers sur 64 bits (cf. Annexe E.7.1 p. 172).
nombre doctets

BIT_SIZE

DIGITS

HUGE

RANGE

32

31

2147483647 = 2

64

63

9223372036854775807 = 2

31

1
63

9
1

18

Le comportement en cas de dpassement de capacit entire dpend du compilateur et des


options choisies. Avec les compilateurs g95 et gfortran, loption -ftrapv provoque un arrt du
programme en cas de dpassement de capacit lors dun calcul en entier.
Types rels par dfaut Les rels sont, sur la plupart des machines, stocks sur 4 octets, dont
24 bits (dont 1 pour le signe) pour la mantisse et 8 bits pour lexposant. Avec des options de
compilation (cf. Annexe E.7.2 p. 173), on peut passer 8 octets dont 53 bits (dont 1 pour
le signe) pour la mantisse et 11 bits pour lexposant (variante de rels aussi disponible sous le
type DOUBLE PRECISION). On se reportera lannexe C p. 154 pour une description de la norme
IEEE 754 qui dfinit une mthode de reprsentation portable des rels.
nb doctets
4
8

DIGITS
24
53

PRECISION
6
15

EPSILON
1.192093E-7
2.220446049250313E-016

TINY
1.175494E-38
2.225073858507201E-308

HUGE
3.402823E+38
1.797693134862316E+308

12. Avec le compilateur nagfor de nag, par dfaut, les variantes de type sont numrotes en squence (option
-kind=sequential du compilateur). Mais si on prcise loption de compilation -kind=byte, les valeurs de KIND
reprsentent le nombre doctets occups par la variante de type (cf. Annexe E.2, p. 166).

16

CHAPITRE 2. TYPES, CONSTANTES ET VARIABLES

2.3

Dclaration

Les objets doivent tre dclars en tout dbut 13 de programme, sous-programme, fonction ou
module, prcisment avant les instructions excutables, selon la syntaxe gnrale suivante :

<type > [,<liste_d_attributs >::] <liste_d_objets >


Le sparateur :: nest pas obligatoire si la dclaration ne comporte pas dattributs ni dinitia lisation, mais il est fortement conseill. Pour chaque objet dclar, on peut prciser des attributs
qui seront dcrits en dtail plus loin :
pour les variables :
PARAMETER constante nomme (cf. 2.5.1, p. 18)
DIMENSION profil dun tableau (cf. 7.1.1, p. 79)
ALLOCATABLE objet allou dynamiquement (cf. 7.5.3, p. 91)
SAVE objet statique (cf. 6.1.2, p. 58)
POINTER objet dfini comme un pointeur (cf. 11.1, p. 118)
TARGET objet cible potentielle dun pointeur (cf. 11.1, p. 118)
pour les procdures :
EXTERNAL caractre externe dune procdure (cf. 6.5.3, p. 71)
INTRINSIC caractre intrinsque dune procdure (cf. 6.5.3, p. 71)
pour les arguments des procdures :
INTENT vocation (IN, OUT ou INOUT) dun argument muet dune procdure (cf. 6.1.4,
p. 59)
OPTIONAL caractre optionnel dun argument muet dune procdure (cf. 6.5.1, p. 69)
f2003

VALUE pour le passage dargument par copie de valeur (cf. 12.4.1, p. 131)
pour les objets encapsuls dans des modules (cf. 6.4.3 p. 67) :
PUBLIC rend accessible un objet lextrieur du module courant : cest lattribut par
dfaut
PRIVATE limite la visibilit dun objet au module courant

f2003

PROTECTED (fortran 2003 seulement) interdit la modification de lobjet en dehors du


module sans restreindre sa visibilit (impose ainsi de passer par une procdure du module
pour le modifier)

Par dfaut, les variables numriques non dclares suivent un typage implicite dtermin par
leur initiale : les variables dont linitiale est I, J, K, L, M ou N sont des entiers et les autres des
flottants. Lordre IMPLICIT permet de modifier ventuellement cette convention. La dclaration
dune variable impose explicitement son type et prvaut sur ces conventions.
Mais, il est trs fortement conseill de sobliger dclarer toutes les variables, sans mettre en
uvre le typage implicite 14 , grce lordre IMPLICIT NONE, plac avant toutes les dclarations.
Cette contrainte permet en autres de confier au compilateur le reprage des erreurs typographiques
dans les noms de variables : si on a dclar la variable somme et que lon utilise ensuite some sans
dclaration, le compilateur va diagnostiquer une erreur. Elle oblige aussi constituer en tte de
programme une sorte de dictionnaire des variables quil est conseill de commenter et qui facilite
la lecture et la maintenance du code.
13. En fortran 2008, il est possible de dclarer tardivement des objets (comme en C89) au dbut dune structure
de bloc (BLOCK ... END BLOCK), elle mme place aprs des instructions excutables (cf. 4.4, p. 31). La porte et la
dure de vie de ces objets sont alors limites au bloc.
14. Ainsi, le comportement du fortran 90 se rapproche de celui du langage C, dans lequel toutes les variables
doivent tre dclares.

2.4. LES CONSTANTES

IMPLICIT NONE
CHARACTER(LEN=5)
LOGICAL
REAL
COMPLEX

::
::
::
::

17

nom_a_5_lettres ! chane de 5 caractres


test, test1
a, longueur ! on ignore le typage implicite pour longueur
nombre_complexe

On peut spcifier une variante de type en indiquant la valeur du paramtre KIND entre parenthses, mais cette valeur doit tre une constante :
<type >(KIND=<kind >) :: <liste_d_objets >

2.4

Les constantes

Les constantes sont des objets dont la valeur ne peut pas tre modifie lors de lexcution
du programme ; elles ne peuvent constituer le membre de gauche dune instruction daffectation.
On distingue les vraies constantes (literal constants) ou constantes non nommes dune part et les
constantes nommes dautre part (cf. 2.5.1, p. 18), qui sont values lors de la compilation. Il est
fortement conseill de nommer les constantes utilises dans un programme, pour sassurer que la
mme valeur est utilise dans tout le programme et pour simplifier un ventuel changement de
prcision dune constante flottante, voire la transformer en une variable lors dune gnralisation
du programme.

Exemples de constantes vraies dans les types prdfinis


-250
17
B'101'
O'17'
Z'1F'
3.14
-.33
2.1e3
-2e-3
2.1d3
(1.5, -2.)
.true.
.false.
'bonjour !'
"bonjour !"
'M1 "P & A"'
"aujourd'hui"
'aujourd''hui'
''

2.5

!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!

entier
entier
entier en binaire : 5
entier en octal : 15
entier en hexadcimal : 31
rel en notation dcimale
rel en notation dcimale
rel en notation mantisse et exposant
rel en notation mantisse et exposant
double prcision
complexe 1,5 - 2i
boolen: vrai
boolen: faux
chane de caractres dlimite par des apostrophes (')
chane de caractres dlimite par guillemets (")
chane de caractres (entre les ', seul ' est interprt)
chane de caractres (l'apostrophe est autorise entre les ")
chane de caractres (l'apostrophe double permet
d'insrer une seule apostrophe dans la chane)
chane de caractres vide

Initialisation

Il est possible dinitialiser des objets ds leur dclaration 15 , en leur affectant comme valeur des
constantes vraies du mme type 16 , par exemple
15. Une variable locale une procdure devient statique si on linitialise au moment de la dclaration, elle se
comporte donc comme si elle possdait lattribut SAVE (cf. 6.1.2, p. 58). Ce nest pas le cas en C, o linitialisation
se fait chaque appel de la fonction, sauf si on spcifie lattribut static pour la variable.
16. Veiller initialiser par exemple les variables de type DOUBLE PRECISION avec des constantes du mme type,
sous peine de perte de prcision : dans lexemple qui suit, les derniers chiffres significatifs de r nauraient pas de

18

CHAPITRE 2. TYPES, CONSTANTES ET VARIABLES

IMPLICIT NONE
CHARACTER(LEN=5)
LOGICAL
REAL
COMPLEX
DOUBLE PRECISION

::
::
::
::
::

nom_a_5_lettres = 'dbut'
test = .TRUE. , test1 = .FALSE.
a = 0. , longueur = 1.e3
nombre_complexe = (1.,-1.)
r = 1.23456789012345d0

Mais des expressions simples, dites expressions dinitialisation peuvent aussi tre utilises pour
initialiser les variables : elles doivent pouvoir tre values par le compilateur.
IMPLICIT NONE
REAL :: longueur = 10., largeur = 2.
REAL :: surface = longueur * largeur
REAL :: pi = 4.*ATAN(1.)
REAL :: enorme = HUGE(1.e0)
f2003 Sont notamment autoriss dans les expressions dinitialisation les fonctions intrinsques lmentaires (cf. annexe A, p. 138), les fonctions intrinsques de transformation (portant sur les tableaux),
et les constructeurs de tableaux 17 (cf. 7.1.3, p. 81) et de structures (cf. 9.2.1, p. 103).

2.5.1

Les constantes nommes (ou symboliques),

Pour dclarer une constante nomme, cest dire attribuer une valeur fixe la compilation
un identificateur, il faut lui adjoindre lattribut PARAMETER, et linitialiser.
IMPLICIT NONE
INTEGER, PARAMETER :: n_points = 100
REAL, PARAMETER
:: pi = 3.1416
Il nest alors plus possible de modifier la valeur de ces constantes nommes, par exemple en crivant
pi=3.15.
Les constantes entires nommes peuvent aussi tre utilises pour paramtrer les dimensions de
certains tableaux (cf. 7.5.1, p. 89), qui seront ainsi fixes au moment de la compilation 18 .

2.5.2

Variantes des types prdfinis

Les types prdfinis comportent des variantes (sous-types), notamment selon le nombre doctets
choisis pour stocker lobjet, variantes que lon peut slectionner laide du paramtre KIND.
f2008
En fortran 2008, la liste des paramtres de variantes de type a t introduite dans le standard.
ils sont dfinis dans le module intrinsque ISO_FORTRAN_ENV 19 (cf. 6.4.5, p. 69), en particulier :
les 4 variantes dentiers obligatoires nomms en fonction de leur nombre de bits INT8, INT16,
INT32, INT64 20 , ainsi que le tableau des paramtres des variantes dentiers INTEGER_KINDS
qui comporte au moins 4 lments.
sens en labsence de d0
17. En fortran 95, les fonctions intrinsques ntaient gnralement pas autorises dans les expressions dinitialisation, quelques exceptions prs, parmi lesquelles les fonctions de prcision numrique et certaines fonctions lies au
profil des tableaux, dont REPEAT, RESHAPE, SELECTED_INT_KIND, SELECTED_REAL_KIND, TRANSFER, TRIM, LBOUND,
UBOUND, SHAPE, SIZE, KIND, LEN, BIT_SIZE, HUGE, EPSILON, TINY...
Ainsi, REAL :: enorme = HUGE(1.e0) tait autoris, mais REAL :: pi = 4.*ATAN(1.) ntait pas admis en fortran 95. Ces restrictions ont t leves avec le fortran 2003.
18. En C, dclarer une variable avec lattribut const permet de diagnostiquer une ventuelle tentative de modification (erreur dtecte par le compilateur gcc depuis la version 4.0), mais ne suffit pas pour en faire une constante
nomme, susceptible par exemple de dfinir la dimension dun tableau. Pour ce faire, il faut recourir la directive
#define du prprocesseur.
19. Avant la norme 2008, le compilateur nag (cf. Annexe E.2, p. 166) fournissait un module f90_kind.f90 qui
dfinissant lensemble des variantes de type.
20. Ces types entiers dont le nombre de bits est impos sont rapprocher des entiers de taille exacte int8_t,
int16_t et int32_t du C99 dfinis via stdint.h.

2.5. INITIALISATION

19

les 3 variantes de rels obligatoires nomms en fonction de leur nombre doctets REAL32,
REAL64, REAL128, ainsi que le tableau des paramtres des variantes de rels REAL_KINDS, qui
comporte au moins 3 lments, mais parfois plus.
La norme du fortran 2008 impose donc la prsence dentiers sur 64 bits et de rels sur 128 bits 21 .
chaque type est associ un sous-type par dfaut, qui peut dpendre de la machine ; ainsi,
les types numriques prdfinis ne garantissent pas une prcision indpendante de la machine. Si
lon veut sassurer de la portabilit numrique dune dclaration, en termes de domaine (range)
couvert ou de prcision, il faut faire appel des fonctions intrinsques afin de choisir les sous-types
en fonction du domaine et de la prcision.
pour les entiers, la fonction SELECTED_INT_KIND(r) o r est un entier positif, renvoie un
entier donnant le numro de la variante du type entier qui permet de couvrir le domaine
[10+r , 10+r ]. Si aucune variante entire ne convient, cette fonction renvoie la valeur -1 ;
pour les rels, la fonction SELECTED_REAL_KIND([p][,r]) renvoie un entier donnant le numro de la variante du type rel dont la prcision est au moins p (au sens donn par la
fonction PRECISION) ou une tendue couvrant le domaine fix par r (au sens donn par la
fonction RANGE, cest dire dont la valeur absolue reste dans lintervalle [10r , 10+r ]). Si
aucune variante flottante ne convient, cette fonction renvoie une valeur ngative.
Enfin la notion de portabilit numrique reste limite par la disponibilit des variantes dans un
environnement (processeur et compilateur) donn de programmation. Un programme qui requiert
une prcision ou un domaine exigeants pourra, dans certains environnements, ne pas trouver les
variantes ncessaires pour sexcuter. Mais il existe des bibliothques qui permettent des calculs
dans des prcisions non limites par le compilateur, par exemple avec des types drivs, notamment
fmlib en fortran.

2.5.3

Exemples de constantes nommes spcifiant les variantes des types


prdfinis

Il faut en premier lieu demander au compilateur le paramtre (KIND) de la variante de type


voulue avec SELECTED_INT_KIND, SELECTED_CHAR_KIND ou SELECTED_REAL_KIND : le rsultat est
une constante utilisable pour les dclarations de variables qui suivent et aussi pour dsigner la
variante associe des constantes. Le caractre soulign _ permet de prciser la variante du type
choisie : la variante 22 est indique aprs la valeur pour une constante numrique et avant pour
une constante chane de caractres (cf. 8.1.3, p. 95).
! recherche des variantes
INTEGER, PARAMETER :: ki = SELECTED_INT_KIND(10)
! ki=8 sous g95 32/64bits
! choix d'un type entier permettant de reprsenter 10**10
INTEGER, PARAMETER :: kr = SELECTED_REAL_KIND(9,100) ! kr=8 sous g95 32/64bits
! => type rel permettant de reprsenter 10**100 avec 9 chiffres significatifs
! dclaration des variables dans ces variantes
INTEGER(KIND = ki) :: i
REAL(KIND = kr)
:: r
WRITE(*,*) "ki = ", ki, " kr = ", kr ! dpendent du compilateur
i = 1000000000_ki
! 100000000_8 aurait t moins portable
r = 1.123456789e99_kr
! 1.123456789e99_8 aurait t moins portable
! r = 1.123456789e99
! donnerait un dpassement de capacit

2.5.4

Une mthode modulaire pour fixer la prcision des rels

Dans le cadre dun programme sensible la prcision des rels, il est important de disposer dun
moyen rapide et portable de modifier le sous-type de tous les rels utiliss (constantes et variables),
21. Sur les processeurs ne disposant pas dunit flottante suffisante, les rels sur 128 bits, qualifis de quad, sont
simuls de faon logicielle, au dtriment des performances.
22. La variante elle-mme peut tre une constante vraie ou une constante nomme.

20

CHAPITRE 2. TYPES, CONSTANTES ET VARIABLES

sans sappuyer sur des options de compilation (cf. E.7.2). Il suffit pour cela de dfinir la variante
de travail dans un module my_precision sous la forme dune constante nomme (wp), puis de
dclarer toutes les variables relles dans ce sous-type. Noter quil faut aussi exprimer toutes les
B constantes relles dans ce sous-type et spcifier le paramtre optionnel KIND=wp dans les fonctions
o la gnricit ne suffit pas assurer un calcul dans le sous-type voulu. Sachant que les sous-types
rels courants utilisent 32, 64 ou 80 bits, on pourra dfinir les paramtres de type associs (sp, dp,
edp) dans un module prliminaire real_precisions et faire le choix (ligne 11) par renommage via
=> dans le USE (cf. 6.4.3). Cest une mthode largement utilise par les bibliothques.
1
2
3
4
5
6
7

MODULE real_precisions
IMPLICIT NONE
! les differentes variantes de reels disponibles (g95/gfortran)
INTEGER, PARAMETER :: sp=SELECTED_REAL_KIND(p=6)
! simple precision 32 bits
INTEGER, PARAMETER :: dp=SELECTED_REAL_KIND(p=15) ! double precision 64 bits
INTEGER, PARAMETER :: edp=SELECTED_REAL_KIND(p=18) ! extra double precision 80
END MODULE real_precisions

8
9
10
11
12
13

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

MODULE my_precision ! ne modifier que ce module pour choisir la precision wp


!use real_precisions, only : wp => sp ! par exemple simple precision
USE real_precisions, ONLY : wp => dp ! ou sinon double precision
!use real_precisions, only : wp => edp ! ou sinon extra double precision
END MODULE my_precision
PROGRAM test_precision
USE my_precision
IMPLICIT NONE
! toujours utiliser le parametre (kind) de sous-type reel wp = working precision
! dans les declarations, dans les constantes et comme argument optionnel
REAL(kind=wp) :: r1 = .1_wp ! constante en accord avec le type
REAL(kind=wp) :: r2 = .1
! constante du type reel par defaut
REAL(kind=wp) :: r3, r4
r3 = REAL(HUGE(1)-100, kind=wp) ! conversion dans sous-type voulu
r4 = REAL(HUGE(1)-100) ! sans prciser le sous-type => par dfaut
WRITE(*,*) "digits=", DIGITS(r1), "epsilon=", EPSILON(r1)
WRITE(*,'(f23.21,a)') r1, " = 0.1 reprsent la prcision de travail"
WRITE(*,'(f23.21,a)') r2, " = 0.1 reprsent la prcision par dfaut"
WRITE(*,'(i10.10, a)') HUGE(1)-100, "
= huge(1) - 100 en entier"
WRITE(*,'(f12.1,a)') r3, " = huge(1) - 100 en rel la prcision de travail"
WRITE(*,'(f12.1,a)') r4, " = huge(1) - 100 en rel la prcision par dfaut"
END PROGRAM test_precision

digits= 53 epsilon= 2.220446049250313E-16


0.100000000000000005551 = 0.1 reprsent la prcision de travail
0.100000001490116119385 = 0.1 reprsent la prcision par dfaut
2147483547
= huge(1) - 100 en entier
2147483547.0 = huge(1) - 100 en rel la prcision de travail
2147483520.0 = huge(1) - 100 en rel la prcision par dfaut

2.6

Fonctions de conversion de type

Fortran possde de nombreuses fonctions de conversion (explicite) entre les types numriques et
leurs variantes, fonctions dcrites dans lannexe A.2, p. 140. En particulier, la conversion implicite
dentier en flottant est assure par REAL et celle de flottant en entier par INT qui tronque vers zro,
mais dautres choix sont possibles pour les conversions explicites : au plus proche avec NINT, par
excs avec CEILING, par dfaut avec FLOOR.
Ces fonctions de conversion numrique admettent un paramtre optionnel de KIND qui permet
de prciser la variante de type du rsultat.

Chapitre 3

Oprateurs et expressions
3.1

Les oprateurs numriques

Outre loprateur unaire - qui calcule loppos dun nombre 1 , le fortran dispose des quatre
oprateurs binaires daddition (+), de soustraction (-), de multiplication (*) et de division (/).
Ces quatre oprateurs binaires sont prvus pour travailler avec des oprandes de mme type (et
mme sous-type).
Mais le fortran 2 possde aussi un oprateur dlvation la puissance, not ** et qui est dfini
diffremment suivant la nature de lexposant :
si n est entier positif, a**n est dfini pour tout a rel ou entier par le produit de n facteurs
a a a (lexposant nest pas converti en rel) ;
si n est entier ngatif, a**n est dfini comme 1/a**(-n) ;
si x est rel, a**x nest dfini que si a est strictement positif et vaut alors exp(x ln(a))
Ainsi, pour lever un nombre une puissance entire positive, il faudra viter dutiliser un exposant
rel, comme par exemple dans a**4., qui forcerait lutilisation de la deuxime mthode, moins
prcise numriquement et plus coteuse.

3.1.1

Rgles de priorit entre les oprateurs numriques binaires

Quand lordre dvaluation nest pas impos par lutilisation de parenthses, les expressions
numriques sont values en respectant lordre de priorit suivant : (1) ** (2) * et / (3) + et -.
niveau de priorit gal et en labsence de parenthses, les valuations seffectuent en principe de
gauche droite, sauf pour loprateur **, pour lequel lvaluation se fait de droite gauche pour
c
c
respecter linterprtation classique de la notation mathmatique ab = a(b ) .
expression

value comme

a + b ** c / d / e

a + ( ( (b**c) / d ) / e )

a ** b ** c * d + e

( ( a ** (b**c) ) * d ) + e

cest--dire
bc /d
a+
e
bc
a d+e

Mais un compilateur peut sautoriser de modifier cet ordre, par exemple pour des raisons de
rapidit de calcul. Ainsi a/b/c est a priori valu comme (a/b)/c , mais si le compilateur
optimise la vitesse de calcul et considre que le processeur est plus rapide pour effectuer une
multiplication quune division, il pourra demander dvaluer dans lordre a/(b*c) .

3.1.2

Imperfections numriques des oprations lies aux types

Les oprations associatives algbriquement peuvent savrer non associatives sur ordinateur B
cause :
1. + peut aussi tre utilis comme oprateur unaire.
2. Contrairement au langage C, qui doit faire appel la fonction pow.

21

22

CHAPITRE 3. OPRATEURS ET EXPRESSIONS

des erreurs darrondi sur les rels en prcision limite,


ou des dpassements de capacit sur les rels comme sur les entiers.
Il est donc parfois prudent dimposer lordre dvaluation par des parenthses, voire de reformuler
les expressions.
Exemple de dpassement de capacit
2 5 k 4
avec des rels sur 32 bits.
15 c2 h3
4
3
Les calculs de k et de h vont provoquer des dpassements de capacit 3 par valeur infrieure
(underflow) : numrateur et dnominateur tant alors considrs comme nuls, leur rapport 0/0
est indtermin, et est affich sous la forme NaN soit Not-A-Number (cf C.1.2, 155). La
factorisation de (k/h)3 dans lexpression de limite le domaine des rsultats intermdiaires et
permet dviter le dpassement.
Cest le cas du calcul naf de la constante de Stefan =

Comment limiter les erreurs darrondi


Si par exemple a et b sont de signes opposs et de valeur absolue trs proches et trs suprieure
c, par prudence, on vitera dcrire a + b + c qui pourrait laisser le choix au compilateur.
On crira (a+b) + c pour minimiser lerreur darrondi, plus faible quavec a + (b+c) .
Le choix de lordre des oprations peut savrer crucial pour minimiser les erreurs darrondi,
par exemple dans lvaluation des sommes de sries. Dans ce contexte, on aura toujours intrt
commencer la sommation en accumulant les termes les plus petits entre eux, cest--dire en
commenant par le terme dindice le plus lev.

De mme, quand on doit parcourir un intervalle pas constant avec une variable relle x dans
une boucle DO avec compteur 4 , le calcul par addition qui accumule les erreurs darrondi doit tre
vit au profit du calcul par multiplication.
x = xmin - dx
DO i=1, n
x = x + dx
END DO

3.1.3

DO i=1, n
x = xmin + REAL(i-1) * dx
END DO

Conversions implicites

Lors de laffectation dune expression numrique dun type donn une variable dun type
numrique diffrent, il y a conversion implicite, avec ventuellement perte de prcision (par exemple
dans la cas dune expression entire affecte une variable relle), voire dpassement de capacit
(comme dans le cas dune expression relle affecte un entier). Noter que le compilateur gfortran
est capable de signaler les conversions implicites, grce loption -Wconversion (cf. E.6.1, p. 171).
REAL
:: r = 3.14, s
INTEGER, PARAMETER :: ki=SELECTED_INT_KIND(14) ! variante pour stocker 10**14
INTEGER :: j
INTEGER(KIND=ki) :: i = 1000000000000_ki ! = 10**12
j = r
! donnera j = 3, comme j = int(r)
s = i
! donnera s trs proche de 1000000000000 environ 1,2 10**5 prs
! mais stock approximativement comme s = real(i)
Il en est de mme lors de lvaluation dexpressions dites mixtes impliquant des oprandes de types
numriques diffrents : les oprandes sont alors promus au type le plus riche avant valuation. La
3. Noter cependant que lunit de calcul flottant (Floating Processor Unit) effectue bien souvent les calculs dans
des registres de 80, voire 128 bits permettant une prcision et un domaine tendus pour reprsenter les rsultats intermdiaires. Le dpassement ventuel peut tre mis en vidence en activant une option de compilation (-ffloat-store
cf. E.5.1 pour g95 et gfortran, -float-storecf. E.2.1 pour nagfor) interdisant lusage des registres tendus.
4. On rappelle que le compteur lui-mme est forcment entier pour viter les erreurs darrondi.

23

3.2. LES OPRATEURS DE COMPARAISON

hirarchie des types numriques comporte, par ordre de richesse croissante, les entiers, suivis des
flottants et au plus haut niveau les complexes. Au sein dun type donn, les variantes de type sont
classes selon le nombre doctets utiliss : par exemple le type DOUBLE PRECISION est plus riche
que le type prdfini REAL.
COMPLEX
REAL
INTEGER
v = u +
v = u +
s = r +
!
j = u +

r
i
i
r

:: u, v
:: r, s
:: i, j
! est calcul comme v = u + cmplx(r)
! est calcul comme v = u + cmplx(i)
! est calcul comme s = r + real(i)
combinaison des deux conversions implicites
! est calcul comme j = int(u + cmplx(r))

Pour une bonne lisibilit, on sefforcera de rendre explicites de telles conversions, en utilisant les
fonctions intrinsques dites de conversion de type 5 (cf. Annexe A.2, p. 140).

Cas de la division entire


Noter que loprateur / appliqu des entiers permet de calculer le quotient au sens de la B
division euclidienne 6 : par exemple avec des constantes, 5/3 donne 1, alors que 5./3. donne bien
1.666667. Ne pas croire quil suffit de stocker le rsultat de la division de deux entiers dans une
variable flottante pour imposer une division flottante : cest seulement le rsultat de la division
euclidienne qui est ensuite converti en flottant.
INTEGER :: i, j
REAL
:: x, y
DOUBLE PRECISION :: t1, t2
i = 3
j = 2
x = i / j
y = REAL(i) / REAL(j)
t1 = 1./3.
t2 = 1./3.d0

Dans lexemple ci-contre, x vaut 1. alors quavec


la conversion force dau moins un des oprandes
en flottant, y vaut 1.5. De mme, dans t1, la
division est value en simple prcision et le rsultat converti en double, alors que dans t2, elle
est value en double prcision.

Noter enfin que llvation dun entier une puissance entire ngative va donner lieu une B
division entire : par exemple 10**(-3) sera interprt 7 comme 1/10**3 ou encore 1/1000 qui est
nul. Mais 10.**(-3) donnera bien .001.

3.2

Les oprateurs de comparaison

Fortran possde six oprateurs de comparaison dont le rsultat est une variable boolenne.
Lancienne notation du fortran 77 est accepte (cf. table 3.1, p. 24).

5. Ces fonctions sont les quivalents de loprateur de conversion explicite du langage C ou cast, not en prfixant
lexpression par le type darrive entre parenthses.
6. Ce comportement est commun beaucoup dautres langages. Mais il est source de tellement derreurs que par
exemple le langage python a chang de convention au passage de la version 2 la version 3 en ajoutant un oprateur
spcifique, not // pour la division entire !
7. En particulier, si la constante relle 1.5e-3 vaut 1, 5 103 , lexpression constante relle 1.5*10.**(-3) a la
mme valeur alors que lexpression 1.5*10**(-3) est nulle.

24

CHAPITRE 3. OPRATEURS ET EXPRESSIONS

fortran
<
<=
==
>=
>
/=

fortran77
.LT.
.LE.
.EQ.
.GE.
.GT.
.NE.

signification
infrieur
infrieur ou gal
gal
suprieur ou gal
suprieur
diffrent de

remarques propos des notations


Ne pas confondre avec loprateur daffectation =
Ne pas confondre avec != du langage C

Table 3.1 Oprateurs de comparaison

REAL
INTEGER
IF( a > 0 ) b = LOG(a)
IF( i /= 0 ) r = 1. / REAL(i)

:: a, b, r
:: i
! a > 0 est valu .true. si a est positif

tant donn que les nombres flottants ne sont reprsents quapproximativement en machine, les
tests dgalit entre flottants sont dconseills ; on prfrera comparer les diffrences un seuil, en
utilisant la fonction intrinsque EPSILON (cf. annexe A.4, p. 142).
On remplacera par exemple : IF ( a == b ) THEN par :
IF ( ABS(a-b) <= c *ABS(a) * EPSILON(a) ) THEN
o c est une constante suprieure 1.

3.3

Les oprateurs boolens

Fortran dispose de quatre oprateurs logiques binaires permettant de combiner des expressions
logiques entre elles, ainsi que de loprateur unaire de ngation (cf. table 3.2, p. 24).

.AND.
.OR.
.NOT.
.EQV.
.NEQV.

ET
OU (inclusif)
Ngation unaire
quivalence
OU exclusif

Table 3.2 Oprateurs boolens

REAL
LOGICAL
grand = r > 1000.
petit = r < .0001
moyen = .NOT. (grand .OR. petit)

:: r
:: grand, petit, moyen

Lvaluation dune expression logique ne ncessite pas forcment celle de toutes ses sousexpressions : en particulier, si le premier oprande dun AND est faux ou si le premier oprande
dun OR est vrai, le rsultat ne dpend pas du second, mais la norme 8 ne garantit pas quil ne soit
B pas valu 9 . Afin dcrire du code portable, on ne sappuiera donc pas sur cette proprit pour
conditionner un calcul (cf. par exemple 6.5.1, p. 69).
8. Le compilateur g95 fournit cependant une option -fshort-circuit qui assure que le second membre dun
.AND. ou dun .OR. ne soit valu que si ncessaire.
9. Le langage C, linverse, assure une valuation minimale des oprandes du && et du ||.

3.4. OPRATEUR DE CONCATNATION DES CHANES DE CARACTRES

3.4

25

Oprateur de concatnation des chanes de caractres

Loprateur // permet de concatner 10 deux chanes de caractres.


CHARACTER(len=5)
CHARACTER(len=4)
CHARACTER(len=13)
date = jour//'-04-'//mois

3.5

:: jour='mardi'
:: mois='juin'
:: date
! contiendra 'mardi-04-juin'

Priorits entre les oprateurs

En fortran, les oprateurs intrinsques numriques dune part, loprateur de concatnation


de chanes dautre part ne manipulent que des types respectivement numriques ou chanes. La
prsence du type boolen 11 impose une premire hirarchie parmi les oprateurs : les comparaisons
donnant un rsultat boolen, elles ont une priorit infrieure aux oprateurs numriques et
loprateur //. Les oprateurs portant sur des boolens viennent donc en dernire priorit.
lintrieur de cette premire hirarchie, on place en tte lopration dlvation la puissance
(avec valuation commenant par la droite), multiplication et division avant addition et soustraction, mais les oprateurs unaires (+, -) avant leurs correspondants binaires.
Concernant les oprateurs logiques, .NOT. unaire est prioritaire devant les oprateurs binaires,
et .AND., assimil la multiplication, est prioritaire devant .OR., assimil laddition.
Les oprateurs intrinsques du fortran sont prsents par ordre de priorit dcroissante dans le
tableau 3.3, p. 25.
type
numriques
chanes
comparaisons
boolens

oprateurs
**
* et /
+ et - unaires
+ et - binaires
//
==, /=, <, <=, >=, >
.NOT.
.AND.
.OR.
.EQV. et .NEQV.

Table 3.3 Hirarchie des oprateurs intrinsques, classs par ordre de priorit dcroissante ; les
oprateurs figurant sur une mme ligne ont la mme priorit.
Par exemple, si x et y sont des rels, et ch1 et ch2 des chanes de longueur 2, lexpression :
x-y > -2. .or. x+y < 1. .and. ch1//ch2=='oui!'
est value comme :
((x-y) > -2.) .or. (((x+y) < 1.) .and. ((ch1//ch2) == 'oui!'))
Mais, par prudence et pour la lisibilit du code, on nhsitera pas expliciter les priorits par des
parenthses.
Noter que les oprateurs surchargs (cf. 10.2.1, p. 113) hritent de leur position intrinsque
dans la hirarchie. En revanche, les oprateurs nouvellement dfinis (cf. 10.2.2, p. 114) acquirent
la plus forte priorit sils ont unaires et la plus faible sils sont binaires.
10. En langage C, la concatnation de chanes de caractres est obtenue par simple juxtaposition, sans oprateur
explicite.
11. En C, la situation est nettement plus complexe : dune part, les oprateurs de comparaison donnent des rsultats
de type entier, susceptibles dintervenir dans des oprations numriques. dautre part, loprateur = daffectation
peut tre employ plusieurs fois dans une expression. Lusage des parenthses est donc encore plus conseill pour
faciliter linterprtation dune expression en C.

Chapitre 4

Structures de contrle

Le nommage des structures de contrle est facultatif, mais savre prcieux pour la lisibilit des
codes et leur maintenance ; il svre cependant ncessaire dans le cas dune rupture de squence
(cf. 4.3.3) qui ne concerne pas la boucle intrieure. Plus gnralement, il est fortement conseill de
nommer systmatiquement les structures comportant des ruptures de squence.

4.1
4.1.1

Structures IF
Linstruction IF

La forme la plus simple de lexcution conditionnelle est rserve au cas dune instruction
unique.

IF (<expression logique >) <instruction >


Si lexpression logique est value .TRUE., linstruction est excute ; sinon, le contrle est pass
linstruction suivante.
INTEGER :: i, j, k
IF(j /= 0) k = i/j

4.1.2

! k n'est calcul que si j est diffrent de 0

La structure IF ... END IF

Pour conditionner lexcution dun bloc dinstructions une condition, on emploie la structure :

[<nom > :] IF (<expression logique >) THEN


<bloc d'instructions > ! excut si la condition est vraie
END IF [<nom >]
o <nom > est un identificateur optionnel permettant dtiqueter le test.
INTEGER :: i
...
chiffre: IF (i < 10) THEN
WRITE(*,*) 'i est infrieur 10'
END IF chiffre
Cette structure peut comporter un bloc ELSE qui nest excut que si la condition est value
.FALSE. 1 .
1. Si lidentificateur est spcifi en tte de la structure IF, il devient ncessaire la fin du END IF, mais pas
forcment aprs le ELSE.

26

27

4.2. STRUCTURE SELECT CASE

[<nom > :] IF (<expression logique >) THEN


<bloc d'instructions > ! excut si la condition est vraie
ELSE [<nom >]
<bloc d'instructions > ! excut si la condition est fausse
END IF [<nom >]
Si un branchement est possible de lintrieur de la structure vers lextrieur, aucun accs vers cette
structure nest autoris sans passage par le test initial. Ces structures peuvent tre imbriques de
faon complexe, bien que, parfois, le recours un SELECT CASE savre plus efficace et plus lisible.
INTEGER :: i
...
chiffre: IF (i < 10) THEN
WRITE(*,*) 'i est infrieur 10'
ELSE chiffre
WRITE(*,*) 'i est suprieur ou gal 10'
END IF chiffre

4.1.3

Utilisation du ELSE IF

Dans le cas o plusieurs tests imbriqus sont effectus,


REAL :: a, b
IF ( a <= 0. ) THEN
...
ELSE
IF ( b <= 0. ) THEN
...
ELSE
...
END IF
END IF

! a <= 0
! a > 0

et

b <= 0

! a > 0

et

b > 0

le test ELSE IF permet de raccourcir lcriture. Noter qualors un seul END IF ferme la
structure globale.
REAL :: a, b
IF ( a <= 0. ) THEN
...
ELSE IF ( b <= 0. ) THEN
...
ELSE
...
END IF

! a <= 0
! a > 0

et

b <= 0

! a > 0

et

b > 0

Sous cette dernire forme (non-imbrique), il est possible dajouter autant de clauses ELSE IF(...) THEN
que ncessaire et la dernire clause ELSE nest pas obligatoire.

4.2

Structure SELECT CASE

Lorsque les choix possibles sont nombreux, et portent sur une mme expression, la structure
SELECT CASE est souvent plus efficace que son quivalent laide de IF imbriqus. Elle permet, au

28

CHAPITRE 4. STRUCTURES DE CONTRLE

vu de la valeur dune expression, de choisir un traitement parmi un ensemble de cas qui doivent tre
numrs : lexpression tester doit faire lobjet dun test dgalit ; cest pourquoi cette structure
ne peut sappliquer qu des types possdant une reprsentation exacte, lexclusion des rels.

[<nom > :] SELECT CASE (<expression >)


CASE (<slecteur_1 >) [<nom >]
<bloc d'instructions >
CASE (<slecteur_2 >) [<nom >]
<bloc d'instructions >
...
CASE (<slecteur_n >) [<nom >]
<bloc d'instructions >
CASE DEFAULT [<nom >]
<bloc d'instructions >
END SELECT [<nom >]
o <expression > est une expression de type entier, boolen ou chane de caractres, et <slecteur_i >
une constante ou une liste de constantes spares par des virgules, un lment de la liste pouvant
tre constitu dun intervalle de valeurs spcifi selon la syntaxe suivante :
<borne_infrieure >:<borne_suprieure >,
lune ou lautre des bornes pouvant tre omise 2 , ce qui permet de reprsenter un nombre infini de
valeurs. Le cas DEFAULT concerne les expressions qui nont concid avec aucun des slecteurs.
INTEGER :: i
tri: SELECT CASE (i)
CASE(0) tri
WRITE(*,*) ' i = 0'
CASE(1,-1) tri
WRITE(*,*) ' i = 1 ou i = -1'
CASE(2:10) tri
WRITE(*,*) ' 2 <= i <= 10'
CASE(11:) tri
WRITE(*,*) ' i >= 11'
CASE DEFAULT tri
WRITE(*,*) 'i < -1'
END SELECT tri

CHARACTER(len=3) :: rep
valid: SELECT CASE (rep)
CASE('oui','OUI') valid
WRITE(*,*) ' oui'
CASE('non','NON') valid
WRITE(*,*) ' non'
CASE DEFAULT valid
WRITE(*,*) 'rponse invalide'
END SELECT valid
2. Comme dans les shells de type sh dunix, mais contrairement au comportement du switch en langage C et des
shells de type csh, ds quun choix a t slectionn (et donc un bloc dinstructions excut), le contrle est pass
la fin de la structure ; cela quivaudrait en C faire suivre chaque bloc par linstruction break (ou breaksw en csh).

4.3. STRUCTURES DE BOUCLES

4.3

29

Structures de boucles

Pour effectuer des itrations, le fortran dispose des boucles DO avec ou sans compteur, et de la
boucle DO WHILE. Mais, lorsquil sagit de conditionner le traitement des lments dun tableau par
un test portant sur un tableau conformant (cf. 7.1.1), lutilisation de linstruction WHERE, ou de la
structure WHERE ... END WHERE (cf. 7.3.2, p. 84) savre plus efficace.

4.3.1

Boucles DO avec compteur

[<nom > :] DO <entier >=<debut >,<fin > [,<pas >]


<bloc d'instructions >
END DO [<nom >]
o <debut >, <fin > et <pas > sont des expressions entires 3 . La valeur du pas dincrmentation du
compteur est 1 par dfaut, mais peut tre ngative. Pour certaines combinaisons des paramtres, il
est possible que le bloc ne soit excut aucune fois. Il est interdit de modifier la valeur du compteur
au sein de la boucle ; sa valeur la fin de la boucle est la premire valeur qui ne respecte pas la
condition de fin de boucle, sauf en cas de sortie par EXIT.
INTEGER :: i, imax = 10, n
n = 0
impairs: DO i = 1, imax, 2
! donc i = 1, 3, 5, 7, 9
n = n + i
END DO impairs
WRITE (*,*) 'somme des entiers impairs infrieurs 10', n

4.3.2

Boucles DO WHILE

Si le nombre de passages nest pas connu avant lentre dans la boucle, elle doit tre contrle
non par un compteur mais par un test logique : cest lobjet de la boucle WHILE qui intervient de
faon classique dans les mthodes itratives. Par prudence, on comptera malgr tout le nombre de
passages pour dclencher une sortie par EXIT (cf. 4.3.3) si le nombre de passages dpasse une limite
raisonnable.

[<nom > :] DO WHILE (<expression_logique >)


<bloc d'instructions >
END DO [<nom >]
Tant que lexpression logique est vraie, le bloc dinstruction est excut. Pour que la boucle ait
un intrt, il faut que le bloc dinstruction modifie la valeur de lexpression logique un moment
donn.
INTEGER :: i, imax = 10, n
n = 0
i = 1
impairs: DO WHILE ( i <= imax )
n = n + i
i = i + 2 ! modification de l'expression qui intervient dans le test
END DO impairs
WRITE (*,*) 'somme des entiers impairs infrieurs 10', n
3. La possibilit dutiliser un indice de boucle rel a disparu de la norme lors du passage au fortran 90.

30

4.3.3

CHAPITRE 4. STRUCTURES DE CONTRLE

Ruptures de squence dans les boucles : EXIT et CYCLE

Les ruptures de squence dans les boucles sont possibles grce aux branchements EXIT et
CYCLE 4 .
Branchement lindice suivant (ventuel) : CYCLE
Linstruction CYCLE lintrieur dune structure DO ... END DO permet de court-circuiter la
fin du bloc et de passer le contrle lindice de boucle suivant.
INTEGER :: i, imax = 10, n
n = 0
impairs : DO i = 1, imax
! a priori 1,2,3,4, ... 10
IF ( modulo(i,2) == 0 ) CYCLE ! ne pas considrer les entiers pairs
n = n + i
END DO impairs
WRITE (*,*) 'somme des entiers impairs infrieurs 10', n
En cas de boucles imbriques, linstruction CYCLE concerne a priori la boucle la plus interne dans
laquelle elle est situe. Pour quelle puisse sadresser une boucle externe, il est ncessaire de
nommer la boucle et dutiliser son nom comme argument de CYCLE 5 .
INTEGER :: i, imax, j, jmax
externe: DO i = 1, imax
...
interne: DO j = 1, jmax
...
IF (<expr_log >) CYCLE externe ! fait passer au i suivant
...
END DO interne
...
END DO externe
Sortie de boucle : EXIT
Linstruction EXIT lintrieur dune structure DO ... END DO permet de sortir immdiatement
de la boucle et de passer le contrle linstruction qui suit le END DO.
INTEGER :: i, n
n = 0
DO i = 1, 1000, 2
! a priori de 1 999
IF ( i > 10 ) EXIT
! limitation 10 (un seul EXIT excut)
n = n + i
END DO
WRITE (*,*) 'somme des entiers impairs infrieurs 10', n
Dans le cas de boucles imbriques, comme pour linstruction CYCLE, linstruction EXIT ne sort
que de la boucle la plus interne dans laquelle elle est situe. Pour pouvoir sortir directement dune
boucle externe, il faut nommer la-dite boucle et utiliser la syntaxe EXIT <nom > 6 .
4. Ces instructions correspondent respectivement break et continue en langage C.
5. Ces possibilits de branchement sadressant une boucle externe nomme suivant la mme syntaxe quen
fortran existent aussi en java pour les branchements break et continue concernant des structures de contrle itratives
comme while ou for.
6. En fortran 2008, cette syntaxe sapplique dautres structures que les blocs (cf. 4.5, p. 32).

4.4. LA STRUCTURE BLOCK

4.3.4

31

Boucles DO sans compteur

[<nom > :] DO
<bloc d'instructions >
END DO [<nom >]
Cette structure de boucle, a priori infinie, na dintrt que si le bloc comporte une instruction
EXIT permettant de sortir de la boucle au vu dun test IF 7 .
INTEGER :: i
positifs: DO
WRITE(*,*) 'entrer un entier positif, sinon 0 pour terminer'
READ(*,*) i
IF ( i == 0 ) EXIT positifs
...
! bloc d'instructions
END DO positifs

f2008

4.4

La structure BLOCK

Fortran 2008 a introduit une structure de bloc, comparable celle dlimite par des accolades
en C89, entit o il est possible de dclarer des types, des variables, des constantes locales, aprs
des instructions excutables 8 . Les blocs peuvent tre imbriqus et nomms.

[<nom > :] BLOCK


<dclarations >
<instructions excutables >
END BLOCK [<nom >]
La porte de ces dclarations est alors limite au bloc o elles sont dclares et ses sous-entits..
En particulier, les tableaux dclars et allous dans un bloc sont implicitement dsallous en sortie
de bloc. Linstruction IMPLICIT est interdite dans un bloc.
Les entits dclares localement dans le bloc masquent celles de mme nom dclares dans
le contexte englobant. La structure de bloc permet donc dviter les conflits de nommage, en
particulier lors de linclusion de code via INCLUDE ou linstruction #include pour le prprocesseur.
En informant le compilateur du caractre local de certaines entits, elle peut aussi permettre daider
loptimisation du code.
PROGRAM bloc
! ok gfortran 4.9 le 16/10/2015
! ok nagfor 5.3(854) le 21/10/2015
IMPLICIT NONE
INTEGER :: i
INTEGER :: tmp ! globale
tmp = 5
WRITE(*,*) "boucle sur", tmp,"cas"
DO i=1, tmp
BLOCK
INTEGER :: tmp ! locale au bloc
! tmp locale masque tmp globale
7. condition de placer le test pour la sortie de la boucle en tte de bloc, cette structure permet de remplacer
la structure DO WHILE ... END DO, dconseille car mal adapte au calcul parallle.
8. Noter que, la diffrence du C99 ou du C++, fortran exige toujours que, dans le bloc, les dclarations soient
places avant les instructions excutables.

32

CHAPITRE 4. STRUCTURES DE CONTRLE

tmp = 2*i
WRITE(*,*) "locale", tmp
END BLOCK
END DO
WRITE(*,*) "globale", tmp
END PROGRAM bloc

f2008

4.5

Sortie de structure quelconque avec linstruction EXIT


nomm

En fortran 2008, linstruction de sortie EXIT peut sappliquer dautres structures que les
boucles, condition quelles soient nommes. En plus des boucles, EXIT suivi dun nom permet
notamment de sortir des structures nommes BLOCK, IF, SELECT CASE. Il faut donc distinguer deux
syntaxes :
EXIT suivi dun nom de structure transfre le contrle la fin de la structure ainsi nomme,
quelle quelle soit ;
EXIT non suivi dun nom de structure transfre le contrle la fin de la boucle englobante la
plus interne.
Pour viter toute ambigut en fortran 2008, on suivra le conseil de Metcalf et al. (2011) en
utilisant systmatiquement la syntaxe EXIT <nom >, y compris pour indiquer la sortie de la boucle
la plus interne.
externe : do i=1,n
interne: block
if(i >2) then
write(*,*) "sortie"
! exit ! sortie de la boucle do
! exit externe ! sortie de la boucle do
exit interne ! sortie du bloc nomm
end if
write(*,*) "dans le bloc", 2*i
end block interne
write(*,*) "dans la boucle", -2*i
end do externe

4.6
4.6.1

Autres instructions de contrle


Instruction CONTINUE

Linstruction vide CONTINUE, trs utilise pour dlimiter les fins de boucles dans les anciennes
versions du fortran, voit, avec lapparition du END DO, son emploi rduit aux rares branchements
spcifis par des tiquettes numriques (cf. 4.6.2, p. 32 et 4.6.6, p. 34).

4.6.2

Branchement par GO TO

Linstruction GOTO <tiquette_numrique > permet le branchement vers linstruction repre


par ltiquette numrique. Ltiquette numrique est un nombre entier positif qui doit tre plac
en dbut de ligne (premier caractre non blanc) et spare dau moins un espace de linstruction
sur laquelle se fait le branchement. Invitable dans les versions anciennes du fortran, lusage du
GOTO est fortement dconseill pour la lisibilit des programmes, et doit tre rserv au traitement
des circonstances exceptionnelles, quand elles ne peuvent tre gres via CYCLE ou EXIT.

4.6. AUTRES INSTRUCTIONS DE CONTRLE

4.6.3

33

Instruction STOP

Linstruction STOP [<code d'arrt >] impose larrt immdiat du programme et laffichage
ventuel du code darrt (une chane de caractres ou un entier dau plus 5 chiffres) qui peut tre
lui-mme repris par certains systmes dexploitation. Elle est utilise pour interrompre lexcution
en fin de programme principal ou un endroit quelconque depuis une procdure quelconque dans
des circonstances exceptionnelles ne permettant plus de poursuivre le traitement.
PROGRAM trait
...
CALL sub_prog
...
IF ( ... ) STOP 10
...
STOP
END PROGRAM trait
SUBROUTINE sub_prog
...
IF ( ... ) STOP 12
...
RETURN
END SUBROUTINE sub_prog

4.6.4

! interruption exceptionnelle
! fin normale

! arret exceptionnel
! retour normal au programme principal

Instruction RETURN

Linstruction RETURN transfre le contrle de la procdure (sous-programme ou fonction) o elle


est situe la procdure layant appele 9 . Elle nest pas autorise dans le programme principal.
Elle permet de mnager plusieurs retours de contrle vers le programme appelant, dans le cas de
traitements conditionnels.
Lexemple lmentaire qui suit nest cependant pas un modle de programmation structure et
de lisibilit.
PROGRAM trait
...
y1 = rac_cub(x1)
y2 = rac_cub(x2)
...
END PROGRAM trait
! une fonction racine cubique tendue tous les rels
FUNCTION rac_cub(x)
IMPLICIT NONE
REAL, INTENT(IN) :: x
REAL
:: rac_cub
rac_cub = 0.
! cas o x=0
IF ( x == 0. ) RETURN
! retour immdiat au programme principal
! la suite n'est vue que pour x non nul
rac_cub = ABS(x) ** (1./3.) ! calcul de la valeur absolue
IF ( x > 0 ) RETURN
! retour immdiat si x>0
rac_cub = - rac_cub
! cas x<0 : il faut encore changer le signe
RETURN
! retour au programme principal
END FUNCTION rac_cub
9. Ne pas confondre RETURN, qui rend le contrle lappelant, et STOP, qui interrompt lexcution.

34

4.6.5

CHAPITRE 4. STRUCTURES DE CONTRLE

Remarques sur les instructions STOP et RETURN

En fortran 77, linstruction STOP dans le programme principal, de mme que linstruction RETURN
dans les sous-programmes et fonctions, taient obligatoires juste avant END, quand END ntait quun
dlimiteur. En fortran 90, END est aussi un ordre excutable et STOP en fin de programme principal
ainsi que RETURN en fin de sous-programme ou de fonction sont donc devenus facultatifs.

4.6.6

Branchements dans les entres-sorties

Certains ordres dentre-sorties (cf. 5.3, p. 41), notamment OPEN, READ, WRITE 10 possdent
des arguments optionnels (accessibles par mot-clef) de branchement des instructions tiquetes
permettant de traiter des circonstances particulires quil est toujours prudent de prvoir :
en cas derreur : ERR=<tiquette_numrique > (OPEN, READ, WRITE) ;
en cas de fin de fichier : END=<tiquette_numrique > (READ) ;
en cas de fin denregistrement : EOR=<tiquette_numrique > (READ).
...
OPEN(...)
READ(..., ERR=900, ...)
...
STOP
900 CONTINUE
WRITE(*,*) 'erreur de lecture'
STOP 12
END PROGRAM ...

! traitement normal
! arrt normal
! branchement en cas d'erreur de lecture
! arrt exceptionnel aprs erreur de lecture

Pour viter les branchements sur des tiquettes numriques, on prfrera tester si le code de
retour IOSTAT des oprations dentres-sorties est non nul pour traiter ces cas particuliers laide
f2003 des structures de contrle classiques. Avec fortran 2003, les constantes IOSTAT_END et IOSTAT_EOR
du module ISO_FORTRAN_ENV permettent de distinguer dans ces cas les fins de fichier et denregistrement (cf. 5.3.1 p. 41). On peut aussi appeler une des fonctions boolennes IS_IOSTAT_END ou
IS_IOSTAT_EOR.

10. BACKSPACE, CLOSE, ENDFILE, INQUIRE et REWIND possdent aussi un argument optionnel de mot-clef ERR.

Chapitre 5

Entressorties, fichiers
Fortran dispose doutils sophistiqus pour raliser des transferts dinformations avec des fichiers,
mais il nest pas ncessaire de connatre toutes leurs possibilits pour mettre en uvre des programmes lmentaires. En sortie comme en entre, la mise en forme des donnes peut en effet tre
effectue avec dautres outils (filtres sous unix par exemple) plus adapts la manipulation des
chanes de caractres dans ces tapes de pr- ou post-traitement qui nimpliquent pas de calculs
lourds. Cest pourquoi, nous aborderons dabord (5.1) les entres-sorties standard (interactions
avec le terminal) avant de prsenter les concepts gnraux (5.2) et la syntaxe dtaille (5.3) des
instructions dentres-sorties. Ltude des nombreux exemples prsents dans les dernires sections
5.5 et 5.6 du chapitre devrait clairer les notions introduites dans les sections 5.2 et 5.3.

5.1

Introduction : entres et sorties standard

Nous avons dj utilis, sans les prsenter explicitement, les instructions daffichage (PRINT) et
de lecture (READ) au format libre. Ils respectent la syntaxe suivante :

PRINT *, <liste d'expressions >


READ *, <liste de variables >
o * reprsente le format libre et o les lments de la liste dentre-sortie sont spars par des
virgules.
INTEGER :: i, j
REAL :: a
PRINT *, 'donner deux entiers et un rel'
! affichage au format libre
READ *, i, j, a
! lecture au format libre
PRINT *, 'vous avez choisi i = ', i, ' j = ', j, ' a = ', a
Dans lexemple prcdent, la liste qui suit PRINT comporte seulement des chanes de caractres
constantes et des variables. Mais elle peut aussi comporter des expressions :
PRINT *, 'a = ', a, ' a*a = ', a**2, ' sin(a) = ', sin(a)

5.1.1

Une instruction dE/S = un enregistrement

La principale rgle rgissant la progression par dfaut des lignes dans les entres-sorties veut
que :
Chaque instruction de lecture ou dcriture provoque le passage la ligne suivante.
35

36

CHAPITRE 5. ENTRESSORTIES, FICHIERS

En particulier, si la liste est vide, en criture linstruction PRINT * produit un saut de ligne, de
mme quen lecture linstruction READ * saute une ligne dentres qui reste inexploite.
Cette rgle, essentielle pour comprendre en particulier criture et lecture des tableaux implique
que, si on utilise une boucle explicite pour afficher les lments dun tableau, on affiche un lment
par ligne (affichage en colonne). Pour afficher le tableau en une seule ligne, il faut (cf. 5.4.4, p. 50) :
soit, comme en fortran 77, utiliser une boucle implicite, qui produit au vol la liste des
lments pour linstruction dcriture,
soit, de faon plus concise, utiliser la notation globale pour lensemble des lments du tableau
afficher.

5.1.2

Saisie de donnes au clavier

Les donnes doivent tre crites au clavier sous une des formes admissibles pour les constantes
(cf. 2.4, p. 17) du type de la variable affecter. la conversion implicite prs des entiers en rels,
une diffrence de type provoque une erreur dexcution lors de la lecture.
Lors de la lecture dun enregistrement, une combinaison quelconque des saisies suivantes au
clavier :
un ou plusieurs espaces ;
une virgule 1 ;
un ou plusieurs changements de ligne,
est considre comme un sparateur de donnes, permettant de passer la lecture de la variable
suivante.
Au lieu de rpter <n > fois une valeur <val >, on peut utiliser la notation <n >*<val >. Tant que
la liste des variables 2 nest pas pas puise, la lecture des donnes peut se poursuivre sur plusieurs
lignes, donc la lecture dun enregistrement peut correspondre la saisie de plusieurs lignes.
Mais on peut arrter la lecture de lenregistrement avant davoir puis la liste par la saisie du
caractre / de fin denregistrement. Il est aussi possible de sauter une variable au sein de la
liste en saisissant deux virgules successivement. Dans ces deux cas, les variables non lues gardent
leur valeur antrieure.
Par exemple, pour les jeux dentres indiqus gauche de la flche (=), le programme suivant
affichera ce qui est indiqu droite.
PROGRAM lecture
IMPLICIT NONE
INTEGER :: i=10, j=20, k=30
! 3 entiers initialiss
PRINT *, 'donner 3 entiers'
READ *, i, j, k
PRINT *, ' i=', i, ' j=', j , ' k=', k
END PROGRAM lecture

1 2 3

1,,3

1,
3

1,2,3

2,

1
2
3

i= 1

j= 2

k= 3

1
,
,
3

i= 1

j= 20

k= 3

1 2 ,,

i= 1

j= 2

k= 30

1. Le sparateur de donnes virgule , est chang en point-virgule ; dans le cas o on a choisi la virgule
comme sparateur dcimal (cf. 5.4.2, p. 49).
2. Au sens scalaire du terme, donc par exemple chacun des lments dun tableau de rels.

37

5.2. GNRALITS ET TERMINOLOGIE

3*1

6*1

i= 1

j= 1

k= 1

Si on fournit plus de donnes que ncessaire, les donnes superflues sont perdues : ne pas croire
quelles sont disponibles pour linstruction de lecture suivante.
Le programme suivant comporte deux instructions de lecture, et ne peut lire lentier l quaprs
un changement denregistrement.
PROGRAM lecture2
IMPLICIT NONE
INTEGER :: i=10, j=20, k=30, l=40
! 4 entiers initialiss
PRINT *, 'donner 3 entiers puis 1 entier'
READ *, i, j, k
READ *, l
PRINT *, ' i=', i, ' j=', j, ' k=', k, ' l=', l
END PROGRAM lecture2
1
2
i= 1 j= 2 k= 3 l=4
=
3
4
Dans les applications lmentaires et en phase de mise au point, on se contente souvent du
format libre pour les entres et les sorties avec le terminal. Sil est parfois ncessaire de contraindre
le format en sortie pour amliorer la lisibilit, mme lcran, linverse, pour la lecture au clavier,
il est conseill dutiliser le format libre, sauf informer explicitement lutilisateur des contraintes
du format de saisie. En revanche, lorsque la quantit des donnes dentre devient importante, il
est souvent plus efficace de les saisir dans un fichier avec toutes les possibilits dun diteur, puis
de faire lire ce fichier par le programme.
1 2 3
4

5.2

1 2 3 -4 -5
4 -4

Gnralits et terminologie

Dans les changes de donnes plus massifs quavec le terminal, ou avec des fichiers dont le
format peut tre impos par dautres applications, il est souvent ncessaire de prciser les rgles
de conversion en entre ou en sortie grce une spcification de format.
INTEGER :: k
INTEGER, DIMENSION(100) :: ti ! tableau de 100 entiers
REAL, DIMENSION(100) :: tr
! tableau de 100 rels
OPEN(9, FILE='donnees.dat')
! ouverture du fichier => connect l'unit 9
DO k = 1, 100
READ(9, '(i4, f9.5)') ti(k), tr(k) ! lecture d'un enregistrement
END DO
CLOSE(9)
! fermeture du fichier
Dans cet exemple, chaque instruction READ lit dans le fichier donnees.dat un enregistrement
constitu dun entier cod sur 4 chiffres, suivi dun rel sur 9 caractres dont 5 aprs le point
dcimal. La chane de caractres i4, f9.5 constitue le format de lecture. Lobjectif de ce chapitre
est de dcrire les diffrentes instructions permettant les changes de donnes et dintroduire la
syntaxe des spcificateurs de format.

5.2.1

Fichiers externes et fichiers internes

Fichiers externes
Outre les entressorties standard qui soprent via le terminal, fortran peut contrler plusieurs
flux de donnes en lecture ou en criture associs des fichiers externes (external files), hbergs

38

CHAPITRE 5. ENTRESSORTIES, FICHIERS

par des priphriques (disquettes, disques, bandes magntiques, CD, ...).


Ces fichiers externes doivent tre connects des units logiques (logical unit) laide de linstruction OPEN. Linstruction CLOSE permet de fermer le fichier et donc de librer lunit logique
pralablement connecte. Une unit logique est dsigne par un entier positif ou nul.
Lentier dsignant lunit logique peut tre choisi entre 0 et une limite suprieure dpendant du
processeur 3, 4, 5 .
Units logiques standard
Mais les units logiques standard dentre et de sortie sont prconnectes par dfaut, et peuvent
tre dsignes par le symbole *.
Sous unix, lentre standard (clavier) et la sortie standard (cran) sont traditionnellement prconnectes respectivement aux units logiques 5 et 6. La sortie derreur standard est prconnecte
par dfaut lunit logique 0 ; pour crire sur la sortie derreur, il suffirait donc de prciser le
numro dunit logique 0.
Mais depuis fortran 2003, le module intrinsque ISO_FORTRAN_ENV (cf. 5.3.1, p. 41) dfinit
plusieurs constantes nommes caractrisant lenvironnement, dont les numros des units logiques
f2003 standard : input_unit, output_unit et error_unit, qui permettent donc de dsigner ces units
logiques de faon portable.
Fichiers internes
loppos des fichiers externes stocks sur un dispositif priphrique, on parle aussi dcriture
et de lecture sur des fichiers internes (internal files) cf. 8.4.3 p. 99 lorsque lon code des donnes
numriques sous forme de chanes de caractres (criture) ou inversement que lon dcode des
chanes de caractres reprsentant des donnes (lecture). Les fichiers internes ne sont que de simples
variables de type chane de caractres, explicitement dclares dans le programme et stockes en
mmoire vive. Ils sont notamment utiliss pour gnrer des formats variables pour des oprations
dentres-sorties (cf. 5.4.5, p. 51).

5.2.2

Notion denregistrement

Un enregistrement (record) est la gnralisation un fichier de la notion de ligne sur un terminal.


Un fichier est une suite denregistrements.
Lors dune opration dentre-sortie sur un fichier en accs squentiel, chaque instruction de
lecture ou dcriture provoque par dfaut 6 le passage lenregistrement suivant.

5.2.3

Fichiers formats et fichiers non formats

Les donnes numriques peuvent tre stockes dans des fichiers :


soit sous la forme de chanes de caractres (qui seront bien sr eux-mmes cods en binaire) :
les fichiers sont dits alors formats ou cods (formatted). Les entres-sorties standard seffectuent sous forme code.
soit directement sous la forme binaire utilise pour le stockage dans la mmoire de la machine :
les fichiers sont dits alors non-formats (unformatted).
Ainsi, lors des entres-sorties formates de donnes numriques sur des fichiers externes, les
instructions dcriture ou de lecture dclenchent en ralit successivement deux oprations : une
conversion 7 selon les rgles dfinies par un format et un transfert de donnes vers un priphrique.
Plus prcisment, suivant quil sagisse dentre ou de sortie formate, elle signifiera :
3. La limite suprieure est bien souvent celle des entiers par dfaut : soit 231 1 sur processeur 32 bits et 263 1
sur processeur 64 bits avec le compilateur g95 ; mais elle reste de 231 1 avec le compilateur xlf dibm.
4. Certaines bibliothques se rservent lusage dune plage fixe de numros dunits logiques, qui ne sont plus, en
consquence, disponibles pour les programmes de lutilisateur de ses bibliothques.
5. La lecture ou lcriture sur une unit logique n non connecte force la connexion implicite un fichier externe
dont le nom par dfaut est fort.n sous unix.
6. Il est possible, en fortran 90, de faire exception cette rgle grce loption ADVANCE=no.
7. Dans le cas dun fichier interne, cest la seule opration dclenche par linstruction dentre-sortie.

5.2. GNRALITS ET TERMINOLOGIE

39

soit dabord une lecture de chanes de caractres, puis une conversion en reprsentation
interne ;
soit dabord une conversion de la reprsentation interne en chanes de caractres, puis une
criture de chanes de caractres.
Si la conversion provoque une erreur lexcution, cest lensemble de linstruction qui choue,
ce qui savre particulirement gnant par exemple pour les entres interactives, en cas de faute de
frappe. Pour fiabiliser les saisies au clavier, on est amen exploiter les codes de retour de READ 8 .
La lecture seffectue alors dans une boucle qui ne sarrte que lorsquil ny a plus derreur.
1
2
3
4
5
6
7
8
9
10
11

PROGRAM robust_lect
IMPLICIT NONE
INTEGER :: i=-100, ok
WRITE(*,*) 'entrer un entier'
DO
READ(*, *, iostat=ok) i
IF(ok==0) EXIT
WRITE(*,*) 'erreur: recommencez'
END DO
WRITE(*,*) 'i=', i
END PROGRAM robust_lect
Choix entre fichier format ou non-format
Le choix entre les deux types de fichiers pour stocker des donnes numriques est dict par les
critres suivants :
non-formats : pas de conversion, donc transfert plus rapide et sans perte de prcision, fichiers
plus compacts ; mais fichiers non portables 9 et difficiles lire par dautres outils 10 ; en particulier, dans les fichiers binaires en accs squentiel, fortran crit et sattend lire, en tte
et en fin (cest moins gnant) de chaque enregistrement, une balise denregistrement (record
marker), sous forme dun entier 11 indiquant le nombre doctets de lenregistrement : il faut
en tenir compte si on accde au fichier au travers de programmes utilisant dautres langages ;
formats : lisibilit par dautres outils (filtres ou simples diteurs de texte), portabilit entre
applications et entre machines ; mais fichiers plus volumineux et accs plus lent ; perte de
prcision possible.

5.2.4

Mthodes daccs aux donnes

On distingue deux mthodes daccs aux enregistrements stocks dans des fichiers :
8. Cela impose dutiliser la deuxime syntaxe, plus complte, de READ, cf. 5.3.4, p. 44.
9. Les donnes numriques sur plusieurs octets peuvent tre enregistres en mmoire de deux faons, selon lordre
choisi entre les octets qui reprsentent la valeur en binaire :
dans lordre des poids dcroissants (octets de poids fort au dbut) : on parle dorientation big-endian ou
gros-boutiste.
dans lordre des poids croissants (octets de poids faible au dbut) : on parle dorientation little-endian ou
petit-boutiste.
Si la majorit les processeurs de PC, en particulier les x86 ont adopt lorientation litte-endian, les processeurs
de serveurs ibm, les PowerPC et les ia64 notamment sont dorientation big-endian. On notera que ces diffrences
peuvent concerner les entiers, mais aussi les flottants, car la norme IEEE 754 (cf. annexe C, p. 154) ne spcifie pas
lorientation des octets, et les caractres multi-octets dunicode (UTF-16 et UTF-32).
10. Sous unix, la commande od (octal dump) permet dafficher sous diverses formes le contenu binaire dun fichier.
Elle permet entre autres dafficher un aperu du contenu de fichiers binaires grce une ou plusieurs options -t qui
spcifient comment interprter les octets (nombre doctets grouper et conversion suivant un type), par exemple :
od -t d4 pour des entiers en dcimal sur 4 octets (32 bits) ;
od -t f4 ou od -t fF pour des rels sur 4 octets (32 bits) ;
od -t f8 ou od -t fD pour des rels en double prcision sur 8 octets (64 bits).
11. Cet entier peut tre cod sur 64 bits sur les processeurs 64 bits.

40

CHAPITRE 5. ENTRESSORTIES, FICHIERS

laccs squentiel (sequential), o les enregistrements sont stocks les uns la suite des
autres 12 et o, pour accder un enregistrement particulier, il est ncessaire de lire tous
les enregistrements prcdents ; dans ce mode, il nest pas possible de modifier un enregistrement sans compromettre lintgrit de tous les suivants ;
laccs direct (direct), o les enregistrements sont reprs par un numro qui permet (moyennant la connaissance de la taille, ncessairement fixe, des enregistrements) de calculer la
position de lenregistrement dans le fichier et daccder ainsi un enregistrement particulier
(y compris en criture) sans lire explicitement ceux qui le prcdent, ni affecter les suivants
(cf. 5.6, p. 54).
f2003 Le fortran 2003 a introduit une troisime mthode inspire du langage C, laccs stream ou flot,
combinant des avantages des deux prcdents. Le positionnement dans le fichier se fait en spcifiant le numro dunits de stockage (en gnral des octets) en commenant 1 en dbut de
fichier. Les fichiers formats en accs stream ont aussi une structure denregistrement, mais les fins
denregistrement doivent tre explicitement spcifies en crivant le caractre fourni par la fonction
intrinsque NEW_LINE 13 .
Choix entre accs direct et accs squentiel
Le choix entre les mthodes daccs aux donnes dpend de leur nature (qui peut dterminer
la taille des enregistrements), de leur volume (stockable facilement ou non dans des tableaux en
mmoire) et de lusage quon leur prvoit. Ce choix est parfois impos par les contraintes suivantes :
les enregistrements dun fichier accs direct sont ncessairement de taille fixe ;
seul laccs direct permet dcrire un enregistrement sans avoir rcrire la totalit du fichier.
Ainsi, les fichiers de bases de donnes, dont les enregistrements doivent pouvoir tre mis jour
de faon individuelle, et dont le volume ne permet pas un stockage facile en mmoire vive, sont
stocks dans des fichiers accs direct.
Parfois, alors que les deux mthodes sont envisageables, des considrations de performances
(mme en lecture seule) peuvent amener prfrer laccs direct, si par exemple on doit trs souvent
accder des donnes non contiges, de faon alatoire. Supposons par exemple quune fonction soit
chantillonne dans le plan au sein dun fichier selon une grille en coordonnes rectangulaires et que
lon souhaite la rchantillonner selon des coordonnes polaires ; lorsque lon calculera les valeurs
de la fonction en suivant un cercle, on devra accder des donnes certainement non contiges
dans le fichier initial, quil sera donc prfrable de lire en accs direct ; il sera donc prfrable de
crer le fichier initial en accs direct.

5.2.5

Notion de liste dentre-sortie

Dans une instruction dentre-sortie, les informations changes sont spcifies par une liste
dentre-sortie (i/o-list), qui est une liste dexpressions pour une instruction dcriture, mais doit
tre une liste de variables pour une instruction de lecture. Si un lment de la liste est un tableau,
il est quivalent la liste des lments du tableau 14 ; sil sagit dune structure, elle doit tre interprte comme la liste des champs de la structure. Enfin, la liste dentre-sortie peut comporter des
boucles implicites (aussi utilises comme constructeurs de tableau, cf. 7.1.3, p. 81), ventuellement
imbriques.
Dans lexemple suivant, chacune des trois instructions affiche le tableau t de la mme faon sur
une ligne.
INTEGER, DIMENSION(3) :: t = (/ 1, 2, 3 /)
INTEGER :: i
WRITE(*, '(3i4)') t

! tableau initialis
! affichage global

12. Comme sur une bande magntique qui est un support physique accs squentiel.
13. La fonction intrinsque NEW_LINE prend pour argument un caractre quelconque et rend le caractre de fin de
ligne de mme sous-type. Cest lquivalent du \n du langage C.
14. Le tableau est transform en liste en faisant varier dabord le premier indice, puis le deuxime, ... (cf. 7.1.2,
p. 80).

41

5.3. INSTRUCTIONS DENTRES-SORTIES

WRITE(*, '(3i4)') t(1), t(2), t(3)


WRITE(*, '(3i4)') (t(i), i=1, 3)

5.3

! liste exhaustive
! boucle implicite

Instructions dentres-sorties

Une opration de transfert de donnes requiert en gnral une instruction OPEN de connexion
entre unit logique et fichier, des instructions dchange READ ou WRITE, et enfin une instruction
CLOSE de libration de lunit logique. Les instructions dentres-sorties OPEN, READ, WRITE, PRINT
et INQUIRE se partagent des arguments obligatoires ou optionnels accessibles par mot-clef dont on
va dcrire les plus usits.
f2003

5.3.1

Le module intrinsque ISO_FORTRAN_ENV

Depuis fortran 2003, le module intrinsque ISO_FORTRAN_ENV dfinit des constantes nommes
qui permettent de dsigner de faon portable des paramtres concernant les entres sorties, notamment :
Les numros des units logiques prconnectes aux flux standard :
INPUT_UNIT, qui dsigne lentre standard (descripteur 0 sous unix permettant des redirections dentre via < fichier) ;
OUTPUT_UNIT, qui dsigne la sortie standard (descripteur 1 sous unix permettant des
redirections de sortie via > fichier) ;
ERROR_UNIT, qui dsigne la sortie derreur standard (descripteur 2 sous unix permettant
des redirections derreur standard via 2> fichier).
Si les units dentre et de sortie standard peuvent tre dsignes par * de faon plus rapide
que INPUT_UNIT et OUTPUT_UNIT, lutilisation de ERROR_UNIT est ncessaire pour dsigner la
sortie derreur de faon indpendante du compilateur.
Les entiers rendus par IOSTAT= dans les cas dchec doprations dentres/sorties suivants :
IOSTAT_END qui dsigne la fin de fichier ;
IOSTAT_EOR qui dsigne la fin denregistrement (End Of Record) ;
La valeur du code de retour IOSTAT peut tre compare ces paramtres pour effectuer
des traitements spcifiques au lieu davoir recours aux arguments optionnels END= ou EOR=
(cf. 4.6.6 p. 34), qui, eux, ncessitent le branchement sur une tiquette numrique.
FILE_STORAGE_UNIT qui dsigne lunit de mesure en bits (en gnral 8) des tailles denregistrement (RECL) dans les oprations OPEN (cf. 5.3.2 p. 42) et INQUIRE (cf. 5.3.7 p. 45).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

PROGRAM unites_standard
! standard fortran 2003 : emploi du module ISO_FORTRAN_ENV
USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : error_unit, input_unit, output_unit
IMPLICIT NONE
INTEGER :: i
WRITE(*,*) "entrer un entier"
! lecture sur l'entre standard (descripteur 0 sous unix)
! redirection d'entre par < fichier
READ(input_unit, *)i
WRITE(*,*) "i vaut ", i
! criture sur la sortie standard (descripteur 1 sous unix)
! redirection par 2> fichier
WRITE(output_unit,*) "message sur la sortie standard"
! criture sur la sortie standard d'erreur (descripteur 2 sous unix)
! redirection par 2> fichier
WRITE(error_unit,*) "message d'erreur"
END PROGRAM unites_standard

42

CHAPITRE 5. ENTRESSORTIES, FICHIERS

Noter que fortran 2003 fournit aussi les deux fonctions IS_IOSTAT_END et IS_IOSTAT_EOR qui
attendent pour argument la valeur du code de retour IOSTAT et rendent un boolen vrai en cas de fin
de fichier ou de fin denregistrement. Ces fonctions boolennes testent donc lgalit IOSTAT_END
ou IOSTAT_EOR.

5.3.2

OPEN

Linstruction OPEN permet de connecter un fichier une unit logique.

OPEN ([UNIT=]<entier >, FILE=<nom_fichier >, ERR=<tiquette >, &


IOSTAT=<iostat >, ...)
Dans cette syntaxe, seul le premier argument (numro dunit logique) est positionnel et tous les
paramtres sont accessibles par mot-clef. Seuls les paramtres dsigns par les mots-clefs UNIT et
FILE sont presque toujours obligatoires, la plupart des autres paramtres sont optionnels avec des
valeurs par dfaut indiques ci-dessous.
[UNIT=]<entier > dsigne le numro de lunit logique ; cette unit logique ne doit pas tre
dj connecte 15 ;
f2008

NEWUNIT=<nu > renvoie un numro dunit logique non utilis dans la variable entire <nu >.
Cet argument, introduit par fortran 2008, permet dviter davoir prendre en charge soimme (cf. 5.3.7, p. 45) la recherche dun numro libre. Pour viter toute collision avec des
numros (positifs) attribus avec UNIT=, le numro rendu est ngatif (et diffrent de -1).
FORM=<fmt > o <fmt > est une chane de caractres gale 'FORMATTED' (valeur par dfaut)
ou 'UNFORMATTED' pour un fichier non format ;
FILE=<nom_fichier > dsigne le nom du fichier connecter, sous forme dune chane de
caractres (constante ou variable) ;
ERR=<tiquette > dsigne une tiquette numrique permettant un branchement 16 en cas
derreur ;
IOSTAT=<iostat > est un paramtre de sortie qui rend une variable entire nulle si lopration
sest droule sans erreur, ou sinon une valeur prcisant le type derreur rencontre ;
STATUS=<status > dsigne ltat du fichier ouvrir et peut valoir :
'OLD' dans le cas dun fichier prexistant
'NEW' dans le cas o le fichier nexiste pas
'REPLACE' qui permet le remplacement ou la cration suivant que le fichier existe ou
non
'UNKNOWN' dans le cas o on ne sait pas a priori si le fichier existe
'SCRATCH' pour un fichier temporaire qui sera dtruit lors de linstruction CLOSE

f2003

ACCESS=<mthode > spcifie si le fichier est en accs squentiel 'SEQUENTIAL' (par dfaut),
en accs direct 'DIRECT' ou (en fortran 2003 seulement) en accs stream 'STREAM' ;
ACTION=<mode > indique les oprations possibles sur le fichier (elles supposent que lutilisateur
possde des droits daccs suffisants sur le fichier)
'READ' si ouvert en lecture seule
'WRITE' si ouvert en criture seule
'READWRITE' (dfaut) si ouvert en lecture et criture
POSITION=<pos > prcise la position louverture dun fichier en accs squentiel :
'APPEND' positionne la fin du dernier enregistrement avant la marque de fin de fichier
et permet dajouter des informations la fin dun fichier existant
'REWIND' positionne en dbut de fichier
15. On peut vrifier quun numro dunit logique est disponible en utilisant linstruction INQUIRE (cf. 5.3.7, p. 45).
16. On vitera ce branchement en testant si le code de retour IOSTAT est non nul.

5.3. INSTRUCTIONS DENTRES-SORTIES

43

'ASIS' ouvre le fichier la position courante sil est dj connect, mais dpend du
processeur sinon
RECL=<entier > indique la longueur des enregistrements pour un fichier accs direct (paramtre obligatoire dans ce cas) ou la longueur maximale des enregistrements pour un fichier
squentiel (paramtre optionnel dans ce cas, la valeur par dfaut dpendant du compilateur) ;RECL sexprime en nombre de caractres pour les fichiers formats, mais dans une unit
qui peut tre loctet ou le mot de 32 bits, selon le compilateur et ses options ;
BLANK est une chane de caractres spcifiant linterprtation des blancs dans les lectures de
donnes numriques : si elle vaut 'null' (par dfaut), les blancs sont ignors, si elle vaut
'zero', ils sont interprts comme des zros ;
DELIM spcifie le dlimiteur des chanes de caractres en criture, qui peut tre 'none' (dfaut), 'quote' ou 'apostrophe'.
DECIMAL spcifie le sparateur entre la partie entire et la partie fractionnaire des nombres flottants. Par dfaut, cest le point, mais la virgule peut lui tre substitue par DECIMAL='comma'. f2003
Pour rtablir le point, il faut prciser DECIMAL='point'.
Noter que ces conventions peuvent aussi tre modifies dans les ordres de lecture (cf. 5.3.4,
p. 44) et dcriture (cf. 5.3.5, p. 45).
ENCODING permet de prciser le codage des chanes de caractres dans le fichier format
ouvrir. Les fichiers texte au codage UTF-8 dUnicode sont pris en charge par le standard f2003
2003 grce au paramtre optionnel ENCODING='UTF-8' de OPEN. Il est prudent de lire de
tels fichiers dans des variables chane de caractres dont la variante de type, par exemple
'ISO_10646' (cf. 8.1.3, p. 95), permet de reprsenter les caractres dUnicode.
Exemple de lecture dun fichier de 6 caractres cods en UTF-8 et dcriture en
code ISO-8859-1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

PROGRAM io_utf8_latin1
IMPLICIT NONE
! 9 oct 2012 fichier source en iso-latin1
! avec NAG Fortran Compiler Release 5.3(854)
! les kind des chanes (4 en utf-32 et 1 en default)
INTEGER, PARAMETER :: utf32=SELECTED_CHAR_KIND('ISO_10646') ! UCS_4 = UTF-32
INTEGER, PARAMETER :: def_char=SELECTED_CHAR_KIND('DEFAULT') ! Default=latin1
CHARACTER(LEN=6, KIND=def_char) :: latin
CHARACTER(LEN=6, KIND=utf32) :: lu_utf32 ! chane UTF-32
! lecture sur fichier externe cod UTF-8
OPEN(UNIT=10, FILE='fichier-utf8.txt', ENCODING='utf-8')
READ(10, *) lu_utf32(1:)
CLOSE(10)
latin = lu_utf32 ! transcodage UTF32-> default =latin1
WRITE(*,*) "latin1:", latin ! affichage iso-latin1
! criture sur fichier externe en latin1
OPEN(UNIT=10, FILE='fichier-latin1.txt', ENCODING='DEFAULT') ! latin1
WRITE(10,'(a)') latin
CLOSE(10)
END PROGRAM io_utf8_latin1

Le texte du fichier cod UTF-8 est lu dans des variables de type chanes UTF-32, puis converti 17
dans des variables de type ISO-8859-1 et enfin crit dans un fichier au codage par dfaut.
Exemples
Pour connecter le fichier format lect.dat lunit 10 en accs squentiel, on peut se contenter
de linstruction :
17. Noter que dans la norme fortran 2003, seul le transcodage depuis et vers le code par dfaut est requis : ici, le
dfaut tant ISO-8859-1, il permet de transcoder des chanes avec des caractres non-ascii en UTF-32 vers du latin1.

44

CHAPITRE 5. ENTRESSORTIES, FICHIERS

OPEN(UNIT=10, FILE='lect.dat')
Il est aussi possible de prciser :
OPEN(UNIT=10, FILE='lect.dat', FORM='formatted', ACCESS='sequential')
Mais il est prudent de prvoir une gestion des erreurs avec par exemple :
INTEGER :: ok ! status de retour
OPEN(UNIT=10, FILE='lect.dat', IOSTAT=ok)
IF( ok /= 0 ) THEN
PRINT *, 'erreur fichier lect.dat'
STOP
! arrt dfaut de meilleure solution
END IF

5.3.3

CLOSE

Linstruction CLOSE permet de dconnecter une unit logique dun fichier 18 . Elle libre lunit
logique pour une nouvelle connexion.

CLOSE ([UNIT=]<entier >, ERR=<tiquette >,


IOSTAT=<iostat >, STATUS=<stat >)

&

Les arguments de CLOSE sont tous optionnels sauf lunit logique et ont la mme signification
que dans linstruction OPEN, sauf STATUS=<status > qui dsigne ici le devenir du fichier aprs
dconnexion et peut valoir :
'KEEP' (par dfaut 19 ) pour conserver un fichier prexistant ;
'DELETE' pour dtruire le fichier la dconnexion.

5.3.4

READ

Linstruction READ possde deux variantes :


dans la premire, lunit logique nest pas prcise et il sagit de lentre standard ; elle est le
symtrique en entre de PRINT (cf. 5.1, p. 35) ;
la seconde respecte la syntaxe suivante, o seul le premier argument (lunit logique) est
positionnel :

READ ([UNIT=]<entier >, ERR=<tiquette >, END=<tiquette >, &


IOSTAT=<iostat >, ...) liste d'entres
Selon le type de fichier et daccs, dautres arguments deviennent obligatoires ou optionnels 20 :
aucun autre argument pour les fichiers squentiels non formats ;
largument FMT=<format > spcifiant le format est obligatoire et les arguments ADVANCE='no',
SIZE=<taille > (qui donne le nombre de caractres effectivement lus par linstruction READ),
EOR=<tiquette > (branchement si on rencontre la fin de lenregistrement en cas de lecture
avec ADVANCE='no') sont optionnels pour les fichiers squentiels formats ;
END=<tiquette > branchement si on rencontre la fin de fichier ;
largument REC=<numro_d_enregistrement > est obligatoire pour les fichiers en accs direct non formats ; les arguments REC=<numro_d_enregistrement > et FMT=<format > sont
obligatoires pour les fichiers en accs direct formats ;

45

5.3. INSTRUCTIONS DENTRES-SORTIES

largument optionnel POS=<position > permet de choisir la position en units de stokage f2003
dans les fichiers en accs stream.
Les branchements conditionnels EOR= et END= sont dconseills en fortran 2003, o lusage du f2003
module intrinsque ISO_FORTRAN_ENV ou des fonctions boolennes IS_IOSTAT_END ou IS_IOSTAT_EOR
(cf. 5.3.1, p. 41) permet de tester si le code de retour IOSTAT vaut IOSTAT_EOR ou IOSTAT_END.

5.3.5

WRITE

Linstruction WRITE suit la syntaxe gnrale

WRITE ([UNIT=]<entier >, ERR=<tiquette >, &


IOSTAT=<iostat >, ...) liste_de_sortie
o seul le premier paramtre est positionnel et laquelle, il faut ajouter suivant le type de fichier
et daccs dautres paramtres obligatoires ou optionnels (cf. 5.4.4, p. 50) :
aucun autre argument pour les fichiers squentiels non formats ;
largument FMT=<format > spcifiant le format est obligatoire et largument ADVANCE='no',
est optionnel pour les fichiers squentiels formats ;
largument REC=<numro_d_enregistrement > est obligatoire pour les fichiers en accs direct
non formats ;
les arguments REC=<numro_d_enregistrement > et FMT=<format > sont obligatoires pour
les fichiers en accs direct formats ;
largument optionnel POS=<position > permet de choisir la position en units de stokage f2003
dans les fichiers en accs stream.

5.3.6

PRINT

Linstruction PRINT <fmt > [, <liste >] permet dcrire en mode format sur la sortie standard la liste optionnelle des variables ou constantes indiques aprs la virgule ; elle est quivalente
WRITE(*, <fmt >) [, <liste >].

5.3.7

INQUIRE

Linstruction INQUIRE permet de senqurir de certains paramtres caractrisant un flux dentre


sortie, dfini :
soit par un nom de fichier (seule solution si le fichier na pas t ouvert) ;
soit par une unit logique ;
soit par une liste de sortie.
Par exemple, avant de connecter un fichier une unit logique via linstruction OPEN, on peut
rechercher un numro dunit logique disponible 21 et sassurer que le fichier existe.
LOGICAL :: pris, present
INTEGER :: n = 1, nmax = 99
DO n = 1, nmax
INQUIRE(UNIT=n, OPENED=pris)
IF (.not. pris) EXIT
END DO
INQUIRE(FILE='fichier', EXIST=present)
18.
19.
20.
21.

! l'unit n est libre

Larrt dun programme provoque implicitement un CLOSE sur toutes les units connectes par le programme
Sauf pour les fichiers ouverts avec STATUS='scratch', pour lesquels la valeur par dfaut est DELETE.
avec un sens identique celui ventuellement donn pour linstruction OPEN
En fortran 2008, on prfrera utiliser largument NEWUNIT de OPEN (cf. 5.3.2, p. 42).

46

CHAPITRE 5. ENTRESSORTIES, FICHIERS

IF(present) THEN
OPEN(UNIT=n, FILE='fichier', ...)
...
ELSE
...
END IF

! le fichier existe

Le paramtre de sortie ENCODING du standard 2003 permet dobtenir le codage des chanes de
f2003 caractres dans un fichier format connect une unit logique. On peut ainsi dtecter le codage
'UTF-8' dUnicode mais 'UNKNOWN sera rendu si la dtection nest pas possible.
Dautre part, linstruction INQUIRE permet dvaluer la taille de lenregistrement que crerait
lcriture non-formate dune liste 22 . Elle permet ainsi de connatre la longueur dun enregistrement
dun fichier non-format en accs direct avant de le connecter une unit logique (cf. 5.6.2, p. 55),
de faon rendre linstruction douverture du fichier indpendante de la machine.
INTEGER :: long, iunit
INQUIRE(IOLENGTH=long) <liste d'expressions >
...
OPEN(iunit, FILE=..., ACCESS='direct', FORM='unformatted', RECL=long)
...
Enfin, pour les fichiers en accs stream, INQUIRE permet de senqurir de la position courante
dans le fichier exprime en units de stockage qui sont souvent des octets. Dans le cas dun fichier
non format, les dcalages peuvent tre calculs avec INQUIRE(IOLENGTH=variable).
INTEGER :: iunit, positionx
REAL :: x, y
OPEN(iunit, FILE=..., ACCESS='stream', FORM='unformatted')
...
INQUIRE(iunit, POS = positionx) ! POS = argument de sortie (prochaine I/O)
READ(iunit) x ! lecture de x
...
WRITE(iunit, POS = positionx) y ! POS = argument d'entre
! criture de y la place de x
...

5.3.8

Instructions de positionnement dans les fichiers

Il existe enfin des instructions permettant, sans effectuer de transfert de donnes, de modifier
la position courante dans un fichier daccs squentiel :
REWIND ([UNIT=]<entier > [, ERR=<tiquette >] [, IOSTAT=<iostat >])
positionne en dbut de fichier ;
BACKSPACE ([UNIT=]<entier > [, ERR=<tiquette >] [, IOSTAT=<iostat >])
positionne avant lenregistrement courant si on est dans un enregistrement ou avant le prcdent enregistrement si on est entre deux enregistrements (cette instruction permet la relecture
dun enregistrement) ;
ENDFILE ([UNIT=]<entier > [, ERR=<tiquette >] [, IOSTAT=<iostat >])
crit 23 une marque de fin de fichier la position courante et positionne juste aprs cette
marque de fin de fichier.
22. Cette taille dpend en gnral de la machine.
23. Ne pas croire que ENDFILE est une simple instruction de positionnement en fin de fichier. Ce positionnement
est possible louverture du fichier via loption POSITION='APPEND' de linstruction OPEN (cf. 5.3.2).

47

5.4. DESCRIPTEURS DE FORMAT

5.3.9

Entres-sorties sans avancement automatique

Le paramtre ADVANCE='no' permet de ne pas avancer automatiquement lenregistrement


suivant chaque instruction dentre-sortie sur un fichier en accs squentiel et donc de transfrer
des parties denregistrement, cest dire de lignes pour les interactions avec le terminal 24 .
Par exemple, pour maintenir le curseur juste aprs une invite saisir une donne, on crira :
WRITE(*, '(a)', ADVANCE='no') 'entrer un entier : '
READ(*, *) i
De mme, pour traiter une saisie incomplte au clavier, on pourra utiliser le branchement EOR et
le paramtre de retour SIZE :
INTEGER :: nlus = 4
CHARACTER(len=4) :: chaine='++++'
WRITE(*, '(a)') 'entrer quatre caractres'
READ(*, '(a4)', advance ='no', size=nlus, eor=999) chaine(1:4)
GO TO 1000
! si lecture correcte
999 WRITE(*,*) 'saisie tronque' ! si retour chariot avant les 4 caractres
1000 WRITE(*, *) nlus, ' caractres lus'

5.4

Descripteurs de format

Les rgles de conversion entre reprsentation interne des donnes et chane de caractres des
fichiers formats sont dtermines par le format de lecture ou dcriture. Le format peut tre spcifi
sous une des formes suivantes :
le format libre, dsign par * ;
une chane de caractres constante ou variable, dcrivant le format entre parenthses ;
une tiquette numrique (entier positif) faisant rfrence une instruction dite de format.
Le format libre est utilis pour les changes avec le terminal, en phase de test ou pour accder des
fichiers manipuls toujours sur la mme machine, car il nest pas portable. Mais, pour des changes
de donnes plus massifs avec des fichiers ou de donnes dont le format peut tre impos par des
applications externes, il est souvent ncessaire de prciser les rgles de conversion en entre ou en
sortie grce une spcification de format. La dernire forme, avec tiquette numrique dinstruction
est prfre lorsquune mme spcification de format est utilise plusieurs fois dans une unit de
programme ; il est alors dusage de regrouper les instructions de format en fin de programme et de
leur rserver une plage dtiquettes numriques particulire.
CHARACTER(LEN=4) :: fmt1, fmt2
INTEGER :: j = 12
WRITE(*, *) 'bonjour'
WRITE(*, '("bonjour")')
WRITE(*, '(a7)') 'bonjour'
fmt1='(a7)'
WRITE(*, fmt1) 'bonjour'
WRITE(*, 1000) 'bonjour'
1000 FORMAT(a7)
!
WRITE(*, *) j
WRITE(*, '(i)') j

! format libre
! chane de caractres constante
! chane de caractres variable
! tiquette numrique
! format libre
! chane de caractres constante

24. Cest le comportement par dfaut en langage C, o les changements de ligne doivent tre explicitement spcifis
par des \n. On retrouve ce comportement par dfaut avec laccs STREAM du fortran 2003.

48

CHAPITRE 5. ENTRESSORTIES, FICHIERS

WRITE(*, '(i2)') j
fmt2='(i2)'
WRITE(*, fmt2) j
fmt2='(i4)'
WRITE(*, fmt2) j
WRITE(*, 1100) j
1100 FORMAT(i2)

! chane de caractres variable


! chane de caractres variable
! tiquette numrique

Comme le format est une expression de type chane de caractres, il peut tre dfini par une
variable value lors de lexcution : cette mthode sera prsente la sous-section 5.4.5, p. 51.
On distingue les descripteurs actifs, qui spcifient le mode de conversion dune donne en chane
de caractres ou rciproquement (a priori un descripteur actif par lment de la liste dentre-sortie),
les chanes de caractres et les descripteurs de contrle, qui, entre autres, rglent le positionnement,
grent les espaces et les changements denregistrement.

5.4.1

Descripteurs actifs

Dune faon gnrale, le premier paramtre (entier), n , dtermine le nombre total de caractres
occups par la donne code, cest dire avant conversion en lecture ou aprs conversion en criture.
La signification de lventuel deuxime paramtre dpend du type de donne convertir.
Si le champ est plus large que ncessaire, la donne code est justifie droite ; en criture, le
champ est complt par des blancs gauche. Si la largeur n du champ de sortie est insuffisante
compte tenu de tous les caractres requis (signe, exposant ventuel avec son signe, ...), la conversion
en sortie est impossible et provoque lcriture de n signes * 25 .
entiers (en sortie, p prcise le nombre minimal de caractres de chiffres ou de lettres (hors
signe et blancs), quitte complter par des zros gauche) :
In [.p ] en base 10
rels (p spcifie le nombre de chiffres aprs la virgule) :
Fn.p en notation dcimale
en virgule flottante :
mantisse (<1) plus exposant : En.p
mantisse (<1) plus exposant avec q chiffres : En.p [eq ]
notation scientifique (mantisse entre 1 et 10) : ESn.p
notation ingnieur (mantisse entre 1 et 1000, exposant multiple de 3) : ENn.p
boolens : Ln
chane de caractres : An
Pour une analyse plus bas niveau, les descripteurs B, O et Z (voir les notations associes pour les
f2008 constantes, 2.4, p. 17) sont utilisables pour les entiers et, en fortran 2008, les rels :
Bn [.p ] en binaire
On [.p ] en octal
Zn [.p ] en hexadcimal
Enfin, un descripteur qualifi de gnral permet la conversion de tous les types de donnes : Gn.p .
Dans le cas des rels, il assure une conversion en virgule fixe (format Fn.p ) si possible (si la valeur
absolue de lexposant nest pas trop grande) ou sinon en virgule flottante (format En.p ).
Les nombres complexes sont traits comme un couple de nombres rels, entre parenthses et spars par une virgule, comme dans les constantes complexes ; ils ncessitent donc deux descripteurs
de format rels.
f95
Enfin, on peut demander que la largeur du champ sajuste lexcution de faon nutiliser
que le minimum de caractres ncessaires en spcifiant une largeur nulle pour les spcificateurs I,
25. Ce comportement est contraire celui du langage C, qui tendrait alors le champ occup pour convertir la
donne.

5.4. DESCRIPTEURS DE FORMAT

49

B, O, Z et F, en sortie seulement 26 . Cette possibilit a t tendue au format G en fortran 2008,


avec G0 pour tous les types intrinsques et G0.p pour les rels.
f2008

5.4.2

Descripteurs de contrle

X provoque lcriture dun blanc en sortie et le saut dun caractre en entre


/ provoque le changement denregistrement (cest dire le changement de ligne)
Tabulations
Tn positionne le pointeur sur le n ecaractre de lenregistrement
TLn (tab left) dplace le pointeur de n caractres vers la gauche
TRn (tab right) dplace le pointeur de n caractres vers la droite ; TRn est quivalent
n X.
Interprtation des blancs en lecture 27
BN ignore les blancs (internes ou finaux) en lecture de champs numriques
BZ considre les blancs (internes ou finaux) comme des zros en lecture de champs
numriques
Signe plus optionnel : les trois options qui suivent contrlent lcriture ventuelle dun signe
+ devant les quantits positives ; si une option est spcifie, elle reste en vigueur tant quune
autre option ne vient pas la contredire, pour toutes les critures qui suivent dans la mme
instruction.
SP (sign print) force lcriture du signe + devant les quantits positives
SS (sign suppress) supprime lcriture du signe + devant les quantits positives
S rtablit loption par dfaut dpendant du processeur 28 pour lcriture du signe +
devant les quantits positives
: interrompt la prise en compte des descripteurs passifs lorsque la liste est puise par les
descripteurs actifs du format
k P descripteur de changement dchelle, applicable seulement aux rels et complexes, et qui
modifie les valeurs des rels lus ou crits sans exposant 29 , mais simplement la forme de ceux
crits avec exposant. Il sapplique toutes les conversions via les descripteurs qui le suivent
dans la mme instruction, et peut tre modifi par un descripteur n P ou annul par 0P.
en entre, k P divise par le facteur 10k les valeurs lues sans exposant 30 , permettant par
exemple une saisie plus rapide dune srie de valeurs trs faibles ;
en sortie, cest le format qui impose la prsence ou labsence dun exposant (sauf pour
le format G) et leffet de k P appliqu un rel dpend du format de conversion :
en format F, il multiplie par 10k ;
en format E, la mantisse est multiplie par 10k alors que lexposant est diminu de
k , la valeur restant inchange ;
en format G, leffet dpend du choix entre E et F suivant la valeur ;
en format EN et ES, le facteur dchelle est sans effet.
dc (decimal comma) ou dp (decimal point) spcifient le sparateur dcimal : par dfaut cest un f2003
point, mais ces spcificateurs permettent de le changer et la modification perdure jusquau
26. Ce format de largeur minimale spcifie par n=0 est comparable au format par dfaut du langage C, o lon
ne prcise pas la largeur du champ.
27. Bien noter que les formats BN et BZ ne contrlent pas blancs et zros en criture, qui dpendent du compilateur.
Linterprtation des blancs en lecture peut aussi tre spcifie de faon plus gnrale via le paramtre optionnel
BLANK= de linstruction OPEN.
28. Pour crire des fichiers portables, on ne laissera donc pas le choix au processeur, et on spcifiera systmatiquement soit SP, soit SS.
29. On vitera lemploi du descripteur k P cause de cette modification de valeur peu explicite lors de la conversion.
30. En particulier, malgr un format de lecture E ou D, on peut lire un rel avec ou sans exposant et la conversion
dpendra alors de la forme lors de la lecture, rendant le rsultat imprvisible pour une saisie au clavier : cela constitue
une raison supplmentaire pour viter lemploi du format P en lecture.

50

CHAPITRE 5. ENTRESSORTIES, FICHIERS

prochain descripteur dp ou dc. Ce choix 31 peut aussi tre fait au niveau des instructions
OPEN (cf. 5.3.2, p. 42), READ (cf. 5.3.4, p. 44), et WRITE (cf. 5.3.5, p. 45), selon la syntaxe
decimal='point' ou decimal='comma'. Dans le cas o le sparateur dcimal est la virgule,
en entre, le sparateur entre valeurs passe de la virgule au point-virgule ; (cf. 5.1.2, p. 36).
Exemple :

la saisie 1,23;5,67e8, le programme suivant

PROGRAM decimal_comma
IMPLICIT NONE
REAL :: r,t
WRITE(*,*) 'entrer 2 rels spars par ; (notation dcimale avec virgule)'
READ(*, *, decimal='comma') r, t
WRITE(*, '("avec virgule", dc, 2e12.4)') r, t
WRITE(*, '("avec point ", dp, 2e12.4)') r, t
END PROGRAM decimal_comma
affiche :
avec virgule
avec point

5.4.3

0,1230E+01
0.1230E+01

0,5670E+09
0.5670E+09

Syntaxe des formats et rgles dexploration

Une liste de descripteurs, spare par des virgules, peut tre rige en groupe de descripteurs,
dlimit par des parenthses.
Un facteur de rptition (entier positif prfixant le descripteur) peut tre appliqu un
descripteur de format ou un groupe de descripteurs.
Chaque instruction dentre-sortie provoque le passage lenregistrement suivant, sauf si largument optionnel ADVANCE='no' a t spcifi.
En principe la liste dentre-sortie comporte autant dlments quil y a de descripteurs actifs
dans le format. Dans le cas contraire, on applique les principes suivants :
B

Si la liste puise les descripteurs actifs du format, il y a passage lenregistrement


suivant 32 et r-exploration du format en partant de la parenthse ouvrante correspondant
lavant-dernire parenthse fermante du format, et en tenant compte de son ventuel facteur
de rptition.
Si la liste contient moins dlments quil y a de descripteurs actifs dans le format, il est honor
jusquau premier descripteur actif redondant exclus, sauf si on rencontre le descripteur de
contrle :, qui interrompt lexploration du format lorsque la liste est puise.

5.4.4

Boucles et changements denregistrement

Comme, en accs squentiel, chaque instruction dentre-sortie fait par dfaut progresser dun
enregistrement dans le fichier, une boucle explicite sur le nombre dlments dun tableau avec une
instruction READ/WRITE dans la boucle ne permet pas de lire ou crire tous les lments du tableau
dans un enregistrement unique. On peut alors utiliser soit une instruction agissant sur le tableau
global, soit une boucle implicite. Mais, pour viter des changements denregistrements intempestifs,
il faut aussi sassurer (cf. 5.4.3, p. 50) que le format spcifi nest pas puis par la liste, ce qui
provoquerait une rexploration du format.
31. Avec le compilateur g95, il est possible de choisir la virgule comme sparateur dcimal au moment de lexcution, grce la variable denvironnement G95_COMMA boolenne, par dfaut FALSE (cf. E.5, p. 169).
32. Sauf pour les fichiers accs stream ou dans le cas o ADVANCE=no a t pralablement spcifi.

51

5.4. DESCRIPTEURS DE FORMAT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

PROGRAM format_tab
IMPLICIT NONE
INTEGER, DIMENSION(3) :: t = (/ 1, 2, 3 /)
! tableau initialis
INTEGER :: i
WRITE(*, '(3i4)') t(:)
! tableau global => affichage en ligne
DO i = 1, 3
! boucle explicite
WRITE(*, '(i4)') -t(i)
! => un changement d'enregistrement par ordre
END DO
! => affichage en colonne
WRITE(*, '(3i4)') (2* t(i), i=1, 3)! boucle implicite => affichage en ligne
WRITE(*, '(i4)') (-2*t(i), i=1, 3) ! format rexplor => en colonne
DO i = 1, 3
! boucle explicite
WRITE(*, '(i4)', ADVANCE='no') 3*t(i) ! mais option advance='no'
END DO
! => affichage en ligne
WRITE(*, *)
!passage l'enregistrement suivant la fin
END PROGRAM format_tab
Le programme prcdent affiche successivement :
t en ligne avec le tableau global (ligne 5) ;
-t en colonne avec la boucle explicite (lignes 6 8) ;
2*t en ligne avec la boucle implicite (ligne 9) ;
-2*t en colonne malgr la boucle implicite (ligne 10),
car le format ne satisfait quun lment de la liste et
est donc rexplor ;
3*t en ligne malgr la boucle explicite (lignes 11
13), grce ADVANCE='no'.

5.4.5

1
-1
-2
-3
2
-2
-4
-6
3

Format variable

Il nexiste pas proprement parler 33 de format variable en fortran. Mais il est possible de
dterminer le format lexcution, car il peut tre dfini par une variable chane de caractres.
Lopration seffectue donc en deux tapes, avec par exemple :
une instruction dcriture sur un fichier interne qui construit la variable de type chane contenant le format ;
linstruction dentre-sortie utilisant ce format.
titre dexemple, le programme suivant montre comment choisir le nombre n de chiffres (entre
1 et 9) pour afficher un entier i.
1
2
3
4
5
6
7
8
9
10

PROGRAM var_fmt
! format variable l'excution
IMPLICIT NONE
INTEGER :: i = 123 ! le nombre (au maximum 9 chiffres) afficher
INTEGER :: n
! le nombre de chiffres (<=9) pour l'afficher"
CHARACTER(LEN=1) :: chiffres ! n cod sur un caractre
CHARACTER(LEN=6) :: fmt="(i?.?)" ! la chane de format modifier
n = 4
! premier cas
! criture sur fichier interne (en format fixe !)
WRITE(fmt(3:3), '(i1)') n
33. Certaines extensions propritaires du fortran, notamment le compilateur dIntel (cf. chap. E.4, p. 168) , celui
dIbm, xlf, (cf. chap. E.1, p. 165) et celui de Portland (cf. chap. E.3, p. 167), permettent le format variable : des
expressions numriques entires encadres par les dlimiteurs < et > peuvent figurer dans la chane de caractres dfinissant le format ; elles sont interprtes chaque opration dentre-sortie. Par exemple, WRITE(*,"(I<j>.<j>)") j
permet dcrire lentier j avec exactement j chiffres. Le format variable est aussi disponible dans le langage C avec
le spcificateur de format * : printf("%*d\n", n, i); imprime lentier i avec n chiffres.

52

11
12
13
14
15
16
17
18
19

CHAPITRE 5. ENTRESSORTIES, FICHIERS

WRITE(fmt(5:5), '(i1)') n
WRITE(*, fmt) i
n = 7
! deuxime cas
! autre mthode : criture sur une sous-chane
WRITE(chiffres, '(i1)') n
! concatnation pour construire le format
fmt = "(i" // chiffres // "." // chiffres // ")"
WRITE(*, fmt) i
END PROGRAM var_fmt
Avec n=4 puis n=7, il produit les affichages successifs :
0123
0000123

5.5
5.5.1

Exemples dentres-sorties formates


Descripteurs de donnes numriques en criture

criture de donnes entires


Noter que les lignes trop longues ont t replies : la suite est introduite par le symbole .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

criture des entiers 1, 20, 300, -1, -20, -300 et 0


criture de ces entiers en format libre
1 20 300 -1 -20 -300 0
criture de ces entiers en format In[.p] (dcimal)
|i1|.....|1|*|*|*|*|*|0|
|i1.0|...|1|*|*|*|*|*||
|i2|.....|1|20|**|-1|**|**|0|
|i2.2|...|01|20|**|**|**|**|00|
|i3|.....|1|20|300|-1|-20|***|0|
|i4|.....|1|20|300|-1|-20|-300|0|
|i4.2|...|01|20|300|-01|-20|-300|00|
|i5|.....|1|20|300|-1|-20|-300|0|
|sp,i5|..|+1|+20|+300|-1|-20|-300|+0|
|i5.0|...|1|20|300|-1|-20|-300||
|i5.4|...|0001|0020|0300|-0001|-0020|-0300|0000|
|i5.5|...|00001|00020|00300|*****|*****|*****|00000|
format I0 largeur ajustable (f95/2003 seulement )
|i0|.....|1|20|300|-1|-20|-300|0|
|i0.2|...|01|20|300|-01|-20|-300|00|
criture de ces entiers en format Zn[.p] (hexadcimal)
|z8|.....|1|14|12C|FFFFFFFF|FFFFFFEC|FFFFFED4|0|
|z8.8|...|00000001|00000014|0000012C|FFFFFFFF|FFFFFFEC|FFFFFED4|00000000|
format Z0 largeur ajustable (f95/2003 seulement)
|z0|.....|1|14|12C|FFFFFFFF|FFFFFFEC|FFFFFED4|0|
|z0.4|...|0001|0014|012C|FFFFFFFF|FFFFFFEC|FFFFFED4|0000|
criture de ces entiers en format On[.p] (octal)
|o8|.....|1|24|454|********|********|********|0|
|o8.8|...|00000001|00000024|00000454|********|********|********|00000000|
format O0 largeur ajustable (f95/2003 seulement)
|o0|.....|1|24|454|37777777777|37777777754|37777777324|0|
|o0.4|...|0001|0024|0454|37777777777|37777777754|37777777324|0000|
criture de ces entiers en format Bn[.p] (binaire)
|b8|.....|1|10100|********|********|********|********|0|

5.5. EXEMPLES DENTRES-SORTIES FORMATES

34
35
36
36
37
37

|b8.8|...|00000001|00010100|********|********|********|********|00000000|
format B0 largeur ajustable (f95/2003 seulement)
|b0|.....|1|10100|100101100|11111111111111111111111111111111|111111111111111111111

11111101100|11111111111111111111111011010100|0|
|b0.4|...|0001|10100|100101100|11111111111111111111111111111111|111111111111111111

11111111101100|11111111111111111111111011010100|0000|
criture de donnes relles

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

criture des rels 1.23456789, 1.23456789e4, 1.23456789e-2


puis de leurs opposs
criture de ces rels en format libre
1.234568 12345.68 0.01234568
-1.234568 -12345.68 -0.01234568
criture de ces rels en format Fn.p
format Fn.p avec n >0 (fortran 90)
|f9.1|...|1.2|12345.7|0.0|
|f9.1|...|-1.2|-12345.7|0.0|
|f9.3|...|1.235|12345.680|0.012|
|f9.3|...|-1.235|*********|-0.012|
format F0.p largeur ajustable (fortran 95/2003 seulement)
|f0.0|...|1.|12346.|0.|
|f0.0|...|-1.|-12346.|0.|
|f0.3|...|1.235|12345.680|0.012|
|f0.3|...|-1.235|-12345.680|-0.012|
criture de ces rels en format En.p[eq]
|e12.4|..|0.1235E+01|0.1235E+05|0.1235E-01|
|e12.4|..|-0.1235E+01|-0.1235E+05|-0.1235E-01|
|e12.4e1||0.1235E+1|0.1235E+5|0.1235E-1|
|e12.4e1||-0.1235E+1|-0.1235E+5|-0.1235E-1|
criture de ces rels en format ESn.p (scientifique)
|es12.4|.|1.2346E+00|1.2346E+04|1.2346E-02|
|es12.4|.|-1.2346E+00|-1.2346E+04|-1.2346E-02|
criture de ces rels en format ENn.p (ingnieur)
|en12.4|.|1.2346E+00|12.3457E+03|12.3457E-03|
|en12.4|.|-1.2346E+00|-12.3457E+03|-12.3457E-03|
criture de ces rels en format Gn.p (gnral)
|g9.3|...|1.23|0.123E+05|0.123E-01|
|g9.3|...|-1.23|-.123E+05|-.123E-01|

5.5.2
1
2
3
4
5
6
7
8
9
10

Descripteurs de contrle en criture

criture des six entiers 1, 20, 300, -1, 20, -300


Espace avec "x" (i4, x, i4, x, i4, x, i4, x, i4, x, i4)
120300-1-20-300
Rptition: (6i4)
120300-1-20-300
Groupement avant rptition : (6(x,i4))
120300-1-20-300
Changement d'enregistrement forc par "/" : (3(x,i4),/,3(x,i4))
120300
-1-20-300

11
12

53

Liste plus longue => rexploration avec changement d'enregistrement

54

13
14
15
16
17
18
19
20
21
22

CHAPITRE 5. ENTRESSORTIES, FICHIERS

Rexploration du format (x, i4, x, i4)


120
300-1
-20-300
Rexploration du format (3(x, i4))
120300
-1-20-300
Rexploration partir de 3(x, i4) : (9x, 3(x, i4))
120300
-1-20-300

23
24
25
26
27
28
29
30

Liste plus courte => arrt avant le 1er descripteur actif inutilis
arrt aprs "[<" dans le format (8("[","<",i4,">","]"))
[<1>][<20>][<300>][<-1>][<-20>][<-300>][<
Liste plus courte avec ":" => arrt juste aprs le ":"
suivant le dernier descripteur actif utile
arrt via ":" (8("[","<",i4,">",:,"]"))
[<1>][<20>][<300>][<-1>][<-20>][<-300>

31
32
33
34
35
36
37
38
39
40

Usage des tabulations


Rfrence (6(6x, i4))
120300-1-20-300
12345678901234567890123456789012345678901234567890123456789012345678901234567890
Tabulation droite format (6(tr6, i4))
120300-1-20-300
Tabulations absolues et gauche => changement d'ordre possible !
format (t7,i4, t17,i4, t27,i4, t57,i4, tl14,i4, tl14,i4)
120300-300-20-1

5.6

Exemples de fichiers en accs direct

Les deux exemples lmentaires suivants prsentent lcriture dun fichier accs direct, sa
lecture avec affichage des donnes et la mise jour dun des enregistrements.

5.6.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Exemple de fichier format en accs direct

PROGRAM direct
! fichier format en accs direct
IMPLICIT NONE
INTEGER :: ok=0, i, ir, nr
REAL :: a
INTEGER, PARAMETER :: iunit=11, n=10, recl=12
! cration du fichier en accs direct
OPEN(FILE='base.dat', UNIT=iunit, ACCESS='direct', RECL=recl, &
FORM='formatted', STATUS='replace')
ecriture: DO i=1, n
WRITE(UNIT=iunit, REC=i, FMT='(i4, 2x, f6.2)') 1000+i, 10*i + float(i)/10.
END DO ecriture
! lecture du fichier en accs direct et affichage
ir=1
lecture: DO ! on ne sait pas a priori o s'arrter
READ(UNIT=iunit, REC=ir, FMT='(i4, 2x, f6.2)', IOSTAT=ok) i, a
IF (ok /= 0) EXIT ! fin de fichier
WRITE(*, '(i4, 2x, f6.2)') i, a
ir = ir + 1

5.6. EXEMPLES DE FICHIERS EN ACCS DIRECT

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

55

END DO lecture
WRITE(*,*) ir-1, ' enregistrements lus'
ok=0
! modification d'un enregistrement du fichier en accs direct
WRITE(*,*) 'choisir un numro d''enregistrement modifier'
READ *, nr
READ(UNIT=iunit, REC=nr, FMT='(i4, 2x, f6.2)') i, a
WRITE(*,*) 'ancienne valeur ', a, ' entrer la nouvelle valeur relle'
READ *, a
WRITE(UNIT=iunit, REC=nr, FMT='(i4, 2x, f6.2)') i, a
ir=1
relecture: DO ! on ne sait pas a priori o s'arrter
READ(UNIT=iunit, REC=ir, FMT='(i4, 2x, f6.2)', IOSTAT=ok) i, a
IF (ok /= 0) EXIT ! fin de fichier
WRITE(*, '(i4, 2x, f6.2)') i, a
ir = ir + 1
END DO relecture
WRITE(*,*) ir-1, ' enregistrements lus'
ok=0
CLOSE(iunit)
END PROGRAM direct

5.6.2

Exemple de fichier non-format en accs direct

Dans le cas non-format, cest linstruction INQUIRE (ligne 8) qui permet de dterminer la taille
de lenregistrement, qui dpend du processeur.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

PROGRAM direct
! fichier non format en accs direct
IMPLICIT NONE
INTEGER :: ok=0, i, ir, nr, recl
REAL :: a
INTEGER, PARAMETER :: iunit=11, n=10
! calcul de la longueur d'un enregistrement via INQUIRE
INQUIRE(IOLENGTH=recl) i, a !
WRITE(*,*) 'longueur d''un enregistrement ', recl
! cration du fichier en accs direct
OPEN(FILE='base.dat', UNIT=iunit, ACCESS='direct', RECL=recl, &
FORM='unformatted', STATUS='replace')
ecriture: DO i=1, n
WRITE(UNIT=iunit, REC=i) 1000+i, float(10*i) + float(i)/10.
END DO ecriture
! lecture du fichier en accs direct et affichage
ir=1
lecture: DO ! on ne sait pas a priori o s'arrter
READ(UNIT=iunit, REC=ir, IOSTAT=ok) i, a
IF (ok /= 0) EXIT ! fin de fichier
WRITE(*, '(i4, 2x, f6.2)') i, a
ir = ir + 1
END DO lecture
WRITE(*,*) ir-1, ' enregistrements lus'
ok=0
! modification d'un enregistrement du fichier en accs direct
WRITE(*,*) 'choisir un numro d''enregistrement modifier'
READ *, nr
READ(UNIT=iunit, REC=nr) i, a

56

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

CHAPITRE 5. ENTRESSORTIES, FICHIERS

WRITE(*,*) 'ancienne valeur ', a, ' entrer la nouvelle valeur relle'


READ *, a
WRITE(UNIT=iunit, REC=nr) i, a
! re-lecture du fichier en accs direct et affichage
ir=1
relecture: DO ! on ne sait pas a priori o s'arrter
READ(UNIT=iunit, REC=ir, IOSTAT=ok) i, a
IF (ok /= 0) EXIT ! fin de fichier
WRITE(*, '(i4, 2x, f6.2)') i, a
ir = ir + 1
END DO relecture
WRITE(*,*) ir-1, ' enregistrements lus'
ok=0
CLOSE(iunit)
END PROGRAM direct

Chapitre 6

Procdures
6.1
6.1.1

Introduction
Intrt des procdures

Ds quun programme commence dpasser une page ou comporte des duplications dinstructions, il savre avantageux de le scinder en sous-ensembles plus lmentaires, nomms procdures,
qui seront appeles par le programme principal. En itrant ce processus, on structure le code source
en une hirarchie de procdures plus concises et modulaires, qui permet :
damliorer la lisibilit et de faciliter la vrification et la maintenance ;
de rutiliser des outils dj mis au point par dautres applications, au prix dune gnralisation
et dun paramtrage des procdures.
Par exemple, au lieu de dupliquer chaque usage toutes les instructions de calcul de la somme
des n premiers entiers (le seul paramtrage de cet exemple lmentaire), il est prfrable de les
crire une fois pour toutes dans un sous-programme not cumul qui sera appel chaque fois que
ncessaire. Ce sous-programme devra communiquer avec lappelant via deux arguments :
le nombre des entiers sommer fourni par lappelant (argument dentre) ;
la valeur de la somme renvoye lappelant (argument de sortie).
SUBROUTINE cumul(n, s)
IMPLICIT NONE
INTEGER, INTENT(in) :: n
INTEGER, INTENT(out) :: s
INTEGER
:: i
s = 0
DO i = 1, n
s = s + i
END DO
END SUBROUTINE cumul

! argument d'entre
! argument de sortie
! variable locale

Les appels successifs de ce sous-programme se feront alors de la manire suivante :


...
CALL cumul(10, s)
! appel de cumul pour sommer les 10 premiers entiers
PRINT *, ' somme des 10 premiers entiers = ', s
...
p = 5
CALL cumul(p, s)
! appel de cumul pour sommer les 5 premiers entiers
PRINT *, ' somme des ', p, ' premiers entiers = ', s
...
57

58

CHAPITRE 6. PROCDURES

6.1.2

Variables locales, automatiques et statiques

Les variables dclares au sein dune procdure sont, a priori, locales. On dit que leur porte
(scope) est limite lunit de programme. Par dfaut, les variables locales dune procdure nont
dexistence garantie que pendant son excution : elles sont qualifies dautomatiques ; elles ne sont
pas ncessairement mmorises 1 entre deux appels. Cest le cas de la variable i dans la procdure
cumul (cf. 6.1.1, p. 57).
On peut cependant forcer cette mmorisation, pour en faire des variables statiques, grce
B lattribut SAVE. Ne pas croire qualors la porte de la variable soit tendue : elle reste locale
mais est alors permanente. De plus, si une variable locale est initialise lors de sa dclaration,
elle devient immdiatement une variable statique 2 . Ne pas oublier que linitialisation est effectue
par le compilateur, une fois pour toute et diffre donc dune instruction excutable daffectation
effectue chaque appel 3 .
Par exemple, le sous-programme compte suivant affiche le nombre de fois quil a t appel. Si la
variable locale ntait pas statique, il faudrait passer n en argument de compte pour le mmoriser.
SUBROUTINE compte
IMPLICIT NONE
INTEGER, SAVE :: n = 0 !
n = n + 1
print *, n
END SUBROUTINE compte

n est locale, mais statique

Si lon souhaite rendre statiques toutes les variables locales dune procdure, ce qui est fortement
dconseill 4 , il suffit dinsrer lordre SAVE 5 avant toutes les dclarations. On peut aussi passer
une option au compilateur (cf. annexe E, p.165) : -fnoautomatic pour le compilateur gfortran,
-fstatic pour le compilateur g95, -qsave pour xlf dibm, -save pour le compilateur nag, -save
pour le compilateur ifort dintel, -static pour celui f90 de dec.

6.1.3

Arguments des procdures

La communication entre une procdure et le programme appelant peut se faire par le passage
de paramtres appels arguments de la procdure. Ces arguments sont :
dclars comme arguments muets (dummy arguments) formels ou symboliques lors de la dfinition de la procdure ;
spcifis comme arguments effectifs (actual arguments) lors des appels de la procdure, pouvant prendre des valeurs diffrentes chaque appel.
En fortran, les passages darguments se font par rfrence 6 ce qui permet de partager les zones
mmoires des variables stockant les arguments entre appel et appelant. Lors de lappel de la
procdure, la liste des arguments effectifs doit respecter :
le nombre (hormis dans le cas darguments optionnels, cf. 6.5.1, p. 69),
lordre (hormis en cas de passage par mot-clef, cf. 6.5.2, p. 70),
1. Cela dpend des options de compilation qui peuvent forcer ou non un stockage statique ;
2. Par souci de lisibilit, on prcisera explicitement lattribut SAVE dans la dclaration de toute variable locale
initialise, au lieu de sappuyer sur le caractre statique implicite.
3. Au contraire, en C, une variable locale initialise est initialise lexcution, chaque appel la fonction hte ;
pour la rendre permanente (statique), il faut lui adjoindre lattribut static.
4. Sauf lors de certaines oprations de dboggage.
5. Linstruction SAVE doit alors tre seule sur la ligne. Elle peut aussi tre utilise sous la forme
SAVE :: liste_de variables pour dclarer statiques une liste de variables.
6. Au contraire, dans le langage C, les passages darguments se font par copie : cela permet deffectuer des
conversions si le type de largument effectif diffre de celui de largument formel. Mais, si lon souhaite modifier des
variables de lappelant, cela impose de transmettre des copies de leurs adresses la fonction appele : les arguments
de la fonction appele seront donc des pointeurs vers le type de la variable modifier ; on accdera alors aux zones
mmoire de ces variables par indirection depuis la fonction appele.

59

6.2. SOUS-PROGRAMMES ET FONCTIONS

et le type 7 et la variante de type ventuelle


des arguments muets dclars dans la procdure.

6.1.4

Lattribut INTENT des arguments

Le fortran 90 a introduit, dans un but de fiabilisation des communications entre procdures, un


attribut facultatif de vocation, INTENT, permettant de spcifier si un argument est :
INTENT(in) : un argument dentre, qui ne doit pas tre modifi par la procdure (cest le
seul cas o largument effectif peut tre une expression, en particulier une constante) ;
INTENT(out) : un argument de sortie, qui doit affect au sein de la procdure (il est indtermin au dbut de la procdure) ;
INTENT(inout) : un argument dentre-sortie, fourni la procdure, mais ventuellement
modifi par cette procdure.
En prcisant ces attributs, on permet au compilateur un meilleur contrle, lui donnant les moyens
de dtecter par exemple une modification involontaire dun argument dentre (INTENT(IN)) dans
la procdure, ou labsence daffectation dun argument de sortie (INTENT(OUT)) au sein de la
procdure.
Par exemple, le calcul de laire dun triangle effectu maladroitement comme suit, sans prciser B
la vocation des arguments, produit un effet de bord involontaire qui est de diviser base par deux.
SUBROUTINE aire(base, hauteur, surface)
IMPLICIT NONE
REAL :: base, hauteur, surface
base = base / 2.
surface = base * hauteur
END SUBROUTINE aire

! version sans vocation des arguments


! dclaration des arguments
! modification de base autorise
! forme maladroite du calcul de surface

Si on avait prcis que largument base est un argument dentre, le compilateur naurait pas
accept la modification de la variable base dans le sous-programme aire.
SUBROUTINE aire(base, hauteur, surface)
IMPLICIT NONE
REAL, INTENT(IN)
:: base, hauteur
REAL, INTENT(OUT) :: surface
base = base / 2.
surface = base * hauteur
END SUBROUTINE aire

! version avec vocation des arguments


!
!
!
!

dclaration des arguments d'entre


dclaration des arguments de sortie
affectation de base interdite ici
forme maladroite du calcul de surface

La vocation INTENT(INOUT) pour un argument modifiable, nimpose pas de contrainte dans la


procdure, mais permet au compilateur dimposer lemploi dune variable comme argument effectif alors quune expression est accepte dans le cas dun argument vocation INTENT(IN) non
modifiable.

6.2

Sous-programmes et fonctions

On distingue deux sortes de procdures :


Les sous-programmes (subroutine) sont constitus dune suite dinstructions qui effectuent une
tche dtermine quand on les appelle depuis une autre unit de programme via linstruction
CALL et rendent le contrle lunit appelante aprs excution. Des paramtres ou arguments
peuvent tre changs entre un sous-programme et lunit appelante.
7. Dans le cas dune procdure gnrique (cf. 10.1, p. 111), cest le type des arguments effectifs passs qui
permettra daiguiller vers la procdure spficique adquate.

60

CHAPITRE 6. PROCDURES

Les fonctions (function) sont des procdures qui renvoient un rsultat sous leur nom, rsultat
qui est ensuite utilis dans une expression au sein de lunit de programme appelante : la
simple mention de la fonction (avec ses arguments) dans lexpression provoque lexcution
des instructions que comprend la procdure. Cette notion sapparente ainsi celle de fonction
au sens mathmatique du terme.
Remarques :
Une fonction pourrait tre considre comme un cas particulier dun sous-programme, qui
renverrait un rsultat accessible sous le nom de la fonction. On peut donc en gnral transformer une fonction en sous-programme, quitte utiliser un argument supplmentaire pour
le rsultat et une ou ventuellement plusieurs variables supplmentaires dans lappelant, si
plusieurs appels la fonction coexistent dans une mme expression.

linverse, sil sagit deffectuer une action qui nest pas un simple calcul et par exemple
modifier les arguments dappel, on prfre le sous-programme. Paralllement, il est dusage de
ne pas modifier les paramtres dappel dune fonction, considrs comme arguments dentre
(cf. 6.1.4, p. 59).

6.2.1

Sous-programmes

Un sous-programme est introduit par linstruction SUBROUTINE, suivie du nom du sous-programme


et de la liste ventuelle de ses arguments muets entre parenthses et spars par des virgules, et
dlimit par linstruction END 8 , ventuellement suivie de SUBROUTINE, ventuellement suivi du nom
du sous-programme 9 .

SUBROUTINE <nom_sous_programme> [(<arg_1>, <arg_2>, ... )]


...
[RETURN]
END [SUBROUTINE [<nom_sous_programme> ] ]
Par exemple, le sous-programme aire,
SUBROUTINE aire(base, hauteur, surface)
IMPLICIT NONE
REAL, INTENT(IN)
:: base, hauteur
REAL, INTENT(OUT) :: surface
surface = base * hauteur / 2.
END SUBROUTINE aire

! arguments muets
! dclaration des arguments d'entre
! dclaration des arguments de sortie
! calcul de surface

peut tre appel par exemple via


...
REAL :: b1, h1, s1, b2, h2, s2
...
b1 = 30.
h1 = 2.
CALL aire(b1, h1, s1)
PRINT *, ' Surface = ', s1
b2 = 2.
h2 = 5.
CALL aire(b2, h2, s2)
PRINT *, ' Surface = ', s2
...

! appel avec arguments effectifs de mme type


! s1 = 30.
! appel avec arguments effectifs de mme type
! s2 = 5.

8. On peut insrer RETURN avant END, cf. 4.6.4, p. 33.


9. Pour amliorer la lisiblit des sources, on utilisera systmatiquement cette possibilit de dlimiter clairement
les procdures au lieu de se contenter de les terminer toutes par END.

6.3. PROCDURES INTERNES ET PROCDURES EXTERNES

6.2.2

61

Fonctions

Une fonction est encadre par les dclarations FUNCTION, suivie du nom de la fonction et de la
liste ventuelle de ses arguments muets et linstruction END 10 , ventuellement suivie de FUNCTION,
ventuellement suivie du nom de la fonction 11 . Le type du rsultat peut tre soit dclar dans
lentte, comme prfixe de FUNCTION, soit dclar en mme temps que les arguments, mais il ne
faut pas lui attribuer une vocation INTENT(OUT). La fonction doit comporter une ou plusieurs
instructions qui affectent une valeur au rsultat.

[<type> ] FUNCTION <nom_de_la_fonction> [(<arg_1>, <arg_2>, ... )]


...
[RETURN]
END [FUNCTION [<nom_de_la_fonction> ] ]
Par exemple, le sous-programme aire, nayant quun argument de retour, peut tre traduit en
fonction 12 :
FUNCTION surf(base, hauteur)
IMPLICIT NONE
REAL
:: surf
REAL, INTENT(IN) :: base, hauteur
surf = base * hauteur / 2.
END FUNCTION surf

! arguments muets
! dclaration du rsultat
! dclaration des arguments muets
! affectation du rsultat

qui peut tre utilise de la manire suivante :


...
REAL :: b1, h1, b2, h2, somme
...
b1 = 30.
h1 = 2.
PRINT *, ' Surface= ', surf(b1, h1) ! appel avec arguments effectifs
b2 = 2.
h2 = 5.
somme = surf(b1, h1) + surf(b2, h2) ! deux appels dans la mme expression
...
! somme = 30. + 5. = 35.

6.3

Procdures internes et procdures externes

Les procdures appeles (sous-programmes et fonctions) peuvent tre :


soit incluses dans le programme appelant, appel aussi hte(host) de la procdure et qualifies
de procdures internes (internal procedure) ; elles sont alors introduites par la dclaration
CONTAINS ;
soit extrieures au programme appelant (comme en fortran 77) et qualifies alors de procdures
externes (external procedure) ; on verra (cf. 6.4, p. 64) quil est recommand de les insrer dans
des modules.
10. On peut insrer RETURN avant END, cf. 4.6.4, p. 33.
11. Pour amliorer la lisiblit des sources, on utilisera systmatiquement cette possibilit de dlimiter clairement
les procdures au lieu de se contenter de les terminer toutes par END.
12. On aurait aussi pu crire REAL FUNCTION surf(base, hauteur) et viter la dclaration explicite du type du
rsultat.

62

6.3.1

CHAPITRE 6. PROCDURES

Procdures internes : CONTAINS

Les procdures internes sont compiles en mme temps que la procdure qui les appelle, ce qui
permet un contrle de la cohrence des arguments. Mais elles se prtent peu une rutilisation : on
les rservera des procdures trs dpendantes de leur procdure hte. Un seul niveau dimbrication
est possible : une seule instruction CONTAINS est possible dans une procdure 13 .
PROGRAM principal
...
CALL sub1(...)
...
x = fonc1(...)
...
CONTAINS
FUNCTION fonc1(...)
...
END FUNCTION fonc1
SUBROUTINE sub1(...)
...
END SUBROUTINE sub1
END PROGRAM principal
B

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

! appel du sous-programme interne sub1


! appel de la fonction interne fonc1
! introduit les procdures internes

Dans une procdure interne, toutes les entits dclares au sein de la procdure hte sont a
priori accessibles, sauf si on les redclare localement 14 , donc les communications entre lhte et la
procdure interne ne ncessitent pas forcment lemploi darguments.
Voici un exemple mettant profit le caractre global des variables, au dtriment de la lisibilit :
PROGRAM principal
! version sans passage d'arguments
IMPLICIT NONE
REAL :: base, hauteur, surface
! variables globales
base = 30.
hauteur = 2.
CALL aire
PRINT *, ' Surface = ', surface
! surface = 30.
base = 2.
hauteur = 5.
CALL aire
PRINT *, ' Surface = ', surface
! surface = 5.
CONTAINS
SUBROUTINE aire
! version dconseille
! ne pas redclarer base, hauteur ou surface (variables globales)
! sous peine de crer des variables locales distinctes !!!
surface = base * hauteur / 2.
! calcul de surface
END SUBROUTINE aire
END PROGRAM principal

Le simple ajout dune dclaration du type REAL :: base dans le sous-programme aire crerait
une variable locale base, empchant toute visibilit de la variable base du programme principal et
rendant le sous-programme inutilisable : on dit que la variable locale masque la variable globale.
Dans un souci de clart et de portabilit, on vitera de tirer parti de la visibilit des variables
globales 15 ; au contraire, on transmettra explicitement en arguments les variables partages et on
donnera aux variables locales la procdure interne des noms non utiliss par la procdure hte.
13. Sauf en ce qui concerne les procdures de module, qui peuvent inclure une procdure interne.
14. Si on dclare une variable locale dans une procdure interne avec le mme nom quune variable de porte
globale, la dclaration locale masque la variable globale.
15. En particulier, si une procdure interne a t crite en sappuyant sur cette lisibilit, elle ne sera pas aisment
transformable en procdure externe par la suite.

6.3. PROCDURES INTERNES ET PROCDURES EXTERNES

6.3.2

63

Procdures externes

Seules les procdures externes se prtent la rutilisation du code, mais nous verrons que le
contexte le plus fiable de leur utilisation est celui des modules (cf. 6.4, p. 64). Quelles soient places
dans des fichiers spars, ou dans le mme fichier que lappelant, leur compilation, hors contexte
des modules, se droule de faon indpendante. Les communications entre procdure externe et les
procdures appelantes se font au travers des arguments transmis.
Les procdures crites dans dautres langages sont videmment des procdures externes.

6.3.3

La notion dinterface

Dans le cas dune procdure externe, la compilation spare de la procdure appele et de la


procdure appellante ne permet pas au compilateur de connatre, sans information complmentaire,
le type des arguments changs et de vrifier la cohrence entre les arguments effectifs lors de lappel
et les arguments muets dclars. Il est cependant possible dassurer une visibilit de ces dclarations
darguments laide dun bloc dinterface explicite (explicit interface) insr dans la ou les procdures
appelantes 16 . Les dclarations des arguments sont ainsi communiques aux appelants lintrieur
dun bloc dinterface 17 , dlimit par les instructions INTERFACE et END INTERFACE 18 et insr aprs
les dclarations de variables de lappelant.

INTERFACE
! dbut de bloc d'interface
SUBROUTINE sub1(...)
... dclaration des arguments de sub1
END SUBROUTINE sub1
SUBROUTINE sub2(...)
... dclaration des arguments de sub2
END SUBROUTINE sub2
END INTERFACE
! fin de bloc d'interface
Par exemple, avec la fonction externe surf,
FUNCTION surf(base, hauteur)
IMPLICIT NONE
REAL
:: surf
REAL, INTENT(IN) :: base, hauteur
surf = base * hauteur / 2.
END FUNCTION surf

! dclaration du rsultat
! dclaration des arguments muets
! calcul de surface

on doit prciser dans la procdure appelante :


...
REAL :: b1, h1
...
INTERFACE
FUNCTION surf(base, hauteur)
IMPLICIT NONE
REAL
:: surf
! dclaration du rsultat
REAL, INTENT(IN) :: base, hauteur ! dclaration des arguments muets
END FUNCTION surf
END INTERFACE
16. Ces dclarations dinterface du fortran 90 sont rapprocher des prototypes des fonctions en langage C.
17. Un seul bloc dinterface est possible dans une procdure, sauf si on dclare les interfaces via des modules
(cf. 6.4, p. 64).
18. Il nest possible de nommer un bloc dinterface que dans le contexte des interfaces gnriques (cf. 10.1, p. 111).

64

CHAPITRE 6. PROCDURES

...
b1 = 30.
h1 = 2.
PRINT *, ' Surface= ', surf(b1, h1)
...

! arguments effectifs de mme type

Linconvnient immdiat du bloc dinterface explicite est que la dclaration des arguments doit
tre fidlement duplique entre la procdure appele et la ou les blocs dinterface dans la ou les
procdures appelantes. Lors des mises jour du code, il est possible de crer des incohrences entre
ces dclarations et cette technique est donc dconseille. Seule linsertion des procdures externes
dans des modules (cf. 6.4, p. 64) fournit une solution satisfaisante cette question.

6.4

Les modules

Les modules (modules) sont des entits compilables sparment (mais non excutables) permettant dhberger des lments de code ou de donnes qui ont vocation tre utiliss par plusieurs
procdures sans ncessit de dupliquer linformation. Un module est dlimit par les instructions :
MODULE <nom_de_module > et END MODULE <nom_de_module >. Il peut comporter :
des dclarations de types drivs, (cf. 9.6, p. 106) et des dclarations de variables, susceptibles
dtre partags entre plusieurs units de programme,
un bloc dinterface,
et des procdures dites de module (module procedure) introduites par linstruction CONTAINS.
Linstruction USE <nom_de_module >, place avant toutes les dclarations, assure lunit de
programme ou la procdure o elle est place la visibilit de toutes les entits publiques 19 (variables, types drivs, procdures, blocs dinterface) du module 20 .
La compilation du module produit un fichier de module 21 , dont le nom est celui du module et le
suffixe gnralement .mod 22 . Ce fichier sera exploit par linstruction USE lors de la compilation des
modules appelants afin deffectuer notamment les contrles inter-procduraux de respect dinterface
(type, vocation des arguments, ...) : il est donc ncessaire de compiler le ou les modules avant les
procdures qui les utilisent.

Il est fortement recommand dinclure les procdures dans des modules afin que les entits qui
les utilisent disposent dune interface explicite extraite automatiquement par le compilateur.

6.4.1

Exemple de procdure de module

Par exemple, le module surface contient la procdure interne de module surf.


MODULE m_mod
IMPLICIT NONE
CONTAINS
FUNCTION surf(base, hauteur)
REAL
:: surf

! dclaration du rsultat

19. cf. 6.4.3 p. 67


20. Linstruction USE peut elle-mme tre utilise dans un module, permettant ainsi limbrication des modules.
21. La structure de ces fichiers dpend du compilateur, et, pour g95 et plus rcemment, gfortran, par exemple,
plusieurs versions de format de ces fichiers incompatibles entre elles ont exist. De plus, si les fichiers de module de
g95 et gfortran sont en fait des fichiers texte, ceux de gfortran sont compresss avec gzip depuis la version 4.9.
22. On peut comparer ce fichier .mod aux fichiers dentte (header) des fonctions en langage C et linstruction USE
la directive #include. Mais cest le compilateur qui produit automatiquement le fichier .mod en fortran alors quen C,
le fichier dentte doit tre crit par lutilisateur qui doit aussi le maintenir en conformit avec le code de la procdure
chaque mise jour de la liste des paramtres. De plus, cest le compilateur qui interprte linstruction USE alors
quune directive #include est traite par le prprocesseur. Dailleurs, il est possible dutiliser le prprocesseur de la
mme faon en fortran quen C pour inclure des parties de code commun plusieurs units de programme.
Noter que cette inclusion de code pourrait aussi se faire via une directive de compilation INCLUDE, qui fait
partie de la norme du fortran 90, et que certains compilateurs ont intgre comme instruction fortran (hors norme
cependant), mais cette mthode est actuellement dconseille au profit de lemploi de linstruction USE.

65

6.4. LES MODULES

REAL, INTENT(IN) :: base, hauteur


surf = base * hauteur / 2.
END FUNCTION surf
END MODULE m_mod

! dclaration des arguments muets


! calcul de surface

La visibilit du module m_mod et donc de sa procdure interne surf, est assure dans une procdure
appelante par linstruction USE m_mod :
...
USE m_mod
! assure la visiblit du module sans duplication de code
REAL :: b1, h1
b1 = 30.
h1 = 2.
PRINT *, ' Surface= ', surf(b1, h1)
! arguments effectifs de mme type
...
La compilation du module m_mod cre un fichier de module m_mod.mod (dont le nom ne dpend B
pas du nom du fichier source) qui sera consult par le compilateur lorquil rencontrera linstruction
USE m_mod et qui assurera aux units de programmes qui utilisent le module la visibilit de ce
quil dfinit (dclarations, interfaces, ...).
Si on place le module m_mod dans un fichier source spar f_modul.f90, il faut le compiler
(avant les units de programme qui lui font appel), via la commande gfortran -c f_modul.f90,
qui crera deux fichiers (cf. Figure 6.1, p. 66) :
un fichier de module de suffixe .mod : m_mod.mod destin au compilateur ;
un fichier objet de suffixe .o : f_modul.o qui sera utilis par lditeur de liens pour construire
lexcutable partir des objets (via la commande gfortran f_ppal.o f_modul.o -o f_ppal.x).
Une autre mthode consisterait lancer une seule commande :
gfortran f_modul.f90 f_ppal.f90 -o f_ppal.x
(en compilant le module avant lappelant) qui dclencherait la compilation, puis ldition de liens.

6.4.2

Partage de donnes via des modules

La dclaration de variables partageables par plusieurs units de programme, quivalent du


COMMON du fortran 77, est possible lintrieur dun module. Chaque unit de programme qui
attachera ce module par linstruction USE partagera alors ces variables, sauf si leur visibilit a t
restreinte par lattribut PRIVATE (cf. 6.4.3 p. 67).
Les donnes dun module ne sont pas a priori permanentes sauf si :
leur porte stend au programme principal via un USE ;
leur porte a t tendue plus dune unit de compilation via au moins deux USE ;
lattribut SAVE a t prcis explicitement ou impliqu par une initialisation (cf. 2.5, p. 17).
Dans lexemple suivant, si linstruction USE constantes figurait dans le sous-programme init au
lieu de figurer dans le module hte initialisation, la visibilit de pi serait restreinte init.
Dans ce cas, linstruction USE constantes serait ncessaire dans le programme principal.
B
MODULE constantes
IMPLICIT NONE
REAL, SAVE :: pi
! variable statique
END MODULE constantes
MODULE initialisation
USE constantes
! permet la visibilit de la variable pi
CONTAINS
SUBROUTINE init
! sans argument
pi = 4. * atan(1.)
! mais pi est dclar dans le module constantes
END SUBROUTINE init
END MODULE initialisation
PROGRAM principal
! USE constantes ! inutile car visibilit via le module initialisation

66

CHAPITRE 6. PROCDURES

fichier source

PROGRAM ppal
...
USE surface
...

fichier source

f_ppal.f90

MODULE surface
CONTAINS
...

f_surf.f90
END PROGRAM ppal

END MODULE surface

Compilations
2) f90 c f_ppal.f90

fichier de module

1) f90 c f_surf.f90

surface.mod

fichier objet

fichier objet

f_ppal.o

f_surf.o

dition de liens
3) f90 f_ppal.o f_surf.o o f_ppal.x

fichier excutable
f_ppal.x

Figure 6.1 Modules et fichiers impliqus en compilation spare. Respecter lordre des trois
oprations : 1) compilation du module, 2) compilation de lappelant, 3) dition de liens.
USE initialisation ! rend explicite l'interface de la procdure de module init
REAL :: y, x
CALL init
...
y = sin ( pi * x )
...
END PROGRAM principal
Cette technique de partage des informations entre procdures est puissante, mais elle nest pas
aussi explicite que le passage par argument qui reste la mthode privilgier. Elle reste cependant
incontournable dans le cas dappels de procdures imbriqus o la procdure intermdiaire ne
peut pas voir les donnes transmettre 23 : un exemple classique est lapplication dune procdure
fonctionnelle (intgration, drivation, ...) une fonction dune variable, qui possde des paramtres
que la procdure fonctionnelle ignore alors quelle effectue des appels la fonction. Le seul moyen
23. La transmission des donnes seffectue linsu de la procdure intermdiaire : celle qui lappelle et celle quelle
appelle se partagent les donnes grce un USE commun inconnue de la procdure intermdiaire !

6.4. LES MODULES

67

de passer ces paramtres est de les partager via un module.


Dans lexemple suivant, introduit propos du passage dargument de type procdure (cf. 6.5.3,
p. 71), le paramtre puissance de la fonction effective fonct intgrer ne peut pas tre pass
la mthode dintgration integr, mais doit tre communiqu de lappelant (ici le programme
principal) la fonction fonct valuer.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
42
43
44
45
46
47

MODULE mod_fonct
! module dfinissant la fct effective
IMPLICIT NONE
INTEGER :: puissance
! masqu la procdure d'intgration
CONTAINS
FUNCTION fonct(x)
! dfinition de la fonction effective
REAL, INTENT(IN)
:: x
REAL
:: fonct
fonct = x**puissance
! paramtr par puissance par exemple
END FUNCTION fonct
END MODULE mod_fonct
!
MODULE mod_integr
! module dfinissant le sous-programme
IMPLICIT NONE
CONTAINS
SUBROUTINE integr(f, xmin, xmax, somme, n_points) ! f = argument muet
REAL, INTENT(IN)
:: xmin, xmax
REAL, INTENT(OUT)
:: somme
INTEGER, INTENT(IN)
:: n_points
INTERFACE
! interface de la fonction muette
FUNCTION f(x)
REAL, INTENT(IN)
:: x
REAL
:: f
END FUNCTION f
END INTERFACE
REAL
:: x, pas
INTEGER
:: i
pas = (xmax - xmin) / n_points
somme = pas * (f(xmin) + f(xmax)) / 2.
DO i = 2, n_points
x = xmin + (i - 1) * pas
somme = somme + pas * f(x)
END DO
END SUBROUTINE integr
END MODULE mod_integr
PROGRAM principal
USE mod_fonct
! accs au module de la fonction effective
USE mod_integr
! accs au module du sous-programme
IMPLICIT NONE
REAL
:: x0 = 0., x1 = 1., s
INTEGER :: n = 100
puissance = 1
! ne pas redclarer: visibilit assure par use
CALL integr(fonct, x0, x1, s, n)
WRITE(*,*) 'somme de f(x) = x : ', s
puissance = 2
! partag avec fonct, mais inconnu de integr
CALL integr(fonct, x0, x1, s, n)
WRITE(*,*) 'somme de f(x) = x*x : ', s
END PROGRAM principal

6.4.3

lments dencapsulation

Les modules permettent de faciliter la rutilisation des codes et leur maintenance. Au sein dune
procdure que lon souhaite partager, on peut distinguer :

68

CHAPITRE 6. PROCDURES

linterface (qui doit rester parfaitement stable), qui doit tre visible de ses procdures appelantes et doit donc tre publique ;
les dtails de limplmentation (qui peuvent voluer) quil est souvent prudent de masquer
aux utilisateurs, en les rendant privs.
Par dfaut, les entits (types drivs, variables, procdures) dfinies dans un module mon_module
sont publiques et donc rendues accessibles (et, pour les variables, modifiables) par linstruction USE
mon_module. lintrieur dun module, on peut utiliser la dclaration PRIVATE pour masquer toutes
les entits qui suivent cette dclaration en dehors du module o elles sont dclares. On dispose
aussi des attributs PUBLIC et PRIVATE pour spcifier plus finement la visibilit des objets lors de
leur dclaration.

Par ailleurs, on peut aussi, dans la procdure appelante, restreindre la visibilit des objets
publics dun module en spcifiant la liste exhaustive des objets auxquels on souhaite accder 24 :
USE nom_de_module , ONLY: liste_d'objets
Ces deux approches ne sont pas destines aux mmes usages : la premire mthode permet au
concepteur de la procdure de restreindre la visibilit alors que la seconde permet lutilisateur de
choisir les procdures dont il souhaite faire usage.
B
De plus, lorsque lon rutilise des modules rdigs dans un autre contexte, on peut tre confront
des conflits de nommage des identificateurs. Linstruction USE permet le renommage des entits
publiques du module quelle appelle, selon la syntaxe suivante, similaire celle de lassociation
dun pointeur (cf. 11.1.1, p. 119) :
USE nom_de_module , nom_local => nom_dans_le_module
Ce renommage permet aussi une sorte de paramtrage au niveau de la compilation (cf. lexemple
2.5.4 p. 19).
Enfin, sans restreindre la visibilit dune variable, on souhaite parfois rserver aux procdures
f2003 du module o elles sont dclares le droit de modifier leur valeur. La norme fortran 2003 a introduit
lattribut PROTECTED dans cet objectif. Le programme suivant :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

MODULE m_protege
IMPLICIT NONE
INTEGER, PRIVATE
:: m ! non visible en dehors du module
INTEGER, PUBLIC
:: n ! visible et modifiable en dehors du module
INTEGER, PROTECTED :: p ! visible mais non modifiable en dehors du module
! => oblige passer par une des procdures du module pour le modifier
CONTAINS
SUBROUTINE sub1 ! pas de paramtres : m, n et p ont une porte suffisante
m = 1
n = 2
p = 3
WRITE(*,*) "m, n, p dans sub1 ", m, n, p
END SUBROUTINE sub1
SUBROUTINE sub2 ! pas de paramtres : m, n et p ont une porte suffisante
m = 10
n = 20
p = 30
WRITE(*,*) "m, n, p dans sub2 ", m, n, p
END SUBROUTINE sub2
END MODULE m_protege

21
22
23
24
25
26
27
28
29

PROGRAM t_protege
USE m_protege
CALL sub1
WRITE(*,*) "n, p dans l'appelant aprs appel de sub1 ", n, p
CALL sub2
WRITE(*,*) "n, p dans l'appelant aprs appel de sub2 ", n, p
! m = -1 ! serait incorrect car m n'est pas visible ici (priv)
n = -2 ! autoris car n est public dans le module
24. Cette technique savre indispensable lorsque lon utilise une bibliothque : elle permet dviter les trop nombreux avertissements concernant les procdures de la bibliothque non appeles.

6.5. FONCTIONNALITS AVANCES

30
31
32
33

69

! p = -3 ! serait incorrect car p est protg => non modifiable hors du module
! comparer avec l'attribut intent(in) mais ici dans l'appelant
WRITE(*,*) "n, p dans l'appelant aprs affectation de n ", n, p
END PROGRAM t_protege

produit laffichage :
m,
n,
m,
n,
n,
f2003

n, p dans sub1 1 2 3
p dans l'appelant aprs appel de sub1 2 3
n, p dans sub2 10 20 30
p dans l'appelant aprs appel de sub2 20 30
p dans l'appelant aprs affectation de n -2 30

6.4.4

Linstruction IMPORT dans les interfaces

Contrairement aux procdures, en fortran 95, les interfaces encapsules dans un module nont
pas de visibilit sur les entits dclares (ou simplement visibles) dans le module qui les hberge. Le
fortran 2003 a introduit linstruction IMPORT qui permet dans une interface, daccder aux entits
du module soit globalement si on ne spcifie pas de liste, soit seulement celles spcifies par la
liste (voir par exemple les sous-programmes 12.4.2, p. 131).
f2003

6.4.5

Modules intrinsques

La norme 2003 du fortran a introduit plusieurs modules intrinsques dont :


IEEE_ARITHMETIC, IEEE_EXCEPTIONS, et IEEE_FEATURES pour les questions de calcul numrique en flottant ;
ISO_FORTRAN_ENV, pour linteraction avec lenvironnement systme en particulier les entressorties (cf. 5.3.1, p. 41), puis en fortran 2008, pour dfinir les paramtres KIND des sous-types f2008
(cf. 2.5.2, p. 18) et accder aux informations sur le compilateur (cf. A.9, p. 145) ;
et ISO_C_BINDING, pour linter-oprabilit avec le langage C (cf. chap. 12).
On peut accder ces modules avec linstruction USE, INTRINSIC :: en priorit sur un module
utilisateur homonyme.

6.5
6.5.1

Fonctionnalits avances
Arguments optionnels

Lors de la dclaration dune procdure, il est possible de prciser que certains arguments pourront tre omis lors de certains appels, en leur spcifiant lattribut OPTIONAL. Sauf utiliser un
passage darguments par mot-clef (cf. 6.5.2, p. 70), les arguments optionnels doivent tre placs
en fin de liste 25 . Lors de lcriture de la procdure, il faut prvoir un traitement conditionnel suivant que largument a t ou non fourni lors de lappel ; la fonction intrinsque dinterrogation
PRESENT(<arg> ), de rsultat boolen, permet de tester si largument a t effectivement pass.
Par exemple, le sous-programme integr de calcul dintgrale dune fonction (pour le moment
fixe et non paramtre) sur un intervalle [xmin, xmax] pass en argument, comporte deux paramtres optionnels : le nombre de points dvaluation (n_points) et la prcision relative (precision)
demande pour le calcul.
MODULE util
IMPLICIT NONE
CONTAINS
SUBROUTINE integr(xmin, xmax, somme, precision, n_points)
REAL, INTENT(IN)
:: xmin, xmax ! arguments d'entre requis
25. Si tous les arguments sont omis, lappel se fera sous la forme CALL sub() pour un sous-programme et fct()
pour une fonction.

70

CHAPITRE 6. PROCDURES

REAL, INTENT(OUT)
:: somme
! argument de sortie requis
REAL, INTENT(IN), OPTIONAL
:: precision ! argument d'entre optionnel
INTEGER, INTENT(IN), OPTIONAL :: n_points
! argument d'entre optionnel
!
INTEGER
:: points
! variable locale indispensable
...
IF( PRESENT(n_points) ) THEN
points = n_points
! utiliser la valeur transmise
ELSE
points = 200
! valeur par dfaut
END IF
...
somme = ...
END SUBROUTINE integr
END MODULE util
!
PROGRAM principal
USE util
...
CALL integr(xmin1, xmax1, somme1, .1, 100) ! tous les arguments sont passs
CALL integr(xmin2, xmax2, somme2, .1)
! n_points est omis
...
END PROGRAM principal
Remarques : dans cet exemple, la variable locale points est ncessaire, car n_points, dclar
comme argument dentre (INTENT(IN)), ne peut pas tre modifi dans la procdure. Noter par
ailleurs, quil faut conditionner toute rfrence au paramtre optionnel sa fourniture effective et
que la formulation suivante
IF( PRESENT(n_points) .AND. n_points > 1 ) points = n_points
est incorrecte car elle suppose que le second oprande du .AND. nest pas valu (cf. 3.3, p. 24) si
le paramtre optionnel na pas t spcifi.

6.5.2

Transmission darguments par mot-clef

Ds le fortran 77, certaines procdures intrinsques comme linstruction OPEN par exemple
autorisaient le passage dargument par mot-clef, ce qui permettait de saffranchir de lordre des
arguments. Cependant le passage dargument aux procdures dfinies par lutilisateur restait ncessairement positionnel.
En fortran 90, on peut passer certains arguments par un mot-clef, en utilisant la syntaxe
<argument_muet> = <argument_effectif> . Cette possibilit prend tout son sens quand la procdure possde des arguments optionnels. En effet, dans ce cas, le passage par mot-clef est le seul
moyen de fournir un argument qui suit un argument optionnel non spcifi lors de lappel 26 . Plus
prcisment, ds quun argument optionnel a t omis, les arguments qui le suivent ne peuvent plus
tre passs de faon positionnelle.
En reprenant lexemple prcdant (cf. 6.5.2, p. 70), on peut mixer les modes de passage darguments :
...
CALL integr(0., 1., precision=.1, n_points=100, somme=resultat)
!
plus de passage positionnel partir du troisime
! tous les arguments passs, mais en ordre modifi avec les mots-clefs
CALL integr(xmin2, xmax2, somme2, n_points=500)
26. Un appel du type f(x1, , x3) nest pas autoris en fortran.

6.5. FONCTIONNALITS AVANCES

71

! precision est omis, mais on veut passer n_points, donc par mot-clef car aprs
...

6.5.3

Noms de procdures passs en argument

La paramtrisation des sous-programmes conduit parfois transmettre le nom dune procdure


en argument dune autre procdure. Par exemple, un sous-programme dintgration numrique
integr doit accepter en argument le nom de la fonction intgrer. Dans le sous-programe dintgration, lidentificateur (muet) f de la fonction est ncessairement vu comme une fonction ds
que le sous-programme invoque cette fonction. Mais, vu du programme appelant principal, il
est ncessaire dindiquer explicitement que largument effectif fournissant le nom de la fonction
intgrer nest pas une simple variable.
En fortran 77, on informe le compilateur du caractre particulier de cet argument, grce
linstruction EXTERNAL <fonc> 27 , o <fonc> est la fonction intgrer, insre dans la
procdure appelante 28 .
En fortran 90, il vaut mieux assurer la visiblit de linterface de la fonction effectivement
intgre, lappelant, ici le programme principal. Cela est possible soit en dclarant dans
lappelant linterface explicite de la fonction fonct, soit en crant un module mod_fonct avec
cette fonction fonct en procdure interne de module et en dclarant USE mod_fonct dans le
programme principal.
Le premier exemple prsente une version minimale du programme principal avec des procdures integr et fonct externes. Seule linterface explicite de la fonction effective fonct (lignes 7
11) est ncessaire dans le programme principal.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

! version avec procdures externes et interface minimale


PROGRAM principal
IMPLICIT NONE
REAL :: x0 = 0., x1 = 1., s
INTEGER :: n = 100
INTERFACE
FUNCTION fonct(x)
! interface obligatoire de la fonction effective
IMPLICIT NONE
REAL, INTENT(IN)
:: x
REAL
:: fonct
END FUNCTION fonct
END INTERFACE
CALL integr(fonct, x0, x1, s, n)
WRITE(*,*) 'somme = ', s
END PROGRAM principal
! sous-programme externe
SUBROUTINE integr(f, xmin, xmax, somme, n_points) ! f = argument muet
IMPLICIT NONE
REAL, INTENT(IN)
:: xmin, xmax
REAL, INTENT(OUT)
:: somme
INTEGER, INTENT(IN)
:: n_points
! dclaration de f ncessaire, sauf si l'interface de f est connue
REAL
:: f
REAL
:: x, pas
INTEGER
:: i
pas = (xmax - xmin) / n_points
somme = pas * (f(xmin) + f(xmax)) / 2.
27. Sauf dans le cas trs rare o la fonction utilise est une fonction intrinsque du fortran ; alors il faut dclarer
INTRINSIC <fonc>
28. Si IMPLICIT NONE a t dclar dans lappelant, il faut aussi dclarer le type de la procdure sil sagit dune
fonction.

72

28
29
30
31
32
33
34
35
36
37
38
39

DO i = 2, n_points
x = xmin + (i - 1) * pas
somme = somme + pas * f(x)
END DO
END SUBROUTINE integr
! fonction externe
FUNCTION fonct(x)
IMPLICIT NONE
REAL, INTENT(IN)
REAL
fonct = x
END FUNCTION fonct

CHAPITRE 6. PROCDURES

! dfinition de la fonction effective


:: x
:: fonct
! par exemple

Lexemple suivant prsente encore une version du programme principal avec des procdures
externes, mais qui comporte aussi les interfaces explicites du sous-programme integr (lignes 12
18) dans le programme principal et de la fonction symbolique f (lignes 29 34) au sein du
sous-programme integr. Ces deux interfaces sont facultatives ici, mais vivement conseilles.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
42
43
44
45
46
47
48
49
50
51

! version avec procdures externes et interfaces


PROGRAM principal
IMPLICIT NONE
REAL :: x0 = 0., x1 = 1., s
INTEGER :: n = 100
INTERFACE
FUNCTION fonct(x)
! interface obligatoire de la fonction effective
IMPLICIT NONE
REAL, INTENT(IN)
:: x
REAL
:: fonct
END FUNCTION fonct
SUBROUTINE integr(f, xmin, xmax, somme, n_points) ! interface facultative
IMPLICIT NONE
REAL, INTENT(IN)
:: xmin, xmax
REAL, INTENT(OUT)
:: somme
INTEGER, INTENT(IN)
:: n_points
REAL
:: f
END SUBROUTINE integr
END INTERFACE
CALL integr(fonct, x0, x1, s, n)
WRITE(*,*) 'somme = ', s
END PROGRAM principal
! sous-programme externe
SUBROUTINE integr(f, xmin, xmax, somme, n_points) ! f = argument muet
IMPLICIT NONE
REAL, INTENT(IN)
:: xmin, xmax
REAL, INTENT(OUT)
:: somme
INTEGER, INTENT(IN)
:: n_points
INTERFACE
! interface facultative de la fonction muette
FUNCTION f(x)
REAL, INTENT(IN)
:: x
REAL
:: f
END FUNCTION f
END INTERFACE
REAL
:: x, pas
INTEGER
:: i
pas = (xmax - xmin) / n_points
somme = pas * (f(xmin) + f(xmax)) / 2.
DO i = 2, n_points
x = xmin + (i - 1) * pas
somme = somme + pas * f(x)
END DO
! fonction externe
END SUBROUTINE integr
! fonction externe
FUNCTION fonct(x)
! dfinition de la fonction effective
IMPLICIT NONE
REAL, INTENT(IN)
:: x
REAL
:: fonct
fonct = x
! par exmple
END FUNCTION fonct

Enfin, pour viter la lourdeur des interfaces explicites, on prfre souvent intgrer les procdures dans des modules. Avec les modules mod_fonct (lignes 2 11) pour la fonction effective et

6.5. FONCTIONNALITS AVANCES

73

mod_integr (lignes 13 38) pour le sous-programme, seule demeure linterface explicite (lignes 23
28) de la fonction symbolique 29 f.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
42
43
44
45
46
47
48

! version avec modules


MODULE mod_fonct
! module dfinissant la fct effective
CONTAINS
! fonction interne de module
FUNCTION fonct(x)
! dfinition de la fonction effective
IMPLICIT NONE
REAL, INTENT(IN)
:: x
REAL
:: fonct
fonct = x
! par exemple
END FUNCTION fonct
END MODULE mod_fonct
!
MODULE mod_integr
! module dfinissant le sous-programme
CONTAINS
! sous-programme interne de module
SUBROUTINE integr(f, xmin, xmax, somme, n_points) ! f = argument muet
IMPLICIT NONE
REAL, INTENT(IN)
:: xmin, xmax
REAL, INTENT(OUT)
:: somme
INTEGER, INTENT(IN)
:: n_points
! REAL
:: f
! cette dclaration peut remplacer l'interface explicite de f qui suit
INTERFACE
! interface conseille de la fonction muette
FUNCTION f(x)
REAL, INTENT(IN)
:: x
REAL
:: f
END FUNCTION f
END INTERFACE
REAL
:: x, pas
INTEGER
:: i
pas = (xmax - xmin) / n_points
somme = pas * (f(xmin) + f(xmax)) / 2.
DO i = 2, n_points
x = xmin + (i - 1) * pas
somme = somme + pas * f(x)
END DO
END SUBROUTINE integr
END MODULE mod_integr
! version du programme principal avec modules
PROGRAM principal
USE mod_fonct
! chargement du module de la fonction effective
USE mod_integr
! chargement du module du sous-programme
IMPLICIT NONE
REAL :: x0 = 0., x1 = 1., s
INTEGER :: n = 100
CALL integr(fonct, x0, x1, s, n)
WRITE(*,*) 'somme = ', s
END PROGRAM principal

29. on pourrait la remplacer par une simple dclaration de f, ligne 21, moins prcise, car elle ne permet pas de
vrifier le type des arguments.

74

f2003

CHAPITRE 6. PROCDURES

6.5.4

La dclaration PROCEDURE

En fortran 2003, si linterface dune procdure fmodele est visible dans une unit de compilation, on peut sen servir comme modle pour dclarer linterface dautres procdures de mme
interface grce la dclaration PROCEDURE, avec pour argument le nom de la procdure modle.

PROCEDURE(fmodele ) :: f1 , f2
Cette dclaration admet des attributs optionnels, en particulier POINTER, PUBLIC ou PRIVATE. Cette
possibilit, utilise notamment pour les pointeurs de procdures (cf. 11.4, p. 126) et les procdures
passes en argument est le plus souvent associe la dclaration dune interface abstraite de
prfrence un modle. Cest dans ce cadre que sont prsents les exemples (cf. 6.5.5, p. 74). Bien
entendu, PROCEDURE ne peut pas tre utilis pour des procdures gnriques : cette dclaration
dinterface est rserve aux procdures spcifiques (cf. 10.1, p. 111).
Noter que PROCEDURE permet aussi de dclarer des procdures dinterface implicite avec un
argument vide (quivalent dun EXTERNAL), ou dinterface incomplte avec seulement le type de
retour dans le cas dune fonction (par exemple PROCEDURE(REAL) :: freel pour une fonction
valeur de type REAL sans prcision sur les arguments).

f2003

6.5.5

Interfaces abstraites

Lorsque lon doit dclarer linterface commune de plusieurs procdures, il est prfrable de
dclarer une seule fois cette interface, dans un bloc dit dinterface abstraite, en la nommant tel
un type particulier. On peut ensuite faire rfrence cette interface nomme via la dclaration
PROCEDURE pour dclarer de faon beaucoup plus synthtique les interfaces des procdures effectives.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

MODULE abstr_interf
IMPLICIT NONE
! bloc d'interface abstraite avec des interfaces nommes
ABSTRACT INTERFACE
FUNCTION fr_de_r(x)
! fonction relle d'un rel
REAL :: fr_de_r
REAL, INTENT(in) :: x
END FUNCTION fr_de_r
FUNCTION fr_de_2r(x, y)
! fonction relle de 2 rels
REAL :: fr_de_2r
REAL, INTENT(in) :: x, y
END FUNCTION fr_de_2r
END INTERFACE
END MODULE abstr_interf

Ces interfaces abstraites, sortes de patrons de procdures pourront tre invoques pour
rendre explicite linterface de procdures dinterface a priori implicite respectant ce modle (par
exemples dfinies hors module ou dans un module non visible du ct appelant). Il suffit de dclarer
PROCEDURE avec comme argument le nom de linterface abstraite pour expliciter linterface.
Dans lexemple suivant, le non-respect des interfaces est dtect ds la compilation :

75

6.5. FONCTIONNALITS AVANCES

1
2
3
4
5
6
7
8
9
10
11
12
13
14

! fonctions externes hors module


! => interface implicite
FUNCTION f1(x)
IMPLICIT NONE
REAL :: f1
REAL, INTENT(in) :: x
f1 = x
END FUNCTION f1
FUNCTION f2(x, y)
IMPLICIT NONE
REAL :: f2
REAL, INTENT(in) :: x, y
f2 = x*y
END FUNCTION f2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

PROGRAM t_abstract
USE abstr_interf
IMPLICIT NONE
PROCEDURE(fr_de_r) :: f1
! mais interface rendue ainsi visible
PROCEDURE(fr_de_2r) :: f2
REAL :: x, y
INTEGER :: i
x = 10
y = 5
WRITE(*,*) x, f1(x)
WRITE(*,*) i, f1(i) ! => erreur de compilation
! Error: Type mismatch in parameter 'x'
! Passing INTEGER(4) to REAL(4)
WRITE(*,*) x, y, f2(x, y)
WRITE(*,*) f2(x) ! => erreur de compilation
! Error: Missing actual argument for argument 'y'
END PROGRAM t_abstract

Les interfaces abstraites prennent tout leur intrt dans les cas o plusieurs procdures de mme
interface sont susceptibles dtre utilises :
lorsquune mthode sapplique une procdure passe en argument (cf. 6.5.3, p. 71) ;
lorsquon utilise des pointeurs de procdures (cf. 11.4, p. 126) pour une partie de code pouvant
sappliquer plusieurs procdures.
Lexemple de la mthode dintgration integr prend alors la forme suivante :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

! version avec interface abstraite pour l'argument de la mthode


MODULE mod_abstract_fr
! module pour l'interface abstraite
ABSTRACT INTERFACE
! bloc d'interface abstraite
FUNCTION fr(x)
! le modle
REAL, INTENT(IN)
:: x
REAL
:: fr
END FUNCTION fr
END INTERFACE
END MODULE mod_abstract_fr
MODULE mod_integr
USE mod_abstract_fr
! assure la visibilit du modle fr
CONTAINS
SUBROUTINE integr(f, xmin, xmax, somme, n_points) ! f = argument muet
IMPLICIT NONE
PROCEDURE(fr)
:: f ! f est une procdure d'interface fr
REAL, INTENT(IN)
:: xmin, xmax
REAL, INTENT(OUT)
:: somme
INTEGER, INTENT(IN)
:: n_points
REAL
:: x, pas
INTEGER
:: i
pas = (xmax - xmin) / n_points
somme = pas * (f(xmin) + f(xmax)) / 2.
DO i = 2, n_points
x = xmin + (i - 1) * pas
somme = somme + pas * f(x)
END DO
END SUBROUTINE integr
END MODULE mod_integr
!
MODULE mod_fonct
! module dfinissant la fct effective
CONTAINS
FUNCTION fonct(x)
! dfinition de la fonction effective
IMPLICIT NONE
REAL, INTENT(IN)
:: x
REAL
:: fonct

76

36
37
38
39
40
41
42
43
44
45
46
47

CHAPITRE 6. PROCDURES

fonct = x
! par exemple
END FUNCTION fonct
END MODULE mod_fonct
PROGRAM principal
USE mod_fonct
! visibilit de l'interface de la fonction effective
USE mod_integr
! visibilit de l'interface de la mthode
IMPLICIT NONE
REAL :: x0 = 0., x1 = 1., s
INTEGER :: n = 100
CALL integr(fonct, x0, x1, s, n)
WRITE(*,*) 'somme = ', s
END PROGRAM principal

6.5.6

Procdures rcursives

Lorsquune procdure sappelle elle-mme, de faon directe ou indirecte, au travers dune chane
dautres procdures, on la qualifie de rcursive. Contrairement au fortran 77, le fortran 90 permet la rcursivit directe ou indirecte des procdures, par la dclaration explicite via le mot-clef
RECURSIVE.
Mais, dans le cas dune fonction rcursive, le nom de la fonction ne peut plus tre utilis pour
B dsigner le rsultat : on doit alors introduire, aprs le mot-clef RESULT 30 , le nom de la variable
qui stockera le rsultat. Dans une procdure rcursive, une variable avec lattribut SAVE (cf. 6.1.2,
p. 58) est partage par toutes les instances de la procdure, alors que ses variables automatiques
sont spcifiques de chaque instance.
Larchtype de la rcursivit directe est le calcul de la factorielle : n! = n (n 1)! avec 1! = 1,
B quil est imprudent de programmer en type entier sur 32 bits cause du dpassement de capacit
ds n dpasse 12.
INTEGER RECURSIVE FUNCTION fact(n) RESULT(factorielle)
! le type entier s'applique en fait au rsultat : factorielle
IMPLICIT NONE
INTEGER, INTENT(IN)
:: n
IF ( n > 0 ) THEN
factorielle = n * fact(n-1)
! provoque un nouvel appel de fact
ELSE
factorielle = 1
! ne pas oublier d'arrter la rcursion
END IF
END FUNCTION fact
On peut aussi programmer la factorielle comme sous-programme :
RECURSIVE SUBROUTINE fact(n, factorielle)
IMPLICIT NONE
INTEGER, INTENT(IN)
:: n
INTEGER, INTENT(OUT) :: factorielle
IF ( n > 0 ) THEN
CALL fact(n-1, factorielle)
! appel rcursif
factorielle = n * factorielle
ELSE
factorielle = 1
END IF
END SUBROUTINE fact
30. Lutilisation de la clause RESULT est aussi possible pour des fonctions non rcursives.

6.5. FONCTIONNALITS AVANCES

77

On peut rencontrer la rcursivit indirecte lors des calculs numriques dintgrale double, si on
utilise la mme procdure
R x integr (cf. 6.5.3, p. 71) pour intgrer selon chacune des variables : la
fonction de y, F (y) = x01 f (x, y) dx, fait appel, dans son valuation numrique pour chaque valeur
de y, la procdure integr, et lintgrale double sera value en appliquant integr F (y). La
procdure integr devra donc tre dclare rcursive. De plus, il faudra masquer le paramtre y B
lors de lintgration en x pour simuler le passage dune fonction dune seule variable la procdure
dintgration : il sera transmis F par partage via un module (cf. 6.4.2, p. 66).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

MODULE mod_fonct
! module dfinissant la fct effective
IMPLICIT NONE
REAL :: yy
! y fix
CONTAINS
FUNCTION fonct(x)
! dfinition de la fonction effective de x
REAL, INTENT(IN)
:: x
REAL
:: fonct
fonct = x**2 - yy**2
END FUNCTION fonct
END MODULE mod_fonct
!
MODULE mod_param_y
! module des paramtres cachs fonct
IMPLICIT NONE
REAL :: x0, x1
! bornes en x
INTEGER :: nx
! nombre de points en x
END MODULE mod_param_y
!
MODULE mod_integr
! module dfinissant le sous-programme
IMPLICIT NONE
CONTAINS
RECURSIVE SUBROUTINE integr(f, xmin, xmax, somme, n_points)
! f = argument muet de type fonction
REAL, INTENT(IN)
:: xmin, xmax ! bornes
REAL, INTENT(OUT)
:: somme
! rsultat
INTEGER, INTENT(IN)
:: n_points
! nombre de points
INTERFACE
! interface de la fonction muette
FUNCTION f(x)
REAL, INTENT(IN)
:: x
REAL
:: f
END FUNCTION f
END INTERFACE
REAL
:: x, pas
INTEGER
:: i
pas = (xmax - xmin) / n_points
somme = pas * (f(xmin) + f(xmax)) / 2.
DO i = 2, n_points
x = xmin + (i - 1) * pas
somme = somme + pas * f(x)
END DO
END SUBROUTINE integr
END MODULE mod_integr

42
43
44
45
46
47
48
49
50
51
52

MODULE mod_fy
USE mod_param_y
USE mod_fonct, only: yy, fonct
USE mod_integr
CONTAINS
FUNCTION fy(y)
REAL
REAL, INTENT(IN)
REAL
yy = y

! module des paramtres cachs fonct


! module dfinissant le sous-programme
! intgrale en x de la fonction effective
:: fy
:: y
:: s
! transfert de y fonct via mod_fonct

78

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

f95

CHAPITRE 6. PROCDURES

CALL integr(fonct, x0, x1, s, nx) ! intgration en x y fix


fy = s
END FUNCTION fy
END MODULE mod_fy
!
PROGRAM principal
USE mod_param_y
! accs aux paramtres utiliss par fy
USE mod_fy, only:x0, x1, fy, nx ! accs au module de la fct effective de y
USE mod_integr
! accs au module d'intgration 1D
REAL
:: y0 = 0., y1 = 1., s
INTEGER :: ny = 100
! paramtres de l'intgration en x : passs via mod_fy (ne pas redclarer)
x0 = 0.
x1 = 1.
nx = 50
CALL integr(fy, y0, y1, s, ny)
WRITE(*,*) 'somme de f(x, y) = x**2 -y**2 : ', s
END PROGRAM principal

6.5.7

Procdures pures

Dans certaines circonstances de paralllisation des codes, comme lintrieur dune structure
FORALL (cf. 7.4.6, p. 88), seules sont admises les procdures sans effet de bord. Un attribut PURE
permet de certifier quune procdure est sans effet de bord, cest dire :
quelle ne modifie pas de variables non locales : en particulier, sil sagit dune fonction, tous
ses arguments doivent possder lattribut INTENT(IN) ;
quelle ne modifie pas de variables non locales soit visibles car la procdure est interne, soit
rendues visibles par un USE ;
quelle ne fait pas de lecture ou dcriture sur un fichier externe : en particulier, elle ne peut
rien lire au clavier ou afficher ;
quelle ne contient pas de variable locale avec lattribut SAVE : en particulier, pas de variable
initialise la dclaration (cf. 2.5, p. 17) ;
quelle ne comporte pas dinstruction STOP.
Ces conditions imposent quune procdure pure nappelle que des procdures pures. Toutes
les procdures intrinsques sont pures. Les procdures lmentaires (cf. 6.5.8, p. 78) possdent
automatiquement lattribut PURE.
f95

6.5.8

Procdures lmentaires

Une procdure est qualifie dlmentaire (attribut ELEMENTAL) si elle peut tre appele avec
des arguments tableaux conformes de la mme faon quavec des arguments scalaires. La majorit
des procdures intrinsques (cf. annexe A, p. 138) sont lmentaires.
Une procdure lmentaire est automatiquement pure, mais de plus tous ses arguments muets
(ainsi que la valeur renvoye pour une fonction) doivent tre des scalaires sans lattribut POINTER.
Une procdure rcursive (cf. 6.5.6, p. 76) ne peut pas tre lmentaire. Une procdure lmentaire
non-intrinsque ne peut pas tre passe en argument effectif dune autre procdure.
ELEMENTAL REAL FUNCTION my_log(x) ! une fonction log protge pour les x<=0
REAL, INTENT(IN) :: x
IF ( x > 0 ) THEN
my_log = LOG (x)
ELSE
my_log = -1000.
END IF
END FUNCTION my_log

Chapitre 7

Tableaux
7.1

Gnralits

Un tableau (array) est un ensemble rectangulaire 1 dlments de mme type 2 (plus prcisment de mme variante de type), reprs au moyen dindices entiers. Par opposition, on qualifiera
de scalaire un lment du tableau. Les lments dun tableau sont rangs selon un ou plusieurs
axes appels dimensions du tableau. Dans les tableaux une dimension (qui permettent de
reprsenter par exemple des vecteurs au sens mathmatique du terme), chaque lment est repr
par un seul entier, mais le fortran accepte des tableaux jusqu 7 dimensions 3 , o chaque lment
est dsign par un 7-uplet dentiers 4 .

7.1.1

Terminologie des tableaux

rang (rank) dun tableau : nombre de ses dimensions


tendue (extent) dun tableau selon une de ses dimensions : nombre dlments dans cette
dimension
bornes (bounds) dun tableau selon une de ses dimensions : limites infrieure et suprieure
des indices dans cette dimension. La borne infrieure par dfaut vaut 1 5 .
profil (shape) dun tableau : vecteur dont les composantes sont les tendues du tableau selon
ses dimensions ; son tendue (sa taille) est le rang du tableau.
taille (size) dun tableau : nombre total des lments qui le constituent, cest--dire le produit
des lments du vecteur que constitue son profil.
deux tableaux sont dits conformants (conformable) sils ont le mme profil 6 .
La dclaration dun tableau seffectue grce lattribut DIMENSION qui indique le profil du
tableau, ou ventuellement les bornes, spares par le symbole : .
INTEGER, DIMENSION(5)

:: vecteur

REAL, DIMENSION(-2:2)

:: table

!
!
!
!

tableau
indics
tableau
indics

une dimension de 5 entiers


de 1 5
une dimension de 5 rels
de -2 +2

1. Lassemblage non-rectangulaire dlments du mme type est possible grce aux pointeurs, cf. 11.3, p. 123.
2. Lassemblage dlments de types diffrents est possible au sein dun type driv ou structure, cf. chapitre 9,
p. 102. Mais les lments constitutifs dun tableau peuvent tre des structures, et ... les lments de ces structures
peuvent eux-mmes comporter des tableaux !
3. Cette limite est porte 15 en fortran 2008.
4. Certains termes employs en informatique propos des tableaux peuvent avoir un sens profondment diffrent
de leur sens en mathmatiques dans le domaine des espaces vectoriels. Cest le cas, par exemple, de la notion
de dimension : un vecteur trois dimensions de la gomtrie dans lespace peut tre reprsent par un tableau
monodimensionnel, de rang un et de taille trois.
5. Ne pas confondre avec le C o lindexation des tableaux commence zro.
6. Noter que deux tableaux conformants nont pas forcment les mmes bornes.

79

80

CHAPITRE 7. TABLEAUX

REAL, DIMENSION(2,3)

:: m

! tableau 2 dimensions de 2 x 3 = 6 rels


! son profil a 2 lments : 2 et 3
! profil 2 x 3 conformant avec m

REAL, DIMENSION(2,-1:1) :: mat

Les tableaux vecteur et table sont de dimension 1 et ont mme profil : ils sont conformants.
Un lment (scalaire) dun tableau est dsign en prcisant entre parenthses les indices selon
toutes ses dimensions, spars par des virgules. vecteur(2), table(-1) et m(2,2) sont des lments
des tableaux dfinis prcdemment. Cependant, le fortran distingue un tableau monodimensionnel
un seul lment de llment scalaire quil contient :
INTEGER, DIMENSION(1)
INTEGER
i = t(1)
i = t

7.1.2

:: t
:: i

!
!
!
!

tableau un lment
entier
affectation autorise
affectation illicite

Ordre des lments dans un tableau multidimensionnel

Le caractre multidimensionnel des tableaux nest pas respect dans la mmoire des calculateurs,
o les tableaux sont en gnral stocks dans une mmoire un seul indice dadressage. En fortran,
lordre classiquement utilis pour stocker les lments des tableaux est celui o le premier
indice varie le plus vite 7 , cest dire que deux lments dont seul le premier indice diffre dune
unit sont contigus en mmoire.
Pour des tableaux de rang 2, cela signifie que le rangement seffectue colonne par colonne 8 .
Par exemple, la matrice m de 2 lignes par 3 colonnes (au sens mathmatique), est stocke dans le
tableau m dimensionn par lattribut DIMENSION(2,3) de la manire suivante :
matrice

1
m11

3
m12

5
m13

2
m21

4
m22

6
m23

tableau associ

m(1,1)

m(2,1)

m(1,2)

m(2,2)

m(1,3)

m(2,3)

Mais la norme fortran 90 ne spcifie pas lordre de rangement en mmoire des lments dun
tableau, laiss la disposition du compilateur, entre autres pour des raisons defficacit de calcul
suivant les processeurs utiliss : on ne pourra donc pas sappuyer sur cet ordre de stockage pour le
passage de tableaux multidimensionnels en argument de procdures 9 .
Cependant, cet ordre est respect dans les instructions dentre-sortie et, par exemple, par la
fonction RESHAPE (cf. 7.4.3, p. 86) de restructuration des tableaux.
Un exemple de lecture de matrice errone
En particulier, une lecture globale de matrice dans un fichier par un seul ordre READ (sans boucle
implicite) stockera les lments contigus (sur une mme ligne) dans le fichier en incrmentant
B lindice le plus gauche du tableau de rang 2, cest--dire... celui des lignes ! Dans le cas dun
matrice carre, cette lecture remplira le tableau avec la transpose de la matrice figurant sous la
forme habituelle dans le fichier.
7. Contrairement au choix fait en langage C, o lindice qui varie le plus rapidement est celui de la dernire
dimension. Dailleurs, en C, il ny a pas, proprement parler, de tableaux multidimensionnels, mais des tableaux
de tableaux. Cette reprsentation implique une hirarchie qui, par exemple dans le cas des tableaux 2D, permet de
dsigner une ligne, mais pas une colonne de matrice.
8. On suppose ici que, dans un tableau de rang 2 reprsentant un objet mathmatique de type matrice, on
attribue au premier indice le rle de numro de ligne et au deuxime celui de numro de colonne. Cette convention,
qui semble naturelle, peut tre inverse pour des raisons de performance des codes. Par exemple, dans des boucles
imbriques portant sur les lignes et les colonnes, il est plus efficace daccder des lments contigus en mmoire
dans la boucle interne, qui doit donc porter sur lindice rapide, cest dire le premier.
9. En fortran 77, o lordre de stockage tait garanti, on mettait profit la disposition des lments des tableaux
pour passer des sections de tableaux multidimensionnels en tant quarguments effectifs des procdures dans lesquelles largument muet tait dclar monodimensionnel : il suffisait que la section de tableau stende uniquement
selon la dernire dimension du tableau.

81

7.2. SECTIONS DE TABLEAUX

Par exemple, si le fichier mat2x2.dat contient les deux lignes


INTEGER, DIMENSION(2,2)
:: mat
...
OPEN(10, file='mat2x2.dat', STATUS='old')
READ(10, *) mat(:,:)
CLOSE(10)
WRITE(*, *) mat(:,:)

11
21

12
,
22

! matrice 2 lignes x 2 colonnes


! ouverture du fichier en lecture
! lecture globale en format libre
! affichage global en format libre

11 21
; en particulier mat(1,2) = 21
12 22
et mat(2,1) = 12. Mais laffichage global en format libre reproduira (sur une seule ligne) lordre
du fichier initial, 11 12 21 22 , bien que le premier indice du tableau mat soit celui des colonnes.
les ordres prcdents rempliront le tableau mat avec :

Un exemple de lecture correcte de matrice


Pour lire la matrice en affectant chaque ligne du fichier une ligne (au sens mathmatique)
de la matrice, on doit expliciter la boucle sur les lignes, alors que celle sur les colonnes peut tre
implicite ; on fera de mme pour afficher le tableau selon la disposition mathmatique de la matrice
(cf. 5.4.4, p. 50). Par exemple, pour lire une matrice 2x3 dentiers et lafficher :
INTEGER, PARAMETER
:: nl=2, nc=3 ! constantes nommes
INTEGER, DIMENSION(nl, nc)
:: matrice
! matrice 2 lignes x 3 colonnes
INTEGER
:: ligne, colonne
...
OPEN(10, file='mat2x3.dat', STATUS='old')
! ouverture du fichier en lecture
DO ligne = 1, nl
READ(10, *) matrice(ligne,:)
! lecture ligne par ligne
END DO
CLOSE(10)
DO ligne = 1, nl
WRITE(*, *) matrice(ligne,:)
! affichage ligne par ligne
END DO

7.1.3

Constructeurs de tableaux

Lors de sa dclaration, il est possible dinitialiser un tableau de rang 1 grce un constructeur de


tableau qui est un vecteur encadr par les dlimiteurs (/ et /), ou (en fortran 2003) les dlimiteurs
[ et ], et dont les lments peuvent tre des scalaires ou des vecteurs, tous du mme type, spars f2003
par des virgules. Le vecteur pourra tre produit par une ou des boucles implicites.
INTEGER, DIMENSION(3)
INTEGER, DIMENSION(3)
INTEGER
INTEGER, DIMENSION(7)

::
::
::
::

vecteur = (/ 3, 5, 1 /)
vecteur = [ 3, 5, 1 ] ! en fortran 2003
i
v = (/ (2*i, i=1, 4), vecteur /) ! boucle implicite

Le tableau v contient alors les entiers suivants : 2, 4, 6, 8, 3, 5 et 1.


Pour les tableaux de rang suprieur, le constructeur nest pas autoris : on pourra utiliser B
la fonction RESHAPE (cf. 7.4.3, p. 86) qui restructure le tableau mono-dimensionnel v en tableau
multi-dimensionnel matrice suivant le vecteur de profil profil.

7.2

Sections de tableaux

Une section de tableau est un sous-tableau, de rang et dtendues infrieurs ou gaux ceux du
tableau dont il est extrait.

82

CHAPITRE 7. TABLEAUX

7.2.1

Sections rgulires

Une section rgulire (regular section) est un sous-tableau dont les indices dans le tableau initial
sont en progression arithmtique. Une section rgulire peut donc tre dfinie, pour chaque dimension, par un triplet <debut >:<fin >:<pas > 10 . Chacun des lments du triplet est optionnel et les
valeurs par dfaut sont :
<debut > : la borne infrieure selon la dimension, telle quelle a t spcifie lors de la dclaration (donc 1 si elle na pas t prcise dans la dclaration)
<fin > : la borne suprieure selon la dimension, telle quelle a t spcifie lors de la dclaration
<pas > : 1
Noter que le pas peut tre ngatif, ce qui permet dinverser lordre des lments. Comme dans les
boucles DO, si le pas est diffrent de 1, il est possible que la borne finale ne soit pas atteinte.
REAL, DIMENSION(3,6)
:: matrice
REAL, DIMENSION(3)
:: vecteur
REAL, DIMENSION(3,3)
:: sous_matrice
vecteur(:) = matrice(:,5)
vecteur(:) = matrice(1,1:3)
sous_matrice(:,:) = matrice(:,2:6:2)

matrice(1:2,2:6:2)
x
x

x
x

!
!
!
!
!
!
!

3 lignes par 6 colonnes (rang 2)


3 lments ligne ou colonne (rang 1)
3 lignes par 3 colonnes
vecteur est la 5me colonne
extrait de la 1re ligne
extraction des colonnes 2, 4 et 6
de matrice

matrice(::2,2:6:2)

x
x

matrice(2:,3::2)
x
x

x
x

Remarque : chaque fois que lon fixe un indice, on diminue dune unit le rang du tableau,

B mais si on restreint lintervalle dun des indices de faon ne slectionner quune valeur, le rang

reste inchang. Par exemple, si on dclare un tableau de rang deux par :


REAL, DIMENSION(3,6) :: matrice
la section de tableau matrice(2,:) est un tableau de rang 1 11 6 lments ; mais la section
de tableau matrice(2:2,:) reste un tableau de rang 2 de profil (/1, 6/) contenant les mmes
6 lments.

7.2.2

Sections non-rgulires

Les sections non rgulires sont obtenues par indexation indirecte, grce un vecteur dindices.
INTEGER, DIMENSION(3)
:: vecteur_indice = (/ 3, 5, 1 /)
INTEGER, DIMENSION(4,6) :: m
INTEGER, DIMENSION(2,3) :: sous_matrice
sous_matrice = m(1:3:2, vecteur_indice)
Le sous-tableau sous_matrice est alors constitu des lments suivants de m :
m(1,3)
m(3,3)

m(1,5)
m(3,5)

m(1,1)
m(3,1)

10. Ne pas confondre avec scilab, octave ou matlab dans lesquels lordre est dbut:pas:fin.
11. Il est dailleurs trs rare en fortran de dclarer des tableaux dont ltendue est limite 1 sur un des axes,
contrairement ce qui se fait sous scilab ou matlab qui distinguent vecteurs lignes et vecteurs colonnes tous les
deux reprsents par des matrices avec un seul lment selon un des deux axes.

7.3. OPRATIONS SUR LES TABLEAUX

7.3
7.3.1

83

Oprations sur les tableaux


Extension des oprations lmentaires aux tableaux

Les oprateurs agissant sur des types scalaires peuvent tre appliqus des tableaux, par
extension de leur fonction scalaire chacun des lments des tableaux. De telles oprations sont
qualifies doprations lmentaires. Dans le cas des oprateurs binaires, les tableaux oprandes
doivent tre conformants pour que cette opration puisse seffectuer terme terme. Un scalaire est
considr comme conformant avec un tableau quelconque. Dans le cas o les types des lments de
deux tableaux diffrent, il y a conversion implicite avant application de loprateur comme pour
des oprations scalaires.
Pour des raisons de lisibilit, on pourra indiquer le rang des tableaux manipuls par une notation
de section de tableau, par exemple tab(:,:) pour un tableau deux dimensions, au lieu de la
notation plus concise tab qui occulte le caractre multidimensionnel des variables manipules. Mais
dsigner ainsi un tableau allouable comme section de tableau nest pas quivalent : cela inhibe les B
possibilits de (r-)allocation au vol par affectation (cf. 7.5.4, p. 93).
REAL, DIMENSION(2,3)
:: tab, tab1 ! profil [2,3]
REAL, DIMENSION(0:1,-1:1)
:: tab2
! profil [2,3] identique
tab(:,:) = tab(:,:) + 1
! le scalaire 1 est ajout chaque terme du tableau
tab(:,:) = - tab(:,:)
tab(:,:) = tab(:,:) * tab(:,:)
! attention: produit terme terme
! (et non produit matriciel)
tab(:,:) = cos(tab(:,:))
! cosinus de chacun des termes du tableau
tab(:,:) = tab1(:,:) + tab2(:,:) ! tab(1,1) = tab1(1,1) + tab2(0,-1) ...
! seul compte le profil
La multiplication matricielle de deux tableaux peut par exemple seffectuer des deux faons suivantes (en pratique, on utilisera la fonction intrinsque MATMUL, cf 7.4.2, p. 85) :
REAL, DIMENSION(2,3) :: a
! matrice 2 lignes x 3 colonnes
REAL, DIMENSION(3,4) :: b
! matrice 3 lignes x 4 colonnes
REAL, DIMENSION(2,4) :: c
! matrice 2 lignes x 4 colonnes
INTEGER
:: i, j, k
c = 0
! initialisation du tableau c 0
DO i = 1, 2
! boucle sur les lignes de c
DO k = 1, 4
! boucle sur les colonnes de c
somme: DO j = 1, 3
! calcul de la somme : produit scalaire
c(i,k) = c(i,k) + a(i,j) * b(j,k)
!
de a(i,:) par b(:,k)
END DO somme
END DO
END DO
c(:,:) = 0.
! rinitialisation de c
DO k = 1, 4
! boucle sur les colonnes de c
somme_v: DO j = 1, 3
! calcul vectoriel des sommes
c(:,k) = c(:,k) + a(:,j) * b(j,k)
END DO somme_v
END DO

Affectation de sections de tableau avec recouvrement


Dans une instruction vectorielle , il est possible daffecter une section de tableau une
section de tableau avec recouvrement entre membre de gauche et membre de droite de lopration
daffectation : le rsultat peut tre diffrent de celui quaurait donn une boucle explicite avec
affectation scalaire. En effet,

84

CHAPITRE 7. TABLEAUX

Le second membre dune instruction daffectation dans un tableau est compltement valu avant
laffectation elle-mme.
INTEGER
INTEGER, DIMENSION(5)
tab = tab(5:1:-1)

:: i
:: tab = (/ (i, i = 1, 5) /)
! permet d'inverser l'ordre des lments de tab

Une version scalaire aurait ncessit lemploi dune variable tampon supplmentaire pour viter
dcraser des valeurs lors de lchange entre 2 coefficients placs symtriquement :
INTEGER
INTEGER, DIMENSION(5)
INTEGER
do i = 1, 5/2
tampon = tab(i)
tab(i) = tab(6-i)
tab(6-i) = tampon
end do

f95

7.3.2

::
::
::
i=1,

i
tab = (/ (i, i = 1, 5) /)
tampon
2 ici : on s'arrte la moiti du tableau

Instruction et structure WHERE

Lorsque les oprations effectuer sur les lments dun tableau dpendent dune condition
portant sur ce tableau ou un autre tableau conforme, on peut utiliser linstruction WHERE, ou la
structure WHERE ... END WHERE, bien adapte au calcul parallle 12 .

[<nom >:] WHERE (<expression_logique_tableau >)


<bloc d'affectation de tableau(x) conforme(s) >
! excut pour les lments o l'expression est vraie
[ELSEWHERE
<bloc d'affectation de tableau(x) conforme(s) >]
! excut pour les lments o l'expression est fausse
END WHERE [<nom >]
REAL, DIMENSION(10) :: a, b, c
WHERE ( a > 0. ) b = sqrt(a) ! simple instruction where
WHERE ( a > 0. )
! bloc where
c = log(a)
! pour tous les lments positifs du tableau a
ELSEWHERE
c = -1.e20
! pour tous les lments ngatifs ou nuls du tableau a
END WHERE

7.3.3

Affectation dune section non-rgulire

Dans le cas o lopration provoque laffectation dune section non-rgulire de tableau, il est
interdit daffecter plusieurs fois le mme lment, cest dire quil ne peut y avoir de recouvrement
lintrieur du membre de gauche de lopration daffectation 13 .
12. Depuis le fortran 95, il est possible dimbriquer des structures WHERE.
13. Comme lordre daffectation nest pas garanti lexcution, on conoit quautoriser laffectation multiple de
certains lments introduirait une ambigut dans le rsultat. Il est donc logique dinterdire cette possibilit, mais
... parfois difficile de prvoir quand elle pourrait intervenir dans le cas o les indices dterminant les sections sont
variables.

85

7.4. FONCTIONS INTRINSQUES PARTICULIRES AUX TABLEAUX

INTEGER, DIMENSION(3) :: i = (/ 1, 3, 1 /), v = (/ -1, -2, -3 /), w


w = v(i)
! opration licite qui donne w = (/ -1, -3, -1 /)
! opration illicite car double affectation pour w(1)
w(i) = v

7.4

Fonctions intrinsques particulires aux tableaux

La majorit des procdures intrinsques sont lmentaires et peuvent donc tre appeles avec
des arguments tableaux. Mais il existe des fonctions intrinsques spcifiquement consacres la
manipulation des tableaux (cf. A.5, p. 143).

7.4.1

Fonctions dinterrogation

SIZE(array [, dim]) donne ltendue dun tableau selon la dimension dim si cet argument
optionnel est fourni, et le nombre total dlments sinon ;
SHAPE donne le vecteur profil dun tableau (son tendue est le rang du tableau) ;
LBOUND et UBOUND fournissent un vecteur constitu des bornes respectivement infrieures et
suprieures des indices selon chacune des dimensions du tableau. Si une dimension est prcise
comme argument optionnel, elles fournissent un scalaire indiquant les bornes des indices selon
cette dimension.
MINLOC et MAXLOC fournissent le vecteur des indices du premier lment respectivement minimum ou maximum du tableau, mais en indexant le tableau partir dune borne infrieure B
gale 1 selon chaque dimension, quelles que soient les bornes dclares.
Attention : mme si on appelle LBOUND, UBOUND, MINLOC ou MAXLOC dun tableau de rang 1, le B
rsultat reste un tableau de rang 1 un seul lment ; pour obtenir un rsultat scalaire, il faut
utiliser largument optionnel DIM=1.
INTEGER,
INTEGER,
INTEGER
tab(:,1)
tab(:,2)
tab(:,3)

DIMENSION(0:3)
DIMENSION(-2:2,3)

:: v = (/
:: tab
:: i
= (/ (i, i=-2, 2) /)
!
= (/ (2*i, i=-2, 2) /)
!
= (/ (3*i, i=-2, 2) /)
!

La matrice associe tab est alors :

SIZE(v)
SHAPE(v)
LBOUND(v)
LBOUND(v, DIM=1)
MINLOC(v)
MAXLOC(v)
MAXLOC(v, DIM=1)

7.4.2

2
1
0
1
2

4
(/ 4 /)
(/ 0 /)
0
(/ 2 /)
(/ 1 /)
1

3, 2, 2, 3 /)
| -2
| -4
| -6

4
2
0
2
4

6
3
0
3
6

-1
-2
-3

0
0
0

1
2
3

2 |
4 | (transpose de tab)
6 |

SIZE(tab)
SIZE(tab,1)
SIZE(tab,2)
SHAPE(tab)
LBOUND(tab)
UBOUND(tab)
LBOUND(tab,1)
MINLOC(tab)
MAXLOC(tab)

15
5
3
(/ 5, 3 /)
(/ -2, 1 /)
(/ 2, 3 /)
-2
(/ 1, 3 /)
(/ 5, 3 /)

Fonctions de rduction

Les fonctions de rduction renvoient un tableau de rang infrieur (ventuellement un scalaire)


celui pass en argument. Si on spcifie une dimension, seule cette dimension sera affecte par
lopration de rduction et le tableau rendu sera de rang r 1, o r est le rang du tableau initial.

86

CHAPITRE 7. TABLEAUX

SUM et PRODUCT calculent respectivement la somme et le produit des lments du tableau.


MAXVAL et MINVAL fournissent respectivement le maximum et le minimum dun tableau.
DOT_PRODUCT donne le produit scalaire de deux vecteurs :
si u et v sont des vecteurs de rels (ou dentiers), DOT_PRODUCT(u, v) = SUM(u*v).
si u et v sont des vecteurs de complexes, DOT_PRODUCT(u, v) = SUM(CONJG(u)*v).
MATMUL 14 effectue le produit matriciel de deux tableaux 15 . Elle suppose que les profils de
ses arguments permettent lopration :
produit dune matrice de n lignes et p colonnes par une matrice de p lignes et q colonnes
donnant une matrice de n lignes et q colonnes
produit dune matrice de n lignes et p colonnes par un vecteur de taille p donnant un
vecteur de taille n
produit dun vecteur de taille n par une matrice de n lignes et p colonnes donnant un
vecteur de taille p.
PRODUCT(tab, DIM=2)
SUM(tab, DIM=2)
SUM(tab)
MAXVAL(tab, DIM=2)
MAXVAL(tab, DIM=1)
MAXVAL(tab)
MINVAL(tab, DIM=2)
DOT_PRODUCT(tab(:,1), tab(:,3))

(/ -48, -6, 0, 6, 48 )/
(/ -12, -6, 0, 6, 12 )/
0
(/ -2, -1, 0, 3, 6 )/
(/ 2, 4, 6 /)
6
(/ -6, -3, 0, 1, 2 )/
30

Par exemple, les calculs de moments dune srie statistique stocke dans un tableau monodimensionnel peuvent sexprimer de faon trs concise laide de ces fonctions.
INTEGER, PARAMETER
:: n = 1000
REAL, DIMENSION(n)
:: x, y
REAL
:: moyenne_x, moyenne_y, variance_x, covariance
moyenne_x = SUM( x(:) ) / REAL( SIZE( x(:) ) )
moyenne_y = SUM( y(:) ) / REAL( SIZE( y(:) ) )
variance_x = SUM( (x(:) - moyenne_x) ** 2 ) / REAL(SIZE(x(:)) - 1)
covariance = SUM((x(:)-moyenne_x) * (y(:)-moyenne_y)) / REAL(SIZE(x(:)) - 1)

7.4.3

Fonctions de transformation

RESHAPE(source,shape[,pad][,order]) restructure les lments du tableau source suivant


le profil shape. Si le tableau source est de taille infrieure au tableau cible, les lments
manquants sont pris dans le tableau pad. Lordre traditionnel de rangement dans le
tableau cible peut tre modifi via largument (optionnel) order, qui est un tableau de rang 1.
PACK(array, mask [, vector]) rarrange les lments du tableau array slectionns selon
le masque mask (tableau de boolen conforme array) dans un tableau de rang 1. Si largument vector (tableau de rang 1) est fourni, il prescrit ltendue du tableau rsultant et doit
comporter au moins autant dlments que mask comporte de valeurs .true. : les lments
de vector sont utiliss pour complter le rsultat si le nombre dlments vrais du masque
est infrieur ltendue de vector. Les lments du tableau source array sont traits dans
lordre habituel, par colonnes pour une matrice.
14. Avec certains compilateurs, il est possible de faire appel une version optimise de la bibliothque blas pour
effectuer les calculs de MATMUL sur des matrices de grande taille (cf. E.6.1 par exemple avec loption -fexternal-blas
pour gfortran).
15. Rappel : le produit de deux matrices via loprateur * agissant sur deux tableaux nest applicable que sur deux
tableaux conformes et effectue le produit terme terme et non le produit matriciel.

87

7.4. FONCTIONS INTRINSQUES PARTICULIRES AUX TABLEAUX

UNPACK(vector, mask, field) recopie les lments du tableau de rang 1 vector dans un
tableau sous le contrle du masque mask conformant avec le tableau rsultat. Cest donc
mask qui dtermine le profil du tableau rsultat. Si llment du masque est vrai, llment
correspondant du tableau rsultat est pris dans vector, sinon, on lui donne la valeur field.
SPREAD(source, dim, ncopies) cre, par duplication (ncopies fois selon la dimension dim)
du scalaire ou tableau source, un tableau de rang immdiatement suprieur source.
MERGE(tsource, fsource, mask) fusionne les tableaux tsource et fsource selon le masque
mask : les trois arguments et le rsultat sont des tableaux conformants.
CSHIFT(array, shift [, dim]) et EOSHIFT(array, shift [, boundary][, dim]) effectuent des dcalages de shift des lments du tableau selon la dimension ventuellement spcifie (si le paramtre dim nest pas prcis, cela implique dim=1 16 ). Si shift est positif, les
dcalages se font vers les indices dcroissants et rciproquement. CSHIFT effectue des dcalages circulaires (sans perte dlments) alors que EOSHIFT remplace les lments perdus par
des zros du type des lments de array ou par boundary si cet argument optionnel est
prcis.
TRANSPOSE calcule la transpose dune matrice.
INTEGER
:: i
INTEGER, DIMENSION(8)
:: v = (/ (i, i = 1, 8) /), w
INTEGER, DIMENSION(3,4) :: tab1, tab2, tab3
tab1 = RESHAPE(v, (/ 3, 4 /), pad = (/ 0 /) )
w = CSHIFT(v, 2)
tab2 = CSHIFT(tab1, SHIFT=-1 ) ! dcalage des lignes vers le bas
tab3 = CSHIFT(tab1, (/ 1, -2, 2 /), DIM=2) ! un dcalage diffrent par ligne

1
2
3

4
5
6

7
8
0

0
0
0

1
2
3

4
5
6

7
8
0

0
0
0

1
2
3

4
5
6

7
8
9

CSHIFT(v,SHIFT=2)

EOSHIFT(v,SHIFT=2)

RESHAPE(v,(/3,4/),pad=(/0/))

PACK(tab1,mod(tab1,2)==1)
1
-1
2

UNPACK(v(1:4),mod(tab1,2)==1, -1)

-1
3
-1

4
-1
-1
1
1

SPREAD((/1, 2, 3/),dim=1,ncopies=2)

SPREAD((/1, 2, 3/),dim=2,ncopies=2)

-1
-2
-3

-4
-5
-6

-7
-8
-9

F
T
F

T
F
T

F
T
F

-1
2
-3

MERGE

16. Les dcalages sont appliqus chacun des vecteurs constituant le tableau et non globalement.

-1
-1
-1
2
2

3
3

1
2
3

1
2
3

4
-5
6

-7
8
-9

88

CHAPITRE 7. TABLEAUX

1
2
3

4
5
6

7
8
0

0
0
0

CSHIFT(tab1,SHIFT=-1)
ou
CSHIFT(tab1,SHIFT=+2)

1
2
3

4
5
6

7
8
0

0
0
0

CSHIFT(tab1, (/ 1, -2, 2 /), DIM=2)

7.4.4

+1
2
+2

3
1
2

6
4
5

0
7
8

0
0
0

4
8
0

7
0
0

0
2
3

1
5
6

Notion de masque

Parfois, un traitement a priori vectoriel via une fonction intrinsque ne doit pas tre appliqu
tous les lments dun tableau, mais une expression logique tableau peut servir dcider quels
lments seront concerns par linstruction tableau. Certaines procdures intrinsques portant sur
des tableaux acceptent un tel tableau boolen conforme largument trait, appel masque (mask),
en argument optionnel (de mot-clef MASK=).
INTEGER
:: i, produit, somme
INTEGER, DIMENSION(5)
:: v = (/ (i, i = -2, 2) /), w = 2 * v
produit = PRODUCT(v, MASK = v /= 0)
! produit des lments non nuls de v
somme = SUM(w, MASK = v /=0) ! somme des lments de w(i) tels que v(i) non nul

7.4.5

ALL, ANY, COUNT

Trois fonctions intrinsques oprent sur des tableaux de boolens pour vrifier la validit dune
expression logique sur les lments dun tableau :
ALL(<mask >) rend .TRUE. si tous les lments du tableau boolen <mask > sont vrais, .FALSE.
sinon ; elle ralise un ET logique entre les lments du tableau
ANY(<mask >) rend .TRUE. si un au moins des lments du tableau boolen <mask > est vrai,
.FALSE. si tous sont .FALSE. ; elle ralise un OU logique entre les lments du tableau
COUNT(<mask >) rend le nombre (entier) des lments du tableau <mask > qui valent .TRUE..
En pratique, <mask > est produit par application dun test un tableau (ou des tableaux conformes).
INTEGER
:: i, nb_positifs
INTEGER, DIMENSION(5)
:: v = (/ (i, i=-2, 2) /)
REAL, DIMENSION(5)
:: u, u_log
...
nb_positifs = COUNT (v > 0)
! nombre d'lments positifs (2 ici)
IF (ALL(u > 0)) u_log = log(u) ! calcul si tous les lments de u sont > 0
f95

7.4.6

Instruction et structure FORALL

Certaines affectations de tableaux, par exemple combinant deux indices, ne peuvent pas sexprimer de faon globale sur le tableau, malgr leur facilit tre traites en parallle. Par exemple,
une affectation entre tableaux de rang diffrent :
DO i = 1, n
tab(i, i) = v(i) ! copie du vecteur v sur la diagonale de tab
END DO
peut sexprimer laide de linstruction FORALL :
FORALL (i = 1:n) tab(i, i) = v(i)

7.5. TABLEAUX, PROCDURES ET ALLOCATION DYNAMIQUE

89

Les expressions de droite sont alors calcules en parallle pour toutes les valeurs de lindice, comme
si les rsultats intermdiaires taient stocks dans des variables temporaires jusqu la fin des calculs
en attendant laffectation finale du membre de gauche. En particulier, au contraire de ce qui se
passe dans une boucle classique, lordre de parcours des indices est indiffrent ; plus prcisment il
peut tre choisi par le processeur pour optimiser (vectoriser) le calcul. Cette construction savre
donc trs adapte aux calculs de filtrage numrique linaire. Par exemple, linstruction suivante
calcule bien une diffrence finie pour estimer une drive, alors quune boucle dans le sens croissant
des indices ne donnerait pas le mme rsultat.
FORALL (i = 1: size(v)-1 )

v(i+1) = v(i+1) - v(i)

La structure FORALL ... END FORALL permet dexprimer une srie daffectations successives portant sur les mmes indices 17 .
FORALL (i=1:n, j=1:p)
a(i, j) = i + j
b(i, j) = a(i, j) ** i
END FORALL

! tous les a(i,j) sont calculs


! avant de calculer b(i,j)

Linstruction et la structure FORALL admettent de plus un masque (cf. 7.4.4, p. 88), qui linverse
de celui de WHERE, doit tre scalaire, avec une condition logique permettant de slectionner les
indices.
FORALL (i = 1:n, v(i) /=0 ) tab(i, i) = 1./v(i)
Une structure FORALL peut contenir aussi des constructions FORALL et WHERE (cf. 7.3.2, p. 84), mais
ne peut pas appeler des fonctions de transformation de tableaux.

7.5
7.5.1

Tableaux, procdures et allocation dynamique


Les trois mthodes dallocation des tableaux

Lallocation despace mmoire pour des tableaux peut seffectuer, en excluant provisoirement
les arguments muets de procdures, de trois faons diffrentes :
Pour les tableaux de profil fixe, la rservation despace mmoire se fait une fois pour toutes
la compilation. Porte et dure de vie dpendent alors de la procdure hte.
Noter quil est possible, et conseill de paramtrer les profils de ces tableaux par des ex-
pressions entires constantes, en utilisant des constantes symboliques (grce lattribut
PARAMETER). Cette prcaution permet de simplifier un changement de taille de ces tableaux
qui se rduit au changement de constantes symboliques une seule fois dans le code, suivi
dune recompilation.
Au dbut dune procdure, il est possible de dclarer des tableaux locaux de rang fixe dont
le profil dpend dun argument dentre de la procdure ou dun paramtre partag via un
module. Lespace mmoire leur est attribu automatiquement sur la pile (stack), au moment
de lappel de la procdure, et il est bien sr libr la fin de son excution. Cela limite leur
dure de vie lappel de la procdure, et restreint leur porte (scope) cette procdure et
ventuellement celles quelle appelle. Ces tableaux sont qualifis de tableaux automatiques.
Enfin, il est possible de dclarer des tableaux de rang fix la compilation, mais dont le
profil est dfini en cours dexcution : porte et dure de vie de ces tableaux sont dcides par
lutilisateur qui doit prendre en charge lui-mme lallocation et la libration de la mmoire,
prise cette fois sur le tas (heap). Ces tableaux profil diffr sont aussi qualifis de tableaux
dynamiques (cf. 7.5.3, p. 91).
17. Chaque instruction est alors excute sur tous les indices avant de passer la suivante.

90

CHAPITRE 7. TABLEAUX

7.5.2

Tableaux en arguments muets des procdures

Bien entendu, si on travaille avec des tableaux de profil fixe, on peut dclarer leur profil la
fois dans le programme principal et les procdures appeles : on dit que ces tableaux sont profil
B explicite. Rappelons que, dans ce cas, seul compte le profil du tableau et non ses bornes.
MODULE util
IMPLICIT NONE
CONTAINS
SUBROUTINE sub(tab)
REAL, DIMENSION(5), INTENT(INOUT) :: tab
...
! tab(1) contient tab0(-2) au premier appel
...
! tab(1) contient tab1(1) au deuxime appel
END SUBROUTINE SUB
END MODULE util
...
USE UTIL
REAL, DIMENSION(-2:2)
:: tab0
REAL, DIMENSION(5)
:: tab1
CALL sub(tab0)
CALL sub(tab1)
...
Mais, il est plus frquent que des procdures ncessitent lusage de tableaux de rang connu, mais
de profil variable dun appel lautre. On peut passer les tendues en argument de la procdure
pour dclarer ensuite les arguments tableaux, mais cela constitue un risque dincohrence.

La mthode la plus fiable consiste attribuer aux tableaux arguments muets de la procdure
un profil implicite (assumed-shape, profil suppos ), symbolis par des deux points la place
des tendues qui seront dtermines chaque appel par le tableau argument effectif. Pour pouvoir
appeler une procdure utilisant comme argument muet des tableaux de profil implicite, la procdure
appelante doit connatre linterface de la procdure appele. Trois possibilits sont envisageables,
dont la dernire est prfrable :
une procdure interne (cf. 6.3.1, p. 62) ;
une procdure externe complte par son interface explicite (cf. 6.3.3, p. 63) ;
de prfrence, une procdure de module (cf. 6.4, p. 64), dont linterface est rendue explicite
via linstruction USE.
MODULE util
IMPLICIT NONE
CONTAINS
SUBROUTINE sub(tab)
REAL, DIMENSION(:,:)
...
RETURN
END SUBROUTINE sub

:: tab ! profil implicite

SUBROUTINE sub2(tab)
REAL, DIMENSION(:,:)
:: tab ! profil implicite
REAL, DIMENSION(SIZE(tab,1),SIZE(tab,2)) :: aux ! tableau local automatique
...
RETURN
END SUBROUTINE sub2
...
END MODULE util

7.5. TABLEAUX, PROCDURES ET ALLOCATION DYNAMIQUE

PROGRAM principal
USE util
INTEGER, PARAMETER
REAL, DIMENSION(lignes,colonnes)
REAL, DIMENSION(2*colonnes,2*lignes)
...
CALL sub(tab)
CALL sub2(tab)
CALL sub(tab2)
CALL sub2(tab2)
...
END PROGRAM principal

7.5.3

91

:: lignes = 3, colonnes = 4
:: tab
:: tab2

Tableaux dynamiques allouables

Lorsque, par exemple, le profil dun tableau nest connu qu lexcution, on peut lui allouer
dynamiquement la mmoire ncessaire. Il faut alors dclarer ce tableau en prcisant son rang 18
et lattribut ALLOCATABLE, qui en fait un tableau profil diffr (deferred-shape array). Une fois
le profil dtermin, linstruction ALLOCATE permettra dallouer effectivement la mmoire requise,
avant toute opration daffectation sur ce tableau. Aprs avoir utilis le tableau, il est recommand
de librer la mmoire alloue par linstruction DEALLOCATE 19 , en particulier si on souhaite rutiliser
le mme identificateur de tableau avec une autre taille.
Dans un souci de fiabilit des programmes, on prendra soin de tester le statut de retour de la
procdure ALLOCATE et, avant toute opration dallocation ou de libration de mmoire, de tester
ltat dallocation des tableaux grce la fonction dinterrogation ALLOCATED qui fournit un rsultat
boolen.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

PROGRAM alloc1 ! fichier alloc-tab1d.f90


IMPLICIT NONE ! allocation dynamique sans pointeur
INTEGER :: i, n, ok=0
INTEGER, DIMENSION(:), ALLOCATABLE :: ti
!
rang seulement ^^^^^^^^^^^ attribut obligatoire
DO ! boucle sur la taille du tableau jusqu' n<=0
WRITE(*, *) "entrer le nb d'lments du tableau (0 si fin)"
READ(*,*) n
IF(n <=0 ) EXIT
! sortie de la boucle
ALLOCATE(ti(n), stat=ok) ! allocation de la mmoire
IF (ok /= 0) THEN
WRITE(*, *) "erreur d'allocation"
CYCLE ! on passe une autre valeur de n
END IF
DO i=1, n
! affectation du tableau
ti(i) = i
END DO
DO i=1, n
! affichage du tableau en colonne
WRITE(*,*) ti(i)
END DO
IF(ALLOCATED(ti)) THEN
DEALLOCATE(ti) ! libration de la mmoire
END IF
END DO
END PROGRAM alloc1 ! fichier alloc-tab1d.f90
18. Mais sans indiquer sa taille.
19. En fin de programme principal, il est prudent de dsallouer explicitement tous les tableaux dynamiques allous.
En effet, cette opration implique la relecture dinformations sur la taille de la zone mmoire alloue. La dsallocation
peut provoquer une erreur de segmentation si cette relecture est errone, par exemple cause dun dpassement de
mmoire dans un autre tableau stock au voisinage. Ainsi la dsallocation peut rvler utilement une corruption de
la mmoire cause par dautres oprations.

92

CHAPITRE 7. TABLEAUX

Un tableau dynamique local une procdure et allou dans cette procdure est automatiquement
libr la sortie de la procdure (via END ou RETURN), sauf sil est rendu permanent par lattribut
SAVE.
f2003

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
42
43
44
45

Tableau dynamique en paramtre Un tableau dynamique peut aussi tre pass en argument dune procdure, mais, en fortran 95, il doit tre dj allou avant lappel de la procdure et
nest pas considr comme allouable dans la procdure. Ces restrictions sont leves en fortran 2003,
ainsi quavec les extensions spcifiques de la plupart des compilateurs fortran 95 20 . Le tableau doit
alors possder lattribut ALLOCATABLE dans la procdure, qui peut se charger de lallocation. Sil
sagit dun argument de sortie (INTENT(OUT)), il est dsallou si ncessaire lors de lappel de la
procdure.
MODULE m_alloc_sub
IMPLICIT NONE
CONTAINS
SUBROUTINE init_tab(tab, m, n)
INTEGER, INTENT(in) :: m, n
INTEGER, ALLOCATABLE, INTENT(out) :: tab(:,:)
INTEGER :: ok, i, j
IF(.NOT.ALLOCATED(tab)) THEN
ALLOCATE(tab(m, n), stat = ok)
IF (ok /= 0) THEN
WRITE(*, *) 'erreur allocation'
STOP
END IF
DO i = 1, m
DO j = 1, n
tab(i, j) = 1000 * i + j
END DO
END DO
ELSE ! ne devrait pas se produire en fortran 2003 car tab est INTENT(OUT)
WRITE(*, *) 'tableau dj allou'
STOP
END IF
END SUBROUTINE init_tab
END MODULE m_alloc_sub
PROGRAM alloc_proc
USE m_alloc_sub
IMPLICIT NONE
INTEGER, ALLOCATABLE :: t(:,:)
INTEGER :: m, n, i
WRITE (*, *) 'entrer les dimensions du tableau: m et n'
READ (*, *) m, n
! appel du sous programme qui alloue et initialise le tableau
CALL init_tab(t, m, n)
DO i = 1 ,m
WRITE (*, *) t(i, :)
END DO
m = 2 * m
n = 2 * n
! deuxime appel du sous programme avec tab dj allou, mais
! ncessitant une rallocation car les dimensions ont chang
CALL init_tab(t, m, n)
DO i = 1 ,m
WRITE (*, *) t(i, :)
END DO
IF(ALLOCATED(t)) THEN
20. En particulier xlf dibm, le compilateur nag et g95 avec loption -std=f2003 ou -std=f95 assortie de -ftr15581
(cf. E.5.1, p. 170) autorisent lallocation de largument tableau dans la procdure.

7.5. TABLEAUX, PROCDURES ET ALLOCATION DYNAMIQUE

46
47
48

f2003

93

DEALLOCATE(t)
END IF
END PROGRAM alloc_proc

7.5.4

Allocation et rallocation au vol de tableaux dynamiques par affectation

En fortran 2003, un tableau allouable peut tre (r-)allou automatiquement si on lui affecte
une expression tableau :
sil ntait pas allou auparavant, il est allou avec le profil de lexpression qui lui est affecte ;
sil tait dj allou avec un profil diffrent, il est rallou pour ajuster son profil celui du
membre de droite de laffectation.
Noter que si le membre de gauche de laffectation est une section de tableau, aucune allocation B
nest effectue. La rallocation automatique peut donc tre inhibe pour un tableau complet si on
le dsigne comme une section de tableau en prcisant dans le membre de gauche le symbole :
pour chaque dimension. Dans ce cas, les lments de lexpression de droite en dehors du profil du
tableau de gauche sont ignors.
Par exemple, pour des tableaux de rang 1, le programme suivant :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

! allocation automatique par affectation


! fortran 2003 seulement : gfortran 4.6.3 (nov 2013 mageia 2)
! ok avec NAG Fortran Compiler Release 5.2(643) le 12 fev 2009
! ok avec ifort (IFORT) 12.1.3 20120212 + option -assume realloc_lhs
PROGRAM t_alloc_affect
INTEGER, DIMENSION(:), ALLOCATABLE :: v1, v2, v3
v1 = [1, 2] ! allocation de v1 par affectation => 2 lments
WRITE(*,*) "taille de v1=", SIZE(v1), " v1=", v1
v2 = [-3, -2, -1 ] ! allocation de v2 par affectation => 3 lments
WRITE(*,*) "taille de v2=", SIZE(v2), " v2=", v2
v3 = v1
! allocation implicite de v3 => 2 lments
WRITE(*,*) "taille de v3=", SIZE(v3), " v3=", v3
v1 = v2
! rallocation implicite de v1 => 3 lments
WRITE(*,*) "taille de v1=", SIZE(v1), " v1=", v1
v3(:) = v2
! pas de rallocation de v3 => v2(3) inutilis
! provoque une erreur sous gfortran : tableaux non conformants
WRITE(*,*) "taille de v3=", SIZE(v3), " v3=", v3
DEALLOCATE(v1, v2, v3)
END PROGRAM t_alloc_affect
affiche :
taille
taille
taille
taille
taille

de
de
de
de
de

v1=
v2=
v3=
v1=
v3=

2
3
2
3
2

v1=
v2=
v3=
v1=
v3=

1 2
-3 -2 -1
1 2
-3 -2 -1
-3 -2

La (r-)allocation automatique de tableaux par affectation peut entrer en conflit avec certaines
optimisations effectues par le compilateur. Cest pourquoi certains compilateurs disposent dune
option 21 pour choisir si on lautorise, indpendamment du choix du standard fortran 2003 ou
antrieur.
21. -fno-realloc-lhs ou -f-realloc-lhs pour gfortran (cf. E.6.1, p. 171), -Mallocatable=95 ou
-Mallocatable=03 pour pgf95 (cf. E.3.1, p. 167), -assume realloc_lhs ou -assume no-realloc_lhs pour ifort
(cf. E.4.1, p. 168).

Chapitre 8

Chanes de caractres
Ce court chapitre regroupe les outils, dont certains dj introduits dans les chapitres prcdents,
permettant la manipulation des chanes de caractres en fortran : le type chane (cf. chapitre 2), les
expressions de type chane (cf. chapitre 3) , les sous-chanes, les fonctions manipulant des chanes,
les entres/sorties de chanes (cf. chapitre 5), les tableaux de chanes et le passage darguments
chanes dans les procdures.

8.1

Le type chane de caractres

Le langage fortran comporte le type intrinsque CHARACTER pour stocker les chanes de caractres. chaque objet de type CHARACTER est associe une longueur LEN qui est le nombre des
caractres de la chane.

8.1.1

Les constantes chanes de caractres

Les constantes chanes de caractres sont dlimites par des apostrophes simples ' ou 1 des
guillemets ". lintrieur dun des types de dlimiteur, lautre est considr comme un caractre
quelconque, ce qui permet dcrire par exemple "aujourd'hui". Toutefois, on peut aussi introduire
le dlimiteur lintrieur de la chane condition de le dupliquer, comme dans 'aujourd''hui'.
Pour crire une constante chane sur plusieurs lignes, il faut terminer toutes les lignes sauf la
dernire par le symbole & de continuation de ligne. Par dfaut tous les espaces en dbut de ligne
de suite sont alors significatifs (cf. 1.4.2 p. 8) ; mais on peut adopter une prsentation plus agrable
en spcifiant par un symbole & supplmentaire le dbut de la suite de la chane, ignorant ainsi tous
les espaces situs avant.
WRITE (*,*) 'chane de caractres comportant plusieurs lignes dans &
&le programme source sans espace superflu'

8.1.2

Les dclarations de chanes de caractres

CHARACTER(LEN=<longueur >) :: <chaine >


permet de dclarer une chane comportant longueur caractres. La longueur de la chane est bien le
nombre de caractres 2 , espaces inclus, qui la constituent. Un caractre est simplement une chane
de longueur 1. La longueur dun scalaire chane de caractres constant nomm (cest--dire avec
lattribut PARAMETER) peut tre calcule par le compilateur si on spcifie 3 LEN=* dans la dclaration.
1. En langage C, ces dlimiteurs sont spcialiss : le dlimiteur des constantes chanes de caractres est le guillemet " et lapostrophe ' sert dlimiter les constantes de type caractre individuel.
2. En langage C au contraire, le tableau de caractres doit comporter un lment supplmentaire pour indiquer
la fin de la chane.
3. On retrouve la mme proprit quen langage C o la taille dun tableau de caractres constant peut tre
calcule par le compilateur lors de linitialisation.

94

8.2. EXPRESSIONS DE TYPE CHANE DE CARACTRES

95

CHARACTER(LEN=*), PARAMETER :: chaine_fixe="mot"


f2003

8.1.3

Les variantes du type chanes de caractres

Fortran 90 doit donner accs un type de caractres par dfaut, et peut aussi fournir dautres
jeux de caractres dpendant du compilateur de la machine.
Mais fortran 2003 a introduit la possibilit daccder des variantes du type chane associes diffrents codage des caractres, notamment pour les caractres unicode. La fonction
SELECTED_CHAR_KIND rend un entier indiquant le numro du sous-type chane demand en paramtre : parmi les sous-types possibles on trouve DEFAULT, ASCII et ISO_10646 pour les caractres
Unicode (encore not UCS_4 assimilable UTF-32) 4 , mais seul DEFAULT est requis par la norme. Si
la variante demande nest pas disponible, la fonction SELECTED_CHAR_KIND rend -1. La variante
ISO_10646 sera ncessaire pour lire des fichiers texte cods en UTF-8 (cf. 5.3.2, p. 43).
Les constantes chanes de variante de type autre que le dfaut sont dsignes en les prfixant par
le numro du sous-type donn par SELECTED_CHAR_KIND suivi du symbole soulign 5 . Par exemple,
si le codage par dfaut est ISO-8859-1 :
INTEGER, PARAMETER :: defchar = SELECTED_CHAR_KIND('DEFAULT')
CHARACTER(LEN=3, KIND=defchar) :: mot=defchar_"t"
Pour dsigner un caractre unicode en UTF-32, on peut utiliser la fonction CHAR en lui fournissant
les codes-points unicode comme des entiers en hexadcimal (cf. 2.4, p. 17), par exemple :
INTEGER, PARAMETER :: utf32=SELECTED_CHAR_KIND('ISO_10646') ! UCS_4 = UTF-32
CHARACTER(LEN=1, KIND=utf32) :: car1_utf32, car2_utf32
car1_utf32 = CHAR(INT(Z'00E6'), KIND=utf32) ! ligature ae
car2_utf32 = CHAR(INT(Z'FB03'), KIND=utf32) ! ligature ffi (3 octets en UTF-8)

8.2

Expressions de type chane de caractres

Une expression de type chane de caractres peut construite par concatnation de variables ou
de constantes chanes, par extraction de sous-chane ou enfin laide fonctions rsultat chane de
caractres.

8.2.1

Concatnation de chanes

Loprateur // permet de concatner 6 deux chanes de caractres. Par exemple, lexpression


"bonjour" // " au revoir" est value comme "bonjour au revoir".

8.2.2

Sous-chanes

De faon assez semblable aux sous-sections des tableaux, le langage fortran permet de manipuler
des sous-chanes de caractres, selon la syntaxe suivante 7 :
4. Par exemple, le compilateur nag possde quatre variantes du type chane, de paramtres KIND :
1 pour lASCII sur 1 octet qui comporte en fait le codage ISO-8859-1 ;
2 sur deux octets pour le codage UCS_2, qui concide avec UTF-16 ;
3 pour le codage JIS X 0213 permettant daccder aux caractres japonais ;
4 sur quatre octets pour UCS_4, assimilable UTF-32.
5. Ainsi, pour les chanes, on prfixe la variante de type, alors que pour les autres types (entiers, rels), on suffixe
la variante de type.
6. En langage C, la concatnation de chanes de caractres est obtenue par simple juxtaposition, sans oprateur
explicite.
7. On notera que le symbole : nest pas facultatif, mme si on veut dsigner une sous-chane rduite un
caractre.

96

CHAPITRE 8. CHANES DE CARACTRES

chaine1([<deb >]:[<fin >])


dsigne la sous-chane extraite de chaine1 commenant au caractre numro deb et terminant au
caractre numro fin sachant que par dfaut deb vaut 1 et fin est la longueur de chaine1, soit
LEN(chaine1). Si deb est suprieur fin , la sous-chane est vide. Avec les dclarations suivantes :
CHARACTER(LEN=*), PARAMETER :: mot1 = "bonjour", mot2 = "bonjour"
mot1(1:3) vaut "bon" ainsi que mot1(:3) et mot1(4:7) vaut "jour" de mme que mot1(4:)
mais mot2(:4) vaut "bon" et mot2(5:) vaut "jour".

8.2.3

Affectation

Laffectation globale dexpressions chanes de caractres est possible en fortran 8 sachant que le
membre de gauche peut tre une chane ou une sous-chane et le membre de droite une expression
de type chane. Au cas o la longueur des chanes de part et dautre du signe = diffre,
si lexpression chane du membre de droite est plus longue que la variable laquelle on doit
laffecter, la chane de droite est tronque ct droit ;
si lexpression chane du membre de droite est plus courte que la variable laquelle on doit
laffecter, la chane de droite est complte par des espaces pour aboutir la longueur de la
chane de gauche.
Avec les dclarations et les affectations suivantes :
CHARACTER(LEN=7) :: mot1 = "bonjour"
CHARACTER(LEN=9) :: mot2 = "au revoir"
CHARACTER(LEN=17) :: mot3
CHARACTER(LEN=7) :: mot4
CHARACTER(LEN=5) :: mot5
mot3 = mot1 // " " // mot2
mot4 = mot2(1:3) // mot1(4:)
mot5 = mot1(4:7)
mot2(1:2) = "A "
on obtient mot3="bonjour au revoir", mot4="au jour", mot5="jour " et mot2="A

8.3
8.3.1

revoir".

Les fonctions oprant sur les chanes de caractres


Suppression des espaces terminaux avec TRIM

La fonction TRIM(STRING=ch ) dargument et de rsultat de type chane de caractre supprime les blancs droite de la chane passe en argument. Elle rend donc une chane de longueur
LEN_TRIM(ch ) infrieure au gale celle LEN(ch ) de ch .
TRIM(" ab cd ") donne " ab cd"

8.3.2

Justification gauche avec ADJUSTL

La fonction lmentaire ADJUSTL(STRING=ch ) supprime tous les blancs en dbut de la chane


ch et en ajoute autant droite de faon rendre une chane de mme longueur que son argument,
mais justifie gauche.
ADJUSTL(" ab cd ") donne "ab cd
"
TRIM(ADJUSTL(chaine )) enlve donc les espaces la fois gauche et droite.
8. Les chanes de caractres en C tant des tableaux de caractres, il nest pas possible de les affecter globalement
et on doit recourir des fonctions de copie de chanes cette fin.

8.3. LES FONCTIONS OPRANT SUR LES CHANES DE CARACTRES

8.3.3

97

Justification droite avec ADJUSTR

De faon symtrique, la fonction lmentaire ADJUSTR(STRING=ch ) supprime tous les blancs en


fin de la chane ch et en ajoute autant gauche de faon rendre une chane de mme longueur
que son argument, mais justifie droite.
ADJUSTR(" ab cd ") donne "
ab cd"

8.3.4

Les fonctions LEN et LEN_TRIM

La fonction LEN dargument chane et de rsultat entier rend le nombre de caractres de la


chane telle quelle a t dclare la compilation, indpendamment du contenu de la dite chane.
La variante LEN_TRIM ne tiend pas compte des espaces terminaux, mais elle compte ceux en dbut
de chane : LEN_TRIM(chaine) = LEN(TRIM(chaine)). Ainsi, avec les constantes chanes suivantes,
CHARACTER(LEN=*), PARAMETER :: mot1 = "bonjour", mot2 = " bonjour
"
WRITE(*,*) "longueurs totales de mot1 et mot2 ", LEN(mot1), LEN(mot2)
WRITE(*,*) "longueurs sans espaces terminaux ", LEN_TRIM(mot1), LEN_TRIM(mot2)
on affichera des longueurs respectives de 7 et 11, mais des longueurs aprs suppression des espaces
finaux de 7 et 8.
Contrairement LEN, LEN_TRIM est une fonction lmentaire (cf. 8.5, p. 99).

8.3.5

Recherche de sous-chane avec INDEX

La fonction lmentaire INDEX(STRING=ch1 , SUBSTRING=ch2 ) rend un entier donnant la position du dbut de la sous-chane ch2 dans la chane ch1 . Seule la premire occurrence est recherche
et la fonction INDEX rend 0 si la sous-chane cherche nest pas prsente dans la chane ch1 .
Par dfaut, la recherche se fait de gauche droite dans ch1 . Mais cette fonction admet un
paramtre optionnel BACK de type boolen qui, lorsquil est fourni avec la valeur .true. prcise
que la recherche se fait en commenant par la droite : dans ce cas, si la sous-chane ch2 nest pas
prsente dans ch1 , INDEX rend LEN(ch1 ) + 1.
INDEX("attente", "te") donne 3
INDEX("attente", "te", BACK=.true.) donne 6

8.3.6

Recherche des caractres dun ensemble avec SCAN

La fonction lmentaire SCAN(STRING=ch1 , SET=ch2 ) recherche dans la chane ch1 lun des
caractres de lensemble ch2 (peu importe lordre) et rend un entier donnant la position du premier
trouv. Si aucun des caractres de ch2 nest prsent dans ch1 , elle rend 0.
Par dfaut, la recherche se fait de gauche droite dans ch1 . Mais cette fonction admet un
paramtre optionnel BACK de type boolen qui, lorsquil est fourni avec la valeur .true., prcise
que la recherche se fait en commenant par la droite : dans ce cas, lentier rendu est donc la position
dans ch1 du dernier caractre de lensemble ch2 .
SCAN("aujourd'hui", "ru") donne 2 pour le premier u
SCAN("aujourd'hui", "ru", BACK=.true.) donne 10 pour le dernier u

8.3.7

Recherche des caractres hors dun ensemble avec VERIFY

La fonction lmentaire VERIFY(STRING=ch1 , SET=ch2 ) recherche dans la chane ch1 le premier caractre hors de lensemble ch2 (peu importe lordre) et rend un entier donnant la position
du premier trouv. Si tous les caractres de ch1 appartiennent ch2 , elle rend 0.
Par dfaut, la recherche se fait de gauche droite dans ch1 . La fonction VERIFY admet, comme
SCAN, un argument optionnel boolen BACK, qui, sil est positionn .true., prcise que la recherche
se fait de droite gauche.
VERIFY("aujourd'hui", "aeiouy") donne 3 pour le j
VERIFY("aujourd'hui", "aeiouy", BACK=.true.) donne 9 pour le h

98

CHAPITRE 8. CHANES DE CARACTRES

Les fonctions VERIFY et SCAN jouent des rles identiques, ceci prs que leurs arguments
SET=ch2 devraient tre des ensembles complmentaires (relativement lensemble des caractres
prsents dans ch1 ) pour quelles donnent le mme rsultat.
SCAN("aujourd'hui", "dhjr'") donne 3 pour le j
VERIFY("aujourd'hui", "aiou") donne 3 pour le j

8.3.8

Duplication de chanes avec REPEAT

La fonction REPEAT(STRING=ch , NCOPIES=n ) duplique n fois la chane ch et concatne les


copies, rendant une chane de longueur n fois celle de ch .
REPEAT(" ab ", 3) donne " ab ab ab "

8.3.9

Conversion de caractre en entier avec ICHAR et IACHAR

Les fonctions lmentaires ICHAR(c ) et IACHAR(c ) renvoient lentier donnant le numro du


caractre c respectivement dans la variante de type de c ou dans le code ascii. Le rsultat dpend
de la machine et du compilateur sauf avec IACHAR pour les 128 premiers caractres du code ascii.
Par exemple,
IF ((IACHAR(c) >= IACHAR('0')) .AND. (IACHAR(c) <= IACHAR('9'))) permet de tester si c
est un caractre numrique.

8.3.10

Conversion dentier en caractre avec CHAR et ACHAR

Les fonctions lmentaires CHAR(i [, KIND=var_char ]) et ACHAR(i ) renvoient le caractre


correspondant lentier i respectivement dans la variante de type indique par var_char (la
variante DEFAULT si le paramtre de variante de type nest pas prcis) ou dans le code ascii. Le
rsultat dpend de la machine et du compilateur sauf avec ACHAR en ascii pour 1 6 i 6 127.

8.3.11

Comparaison de chanes de caractres avec LLT, LLE, LGE et LGT

Les fonctions lmentaires de comparaison selon lordre lexicographique LLT, LLE, LGE et LGT
admettent deux arguments chanes de caractres et donnent un rsultat boolen. La comparaison
sappuie sur lordre lexicographique de lascii alors que les oprateurs logiques associs effectuent
la comparaison selon lordre lexicographique du jeu de caractres par dfaut, qui dpend de la
machine. Ces fonctions sont donc plus portables que les oprateurs associs. Si les deux chanes
comparer nont pas la mme longueur, la plus courte est complte par des espaces droites avant
comparaison.
LLT
LLE
LGE
LGT

lexically
lexically
lexically
lexically

lower than
lower or equal
greater or equal
greater than

<
<=
>=
>

IF (LGE(c, '0') .AND. LLE(c, '9')) permet aussi de tester si le caractre c est numrique.
f2003

8.3.12

Le caractre de fin de ligne NEW_LINE

Pour permettre lcriture de fichiers en mode stream (cf. 5.2.4, p.40), fortran 2003 a introduit
la fonction NEW_LINE(CHAR=ch ) qui rend le caractre de fin de ligne (new-line associ \n du C)
dans la variante de type caractre de son argument.

8.4
8.4.1

Les entres-sorties de chanes de caractres


Les entres-sorties de chanes formates

Le descripteur de conversion des chanes de caractres est soit (cf. 5.4.1, p.48) :
A : dans ce cas, le nombre de caractres est celui de la variable associe.

8.5. LES TABLEAUX DE CHANES DE CARACTRES

99

An o n est un entier spcifiant le nombre de caractres. Si n est plus grand que la longueur
de la chane crire, on complte par des blancs gauche. Si linverse, n est plus petit que
la longueur de la chane crire, celle-ci est tronque 9 aux n premiers caractres.
Par exemple, si on crit "salut" avec diffrentes largeurs, on obtient :
format
A
A5
A8
A2

8.4.2

rsultat
[salut]
[salut]
[
salut]
[sa]

Les entres de chanes en format libre

En format libre, la lecture des chanes de caractres peut se faire :


avec des dlimiteurs " ou ' , ce qui permet de lire des chanes comportant des
sparateurs comme lespace, la virgule ou le / .
sans dlimiteur et alors la lecture sarrte au premier sparateur (espace, virgule ou / ).

8.4.3

Les fichiers internes : codage en chane de caractres et dcodage

Lcriture de donnes numriques sur des chanes de caractres ou la lecture de donnes dans
des chanes de caractres 10 mettent en uvre les mthodes de conversion voques plus haut, o
les chanes dans lesquelles on crit ou on lit sont qualifies de fichiers internes (cf. 5.2.1, 38).
Par exemple, le programme suivant convertit i et j en chacun 3 caractres quil crit dans la
variable f_int ; puis il lit dans cette mme variable (ou fichier interne) lentier k sur 6 chiffres
obtenus par concatnation de ceux de i et j.
1
2
3
4
5
6
7
8
9
10

PROGRAM fich_int
IMPLICIT NONE
CHARACTER(len=6) :: f_int
INTEGER :: i=100 , j=200 , k
WRITE(*,*) 'i=', i, 'j=', j
WRITE(f_int(1:6), '(2i3.0)') i, j ! criture dans le fichier interne f_int
! les chiffres de i et j sont juxtaposs dans la chane f_int
READ(f_int(1:6), '(i6.0)') k
! lecture de k sur le fichier interne f_int
WRITE(*,*) 'i=', i, 'j=', j, 'k=', k
END PROGRAM fich_int
Il affiche :
i= 100 j= 200
i= 100 j= 200 k= 100200
On utilise notamment la conversion dentiers en chanes de caractres pour composer des formats
variables pour effectuer des oprations dentre-sortie (cf. 5.4.5, p. 51).

8.5

Les tableaux de chanes de caractres

Lassemblage de plusieurs chanes de caractres sous forme de tableau de chanes nest possible B
que si toutes les chanes ont la mme longueur, conformment la structure rectangulaire des
tableaux.
9. Ce comportement diffre du cas de lcriture de donnes numriques, o la conversion ne se fait pas si la largeur
du champ est insuffisante : on crit alors n symboles * .
10. En langage C, ces oprations se font grce aux fonctions sprintf et sscanf.

100

CHAPITRE 8. CHANES DE CARACTRES

CHARACTER(LEN=<longueur >), DIMENSION(<dim >) :: <tab_ch >


Si la syntaxe daccs aux lments du tableau respecte la syntaxe gnrale des tableaux, il est aussi
possible de rfrencer directement des sous-chanes dun lment du tableau. On remarquera que
la fonction LEN applique un tableau de chanes renvoie un scalaire entier, qui est la longueur
B commune de chacun de ses lments, alors que la fonction lmentaire LEN_TRIM renvoie un tableau
dentiers conforme au tableau de chanes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

PROGRAM tab_chaines
IMPLICIT NONE
CHARACTER(LEN=4), DIMENSION(3) :: tab_ch
CHARACTER(LEN=4) :: ch
INTEGER :: i
tab_ch(1:2) = (/ "abcd", "ABCD" /) ! avec constructeur
tab_ch(3) = "1234"
WRITE(*,*) "lgueur commune des chaines ", LEN(tab_ch)
WRITE(*,*) "affichage en colonnes "
DO i=1, SIZE(tab_ch)
WRITE(*,*) tab_ch(i)
END DO
WRITE(*,*) "... en ligne: ", tab_ch
! extraction de sous-chanes pour construire une chane
ch = tab_ch(1)(1:2) // tab_ch(2)(3:4)
WRITE(*,*) "dduite par extraction ", ch
! autre formulation avec des sous-chanes
ch(1:2) = tab_ch(1)(1:2)
ch(3:4) = tab_ch(2)(3:4)
WRITE(*,*) "dduite par extraction ", ch
! remplacer les fins de chane par 1, 2 ou 3 blancs
DO i=1, SIZE(tab_ch)
tab_ch(i)(5-i:) = repeat(" ", i)
END DO
WRITE(*,*) "des blancs en fin "
WRITE(*,*) "affichage en colonnes entre [] "
DO i=1, SIZE(tab_ch)
WRITE(*,*) "[", tab_ch(i), "]"
END DO
WRITE(*,*) "LEN(tab_ch) ", LEN(tab_ch)
WRITE(*,*) "LEN_TRIM(tab_ch) ", LEN_TRIM(tab_ch)
END PROGRAM tab_chaines

8.6

affichage associ
lgueur commune des chaines 4
affichage en colonnes
abcd
ABCD
1234
... en ligne: abcdABCD1234
dduite par extraction abCD
dduite par extraction abCD
des blancs en fin
affichage en colonnes entre []
[abc ]
[AB ]
[1
]
LEN(tab_ch) 4
LEN_TRIM(tab_ch) 3 2 1

Chanes et procdures

Les chanes de caractres peuvent tre passes en argument de procdures sans que leur longueur
soit indique explicitement dans largument formel de type chane, comme on peut le faire pour le
profil des tableaux (si le rang est connu). Au moment de lappel, la longueur de la chane passe
en argument effectif est dtermine dans lappelant et transmise de faon implicite lappel.
Il est aussi possible de dclarer des chanes de caractres automatiques dans les procdures,
chanes dont la longueur dpend dun argument pass la procdure.
Lexemple suivant montre une fonction create_ch qui rend une chane dont la longueur est
passe en argument, ainsi quun sous-programme imprime_tab qui admet en argument un tableau
1D de taille quelconque constitu de chanes de caractres de longueur quelconque (mais identique).

101

8.6. CHANES ET PROCDURES

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

MODULE m_proc_ch
IMPLICIT NONE
CONTAINS
FUNCTION create_ch(deb, n)
CHARACTER(LEN=n) :: create_ch
INTEGER, INTENT(IN) :: deb, n
CHARACTER(LEN=n) :: ch ! automatique
INTEGER :: k
DO k=1, n ! pris dans l'ordre ascii
ch(k:k) = ACHAR(k + deb -1 )
END DO
create_ch = ch
END FUNCTION create_ch
SUBROUTINE imprime(ch)
CHARACTER(LEN=*), INTENT(IN) :: ch
WRITE(*,*) "ch de lg ", LEN(ch), "[", ch, "]"
RETURN
END SUBROUTINE imprime
SUBROUTINE imprime_tab(tab_ch)
CHARACTER(LEN=*), DIMENSION(:), INTENT(IN) :: tab_ch
CHARACTER(LEN=LEN(tab_ch)+2) :: ch ! automatique
INTEGER :: i
WRITE(*,*) "tableau de ", SIZE(tab_ch), " chaines"
WRITE(*,*) " de longueur ", LEN(tab_ch)
DO i=1, SIZE(tab_ch)
ch = "["// tab_ch(i) // "]"
WRITE(*,*) ch
END DO
RETURN
END SUBROUTINE imprime_tab
END MODULE m_proc_ch

32
33
34
35
36
37
38
39
40
41
42
43
44

PROGRAM proc_chaines
USE m_proc_ch
CHARACTER(LEN=4) :: ch4
CHARACTER(LEN=6) :: ch6
CHARACTER(LEN=4), DIMENSION(3) :: tab_ch
ch4 = create_ch(33, 4)
ch6 = create_ch(33, 6)
CALL imprime(ch4)
CALL imprime(ch6)
tab_ch = (/ "abcd", "ABCD", "1234" /)
CALL imprime_tab(tab_ch)
END PROGRAM proc_chaines

affichage associ
ch de lg 4 [!"#$]
ch de lg 6 [!"#$%&]
tableau de 3 chaines
de longueur 4
[abcd]
[ABCD]
[1234]

Chapitre 9

Types drivs ou structures


Pour reprsenter des objets plus sophistiqus que ceux reprsentables avec les types prdfinis,
mme avec les tableaux (dont les lments sont tous de mme type), on peut dfinir des types
drivs (derived types) ou structures 1 , constitus de plusieurs lments ou composantes encore
appeles champs dont les types peuvent tre diffrents. Si un tableau ne permet de regrouper que
des lments homognes dsigns par leur indice, un type driv permet de regrouper des lments
htrognes dsigns par leur identificateur.
Les types drivs permettent de reprsenter des donnes composites ( limage par exemple des
enregistrements dun fichier de donnes) et de les encapsuler afin de simplifier leur manipulation
globale par des procdures (cf. 9.6, p.106) et des oprateurs ddis (cf. 10.2, p.112). Ces possibilits dextension du langage, dfinition de types avec ses oprateurs spcifiques, surdfinition
doprateurs (cf. 10.2.1, p.113) et la notion de procdure attache un type (bounded procedure)
constituent une des richesses du fortran en tant que langage de haut niveau, permettant daborder
la programmation oriente objet.
Citons quelques exemples de donnes qui peuvent tre reprsentes par des types drivs avec
les composantes associes :
une fiche dtudiant : nom, prnom, numro, date de naissance, units denseignement et
notes associes ;
un chantillon de mesures atmosphriques sous ballon sonde un instant donn : altitude,
pression, temprature, humidit, vitesse, orientation du vent (certains paramtres en entier,
dautres en rel) ;
point dune courbe : coordonnes, texte associ, couleur, poids...
Le nombre de champs dun type driv est gnralement plus faible que le nombre dlments
dun tableau, mais il est possible dimbriquer des types drivs, voire de les tendre (cf. 9.3, p. 104),
alors quon ne peut pas construire des tableaux de tableaux. Mais il est possible de construire des
tableaux de types drivs et dinsrer des tableaux dans des types drivs (cf. 9.4, p. 105).

9.1

Dfinition dun type driv

On peut, par exemple, dfinir un type driv point dont les trois composantes sont : une lettre
didentification lettre, suivie des coordonnes (relles) abscisse et ordonnee du point.
TYPE :: point
CHARACTER(LEN=1) :: lettre
REAL :: abscisse
REAL :: ordonnee
END TYPE point
langage fortran
type driv
composante
langage C
structure
champ
mais on emploiera parfois les termes du C, en particulier structure pour dsigner une variable de type driv.
1. La terminologie du fortran et celle du langage C diffrent,

102

9.2. RFRENCE ET AFFECTATION DES STRUCTURES

103

Plus gnralement, la syntaxe de dfinition dun type driv, bien souvent encapsule dans un
module (avant linstruction CONTAINS), est :

TYPE [, <accs > ::] <nom_du_type >


[SEQUENCE]
<dfinition d'un champ >
[<dfinition d'un champ >] ...
END TYPE [<nom_du_type >]
o accs permet de prciser sa visibilit PRIVATE ou PUBLIC. Noter quun type driv public peut
comporter des composantes prives.
Depuis fortran 95, une composante dun type driv peut tre initialise, lors de la dfinition f95/2003
du type, une valeur qui sera considre comme sa valeur par dfaut. Noter que cela ne confre
pas lattribut statique aux objets de ce type.

9.1.1

Lattribut SEQUENCE

La dfinition dun type driv nimplique pas en gnral un ordre ni une taille 2 pour le stockage
en mmoire des composantes, laisss libres pour le compilateur. Dans certains cas, notamment si
on souhaite transmettre des donnes de type driv une procdure crite dans un autre langage
(hormis le C, pour lequel dautres techniques dinteroprabilit existent, cf. chap. 12), on peut
imposer, par linstruction SEQUENCE, le stockage des composantes par concatnation en respectant
lordre de dfinition. Sil sagit de structures imbriques, il est videmment ncessaire que toutes
les sous-structures aient t dfinies avec lattribut SEQUENCE.

9.2
9.2.1

Rfrence et affectation des structures


Constructeur de type driv

Une fois le type driv point dfini, on peut dclarer les variables a et b du type point, et leur
affecter une valeur en utilisant le constructeur de structure, qui est une fonction (automatiquement
cre) nomme comme le type driv. Appeler le constructeur est par exemple ncessaire pour
initialiser une structure lors de sa dclaration (comme pour b ci-aprs) :
TYPE(point) :: a, b = point('B', 1. ,-1.)
a = point('A', 0., 1.)
En fortran 95, les composantes doivent tre passes au constructeur en respectant leur position
dans le type driv, mais depuis fortran 2003, elles peuvent aussi tre dsignes par mot-clef. Les f2003
composantes initialises sont alors considres comme des arguments optionnels du constructeur.
TYPE(point) :: a
a = point(abscisse = 0., lettre ='A', ordonnee = 1.) ! fortran 2003

9.2.2

Slecteur de champ %

Rfrences et affectations une variable de type driv peuvent concerner la structure globale.
Mais seul loprateur daffectation est dfini par dfaut pour les types drivs ; les autres oprateurs B
(y compris le test dgalit ==) doivent tre tendus par lutilisateur (cf. chap 10).
Par exemple :
2. Ne pas croire que la taille dune variable de type driv soit toujours la somme des tailles de ses composantes.
En gnral, pour des raisons defficacit, le compilateur procde un alignement des composantes sur des mots par
exemple de 32 bits par adjonction de zros (zero padding). On a donc intrt dclarer les composantes les plus
volumineuses en tte de structure pour limiter ce remplissage. Enfin, il existe des options de compilation comme
-fpack-derived sous g96 ou gfortran, -noalign records de ifort, pour lviter, au dtriment des performances,

104

CHAPITRE 9. TYPES DRIVS OU STRUCTURES

a = b
! suppose a et b de mme type driv
IF(a==b) WRITE(*,*) "a=b" ! interdit car oprateur de comparaison pas dfini
affecte au point a les mmes composantes que celles du point b.
Les entres/sorties globales de la structure sont quivalentes celles de la liste des composantes
ultimes, dans lordre de la dfinition du type. Elles peuvent se faire au format libre ou en spcifiant
autant de descripteurs de format actifs que de composantes ultimes.
WRITE(*, *) a ! affiche (dans l'ordre) les champs qui constituent la structure a
WRITE(*,'("a= ", A, " x=", F6.2, " y=", F6.2)') a
affiche successivement :
a A
0.00000000
a= A x= 0.00 y=

1.00

1.00000000

Mais on peut aussi accder individuellement chacun des champs qui composent la structure
grce au slecteur de champ % pour les affecter :
a%lettre = 'A'
a%abscisse = 0.
a%ordonnee = 1.
ou pour les rfrencer, y compris dans des expressions :
CHARACTER(LEN=1) :: c
c = a%lettre
WRITE(*, *) a%abscisse, a%ordonnee
WRITE(*, *) sqrt(a%abscisse**2 + a%ordonnee**2)

9.3
9.3.1

Imbrication et extension de structures


Imbrication de structures

Les structures peuvent comporter des composantes qui sont elles-mmes des structures condition que les types des composantes aient t dfinis pralablement. On peut par exemple dfinir
une structure cercle dont un champ est une structure point :
TYPE :: cercle
TYPE(point) :: centre ! de type dfini au pralable
REAL :: rayon
END TYPE cercle
et dclarer ensuite une variable de type cercle et lui affecter une valeur, par exemple grce son
constructeur. Le slecteur % permet daccder aux composantes ultimes du type driv imbriqu.
TYPE(cercle) :: rond
rond = cercle(b, 2.) ! o b est de type point
WRITE(*, *) 'rond = ', rond
WRITE(*, *) 'rond = ', rond%centre, rond%rayon
WRITE(*, *) 'abscisse du centre :', rond%centre%abscisse
WRITE(*, *) 'primtre :', 2.* 3.14159 * rond%rayon

9.4. STRUCTURES ET TABLEAUX

f2003

9.3.2

105

Extension dun type driv

La norme fortran 2003 prvoit aussi que lon puisse tendre un type driv en lui adjoignant des
composantes, grce lattribut EXTENDS 3 . Ce mcanisme permet dhriter des outils conus pour
le type parent (cf. 9.7.1, 109). Le constructeur du type tendu admet deux syntaxes (voir exemple
ci-aprs) :
la syntaxe classique (pour circle1) o lon passe toutes les composantes ;
le passage dun objet du type parent (a de type point) et des seules composantes ncessaires
(ici le rayon) pour ltendre.
TYPE, EXTENDS(point) :: pt_ext_cerc
REAL :: rayon
END TYPE pt_ext_cerc
TYPE(pt_ext_cerc) :: circle1, circle2
circle1 = pt_ext_cerc('B', 2., -0., 2.) ! constructeur du type tendu
circle2 = pt_ext_cerc(a, 2.) ! constructeur partir du type parent
N.-B. : un type driv portant lattribut SEQUENCE (cf. 9.1.1, p. 103) ou BIND (cf. 12.2 p. 130) B
nest pas extensible.
Laccs aux composantes du type parent peut se faire soit directement, soit via le type parent :
WRITE(*,*) "circle1%lettre = ", circle1%lettre ! accs direct
WRITE(*,*) "circle1%point%lettre = ", circle1%point%lettre ! via type parent

9.4

Structures et tableaux

On peut dfinir des tableaux de structures :


TYPE(point), DIMENSION(10) :: courbe
dfinit un tableau de 10 lments de type point. Alors courbe%lettre est un tableau de 10
caractres, alors que courbe(2) est une structure de type point.
On peut aussi dfinir des types drivs dont certains champs sont des tableaux. En fortran 95,
le profil de ces tableaux doit tre connu au moment de la compilation.
TYPE :: point3d
CHARACTER(LEN=1) :: lettre
REAL, DIMENSION(3) :: coordonnees (rels)
END TYPE point3d
TYPE(point3d) :: m
m = point3d('M', (/1., 2., 3./) ) ! coordonnees entires interdites
WRITE(*, *) m
WRITE(*,*) 'coordonne 2 de m ', m%coordonnees(2)
On peut aussi dfinir des tableaux de structures de ce type :
TYPE(point3d), DIMENSION(10) :: courbe3d
Alors courbe3d%coordonnees(1) est le tableau dtendue 10 des coordonnes x des points de la
courbe en trois dimensions. De faon similaire, courbe3d(4)%coordonnees dsigne le tableau 1D
des 3 coordonnes du 4e point de la courbe.
Bien noter quen revanche, la notation courbe3d%coordonnees nest pas autorise car elle B
3. Mais cette possibilit nest pas encore implmente dans tous les compilateurs, notamment dans g95.

106

CHAPITRE 9. TYPES DRIVS OU STRUCTURES

supposerait de composer un tableau 2D partir des indices des objets drivs et de ceux de leurs
coordonnes. La norme prcise que dans une telle expression, au plus une des rfrences peut tre
de rang non nul (cest--dire non scalaire).
f2003

9.5

Types drivs composantes allouables dynamiquement

Pour manipuler des structures comportant des tableaux de dimensions allouables dynamiquement en fortran 95, il tait ncessaire (comme en C) de faire appel aux pointeurs (cf. chap. 11).
Mais ces limitations ont disparu avec la norme fortran 2003 ainsi quavec les options spcifiques de
certains compilateurs fortran 95 4 .
Dans ce cas, lappel du constructeur ainsi que loprateur daffectation se chargent de lallocation des composantes allouables (par un mcanisme dj voqu pour lallocation implicite
des tableaux par affectation, cf. 7.5.4, p. 93). Lopration de copie dune variable de type driv
comportant des composantes de taille variable (tableau, chane...) ralise donc une copie profonde
(deep copy), o les donnes elles-mmes sont dupliques. linverse, en fortran 95 ou en langage
C, la structure ne comporte que des pointeurs vers les donnes dynamiques et la recopie simple par
affectation ne duplique que les pointeurs, ralisant ainsi une copie superficielle (shallow copy). Il est
ncessaire de crer une fonction de recopie profonde qui prend en charge lallocation des donnes
dynamiques que lon souhaite dupliquer.
TYPE :: point
CHARACTER(LEN=1) :: lettre
REAL, DIMENSION(:), ALLOCATABLE :: coord
END TYPE point
...
TYPE(point) :: a, b
! dclaration
a = point('A', (/1. ,-1./) ) ! construction de a => allocation de a%coord
WRITE(*,*) 'a ', a%lettre, a%coord
! affichage de a composante par composante
! WRITE(*,*) 'a ', a ! pas autoris en fortran 2003
b = a ! affectation globale => allocation de b%coord
Noter quil nest pas possible de lire ou dcrire globalement une variable de type driv com-

B posante allouable ou dattribut pointeur via READ ou WRITE, moins de dfinir soi-mme des

procdures dentre et de sortie spcifiques du type driv, en prcisant ventuellement le format


de conversion DT.

9.6

Procdures agissant sur les structures

La transmission de structures en argument de procdures externes suppose que les types drivs
soient connus de lensemble des procdures qui les manipulent. La mthode la plus fiable 5 consiste
insrer la dfinition du type driv dans un module (cf. 6.4, p. 64) qui sera appel par toutes les
procdures utilisant ce type.
1
2
3
4
5
6
7

MODULE m_point ! module de dfinition du type point


IMPLICIT NONE
TYPE point
CHARACTER(len=1) :: lettre
REAL :: abscisse
REAL :: ordonnee
END TYPE point
4. En particulier xlf dibm, le compilateur nag et g95 avec loption -std=f2003 ou -std=f95 assortie de -ftr15581
(cf. E.5.1, p. 170) autorisent les composantes allouables dans les structures.
5. On pourrait aussi employer des interfaces explicites, mais il faudrait alors prciser lattribut SEQUENCE lors de
la dfinition du type driv. De plus, la duplication des dfinitions des structures risque daboutir des dfinitions
incohrentes lors de la mise au point du code

9.7. PROCDURES ATTACHES UN TYPE DRIV

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

107

END MODULE m_point


MODULE m_sym ! module de la procdure de calcul du symtrique
USE m_point
IMPLICIT NONE
CONTAINS
SUBROUTINE sym(m, n) ! sous programme de calcul du symtrique
TYPE(point), INTENT(in) :: m
TYPE(point), INTENT(out) :: n
n = point (m%lettre, m%ordonnee, m%abscisse) ! change des coordonnes
END SUBROUTINE sym
END MODULE m_sym
PROGRAM sym_point
! programme principal
USE m_point ! pour connatre le type point, mais redondant cause du suivant
USE m_sym
! pour connatre l'interface de la procdure sym
IMPLICIT NONE
TYPE(point) :: a, b
! dclaration
a = point('A', 1. ,-1.) ! construction de a
WRITE(*,*) 'a ', a
! affichage de a
CALL sym(a, b)
! appel de sym
WRITE(*,*) 'b ', b
! affichage de b
END PROGRAM sym_point

9.7

Procdures attaches un type driv

Dans le contexte de la programmation oriente objet, il est possible dattacher un type driv
un ensemble de procdures (bound procedures), qui apparatront comme des composantes du type
driv : on les qualifie alors de mthodes. Lensemble, donnes et mthodes constitue alors un objet.
Elles sont introduites aprs le mot-clef CONTAINS, lintrieur de la dfinition du type, par
la dclaration PROCEDURE, suivie du nom de la mthode. Le slecteur de composantes % permet
ensuite de les rfrencer pour les appliquer une structure. Par dfaut, cette structure sera passe
implicitement la procdure comme premier argument ; on peut le prciser par lattribut PASS.
Au contraire, il faut prciser NOPASS pour viter cette transmission par dfaut.
Les procdures attaches au type driv sont dfinies en dehors du type, comme des procdures
classiques, aprs le mot-clef CONTAINS.
Lexemple suivant prsente plusieurs procdures permettant de dterminer le symtrique dun
point du plan par rapport la premire bissectrice des axes (change entre abscisse et ordonne) :
le sous-programme bound_sym_sub attach au type point, que lon peut appeler avec linstruction CALL a%bound_sym_sub(b), o la structure a est transmise implicitement par dfaut ;
la fonction bound_sym_fct attache au type point que lon peut appeler avec lexpression
a%bound_sym_sub(), o la structure a est transmise implicitement par dfaut ;
leurs variantes bound_nopass_sym_sub et bound_nopass_sym_fct avec lattribut NOPASS, o
la structure nest pas transmise implicitement ;
le sous-programme sym non attach au type point, qui nest donc pas accessible avec le
slecteur %.
Seules celles attaches au type point sont dclares dans le type (lignes 14 17).
6
7
8
9
10
11

MODULE m_point ! module de dfinition du type point


IMPLICIT NONE
TYPE :: point
CHARACTER(len=1) :: lettre
REAL :: abscisse
REAL :: ordonnee

108

12
13
14
15
16
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
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

CHAPITRE 9. TYPES DRIVS OU STRUCTURES

CONTAINS ! procdures attaches au type point


! symtries par rapport y=x : change entre abscisse et ordonne
PROCEDURE, PASS :: bound_sym_fct ! PASS = objet pass en 1er arg
PROCEDURE, PASS :: bound_sym_sub
PROCEDURE, NOPASS :: bound_nopass_sym_fct ! NOPASS
PROCEDURE, NOPASS :: bound_nopass_sym_sub !
END TYPE point
CONTAINS
FUNCTION bound_sym_fct(this)
CLASS(point), INTENT(in) :: this ! extension polymorphe du type
TYPE(point) :: bound_sym_fct
bound_sym_fct = point(this%lettre, this%ordonnee, this%abscisse)
END FUNCTION bound_sym_fct
SUBROUTINE bound_sym_sub(this, p_sym)
CLASS(point), INTENT(in) :: this ! extension polymorphe du type
TYPE(point), INTENT(out) :: p_sym
p_sym = point(this%lettre, this%ordonnee, this%abscisse)
END SUBROUTINE bound_sym_sub
FUNCTION bound_nopass_sym_fct(p)
TYPE(point) :: bound_nopass_sym_fct
TYPE(point), INTENT(in) :: p ! CLASS(point), INTENT(in) :: p ! possible aussi
bound_nopass_sym_fct = point(p%lettre, p%ordonnee, p%abscisse)
END FUNCTION bound_nopass_sym_fct
SUBROUTINE bound_nopass_sym_sub(p_sym, p)
TYPE(point), INTENT(out) :: p_sym
CLASS(point), INTENT(in) :: p
p_sym = point(p%lettre, p%ordonnee, p%abscisse)
END SUBROUTINE bound_nopass_sym_sub
END MODULE m_point
MODULE m_sym ! module de la procdure de calcul du symtrique
USE m_point
IMPLICIT NONE
CONTAINS
SUBROUTINE sym(m, n) ! sous programme (non attach) de calcul du symtrique
TYPE(point), INTENT(in) :: m
TYPE(point), INTENT(out) :: n
n = point(m%lettre, m%ordonnee, m%abscisse)
END SUBROUTINE sym
END MODULE m_sym
PROGRAM sym_point
! programme principal
USE m_point ! pour connatre le type point (pas ncessaire cause du suivant)
USE m_sym
! pour connatre l'interface de la procdure sym
IMPLICIT NONE
TYPE(point) :: a, b, c, d, e, f, g ! dclarations
a = point('A', 1. ,-2.) ! construction de a
WRITE(*,*) 'a ', a
! affichage de a
CALL sym(a, b)
! appel de sym non attache au type
WRITE(*,*) 'b ', b
! affichage de b
! procedures PASS => a pass implicitement
c = a%bound_sym_fct()
! avec fct attache au type (a pass implicitement)
WRITE(*,*) 'c ', c
! affichage de c
CALL a%bound_sym_sub(d) ! avec subroutine attache au type
WRITE(*,*) 'd ', d
! affichage de d
! procedures NOPASS => a pass explicitement
e = a%bound_nopass_sym_fct(a) ! avec fct attache au type
WRITE(*,*) 'e ', e
! affichage de e

9.7. PROCDURES ATTACHES UN TYPE DRIV

68
69
70
71
72

109

CALL bound_nopass_sym_sub(f, a) ! avec subroutine attache au type


WRITE(*,*) 'f ', f
! affichage de f
CALL a%bound_nopass_sym_sub(g, a) ! avec subroutine attache au type
WRITE(*,*) 'g ', g
! affichage de g
END PROGRAM sym_point
Noter que, afin dautoriser lapplication des procdures attaches aux types tendus dduits du type
point (mcanisme dhritage), largument this est dclar avec le mot-clef CLASS (cf. ligne 21 par
exemple) au lieu de TYPE.
Dans le cas o lattribut NOPASS a t prcis, mme si lappel se fait comme composante du
type, il faut passer explicitement la structure comme argument si on veut lutiliser dans la procdure
attache (cf. lignes 66 et 70).

9.7.1

Un exemple lmentaire dhritage

Si lon tend le type point au type point_num par ajout dune composante, on peut lui appliquer
les procdures attaches au type parent. Cest lintrt de la dclaration CLASS(point) au lieu de
TYPE(point) de leur argument implicite. Dans lexemple suivant, on ajoute un sous-programme
bound_sym_sub_ext dont largument de sortie est de classe point :
dans le cas particulier o largument effectif est plus prcisment de type point_num, la
procdure construit une structure de type point_num ;
sinon, la procdure construit simplement une structure de type point.
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

MODULE m_point ! module de dfinition du type point et de ses extensions


IMPLICIT NONE
TYPE point
CHARACTER(len=1) :: lettre
REAL :: abscisse
REAL :: ordonnee
CONTAINS ! procdures attaches au type point
! symtries par rapport y=x : change entre abscisse et ordonne
PROCEDURE, PASS :: bound_sym_fct ! PASS = l'objet est pass en 1er arg
PROCEDURE, PASS :: bound_sym_sub
PROCEDURE, PASS :: bound_sym_sub_ext ! rend un objet polymorphe
END TYPE point
TYPE, EXTENDS (point) :: point_num ! ajoute une composante point
INTEGER :: num = -100 ! avec valeur par dfaut
END TYPE point_num
CONTAINS
FUNCTION bound_sym_fct(this)
CLASS(point), INTENT(in) :: this ! extension polymorphe du type
TYPE(point) :: bound_sym_fct
bound_sym_fct = point(this%lettre, this%ordonnee, this%abscisse)
END FUNCTION bound_sym_fct
SUBROUTINE bound_sym_sub(this, p_sym)
CLASS(point), INTENT(in) :: this ! extension polymorphe du type
TYPE(point), INTENT(out) :: p_sym
p_sym = point(this%lettre, this%ordonnee, this%abscisse)
END SUBROUTINE bound_sym_sub
SUBROUTINE bound_sym_sub_ext(this, p_sym)
CLASS(point), INTENT(in) :: this ! extension polymorphe du type
CLASS(point), INTENT(out) :: p_sym ! idem
! on ne peut pas faire de copie car pas forcement de mme type
! p_sym%point = this%point ! impossible
p_sym%lettre = this%lettre
p_sym%abscisse = this%ordonnee
p_sym%ordonnee = this%abscisse
! les autres composantes ventuelles ont les valeurs par dfaut

110

40
41
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
72
73
74
75
76
77
78
79

CHAPITRE 9. TYPES DRIVS OU STRUCTURES

! sauf avec les combinaisons de types qui suivent


SELECT TYPE(p_sym) ! choix en fonction du type
TYPE IS (point_num) ! enrichir p_sym s'il est de type point_num
SELECT TYPE (this) !
TYPE IS (point_num) ! si les 2 sont des point_num, la copie serait possible
p_sym%num = -this%num
CLASS DEFAULT ! si p_sym de type point_num, mais this ne l'est pas
p_sym%num = 10000 ! sinon on prendrait la valeur par dfaut
END SELECT
END SELECT
END SUBROUTINE bound_sym_sub_ext
END MODULE m_point
PROGRAM sym_point
! programme principal
USE m_point ! pour connatre le type point (pas ncessaire cause du suivant)
IMPLICIT NONE
TYPE(point) :: a, b, c, d ! dclarations
TYPE(point_num) :: an, bn, cn, dn, en, fn
a = point('A', 1. ,-1.) ! construction de a
WRITE(*,*) 'a ', a
! affichage de a
b = a%bound_sym_fct()
! avec fct attache au type
WRITE(*,*) 'b ', b
call a%bound_sym_sub(c) ! avec subroutine attache au type
WRITE(*,*) 'c ', c
an%point = a
an%num = 11
WRITE(*,*) 'an ', an
! affichage d'un point numrot
bn = point_num('B', 2., -2., 20) ! constructeur explicite
WRITE(*,*) 'bn ', bn
! affichage d'un point numrot
d = an%bound_sym_fct() ! mthode hrite qui donne un point simple
WRITE(*,*) 'd ', d
! affichage d'un point simple
dn%point = d
dn%num = an%num
WRITE(*,*) 'dn ', dn
! affichage d'un point numrot
call an%bound_sym_sub_ext(cn)
WRITE(*,*) 'cn ', cn
! affichage d'un point numrot
en = point_num('E', 20., -20.) ! constructeur explicite sauf arg par dfaut
WRITE(*,*) 'en ', en
! affichage d'un point numrot
call a%bound_sym_sub_ext(fn)
WRITE(*,*) 'fn ', fn
! affichage d'un point numrot
END PROGRAM sym_point

Cette procdure utilise la structure de contrle SELECT TYPE (cf. lignes 41 et 43) qui sapplique
aux variables dont le type peut varier lexcution (typage dynamique) selon la syntaxe gnrale
suivante :

[<nom >:] SELECT TYPE(<class_var >)


[TYPE IS <type_driv >
<bloc d'instructions >]
[TYPE IS <type_intrinsque >
<bloc d'instructions >]
[CLASS IS <type_driv >
<bloc d'instructions >]
[CLASS DEFAULT
<bloc d'instructions >]
END SELECT [<nom >]

Chapitre 10

Gnricit, surcharge doprateurs


Dans ce chapitre, on introduit, partir de quelques exemples, certains aspects novateurs du
fortran 90, comme la gnricit et la surcharge doprateurs, qui, associs aux modules, au contrle
de visibilit et aux pointeurs, permettent daborder les fonctionnalits dun langage orient objet.

10.1

Procdures gnriques et spcifiques

Le fortran 77 comportait dj la notion de procdure gnrique, mais elle tait rserve aux
procdures intrinsques. Avec les versions 90 et au del, cette notion devient accessible pour les
procdures dfinies par lutilisateur. En fortran 1 , de nombreuses fonctions intrinsques numriques
(cf. annexe A, p. 138) invoquables sous leur nom gnrique font en ralit appel, suivant le type de
leurs paramtres effectifs, une version spcifique particulire. Par exemple, la fonction gnrique
intrinsque MAX rfrence les fonctions spcifiques :
MAX0 si les arguments sont entiers ;
AMAX1 si les arguments sont rels ;
DMAX1 si les arguments sont double prcision.
Pour regrouper sous une mme procdure gnrique plusieurs procdures spcifiques, il faut
dclarer une interface commune obligatoirement nomme et ensuite dresser la liste des procdures
spcifiques qui seront effectivement appeles, avec chacune leur interface. Au moment de lappel
de la procdure gnrique le choix de la procdure spcifique sera fait en fonction :
du nombre des arguments effectifs dappel ;
et du type de ces arguments.
Par exemple dans le cas de fonctions 2 :

INTERFACE <nom_gnrique >


FUNCTION <nom_spcifique_1(...) >
...
END FUNCTION <nom_spcifique_1 >
...
FUNCTION <nom_spcifique_n(...) >
...
END FUNCTION <nom_spcifique_n >
END INTERFACE <nom_gnrique >
1. En langage C, seule la norme C99 permet grce #include <tgmath.h>, dutiliser un nom gnrique pour
les fonctions mathmatiques. Par exemple suivant le type de son argument, la fonction gnrique exp appellera
la fonction spcifique expf pour un float, exp pour un double et expl pour un long double. La gnricit est en
revanche parfaitement disponible en C++.
2. Depuis fortran 95, il est possible de rappeler le nom gnrique la fin de linstruction END INTERFACE.

111

112

CHAPITRE 10. GNRICIT, SURCHARGE DOPRATEURS

Dans linterface gnrique, au lieu de recopier les interfaces des procdures spcifiques, on
f2003 peut se contenter den donner la liste, chacune prcde par MODULE 3 PROCEDURE ::, condition
que chaque procdure spcifique possde une interface explicite visible dans le module hbergeant
linterface gnrique.
Par exemple, pour dfinir une fonction gnrique moy qui calcule la moyenne (en flottant) dun
tableau de rels ou dentiers, il faut dfinir deux fonctions spcifiques moy_reel et moy_int que
lon peut placer dans un module :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

MODULE m_moyenne
IMPLICIT NONE
INTERFACE moy ! interface gnrique pour une famille de procdures spcifiques
MODULE PROCEDURE moy_reel ! version avec tableau de rels
MODULE PROCEDURE moy_int ! version avec tableau d'entiers
! le choix se fera sur le type de l'argument
END INTERFACE moy ! nommage possible en fortran 95 seulement
CONTAINS
FUNCTION moy_reel(tab_r) ! version rels
REAL :: moy_reel
REAL, DIMENSION(:), INTENT(in) :: tab_r
moy_reel = SUM(tab_r(:)) / REAL(SIZE(tab_r(:)))
END FUNCTION moy_reel
FUNCTION moy_int(tab_i)
! version entiers
REAL :: moy_int
INTEGER, DIMENSION(:), INTENT(in) :: tab_i
moy_int = REAL(SUM(tab_i(:))) / REAL(SIZE(tab_i(:)))
END FUNCTION moy_int
END MODULE m_moyenne

20
21
22
23
24
25
26
27
28
29
30
31

PROGRAM t_moyenne
USE m_moyenne
IMPLICIT NONE
INTEGER :: i
INTEGER, DIMENSION(10) :: ti =(/ (i, i=1, 10) /)
REAL, DIMENSION(10) :: tr
tr(:) = REAL(ti(:)) / 10.
! appel de la procdure avec le nom gnrique (moy)
WRITE(*,*) moy( tr(:) ) ! argument tableau de rels => appelle moy_reel
WRITE(*,*) moy( ti(:) ) ! argument tableau d'entiers => appelle moy_int
END PROGRAM t_moyenne
Dans le cas de procdures externes dont le code source est inaccessible ou ne peut pas tre
modifi, il suffit de fournir explicitement linterface des procdures spcifiques pour pouvoir les
intgrer dans une interface gnrique. Cest ce qui est pratiqu pour les bibliothques.

10.2

Linterface-oprateur

En fortran, les oprateurs intrinsques sont soit monadiques, comme +, - et .not. suivis de
leur oprande, soit plus souvent dyadiques et alors entours par leurs deux oprandes. partir de
fortran 90, il est possible :
de dfinir de nouveaux oprateurs ;
et dtendre la porte des oprateurs intrinsques du fortran (surcharge, overloading en anglais) des types pour lesquels leur action nest pas dfinie par le langage.
3. En fortran 2003, le mot-clef MODULE est devenu facultatif.

10.2. LINTERFACE-OPRATEUR

113

Les procdures spcifiques qui permettent de dfinir laction dun oprateur rendent un rsultat
qui peut tre utilis dans une expression ; elles doivent donc tre des fonctions :
un argument (opration monadique) ;
ou deux arguments (opration dyadique).

INTERFACE OPERATOR (<oprateur >)


FUNCTION nom_spcifique_1(...)
...
END FUNCTION nom_spcifique_1
...
FUNCTION nom_spcifique_n(...)
...
END FUNCTION nom_spcifique_n
END INTERFACE
10.2.1

Surcharge doprateurs

Pour surcharger un oprateur, seules doivent tre fournies les fonctions qui dfinissent le rle
de loprateur sur les types pour lesquels il nest pas intrinsquement dfini. Le choix entre les
fonctions spcifiques est fait en fonction du nombre des arguments (1 ou 2) et de leur type. La
priorit de loprateur surcharg est celle de loprateur intrinsque (cf. 3.5, p. 25).
titre dexemple, loprateur // ralise la concatnation entre deux chanes de caractres et on
peut ltendre, en tant quoprateur dyadique 4 sur des rels, au calcul de la rsistance quivalente
une association de deux rsistances en parallle.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

MODULE m_resist
! l'oprateur // est dfini entre deux chanes de caractres seulement
! on le surcharge pour les rels (reprsentant ici des rsistances par ex)
INTERFACE OPERATOR(//)
MODULE PROCEDURE parallele ! liste des fonctions qui tendent l'oprateur
END INTERFACE
CONTAINS
FUNCTION parallele(r1,r2)
IMPLICIT NONE
REAL :: parallele
REAL, INTENT(in) :: r1, r2
parallele = 1. / (1./r1 + 1./r2)
RETURN
END FUNCTION parallele
END MODULE m_resist
!
PROGRAM elec
USE m_resist
IMPLICIT NONE
REAL :: r1, r2
WRITE(*,*) ' entrer deux valeurs de rsistances'
READ *, r1, r2
WRITE(*,*) 'r1 = ', r1, ' r2 = ', r2
WRITE(*,*) 'r1 '//'srie r2 = ' , r1+r2 ! utilisation de // natif
WRITE(*,*) 'r1 // r2 = ' , r1//r2
! utilisation de // surcharg
END PROGRAM elec
4. Loprateur // ne pourrait pas tre dfini comme monadique.

114

CHAPITRE 10. GNRICIT, SURCHARGE DOPRATEURS

10.2.2

Cration doprateurs

Un oprateur nouveau est introduit (identificateur entour par des points, comme les oprateurs
de comparaison) suivant une syntaxe similaire celle de la surcharge des oprateurs existants. Le
nouvel oprateur a la priorit maximale sil est unaire et la plus faible sil est binaire (cf. 3.5, p. 25).
Par exemple, on peut dfinir loprateur .para. dassociation en parallle :
pour les rels, en particulier pour les rsistances ;
pour un type driv capacite reprsentant les capacits.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

MODULE m_parallele
IMPLICIT NONE
TYPE :: capacite
REAL :: capa
END TYPE capacite
INTERFACE OPERATOR(.para.)
! liste des fonctions qui dfinissent l'oprateur
MODULE PROCEDURE parallele_res
! pour les rels (dont les rsistances)
MODULE PROCEDURE parallele_capa
! pour les capacits (type driv)
END INTERFACE
CONTAINS
FUNCTION parallele_res(r1,r2)
REAL :: parallele_res
REAL, INTENT(in) :: r1, r2
parallele_res = 1. / (1./r1 + 1./r2)
RETURN
END FUNCTION parallele_res
FUNCTION parallele_capa(c1,c2)
TYPE(capacite) :: parallele_capa
TYPE(capacite), INTENT(in) :: c1, c2
parallele_capa%capa = c1%capa + c2%capa
RETURN
END FUNCTION parallele_capa
END MODULE m_parallele
!
PROGRAM elec
USE m_parallele
IMPLICIT NONE
REAL :: r1, r2
TYPE(capacite) :: c1, c2, c3
WRITE(*,*) ' entrer deux valeurs de rsistances'
READ(*,*) r1, r2
WRITE(*,*) 'r1 = ', r1, ' r2 = ', r2
WRITE(*,*) 'r1 // r2 = ' , r1.para.r2
! .para. appelle parallele_res
WRITE(*,*) ' entrer deux valeurs de capacits'
READ(*, *) c1%capa, c2%capa
WRITE(*,*) 'c1 = ', c1%capa, ' c2 = ', c2%capa
c3 = c1.para.c2
! .para. appelle parallele_capa
WRITE(*,*) 'c1 // c2 = ' , c3%capa
END PROGRAM elec

10.3

Linterface-affectation

En fortran le symbole = nest pas un oprateur de comparaison, mais le symbole de laffectation


dune expression une variable. Si le type de la variable est diffrent du type de lexpression, cette
affectation se fait grce une conversion implicite de type.

10.3. LINTERFACE-AFFECTATION

115

Il est possible dtendre la porte du symbole daffectation des types pour lesquels son sens
nest pas dfini intrinsquement. On parle alors de surcharge de laffectation et on utilise une syntaxe
particulire qui regroupe les interfaces des sous-programmes deux arguments (le premier est la
variable affecter ou membre de gauche, le second lexpression qui lui sera affecte ou membre de
droite) qui dfinissent le sens de cette affectation. Le choix du sous-programme spcifique appeler
se fait en fonction du type des deux arguments.
Dans lexemple suivant, on dfinit un type hms, heures, minutes, secondes. En surchargeant
laffectation (cf. ligne 10 et suivantes), on construit les conversions en secondes (type entier) et
heures fractionnaires et les conversions rciproques. Via ces conversions, il est possible de surcharger
les oprateurs +, - (monadique opp_hms, ligne 84 et dyadique diff_hms, ligne 75), * et >.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
42
43
44
45

! module de dfinition du type hms (heures, minutes,secondes)


MODULE m_hms
IMPLICIT NONE
TYPE hms
INTEGER :: heures
INTEGER :: minutes
INTEGER :: secondes
END TYPE hms
! interfaces des oprateurs pour le type hms
! surcharge de l'affectation pour conversion
INTERFACE ASSIGNMENT (=)
MODULE PROCEDURE hms2hfrac ! hms -> heures fractionnaires (type rel)
MODULE PROCEDURE hms2s
! hms -> secondes (type entier)
MODULE PROCEDURE hfrac2hms ! heures fractionnaires (type rel) -> hms
MODULE PROCEDURE s2hms
! secondes (type entier) -> hms
END INTERFACE
INTERFACE OPERATOR (+) ! surcharge de l'addition
MODULE PROCEDURE som_hms
END INTERFACE
INTERFACE OPERATOR (-) ! surcharge dyadique et monoadique de "-"
MODULE PROCEDURE diff_hms
MODULE PROCEDURE opp_hms
END INTERFACE
INTERFACE OPERATOR (*) ! surcharge de la multiplication: entier par hms
MODULE PROCEDURE mult_hms
END INTERFACE
INTERFACE OPERATOR (>) ! surcharge de l'oprateur > (suprieur)
MODULE PROCEDURE sup_hms
END INTERFACE
CONTAINS
! surcharges de l'affectation => par des sous-programmes
SUBROUTINE hfrac2hms(t_hms, h) ! t_hms = h
! conversion des heures fractionnaires en heures, minutes, secondes
TYPE(hms), INTENT(out) :: t_hms
REAL, INTENT(in) :: h ! attention: tous les rels sont des heures !
REAL :: tmp
t_hms%heures = INT(h) ! et non floor (cas des ngatifs)
tmp = 60 * (h - t_hms%heures)
t_hms%minutes = INT(tmp)
tmp = 60 * (tmp - t_hms%minutes)
t_hms%secondes = INT(tmp)
END SUBROUTINE hfrac2hms
SUBROUTINE hms2hfrac(h, t_hms) ! h = t_hms
! conversion des heures, minutes, secondes en heures fractionnaires
REAL, INTENT(out) :: h

116

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

CHAPITRE 10. GNRICIT, SURCHARGE DOPRATEURS

TYPE(hms), INTENT(in) :: t_hms


h = REAL(t_hms%heures)+REAL(t_hms%minutes)/60.+REAL(t_hms%secondes)/3600.
END SUBROUTINE hms2hfrac
SUBROUTINE hms2s(s, t_hms) ! s = t_hms
! conversion des heures, minutes, secondes en secondes
INTEGER, INTENT(out):: s
TYPE(hms), INTENT(in) :: t_hms
s = t_hms%secondes + 60*(t_hms%minutes + 60*t_hms%heures)
END SUBROUTINE hms2s
SUBROUTINE s2hms(t_hms, s)
! conversion des secondes en heures, minutes, secondes
TYPE(hms), INTENT(out) :: t_hms
INTEGER, INTENT(in):: s ! attention: tous les entiers sont des secondes !
INTEGER :: tmp
t_hms%heures = s/3600 ! division entire
tmp = s - 3600*t_hms%heures
t_hms%minutes = tmp/60 ! division entire
t_hms%secondes = tmp - 60*t_hms%minutes
END SUBROUTINE s2hms
! surcharges des oprateurs => par des fonctions
FUNCTION som_hms(x, y)
TYPE(hms) :: som_hms
TYPE(hms), INTENT(in) :: x, y
INTEGER :: sx, sy, ss
sx = x ! conversion en secondes par hms2s
sy = y ! conversion en secondes par hms2s
ss = sx + sy
som_hms = ss ! conversion en hms par s2hms
END FUNCTION som_hms
FUNCTION diff_hms(x,y) ! "-" dyadique
TYPE(hms) :: diff_hms
TYPE(hms), INTENT(in) :: x, y
INTEGER :: sx, sy, ss
sx = x ! conversion en secondes par hms2s
sy = y ! conversion en secondes par hms2s
ss = sx - sy
diff_hms = ss ! conversion en hms par s2hms
END FUNCTION diff_hms
FUNCTION opp_hms(x) ! "-" monadique
TYPE(hms) :: opp_hms
TYPE(hms), INTENT(in) :: x
INTEGER :: sx
sx = x ! conversion en secondes par hms2s
opp_hms = -sx ! oppos en entier, puis conversion en hms par s2hms
END FUNCTION opp_hms
FUNCTION mult_hms(n, x)
TYPE(hms) :: mult_hms
INTEGER, INTENT(in) :: n
TYPE(hms), INTENT(in) :: x
INTEGER :: sx
sx = x ! conversion en secondes par hms2s
mult_hms = n * sx ! multiplication entire puis conversion en hms par s2hms
END FUNCTION mult_hms
FUNCTION sup_hms(x, y)
LOGICAL :: sup_hms
TYPE(hms), INTENT(in) :: x, y

10.3. LINTERFACE-AFFECTATION

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

117

INTEGER :: sx, sy
sx = x ! conversion en secondes par hms2s
sy = y ! conversion en secondes par hms2s
sup_hms = sx > sy
END FUNCTION sup_hms
END MODULE m_hms
!
PROGRAM t_hms
! traitement des temps en heures, minutes, secondes
USE m_hms
IMPLICIT NONE
TYPE(hms) :: hms1, hms2, hms3, hms4, hms5
REAL :: h1, h2
INTEGER :: s1, s2
WRITE(*,*) 'entrer deux instants en heures minutes secondes'
READ(*,*) hms1, hms2
h1 = hms1 ! conversion implicite en fraction d'heures
h2 = hms2 ! conversion implicite en fraction d'heures
s1 = hms1 ! conversion implicite en secondes
s2 = hms2 ! conversion implicite en secondes
hms3 = hms1 + hms2 ! addition de deux types hms
hms4 = hms1 - hms2 ! soustraction de deux types hms
hms5 = - 2*hms1
! oppos d'un multiple entier
WRITE(*,*) ' en heures minutes secondes'
WRITE(*,*) ' hms1 = ', hms1, ' hms2 = ', hms2
WRITE(*,*) ' en heures fractionnaires'
WRITE(*,*) ' h1 = ', h1, ' h2 = ', h2
WRITE(*,*) ' en secondes '
WRITE(*,*) ' s1 = ', s1, ' s2 = ', s2
WRITE(*,*) ' somme en h m s ', hms3
WRITE(*,*) ' diffrence en h m s ', hms4
WRITE(*,*) ' -2 fois h1 en h m s ', hms5
IF (hms1 > hms2) THEN ! comparaison
WRITE(*,*) 'hms1 > hms2'
ELSE
WRITE(*,*) 'hms1 <= hms2'
END IF
END PROGRAM t_hms
Lexemple prcdent reste une bauche trs lmentaire. En particulier, la surcharge de laffectation suppose que tous les entiers sont des secondes et tous les rels des heures dcimales : il
faudrait restreindre ces conversions des types spcialiss une seule composante stockant des
temps, mais alors aussi dfinir les oprateurs numriques associs pour ces types.
Pour fiabiliser lusage de type driv hms, il faudrait contraindre les composantes heures, minutes, secondes possder un signe commun, et limiter minutes et secondes lintervalle ouvert
] 60, +60[. On pourrait par exemple interdire laccs direct aux composantes (attribut PRIVATE,
cf. 9.1, p. 102) du type hms, quitte dfinir des procdures publiques de saisie et de communication
des donnes hms prcisment charges de cet accs restreint.

Chapitre 11

Pointeurs
Historiquement, la notion de pointeur a t introduite dans dautres langages, en particulier
le C 1 , pour manipuler les donnes via les adresses de la mmoire quelles occupent : dans cette
vision, un pointeur est une variable type ; le type permet de connatre la taille de la zone mmoire
ncessaire et le mcanisme de codage et de dcodage 2 pour stocker lobjet (variable, structure, ...)
point 3 ; le pointeur est destin stocker des valeurs qui sont les adresses des objets points, mais
ces adresses seules seraient inutilisables sans la connaissance du type de lobjet point.
Mais la notion de pointeur en fortran sapparente plus un descripteur comportant non seulement une adresse, mais aussi dautres informations sur la nature et la structure de la cible que le
pointeur permet de dsigner, notamment afin den assurer une gestion dynamique. La cible peut
tre une donne de type quelconque (scalaire, tableau, structure, voire pointeur), ou une procdure,
mais doit avoir t dclare comme cible potentielle. Dautre part, fortran ne permet pas daccder explicitement ladresse que stocke le pointeur. Dailleurs, il nexiste en fortran ni oprateur
dadresse 4 , ni doprateur dindirection 5 et la cible est dsigne par le pointeur lui-mme.
Dans la norme fortran 95, les pointeurs taient ncessaires pour grer les tableaux dynamiques
dans certains contextes en tant que rsultats de fonctions, arguments formels de procdures ou
composantes de types drivs. La norme 2003 apporte une gestion plus performante des tableaux
dynamiques sans faire appel explicitement aux pointeurs. On rservera donc les pointeurs des
usages plus spcifiques comme la manipulation de structures dynamiques telles que les arbres ou
les listes chanes, ou, dans le cadre de la programmation objet, lincorporation de mthodes dans
les types drivs grce aux pointeurs de procdures.

11.1

Pointeurs, cibles et association

Une variable est considre comme un pointeur si on prcise lattribut POINTER lors de sa
dclaration ; noter que cette dclaration ne rserve alors pas despace pour stocker les valeurs
quelle est susceptible de pointer.
1. Le tableau annexe (cf. D.7, p. 162) rsume approximativement les syntaxes employes dans les deux langages
pour manipuler des pointeurs.
2. Le type ne renseigne pas seulement sur la taille, mais aussi sur le codage de la valeur : par exemple si, sur
une machine 32 bits, 4 octets permettent de stocker un entier par dfaut et aussi un rel simple prcision, le motif
binaire qui reprsente par exemple la valeur numrique 10 ne sera pas le mme en entier et en rel.
3. Cest cette information qui permet en C de faire de larithmtique sur les pointeurs : incrmentation,
diffrence...
4. Si var est une variable, son adresse est dsigne en C par &var. Dailleurs, dans le cadre de linteroprabilit
entre fortran et C (cf. 12.3, p. 130), il faut faire appel en fortran, une fonction spcifique du module ISO_C_BINDING,
c_loc pour accder ladresse dune variable au sens du C.
5. Si ptr est un pointeur, la cible pointe est dsigne par *ptr en C alors quen fortran, ptr dsigne la cible.

118

119

11.1. POINTEURS, CIBLES ET ASSOCIATION

11.1.1

Association une cible nomme

Un pointeur peut tre associ une variable de mme type (et ventuellement sous-type)
qualifie de cible si celle-ci a t dclare avec lattribut TARGET 6 . Linstruction

ptr => trgt


associe le pointeur ptr la cible trgt . Tant que cette association restera en vigueur, toute mention
du pointeur ptr dans une expression fera en fait rfrence la cible trgt .
Une variable pointeur peut aussi tre associe une autre variable pointeur de mme type :
dans ce dernier cas, par transitivit, lassociation est faite avec la cible ultime, dattribut TARGET
cest dire non pointeur.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

PROGRAM pointeurs
IMPLICIT NONE
INTEGER, TARGET :: i=1 , j=2 ! target obligatoire pour pointer vers i ou j
INTEGER, POINTER :: pi, pj, pk
! association entre pointeur et cible : ncessite le mme type
pi => i
! pi pointe sur i
pj => j
! pj pointe sur j
pk => i
! pk pointe aussi sur i
WRITE(*, *) "associations : i, j = ", i, j, " pi, pj, pk = ", pi, pj, pk
! affectation : conversions implicites possibles
pi = 3.5
! affecte int(3.5) la variable i, pointe par pi
pj = pi + 10 ! ajoute 10 la variable pointe (i) et place le rsultat dans j
pk => j
! maintenant pk pointe sur j et plus sur i
WRITE(*, *) "affectations : i, j = ", i, j, " pi, pj, pk = ", pi, pj, pk
! association d'un pointeur un autre (en fait sa cible)
pi => pj
! pi pointe maintenant sur la cible de pj, soit j
WRITE(*, *) "association d'un pointeur un autre : pi, pj, pk = ", pi, pj, pk
END PROGRAM pointeurs
affichera
associations : i, j = 1 2 pi, pj, pk = 1 2 1
affectations : i, j = 3 13 pi, pj, pk = 3 13 13
association d'un pointeur un autre : pi, pj, pk =

13 13 13

En fortran 2008, il est possible dassocier un pointeur une cible ds la dclaration du pointeur,
condition que la cible ait lattribut SAVE et ne soit pas allouable. Cette initialisation de pointeur f2008
est aussi possible vers une cible constituant une partie constante dune variable statique.
Fonctions concernant lassociation des pointeurs
La fonction intrinsque ASSOCIATED qui rend un boolen permet de sinformer sur ltat dassociation dun pointeur. Elle admet deux formes dappel :
ASSOCIATED(<ptr> ) rend .true. si le pointeur <ptr> est associ ;
ASSOCIATED(<ptr> , <target> ) rend .true. si le pointeur <ptr> est associ la cible
<target> .
La dclaration dun pointeur lui donne par dfaut un statut dassociation indtermin. Il est
6. Cette restriction permet dviter de manipuler accidentellement des variables via des pointeurs dune part et
de laisser le compilateur optimiser plus efficacement les instructions manipulant des variables non accessibles via des
pointeurs dautre part. linverse, le langage C nimpose pas cette prcaution, mais la notion de pointeur restreint
introduite en C99 a un objectif similaire.

120

CHAPITRE 11. POINTEURS

donc recommand de le dsassocier explicitement ds la dclaration 7 par <ptr> => NULL() ou,
en dbut de programme par linstruction NULLIFY(<ptr> ).
REAL, POINTER :: ptr1 => NULL()
REAL, TARGET :: r1, r2
WRITE(*, *) ASSOCIATED(ptr1)
ptr1 => r1
WRITE(*, *) ASSOCIATED(ptr1)
WRITE(*, *) ASSOCIATED(ptr1, r1)
WRITE(*, *) ASSOCIATED(ptr1, r2)

11.1.2

! affichera .false.
! affichera .true.
! affichera .true.
! affichera .false.

Association une cible dynamique anonyme

Une autre faon dassocier un pointeur est de lui allouer une zone mmoire, par linstruction
ALLOCATE (cf. ligne 3 du programme suivant), qui, dans le cas dun pointeur, rserve lespace
mmoire et associe le pointeur la mmoire rserve. Comme cette zone mmoire nest pas dsigne
par une variable cible, la cible dynamique est qualifie danonyme. Elle nest accessible quau travers
des pointeurs dont elle est la cible.
Lassociation cesse ds que lon libre la zone mmoire par une instruction DEALLOCATE (cf.
ligne 8). Linstruction DEALLOCATE(<ptr> ) applique un pointeur a donc deux effets :
elle libre la mmoire alloue pour la cible anonyme ;
elle dsassocie le pointeur <ptr> .
B Si on a, entre temps, associ dautres pointeurs cette mme cible (cf. ligne 6), seul celui qui a per-

mis la libration de mmoire est dsassoci par linstruction DEALLOCATE : les autres continuent de
pointer vers une zone mmoire dont rien de garantit quelle ne soit occupe par dautres donnes...
Il est donc fortement conseill de dsassocier (cf. ligne 12), tous les pointeurs qui se partagent cette
cible immdiatement aprs la dsallocation.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

PROGRAM alloc_assoc_pointeurs
REAL, POINTER :: ptr => NULL(), ptr2 => NULL()
ALLOCATE(ptr) ! reservation de mmoire et association de ptr
WRITE(*, *) "ptr associ ? ", ASSOCIATED(ptr) ! affichera .true.
ptr = .25 ! affectation d'une valeur la cible
ptr2 => ptr ! ptr2 pointe aussi vers la cible alloue
WRITE(*, *) "ptr2 associ ptr ?", ASSOCIATED(ptr2, ptr) ! affichera .true.
DEALLOCATE(ptr) ! libre la mmoire et desassocie ptr
WRITE(*, *) "ptr associ ? ", ASSOCIATED(ptr) ! affichera .false.
WRITE(*, *) "ptr2 associ ?", ASSOCIATED(ptr2) ! affichera .true.
WRITE(*, *) "ptr2 associ ptr ?", ASSOCIATED(ptr2, ptr) ! affichera .false.
NULLIFY(ptr2) ! fortement conseill
! si ptr2 est dsassoci, l'instruction suivante provoquerait une erreur
! si ptr2 n'tait pas dsassoci, elle donnerait un rsultat alatoire
! WRITE(*, *) "cible de ptr2 ", ptr2
END PROGRAM alloc_assoc_pointeurs
Mais si on dsassocie tous les pointeurs associs une cible anonyme alloue sans instruction

B DEALLOCATE, la zone mmoire alloue reste rserve, mais nest dfinitivement plus accessible :

on parle alors de fuite de mmoire (memory leak). Si cette fuite de mmoire se produit de faon
rptitive dans une boucle par exemple, elle peut provoquer un dpassement de capacit de la
mmoire. On veillera donc viter de telles pertes de mmoire dans les procdures.

7. Loption -fpointer=null du compilateur g95 (cf. E.5.1, p. 170) permet aussi dinitialiser null les pointeurs
non initialiss dans le code, mais ce nest quune prudence supplmentaire.

11.2. POINTEURS SUR DES TABLEAUX

1
2
3
4
5
6
7
8
9

121

PROGRAM ALLOC_PTR
IMPLICIT NONE
REAL, POINTER :: ptr => NULL()
ALLOCATE(ptr) ! allocation du pointeur
WRITE(*, *) ASSOCIATED(ptr) ! affichera .true.
ptr = 2 ! utilisation de la mmoire alloue
NULLIFY(ptr) ! dassociation avant dallocation ! => memory leak
WRITE(*, *) ASSOCIATED(ptr) ! affichera .false.
END PROGRAM ALLOC_PTR
Lors de lexcution, le programme prcdent compil avec g95 affichera T (true) puis F (false)
et signalera cette fuite de mmoire : Remaining memory: 4 bytes allocated at line 4
Noter quaffecter une valeur un pointeur non associ nest pas autoris, car rien ne spcifie
alors la zone mmoire o stocker la valeur.

11.2

Pointeurs sur des tableaux

Lattribut pointeur peut tre donn une variable tableau condition que seul son rang et non
son profil (cf. 7.1.1, 79) soit spcifi.
INTEGER, DIMENSION(10), POINTEUR :: ptab ! est interdit
INTEGER, DIMENSION(:), POINTEUR :: ptab ! est autoris
Dans le cas de tableaux dont lindice ne commence pas 1, on distinguera les deux formes
dassociation :
INTEGER, DIMENSION(-2:2), TARGET :: tab
INTEGER, DIMENSION(:), POINTER
:: pt1, pt2
pt1 => tab
! qui conserve l'indexation initiale
pt2 => tab(:) ! qui renumrote partir de 1 car tab(:) est une section de tab
Plus gnralement, il est enfin possible de pointer vers une section rgulire de tableau, de rang
infrieur ou gal celui du tableau dont la section est issue.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

PROGRAM section_ptr
INTEGER, DIMENSION(3,5), TARGET :: mat
INTEGER, DIMENSION(:), POINTER
:: pt1 => NULL() ! rang 1
INTEGER, DIMENSION(:,:), POINTER :: pt2 => NULL() ! rang 2
INTEGER :: i, j
WRITE(*,*) "matrice initiale"
DO i=1, 3
mat(i,:) = i* (/ (j, j=1, 5) /)
WRITE(*,*) mat(i,:)
END DO
pt1 => mat(2,:)
pt2 => mat(1:3:2, 2:4)
WRITE(*,*) "deuxime ligne de mat"
WRITE(*,*) pt1
WRITE(*,*) "sous-matrice de mat (lignes 1 et 3 , colonnes 2 4)"
DO i=1, 2
WRITE(*,*) pt2(i,:)
END DO
END PROGRAM section_ptr

122

CHAPITRE 11. POINTEURS

affiche
matrice initiale
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
deuxime ligne de mat
2 4 6 8 10
sous-matrice de mat (lignes 1 et 3 , colonnes 2 4)
2 3 4
6 9 12
Il y aura alors rindexation partir de 1 de la section pointe sauf si on dsigne lindice de dpart
f2003 du pointeur 8 .
pt2(1:, 2:) => mat(1:3:2, 2:4)

Exemple de fonction valeur pointeur


Une fonction peut produire un rsultat tableau avec lattribut pointeur 9 : cela lui permet de
rendre un tableau dont le profil dpend de calculs effectus dans la fonction. Dans ce cas, il ne faut
pas oublier (aprs usage) de dsallouer dans lappelant le tableau allou par la fonction.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

MODULE m_fct_ptr
IMPLICIT NONE
CONTAINS
FUNCTION positifs(x) ! fonction valeur pointeur sur un tableau de rang 1
INTEGER, DIMENSION(:), POINTER :: positifs
INTEGER, DIMENSION(:), INTENT(in) :: x
INTEGER :: p, ok, i, j
p = COUNT( x>0 ) ! comptage du nombre de positifs
ALLOCATE (positifs(p), stat=ok) ! allocation du pointeur
IF(ok /= 0) STOP 'erreur allocation'
j = 0
DO i=1, SIZE(x)
IF (x(i) <= 0 ) CYCLE
j = j +1
positifs(j) = x(i) ! affectation du pointeur
END DO
END FUNCTION positifs
END MODULE m_fct_ptr

19
20
21
22
23
24
25
26
27
28
29
30

PROGRAM ppal
USE m_fct_ptr
IMPLICIT NONE
INTEGER :: i
INTEGER, DIMENSION(10) :: t=(/(i, i=-5, 4) /)
INTEGER, DIMENSION(:), POINTER :: tp => NULL()
WRITE(*, *) "tableau initial ", t(:)
tp => positifs(t) ! appel de la fonction qui alloue le pointeur
WRITE(*, *) size(tp), " lments positifs :", tp(:)
DEALLOCATE(tp) ! pour librer la mmoire
END PROGRAM ppal
8. Cette possibilit nest pas implmente sous gfortran 4.4.3 ni sous g95.
9. Ctait la seule mthode en fortran 95 standard qui nautorisait pas les fonctions rsultat tableau allouable.
Mais ces restrictions nexistent plus en fortran 2003, ou grce certaines extensions propres des compilateurs, en
particulier -ftr15581 pour le compilateur g95 (cf. E.5.1, p. 170).

11.3. TABLEAUX DE TYPES DRIVS CONTENANT DES POINTEURS

123

qui affiche
tableau initial -5 -4 -3 -2 -1 0 1 2 3 4
4 positifs : 1 2 3 4
Les pointeurs permettent de nombreuses autres applications dans le domaine des donnes dynamiques, notamment pour grer les listes chanes.

11.3

Tableaux de types drivs contenant des pointeurs

Lorsquun pointeur possde un attribut de dimension, son profil qui dtermine la taille de la
cible ne peut pas tre fix la dclaration (on parle de profil diffr). Il nest donc pas possible
de dfinir directement des tableaux de pointeurs. Mais il suffit dencapsuler le pointeur dans un B
type driv pour pouvoir simuler un tableau de pointeurs avec un tableau dlments du type
driv qui ne contient que le pointeur. Il est ainsi possible de reprsenter des assemblages nonrectangulaires dlments du mme type, qui ne sont pas reprsentables sous forme de tableaux.
Cela vaut par exemple pour les parties triangulaires infrieure et suprieure dune matrice.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

PROGRAM lower_upper_alloc
IMPLICIT NONE
! pas de tableau de pointeurs => les encapsuler dans un type driv
TYPE iptr
INTEGER, DIMENSION(:), POINTER :: pt => null()
! pointeur de tableau 1D d'entiers
END TYPE iptr
TYPE(iptr), DIMENSION(:), POINTER :: lower=> null(), upper => null()
! tableaux d'lments de type iptr pour stocker les parties triang. inf et sup
INTEGER, ALLOCATABLE, DIMENSION(:,:) :: mat
INTEGER :: ligne, colonne, n
DO
WRITE(*,*) "entrer la dimension de la matrice carre"
READ(*,* ) n
IF (n <=0) EXIT
ALLOCATE(mat(n,n))
DO ligne = 1, n
DO colonne = 1, n
mat(ligne, colonne) = 10*ligne + colonne
END DO
END DO
WRITE(*,*) "matrice complte"
DO ligne = 1, n
WRITE(*,*) mat(ligne, :)
END DO
ALLOCATE(lower(n)) ! allocation du tableau-pointeur de n lignes
ALLOCATE(upper(n)) ! allocation du tableau-pointeur de n lignes
DO ligne = 1, n
ALLOCATE(lower(ligne)%pt(ligne)) ! une allocation par ligne
ALLOCATE(upper(ligne)%pt(n-ligne +1)) ! une allocation par ligne
lower(ligne)%pt = mat(ligne, 1:ligne) ! affectation ligne ligne
upper(ligne)%pt = mat(ligne, ligne:n) ! affectation ligne ligne
END DO
DEALLOCATE(mat) ! libration de la matrice
WRITE(*,*) "partie triangulaire infrieure"
DO ligne = 1, n
WRITE(*,*) lower(ligne)%pt(:) ! impression de la partie triang. inf.
END DO
WRITE(*,*) "partie triangulaire suprieure (non aligne)"

124

40
41
42
43
44
45
46
47
48

CHAPITRE 11. POINTEURS

DO ligne = 1, n
WRITE(*,*) upper(ligne)%pt(:) ! impression de la partie triang. sup.
END DO
DO ligne = 1, n
DEALLOCATE(lower(ligne)%pt, upper(ligne)%pt)
END DO
DEALLOCATE(lower, upper)
END DO
END PROGRAM lower_upper_alloc

entrer la dimension de la matrice carre


matrice complte
11 12 13 14
21 22 23 24
31 32 33 34
41 42 43 44
partie triangulaire infrieure
11
21 22
31 32 33
41 42 43 44
partie triangulaire suprieure (non aligne)
11 12 13 14
22 23 24
33 34
44

Dans lexemple prcdent (programme lower_upper_alloc), les tableaux de pointeurs lower et


upper sont allous (ligne 26, p. 123), aprs le choix de la matrice mat ; puis, les lignes des parties
triangulaires infrieure et suprieure sont alloues (ligne 29, p. 123), et enfin les lments correspondants sont recopis (ligne 31, p. 123). Il y a donc duplication de lespace mmoire de la matrice.
On peut alors librer lespace allou pour la matrice (ligne 34, p. 123) et continuer utiliser les
parties infrieure et suprieure, lower et upper.
Mais on peut aussi, comme dans la version lower_upper_ptr qui suit, se contenter de dsigner
les lments correspondants de la matrice comme cibles (ligne 29, p. 125) des pointeurs des tableaux
lower et upper : dans ce cas, ils suivent les modifications (ligne 40, p. 125) des coefficients de la
matrice. Il est alors prudent de les dsassocier la libration de la matrice (ligne 50, p. 125).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

PROGRAM lower_upper_ptr
IMPLICIT NONE
! pas de tableau de pointeurs => les encapsuler dans un type driv
TYPE iptr
INTEGER, DIMENSION(:), POINTER :: pt => null()
! pointeur de tableau 1D d'entiers
END TYPE iptr
TYPE(iptr), DIMENSION(:), POINTER :: lower=> null(), upper => null()
! tableaux d'lments de type iptr pour stocker les parties triang. inf et sup
INTEGER, ALLOCATABLE, DIMENSION(:,:), TARGET :: mat
INTEGER :: ligne, colonne, n
DO
WRITE(*,*) "entrer la dimension de la matrice carre"
READ(*,* ) n
IF (n <=0) EXIT
ALLOCATE(mat(n,n))
DO ligne = 1, n
DO colonne = 1, n
mat(ligne, colonne) = 10*ligne + colonne

11.3. TABLEAUX DE TYPES DRIVS CONTENANT DES POINTEURS

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

END DO
END DO
WRITE(*,*) "matrice complte"
DO ligne = 1, n
WRITE(*,*) mat(ligne, :)
END DO
ALLOCATE(lower(n)) ! allocation du tableau-pointeur de n lignes
ALLOCATE(upper(n)) ! allocation du tableau-pointeur de n lignes
DO ligne = 1, n
! dsignation de la cible des pointeurs
lower(ligne)%pt => mat(ligne, 1:ligne) !
upper(ligne)%pt => mat(ligne, ligne:n)
END DO
WRITE(*,*) "partie triangulaire infrieure"
DO ligne = 1, n
WRITE(*,*) lower(ligne)%pt(:) ! impression de la partie triang. inf.
END DO
WRITE(*,*) "partie triangulaire suprieure (non aligne)"
DO ligne = 1, n
WRITE(*,*) upper(ligne)%pt(:) ! impression de la partie triang. sup.
END DO
mat = - mat ! modification de la matrice
WRITE(*,*) "mat change de signe"
WRITE(*,*) "partie triangulaire infrieure"
DO ligne = 1, n
WRITE(*,*) lower(ligne)%pt(:) ! impression de la partie triang. inf.
END DO
WRITE(*,*) "partie triangulaire suprieure (non aligne)"
DO ligne = 1, n
WRITE(*,*) upper(ligne)%pt(:) ! impression de la partie triang. sup.
END DO
DEALLOCATE(mat) ! libration de la matrice aprs usage des parties sup/inf
DO ligne = 1, n ! par prudence (ils pointent alors vers une zone dsalloue)
NULLIFY(lower(ligne)%pt, upper(ligne)%pt)
END DO
DEALLOCATE(lower, upper)
END DO
END PROGRAM lower_upper_ptr
entrer la dimension
3
matrice complte
11 12 13
21 22 23
31 32 33
partie triangulaire
11
21 22
31 32 33
partie triangulaire
11 12 13
22 23
33
mat change de signe
partie triangulaire
-11
-21 -22
-31 -32 -33
partie triangulaire
-11 -12 -13
-22 -23
-33

de la matrice carre

infrieure

suprieure (non aligne)

infrieure

suprieure (non aligne)

125

126

CHAPITRE 11. POINTEURS

11.4

Pointeurs de procdures

Un pointeur de procdure est un pointeur destin tre associ une procdure. Il est gnralement dclar via la spcification PROCEDURE (cf. 6.5.4, p. 74) avec lattribut POINTER. Comme
pour les autres objets, le pointeur, une fois associ, dsigne sa cible.

11.5

Manipulation de listes chanes

Les composantes des types drivs peuvent possder lattribut pointeur, ce qui permet la constitution de listes chanes : les listes chanes permettent de reprsenter des ensembles ordonns
dlments (appels noeuds de la liste) dont non seulement le contenu, mais aussi le nombre peut
voluer en cours de lexcution du programme. On peut en particulier insrer ou supprimer des
lments dans la liste tout en conservant lordre : lallocation se fait donc lment par lment,
contrairement ce qui passe pour les tableaux o lallocation, si elle peut tre dynamique, reste
globale. Mais, laccs un lment donn de la liste ncessite de parcourir tous les prcdents alors
quon peut accder directement un lment dindice donn dun tableau.
Dans une liste simplement chane, chaque lment comporte un pointeur vers llment suivant
sauf le pointeur du dernier lment de la liste qui est nul.

donnes 1

donnes 2

donnes 3

pointeur

pointeur

pointeur

pointeur

Figure 11.1 Liste simplement chane trois lments : le dernier lment pointe vers NULL.
Lexemple suivant montre une liste chane permettant de reprsenter une courbe dans le plan :
le type driv point comporte donc un pointeur vers une donne de type point pour chaner la liste.
Pour simplifier, la courbe initialement cre est la deuxime bissectrice des axes. Les procdures
dimpression imprime_chaine (ligne 10, p. 126) et de libration libere_chaine (ligne 26, p.127)
de la liste sont ici implmentes sous forme rcursive. Pour librer la mmoire, il est ncessaire de
commencer par la fin de la liste afin dviter de perdre laccs aux lments suivants. En revanche,
limpression de la liste se fait dans lordre si on imprime avant lappel rcursif (en descendant
la rcurrence) ou dans lordre inverse (procdure imprime_chaine_inverse (ligne 18, p. 127) si on
imprime aprs (en remontant la rcurrence). Enfin, les oprations dinsertion, insere_point
(ligne 57, p. 127) ou de suppression, supprime_point (ligne 35, p. 127) dun point intrieur se
font dans une boucle qui parcourt lensemble de la liste jusquau pointeur nul signifiant laccs au
dernier point.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

MODULE m_chaine
IMPLICIT NONE
TYPE point
! dfinition du type driv point avec un pointeur vers le suivant
REAL :: x
REAL :: y
TYPE(point), POINTER :: next => null() ! f95 seulement (par prudence)
END TYPE point
CONTAINS
RECURSIVE SUBROUTINE imprime_chaine(courant) !
TYPE(point), POINTER :: courant
! affichage en commenant par le dbut : imprimer avant la rcursion
WRITE(*,*) courant%x, courant%y
IF(ASSOCIATED(courant%next)) THEN
CALL imprime_chaine(courant%next)
END IF

11.5. MANIPULATION DE LISTES CHANES

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
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
72
73
74
75
76
77

END SUBROUTINE imprime_chaine


RECURSIVE SUBROUTINE imprime_chaine_inverse(courant) !
TYPE(point), POINTER :: courant
! affichage en commenant par la fin : drouler la rcursion avant
IF(ASSOCIATED(courant%next)) THEN
CALL imprime_chaine_inverse(courant%next)
END IF
WRITE(*,*) courant%x, courant%y
END SUBROUTINE imprime_chaine_inverse
RECURSIVE SUBROUTINE libere_chaine(courant)!
TYPE(point), POINTER :: courant
! attention librer en commenant par la fin
IF(ASSOCIATED(courant%next)) THEN
CALL libere_chaine(courant%next)
END IF
WRITE(*,*) "libration du point de coordonnes", courant%x, courant%y
DEALLOCATE(courant)
END SUBROUTINE libere_chaine
SUBROUTINE supprime_point(debut) !
! suppression d'un point (intrieur seulement)
TYPE(point), POINTER :: debut
TYPE(point), POINTER :: courant=>null(), suivant=>null()
TYPE(point), POINTER :: precedent=>null()
INTEGER :: suppr
precedent => debut
courant => precedent%next
DO
suivant => courant%next
WRITE(*,*) courant%x, courant%y, "supprimer ? 1 si oui"
READ(*,*) suppr
IF (suppr == 1) THEN
precedent%next => courant%next ! court-circuiter le point courant
DEALLOCATE(courant) ! libration du point courant
ELSE
precedent => courant
ENDIF
courant => suivant
IF (.NOT.ASSOCIATED(suivant%next)) EXIT
END DO
END SUBROUTINE supprime_point
SUBROUTINE insere_point(debut) !
! ajout d'un point (intrieur seulement)
TYPE(point), POINTER :: debut
TYPE(point), POINTER :: nouveau=>null(), suivant=>null()
TYPE(point), POINTER :: precedent=>null()
INTEGER :: ajout
REAL :: x, y
precedent => debut
DO
suivant => precedent%next
WRITE(*,*) precedent%x, precedent%y, "insrer ? 1 si oui"
READ(*,*) ajout
IF(ajout == 1) THEN
ALLOCATE(nouveau)
nouveau%next => precedent%next
precedent%next => nouveau
WRITE(*,*) "entrer x et y"
READ(*,*) x, y
nouveau%x = x
nouveau%y = y
ENDIF

127

128

78
79
80
81
82

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

CHAPITRE 11. POINTEURS

precedent => suivant


IF (.NOT.ASSOCIATED(suivant%next)) EXIT
END DO
END SUBROUTINE insere_point
END MODULE m_chaine

PROGRAM linked_list
USE m_chaine
INTEGER :: i, n
TYPE(point), POINTER :: courant => null(), suivant=>null()
TYPE(point), POINTER :: debut => null()
! construction d'une liste chane de n points
WRITE(*,*) 'entrer le nb de points'
READ(*,* ) n
! premier point qui permettra l'accs toute la chane
ALLOCATE(debut)
courant => debut
DO i = 1, n-1
courant%x = REAL(i)
courant%y = -REAL(i)
ALLOCATE(suivant)
courant%next => suivant
courant => suivant
END DO
! dernier point sans successeur
courant%x = REAL(n)
courant%y = -REAL(n)
courant%next => null() ! fin de la liste
WRITE(*,*) "impression dans le sens direct"
CALL imprime_chaine(debut) ! impression dans le sens direct
WRITE(*,*) "impression dans le sens inverse"
CALL imprime_chaine_inverse(debut) ! impression en sens inverse
WRITE(*,*) "suppression de points"
CALL supprime_point(debut) ! suppression de points intrieurs
WRITE(*,*) "impression dans le sens direct"
CALL imprime_chaine(debut) ! impression dans le sens direct
WRITE(*,*) "insertion de points"
CALL insere_point(debut)
! insertion de points intrieurs
WRITE(*,*) "impression dans le sens direct"
CALL imprime_chaine(debut) ! impression dans le sens direct
WRITE(*,*) "libration de la chane"
CALL libere_chaine(debut) ! libration de la chane
END PROGRAM linked_list

donnes 1

donnes 2

donnes 3

pointeur

pointeur

pointeur

pointeur

Figure 11.2 Suppression dun lment intrieur dune liste simplement chane trois lments

Chapitre 12

Inter-oprabilit avec le C
La standardisation de linterfaage entre les langages C et fortran est intervenue seulement
avec la norme fortran 2003. Elle permet de rendre portables les appels de fonctions en C depuis le
fortran et rciproquement. Elle sappuie sur la dfinition en fortran dentits (types, variables et
procdures) dites inter-oprables car quivalentes celles du langage C.
La construction dun excutable partir de code C et de code fortran ncessite une compilation
spare avec des compilateurs C et fortran compatibles, puis une dition de lien qui fournisse toutes
les bibliothques ncessaires. En particulier dans le cas o le programme principal est en C, il faut
spcifier explicitement la bibliothque du fortran lors de ldition de liens si elle est lance par
le compilateur C 1 . Une autre solution consiste confier ldition de liens au compilateur fortran
associ, quitte lui indiquer par une option 2 que le programme principal nest pas en fortran.

12.1

Interoprabilit des types intrinsques

Le module intrinsque iso_c_binding dfinit les paramtres de codage (kind) sous forme de
constantes symboliques pour les sous-types intrinsques inter-oprables avec le langage C. Le tableau suivant dcrit les quivalences entre les principaux types inter-oprables du fortran 2003 et
ceux de la norme C89 du langage C :
C89
char
short_int
int
long int
long long int
size_t
float
double
long double

fortran 2005
CHARACTER(kind=c_char)
INTEGER(kind=c_short)
INTEGER(kind=c_int)
INTEGER(kind=c_long)
INTEGER(kind=c_lon_long)
INTEGER(kind=c_size_t)
REAL(kind=c_float)
REAL(kind=c_double)
REAL(kind=c_long_double)

Ce module dfinit de mme des types complexes et un type boolen inter-oprables respectivement avec les types complexes et le type boolen du C99.
C99
float _Complex
double _Complex
long double _Complex
_bool

fortran 2005
COMPLEX(kind=c_float_complex)
COMPLEX(kind=c_double_complex)
COMPLEX(kind=c_long_double_complex)
LOGICAL(kind=c_bool)

1. Avec le compilateur g95 sous linux et un processeur Intel 32 bits, on lancera par exemple, sous rserve que la
bibliothque fortran soit installe dans ce rpertoire,
gcc partie_c.o partie_fortran.o -L/usr/lib/g95/lib/gcc-lib/i686-pc-linux-gnu/4.0.3/ -lf95 suivi ventuellement de -lm
De plus on sassurera de la compatibilit des versions des compilateurs utiliss.
2. Par exemple gfortran ou g95 avec gcc, ou ifort et loption -nofor-main (cf. E.4.1, p. 168) avec icc.

129

130

CHAPITRE 12. INTER-OPRABILIT AVEC LE C

Il dfinit aussi des types inter-oprables quivalents aux variantes de type entier dfinies en C99,
int8_t, int16_t, int32_t et int64_t nombre de bits fix ainsi que les versions nombre minimal
de bits int_least8_t et suivants ou les plus rapides avec un nombre de bits fix int_fast8_t et
suivants : le nommage en fortran est obtenu par adjonction du prfixe c_, par exemple c_int8_t.
Le module iso_c_binding dfinit enfin des constantes caractres de paramtre de codage (kind)
c_char pour les caractres spciaux du C, comme c_null_char ou c_new_line.

12.2

Inter-oprabilit des types drivs

Les types drivs du fortran peuvent tre rendus inter-oprables avec les structures du C
condition que 3 :
les composantes du type driv fortran soient inter-oprables, publiques, quelles ne soient
pas allouables et ne comportent pas de pointeur (au sens de lattribut pointer en fortran 4 ) ;
Le type driv fortran ne soit pas une extension de type (cf. 9.3.2, p. 105), ne soit pas de type
SEQUENCE (cf. 9.1.1, p. 103), ni un type paramtr et ne possde pas de procdures attaches ;
lattribut bind(c) soit spcifi en fortran dans la dfinition du type driv ;
la structure du C ne comporte pas de champ de bits.

12.3

Inter-oprabilit avec les pointeurs du C

Le module iso_c_binding dfinit des types drivs ( composantes prives) c_ptr et c_funptr
inter-oprables respectivement avec les pointeurs dobjets et de fonctions du C. Les constantes
nommes c_null_ptr et c_null_funptr sont les quivalents en fortran du pointeur nul du C.
Ce module dfinit aussi des procdures de manipulation des pointeurs du C depuis le fortran.
c_loc(x) renvoie une valeur du type c_ptr contenant ladresse au sens du C de son argument.
Cette fonction joue le rle de loprateur & du langage C.
c_funloc(f) renvoie ladresse dune procdure inter-oprable.
c_f_pointer(cptr, fptr, profil) est un sous-programme qui permet de traduire un pointeur du C et un profil ventuel en un pointeur au sens du fortran. Largument dentre cptr
est du type c_ptr. Largument de sortie fptr est un pointeur vers un type inter-oprable. En
sortie, fptr est associ la cible de cptr. Largument dentre profil en gnral optionnel,
est requis si fptr est un tableau.
c_f_procpointer(cptr, fptr) est un sous-programme qui effectue la mme conversion que
c_f_pointer mais pour des procdures.

12.4

Inter-oprabilit des procdures

Linter-oprabilit des procdures entre fortran et C requiert que les paramtres changs soient
inter-oprables, que linterface de la procdure fortran soit explicite et dclare avec lattribut
BIND(C). Lattribut BIND permet aussi de spcifier le nom de la fonction C associe grce au mot
clef NAME selon la syntaxe : BIND(C, NAME=nom_de_la_fonction_en_C ). dfaut du paramtre
NAME dans lattribut BIND le nom en C est le mme quen fortran, mais en minuscule 5 .
Elle exclut notamment :
les procdures internes du fortran ;
les arguments optionnels en fortran et le nombre variable darguments en C ;
les rsultats de fonction non scalaires en fortran ;
Les sous-programmes du fortran correspondent aux fonctions sans valeur de retour (type void)
en C.
3. Lespace occup par les structures est soumis des contraintes dalignement en mmoire qui conduisent parfois
complter une structure par des octets de remplissage. Ces contraintes diffrent suivant les langages, les processeurs
et les compilateurs et peuvent ainsi affecter linter-oprabilit des structures.
4. Mais un type driv inter-oprable peut comporter une composante de type c_ptr ou c_funptr.
5. On rappelle quen fortran, la casse nest pas distingue, cf 1.3.2, p. 7.

12.4. INTER-OPRABILIT DES PROCDURES

12.4.1

131

Le passage par copie de valeur (value)

Comme le passage de paramtre en C se fait par copie de valeur, alors quil se fait par rfrence
en fortran, le fortran 2003 a introduit lattribut VALUE pour modifier le mcanisme de passage
dargument du fortran dans le sens du C. Cette mthode permet de travailler sur la copie passe en
argument sans que cela affecte la valeur ct appelant en retour. Lattribut VALUE peut tre utilis
en dehors de linter-oprabilit avec le C mais nest pas applicable aux paramtres pointeurs ou
allouables et est videmment incompatible avec les vocations INTENT(OUT) et INTENT(INOUT).
linverse, un argument sans lattribut VALUE doit correspondre dans la fonction en C un
pointeur vers le type de largument (inter-oprable) du fortran.

12.4.2

Exemple : appel de fonctions C depuis le fortran

Lexemple suivant montre lappel en fortran de fonctions C sans valeur de retour pour saisir
des rels et les afficher. Elles sont vues du fortran comme des sous-programmes de mme nom en
labsence du paramtre NAME dans lattribut BIND (cf. lignes 6 et 12).
Laccs au type c_float dans linterface fortran (cf. lignes 8 et 14) ncessite soit un USE, soit
un IMPORT (cf. 6.4.4, p. 69).
Le sous-programme daffichage c_write_float peut se contenter dun passage par copie de
valeur, do lattribut VALUE en fortran (cf. ligne 15), car il ne modifie pas la valeur du paramtre. En
revanche, la fonction de lecture, c_read_float, ncessite un passage par pointeur en C, directement
compatible avec le passage dargument utilis par dfaut en fortran.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

Partie fortran 2003


MODULE m_interf
USE, INTRINSIC :: iso_c_binding, ONLY:c_float
IMPLICIT NONE
INTERFACE
! void c_read_float(float *pf);
SUBROUTINE c_read_float(f) BIND(c) !
! USE, INTRINSIC :: iso_c_binding, ONLY:c_float
IMPORT :: c_float ! prfrable au USE !
REAL(kind=c_float), INTENT(out) :: f
END SUBROUTINE c_read_float
! void c_write_float(float f);
SUBROUTINE c_write_float(f) BIND(c) !
! USE, INTRINSIC :: iso_c_binding, ONLY:c_float
IMPORT :: c_float ! prfrable au USE !
REAL(kind=c_float), intent(in), value :: f ! copie de valeur
END SUBROUTINE c_write_float
END INTERFACE
END MODULE m_interf

19
20
21
22
23
24
25
26

1
2

PROGRAM f_appel_c_sub_io
USE m_interf
REAL(kind=c_float) :: r
CALL c_read_float(r)
WRITE (*,*) "float en fortran aprs lecture en C ", r
CALL c_write_float(r)
END PROGRAM f_appel_c_sub_io

#include <stdio.h>
#include <stdlib.h>

3
4

void c_read_float(float *pf);

Partie langage C

132

CHAPITRE 12. INTER-OPRABILIT AVEC LE C

void c_write_float(float f);

6
7
8
9
10
11
12
13

void c_read_float(float *pf){


/* *pf est saisi en C */
printf("saisie d'un float en C\n");
scanf("%g", pf);
printf("float tel que saisi en C %g\n", *pf);
return;
}

14
15
16
17
18

void c_write_float(float f){


printf("valeur affiche en C %g\n", f);
return;
}

12.4.3

Exemple : appel de sous-programmes fortran depuis le C

Lexemple suivant montre lappel en C de sous-programmes fortran pour saisir des rels et les
afficher. Ils sont vus depuis le C comme des fonctions sans valeur de retour dont le nom est donn
par le paramtre NAME dans le BIND (cf. lignes 6 et 13). Le sous-programme daffichage write_float
peut se contenter dun passage par copie de valeur, do lattribut VALUE en fortran (cf. ligne 14),
car il ne modifie pas la valeur du paramtre. En revanche, la fonction de lecture, f_read_float,
ncessite un passage par pointeur en C, directement compatible avec le passage dargument utilis
par le fortran.

1
2

#include <stdio.h>
#include <stdlib.h>

Partie langage C

3
4
5

void f_read_float(float *px);


void f_write_float(float x);

6
7
8
9
10
11
12
13
14

1
2
3
4
5
6
7
8
9
10
11
12
13

int main(void){
float f;
/* f est saisi en fortran */
f_read_float(&f);
printf("valeur du float affiche en C %g\n", f);
f_write_float(f);
exit(EXIT_SUCCESS);
}
Partie fortran 2003
MODULE m_io
USE, INTRINSIC :: iso_c_binding, ONLY:c_float
IMPLICIT NONE
CONTAINS
! void f_read_float(float *px);
SUBROUTINE read_float(x) BIND(c, name="f_read_float") !
REAL(kind=c_float), INTENT(out) :: x
WRITE (*, *) "saisie en fortran: entrer un float"
READ (*,*) x
WRITE (*,*) "float lu en fortran avant passage en C", x
END SUBROUTINE read_float
! void f_write_float(float x);
SUBROUTINE write_float(x) BIND(c, name="f_write_float") !

12.5. INTER-OPRABILIT DES TABLEAUX

14
15
16
17
18

133

REAL(kind=c_float), INTENT(in), value :: x ! passage par copie


WRITE (*,*) "affichage en fortran aprs passage en C "
WRITE (*,*) x
END SUBROUTINE write_float
END MODULE m_io

12.5

Inter-oprabilit des tableaux

Les tableaux ne peuvent tre inter-oprables que si leurs lments sont de type et de paramtres
inter-oprables. De plus, ils doivent soit tre de profil explicite, soit ne comporter quune dimension
indtermine :
la dernire spcifie par * en fortran ;
la premire spcifie par [] en C.
Dans le cas dun tableau de rang 1, si la taille est explicite, elle doit tre prcise et identique dans
les deux langages. Si elle est indtermine en fortran, elle ne doit pas tre prcise en C.
Linter-oprabilit des tableaux de rang suprieur 1 sappuie sur un ordre de rangement en
mmoire qui veut quen fortran, ce soit le premier indice qui dfile le plus vite 6 alors quen C, o
il sagit alors de tableaux de tableaux, cest le dernier indice qui dfile le plus vite. Il faudra donc
systmatiquement changer lordre des tailles pour passer dun langage lautre.
Par exemple le tableau fortran dclar : INTEGER(kind=c_int) :: tab(3,5,6)
pourra tre inter-oprable avec le tableau C : int tab[6][5][3];
Sil reste une dimension indtermine, ce sera la dernire en fortran, tab(3,5,*) et la premire
en C tab[][5][3].

12.5.1

Exemple : fonctions C manipulant des tableaux dfinis en fortran

Les tableaux sont ici de rang deux et de taille fixe pour le compilateur dans le programme principal en fortran afin dviter lallocation dynamique. Mais les fonctions en C supposent seulement
quune tendue est connue : celle dont la connaissance permet de calculer les dcalages effectuer
dans les adresses mmoire pour accder aux lments du tableau, cest dire celle de droite en C,
note C_N2 (cf. ligne 8, partie C), qui correspond celle de gauche en fortran, note F_LIG (cf.
ligne 12, partie fortran). Cette dimension commune, fixe ici grce au prprocesseur, devrait ltre
sous un seul nom dans un fichier unique inclus par le source C et par le source fortran. Avec les
conventions de nommage classiques des compilateurs (cf. annexe E), il est ncessaire de nommer
le source fortran avec comme suffixe .F90 au lieu de .f90 pour le voir trait par le prprocesseur.

1
2
3
4

!
!
!
!

Partie fortran 2003


toutes les tendues du tableau transmis sont fixes
sauf la plus droite en fortran (qui varie le plus lentement)
donc dclares dans l'interface, sauf la dernire *
attention: stockage invers en C

5
6
7

! instruction pr-processeur rpter en C


! ou mieux : inclure un fichier commun dans les deux codes

8
9
10

! pour imposer le traitement par le pr-processeur


! choisir un fichier de suffixe .F90 au lieu de .f90 pour le source

11
12

#define F_LIG 3 !

13
14
15
16

MODULE m_interf
USE, INTRINSIC :: iso_c_binding, ONLY:c_int
IMPLICIT NONE
6. Les lments qui ne diffrent que dune unit de cet indice sont supposs tre contigus en mmoire.

134

17
18
19
20
21
22
23
24
25
26
27
28
29

CHAPITRE 12. INTER-OPRABILIT AVEC LE C

INTERFACE
SUBROUTINE c_print_tab2d(mat, f_col) BIND(c)
IMPORT ::c_int !
INTEGER(kind=c_int), INTENT(in) :: mat(F_LIG, *)
INTEGER(kind=c_int), value :: f_col
END SUBROUTINE c_print_tab2d
SUBROUTINE c_mult_tab2d(mat, f_col) BIND(c)
IMPORT ::c_int !
INTEGER(kind=c_int), INTENT(inout) :: mat(F_LIG, *)
INTEGER(kind=c_int), value :: f_col
END SUBROUTINE c_mult_tab2d
END INTERFACE
END MODULE m_interf

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

1
2

PROGRAM f_appel_sub_c_tab2d
USE m_interf
IMPLICIT NONE
! f_col est connu du compilateur en fortran
! mais est un paramtre pour la fonction dfinie en C
INTEGER(kind=c_int), PARAMETER :: f_col = 4, f_col2 = 2
INTEGER(kind=c_int) :: mat(F_LIG, f_col), mat2(F_LIG, f_col2)
INTEGER :: i, j
! remplissage des tableaux
DO i = 1, F_LIG
DO j = 1, f_col
mat(i,j) = 10 * i + j
END DO
END DO
mat2(:,:) = - mat(:,1:f_col2)
! affichage en fortran
WRITE (*,*) "tableau 2d affich en fortran: 1er indice = ligne"
DO i = 1, F_LIG
WRITE(*,*) mat(i,:)
END DO
WRITE (*,*) "2me tableau 2d affich en fortran: 1er indice = ligne"
DO i = 1, F_LIG
WRITE(*,*) mat2(i,:)
END DO
! appel pour l'affichage en C
CALL c_print_tab2d(mat, f_col)
WRITE(*,*) "deuxime tableau"
CALL c_print_tab2d(mat2, f_col2)
! on multiplie chaque ligne par son numro
WRITE (*,*) "tableau 2d multipli par l'indice de ligne fortran"
CALL c_mult_tab2d(mat, f_col)
! appel pour l'affichage en C
CALL c_print_tab2d(mat, f_col)
END PROGRAM f_appel_sub_c_tab2d

#include <stdio.h>
#include <stdlib.h>

Partie langage C

3
4
5

/* doit tre cohrent avec le 1er indice du tableau fortran */


/* C_N2 = F_LIG ce qui pourrait tre assur par un fichier */

12.5. INTER-OPRABILIT DES TABLEAUX

135

/* commun inclus dans les deux sources fortran et C */

7
8

#define C_N2 3

9
10
11
12
13
14
15

/*
/*
/*
/*
/*
/*

transposition des dimensions entre fortran et C */


en C toutes les dimensions sauf la premire doivent tre connues */
du compilateur => fixes ici par le pr-processeur */
en fortran mat(F_LIG, *) = en C mat[][F_LIG] */
et passe la dimension variable en argument */
mat(F_LIG, f_col) = mat[c_n1][C_N2] avec c_n1=f_col C_N2=f_LIG */

16
17
18
19

/* integer(kind=c_int), intent(inout) :: mat(F_LIG, *) */


void c_print_tab2d(int mat[][C_N2], const int c_n1);
void c_mult_tab2d(int mat[][C_N2], const int c_n1);

20
21
22
23
24
25
26
27
28
29
30
31
32

void c_print_tab2d(int mat[][C_N2], const int c_n1){


int i, j;
printf("affichage en C\n");
for (i=0; i<C_N2; i++){
/* 2e indice C = 1er fortran */
for (j=0; j<c_n1; j++){ /* 1er indice C = 2e fortran */
printf("%d ", mat[j][i]);
}
printf("\n");
}
return;
}

33
34
35
36
37
38
39
40
41
42

void c_mult_tab2d(int mat[][C_N2], const int c_n1){


int i, j;
for (i=0; i<C_N2; i++){
/* 2e indice C = 1er fortran */
for (j=0; j<c_n1; j++){ /* 1er indice C = 2e fortran */
mat[j][i] *= (i+1); /* mult par 1er indice fortran */
}
}
return;
}

12.5.2

Exemple : fortran manipulant des tableaux dynamiques allous


en C

On peut utiliser les fonctions avances du fortran portant sur les tableaux partir du langage
C, y compris dans le cas de tableaux dynamiques allous et dsallous en C. Dans le cas de tableaux
de rang 1, on dfinit en C une structure vecteur (lignes 11 14) comportant un pointeur C sur le
dbut du tableau (de float ici) et un entier spcifiant le nombre de ses lments. On dfinit un type
driv vecteur inter-oprable en fortran (module m_vecteur) constitu des mmes composantes
en utilisant les types inter-oprables c_ptr et c_int associs en fortran.
Une fois largument vecteur pass au fortran par copie 7 (ligne 8), il sagit de lui associer un
tableau de rang 1 de la taille prcise et dont les lments sont ceux points par le pointeur C. Les
tableaux allouables ou les tableaux attribut pointeur du fortran sont plus riches que les pointeurs
du C, car ils comportent les informations sur le profil du tableau.
On utilise donc le sous-programme c_f_pointer (ligne 16) pour effectuer le transfert des informations de la structure C vers le pointeur fortran. ce propos, noter que la conversion du
7. Avec le passage par valeur, on sinterdit de modifier le pointeur C et la taille du tableau, donc de librer ou
de rallouer le tableau en fortran. Bien sr les valeurs des lments du tableau sont modifiables en fortran.

136

CHAPITRE 12. INTER-OPRABILIT AVEC LE C

B paramtre de taille de INTEGER(kind=c_int) en entier par dfaut (ligne 13) est ncessaire pour

spcifier le profil du tableau de faon portable en fortran. Une fois le tableau connu du fortran, on
peut lui appliquer toutes les transformations possibles avec les fonctions-tableau du fortran, tant
que lon ne modifie pas sa taille.

1
2
3
4
5
6
7
8
9
10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

1
2
3
4
5
6
7
8

Dfinition du type driv en fortran 2003


MODULE m_vect
USE, INTRINSIC :: iso_c_binding, ONLY : c_int, c_ptr
IMPLICIT NONE
! dfinition du type driv vecteur tel que vu en C
! ses composantes sont des types fortran inter-oprables C
TYPE, bind(c) :: vecteur
INTEGER(c_int) :: n ! taille du tableau
TYPE(c_ptr) :: ptc_v ! pointeur C
END TYPE vecteur
END MODULE m_vect
Sous-programme fortran 2003
! les vecteurs sont allous dynamiquement et librs par l'appelant (en C)
MODULE m_modif_vect
USE m_vect
IMPLICIT NONE
CONTAINS
SUBROUTINE f_modif_vect(v1) bind(c, name="f_modif_vect")
USE, INTRINSIC :: iso_c_binding, ONLY : c_f_pointer, c_float, c_null_ptr
TYPE(vecteur), INTENT(in), value :: v1 ! passage de la structure par copie
REAL(c_float), DIMENSION(:), POINTER :: ptf_v ! pointeur fortran
! affectation du pointeur de tableau fortran
! avec l'adresse au sens pointeur C et le profil
INTEGER, DIMENSION(1) :: loc_v1_n ! vecteur profil fortran du tableau
loc_v1_n (1)= v1%n ! conversion du type integer(c_int)
! vers le type entier par dfaut (32 ou 64 bits)
! pour spcifier le profil du tableau en fortran
CALL c_f_pointer(cptr=v1%ptc_v, fptr=ptf_v, shape=loc_v1_n)
WRITE(*,*) "on double les valeurs du tableau"
ptf_v(:) = 2* ptf_v(:)
WRITE(*,*) ptf_v(:)
WRITE(*,*) "dcalage circulaire de 2 cases dans le tableau"
ptf_v(:) = CSHIFT(ptf_v(:) , shift=-2)
WRITE(*,*) "rsultat en fortran"
WRITE(*,*) ptf_v(:)
END SUBROUTINE f_modif_vect
END MODULE m_modif_vect
Programme principal en langage C
/* version avec passage du pointeur vers a structure
=> permet de dsallouer et rallouer en fortran */
/* version avec allocation dynamique et type driv */
/* attention compiler avec gcc -lm pour inclure libm.a */
/*
et inclure l'entte associ math.h */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

9
10

/* type driv vecteur */

12.5. INTER-OPRABILIT DES TABLEAUX

11
12
13
14

137

typedef struct {
int n ;
float *v;
} vecteur;

15
16
17
18

void f_modif_vect(vecteur v) ; /* dclaration de la procdure en fortran */


/* passage d'un pointeur vers la structure C => elle est modifiable */
/* attention : aucune vrification avec l'interface fortran bien sr ! */

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

int main(void) {
vecteur v1 = {0, NULL};
int i;
/* Lecture du nombre de dimensions */
while(
printf("Entrez le nombre de composantes : (0 pour terminer) \n"),
scanf("%d", &(v1.n)),
v1.n > 0){
/* Allocation mmoire en C */
v1.v = (float *) calloc((size_t) v1.n, sizeof (float));
/*
size_t: conversion ncessaire en 64 bits */
/* Affectation des composantes */
for (i=0; i<v1.n; i++) {
v1.v[i] = (float) (i+1) ;
}
/* Affichage des composantes */
printf("affichage des %d composantes\n", v1.n);
for (i=0; i<v1.n; i++) {
printf("%f ", v1.v[i]);
}
printf("\n");
/* appel de la subroutine fortran */
printf("appel fortran \n"),
f_modif_vect(v1); /* pointeur vers la structure de vecteur*/
/* Impression du rsultat */
printf("affichage des composantes aprs appel fortran\n");
for (i=0; i<v1.n; i++) {
printf("%f ", v1.v[i]);
}
printf("\n");
/* Libration de la memoire dans le mme langage */
/* on suppose que libration <=> v1.n =0 */
if (v1.n > 0 || v1.v != NULL ) {
free(v1.v);
v1.n = 0;
v1.v = NULL ;
printf("mmoire libre en C\n");
}
}
exit (EXIT_SUCCESS);
}
Si on passe la structure vecteur par pointeur en C, le pointeur du tableau et le nombre de
composantes seront modifiables : il est ainsi possible de librer le tableau et de le rallouer avec
ventuellement une taille diffrente. Cette opration peut tre dclenche par le fortran, mais en
appelant une fonction C laquelle on repasse la structure vecteur. En effet, plus globalement, un
espace mmoire allou dans un langage doit tre dsallou dans ce mme langage.

Annexe A

Procdures intrinsques
Les procdures intrinsques sont des procdures intgres au langage, en ce sens que leur interface est connue (aucune dclaration explicite via USE par exemple nest ncessaire) et que leur code
objet est inclus dans la bibliothque du fortran (aucune autre bibliothque nest requise lors de
ldition de liens). La plupart des procdures intrinsques font partie du standard du fortran 90,
dautres ont t ajoutes en fortran 95 puis en fortran 2003, et en fortran 2008 (les fonctions inverses de trigonomtrie hyperbolique, les fonctions erreur et gamma ainsi que certaines fonctions
de Bessel, voir Site gfortran, de la collection de compilateurs gcc par exemple). Par ailleurs, des
options de compilation (cf. E.5.1, p. 170 pour g95, et E.6.1, p. 171 pour gfortran) permettent
dautoriser lemploi dautres fonctions intrinsques comme extension au standard.
Cette annexe rassemble les principales procdures intrinsques standard du fortran 90, 2003 et
2008. Les fonctions lmentaires (elemental) (cf. 6.5.8, p. 78) sont prcdes du signe .

A.1

Fonctions numriques de base

ABS(a)
ACOS(x)
ACOSH(x)
ASIN(x)
ASINH(x)
ATAN(x)
ATAN2(y,x)
ATANH(x)
BESSEL_J0(x)
BESSEL_J1(x)
BESSEL_JN(n,x)
BESSEL_Y0(x)
BESSEL_Y1(x)
BESSEL_YN(n,x)
CONJG(x)
COS(x)
COSH(x)
DIM(a,b)
ERF(x)
ERFC(x)
EXP(x)
GAMMA(x)

valeur absolue de lentier ou du rel a ou module du complexe a


arccos(x) en radians
argch(x)
arcsin(x) en radians
argsh(x)
arctan(x) en radians dans lintervalle [/2, /2]
argument du nombre complexe x + iy 6= 0, en radians dans lintervalle
argth(x)
J0 (x) fonction de Bessel de premire espce dordre 0
J1 (x) fonction de Bessel de premire espce dordre 1
Jn (x) fonction de Bessel de premire espce dordre n
Y0 (x) fonction de Bessel de deuxime espce dordre 0
Y1 (x) fonction de Bessel de deuxime espce dordre 1
Yn (x) fonction de Bessel de deuxime espce dordre n
x
complexe conjugu
cos(x)
cosh(x)
diffrence positive : max(a b, 0), donc a b si a > b et 0 sinon
a et b doivent tre de mmeR type, entier ou rel
x
erf(x) fonction derreur 2 0 exp(t2 ) dt
R
erfc(x) fonction derreur complmentaire 2 x exp(t2 ) dt
exp(x)
R
(x) fonction gamma 0 tx1 exp(t) dt
(n + 1) = n! si n entier positif

138

f2008
f2008
[, ]
f2008
f2008
f2008
f2008
f2008
f2008
f2008

f2008
f2008
f2008

139

A.1. FONCTIONS NUMRIQUES DE BASE

HYPOT(x,y)
LOG(x)
LOG10(x)
LOG_GAMMA(x)
MAX(a1,a2,...)
MIN(a1,a2,...)
MOD(a,p)
MODULO(a,p)
SIGN(a,b)
SIN(x)
SINH(x)
SQRT(x)
TAN(x)
TANH(x)

x2 + y 2 sans dpassement de capacit vitable a


f2008
ln(x) logarithme nprien
log(x) logarithme dcimal
ln(|(x)|) logarithme de la valeur absolue de la fonction gamma
f2008
valeur maximum
valeur minimum
reste de la division entire de a par p par troncature vers 0, soit
a - int(a/p)*p, fonction impaire de a et paire de p (cf. figure A.1, p. 139) b
reste de la division entire de a par p, soit a - floor(a/p)*p, fonction de
priode |p| en a et son signe est celui de p (cf. figures A.2 et A.3, p. 139)
|a| sign(b)
sin(x)
sinh(x)

x
tan(x)
tanh(x)
p
p
p

a. Pour viter un dpassement avec le calcul du carr, on factorise le plus grand :


x2 + y 2 = |x| 1 + (y/x)2 .
b. MOD est lquivalent de loprateur % du C dans la norme C99, qui spcifie que la divison entire se fait par
troncature vers 0.
MOD(a, +2) = MOD(a, -2)
6
+2
+1

u
4

u
2

0
+1

u
+2

+3

u
+4

+5

1
2

Figure A.1 Graphique de la fonction MOD(a, p) pour p = 2


MODULO(a, +2)
6
+2
+1

u
4

u
2

0u
1

+1

u
+2

+3

u
+4

+5

Figure A.2 Graphique de la fonction MODULO(a, p) pour p > 0,


par exemple p = +2
MODULO(a, 2)
+1 6
5

4
u

2
u

+1

+2
u

+3

+4
u

+5

a
-

1
2

Figure A.3 Graphique de la fonction MODULO(a, p) pour p < 0,


par exemple p = 2

140

ANNEXE A. PROCDURES INTRINSQUES

A.2

Conversion, arrondi et troncature (cf. 2.6)

AIMAG(z)
AINT(a[,kind])
ANINT(a[,kind])
CEILING(a[,kind])
CMPLX(x[,y][,kind])
FLOOR(a[,kind])
INT(a[,kind])
LOGICAL(L[,kind])
NINT(a[,kind])
REAL(a[,kind])

partie imaginaire du complexe z


valeur entire par troncature dun rel, convertie en rel, cest--dire
REAL(INT(a))
valeur entire par arrondi dun rel, convertie en rel, cest--dire
REAL(NINT(a))
conversion en type entier par excs (cf. figure A.4, p.140)
conversion en type complexe
conversion en type entier par dfaut (cf. figure A.5, p. 140)
conversion en type entier par troncature (cf. figure A.6, p. 140)
conversion entre variantes de boolens
conversion en type entier par arrondi (cf. figure A.7, p. 140)
conversion en type rel ou partie relle dun complexe

CEILING(a) 6

FLOOR(a) 6
u

+2
+1
0u
2

+1

+2

0u
2

Figure A.4 Graphique de la fonction


CEILING, entier par excs
INT(a) 6

Figure A.5 Graphique de la fonction


FLOOR, entier par dfaut

+1

+1
+2

Figure A.6 Graphique de la fonction


INT, entier vers zro

A.3

+2
u

0
3/2 1/2 +1/2 +3/2

u 1
u

0
1

+2

NINT(a) 6

+2

+1

1
u 1

+1

+1

u 1
u

+2

u
1
u

Figure A.7 Graphique de la fonction


NINT, entier le plus proche

Gnrateur pseudo-alatoire

Les gnrateurs pseudo-alatoires fournissent des tirages successifs statistiquement indpendants pris dans une suite finie de trs longue priode qui dpend du processeur et du compilateur,

A.3. GNRATEUR PSEUDO-ALATOIRE

141

mais dont linterface dappel RANDOM_NUMBER est, elle, portable. Le gnrateur possde une mmoire, ou tableau dtat, qui progresse naturellement chaque invocation, mais qui peut aussi
tre manipule grce au sous-programme RANDOM_SEED. En mmorisant ltat du gnrateur un
instant donn, et en lui imposant 1 plus tard la valeur mmorise, on peut forcer le gnrateur
reprendre les tirages partir dun tat dtermin et reproduire ainsi plusieurs fois la mme
squence.
RANDOM_NUMBER(harvest)
gnrateur de nombres pseudo-alatoires distribus uniformment
sur [0, 1[; harvest est un scalaire ou un tableau de rels.
RANDOM_SEED(SIZE|PUT|GET) initialisation du gnrateur de nombres pseudo-alatoires a , quatre usages possibles en fonction du mot-clef choisi :
() initialisation des valeurs dpendant du processeur
call RANDOM_SEED()
(SIZE) lecture de la dimension du tableau dtat INTENT(out)
INTEGER :: n
call RANDOM_SEED(SIZE = n)
PRINT *, ' taille ', n
(GET) lecture des valeurs du tableau dtat INTENT(out)
INTEGER :: n
INTEGER, DIMENSION(n) :: tab
call RANDOM_SEED(GET = tab(1:n))
PRINT *, ' tableau d''tat ', tab
(PUT) rinitialisation du tableau dtat INTENT(in)
INTEGER :: n
INTEGER, DIMENSION(n) :: tab
tab(1:n) = ... ! au moins une valeur non nulle
call RANDOM_SEED(PUT = tab(1:n))
Avec le compilateur xlf dibm, un autre mot-clef, GENERATOR
est disponible, qui permet de choisir entre le gnrateur de base
(GENERATOR=1, valeur par dfaut) ou un gnrateur optimis
(GENERATOR=2), plus rapide et de priode plus grande.
a. La taille du tableau dtat du gnrateur alatoire nest pas spcifie par le standard. Elle dpend du compilateur utilis. Sous Linux et processeur Intel ou amd 32 bits, elle est de 1 avec le compilateur f95 de nag, de
2 avec le traducteur f90 (de fortran 90 vers fortran 77) Vast (Pacific Sierra) et le compilateur ifort dIntel, de 4
avec g95 et de 34 avec pgf90 de Portland. Avec un processeur amd 64 bits, cette taille passe 2 avec g95, qui utilise
des entiers par dfaut sur 64 bits, mais cela correspond au mme nombre doctets. Avec gfortran et un processeur
64 bits, la taille du tableau dtat dpend de la version du compilateur (8 en v4.4.7 et 12 en v4.9.2).
Avec le compilateur de Portland sous Solaris de sun, elle est de 4. Sur la machine nec SX5 de lIDRIS, elle est
de 128. Sous dec-osf1 et processeur Alpha de 64 bits, elle est de 2, comme sous aix avec le compilateur xlf dibm.

Exemple dusages du gnrateur alatoire

PROGRAM random_test
IMPLICIT NONE
REAL
:: x
REAL, DIMENSION(3,4) :: alea
INTEGER :: n_alea ! taille de la mmoire du gnrateur alatoire de fortran90
INTEGER, DIMENSION(:), ALLOCATABLE :: mem_alea, mem_alea2 ! tableaux d'tat
1. Ds que lon force le tableau dtat, on risque de perdre lindpendance entre des tirages successifs.

142

10

15

20

25

30

35

40

45

ANNEXE A. PROCDURES INTRINSQUES

INTEGER :: i, erreur_alloc
! tirage d'un nombre pseudo-alatoire entre 0 et 1
CALL RANDOM_NUMBER(x)
WRITE (*, *) ' valeur tire: x = ',x
! tirage d'un tableau de nombres pseudo-alatoires indpendants entre 0 et 1
CALL RANDOM_NUMBER(alea)
WRITE (*, *) ' tableau des valeurs tires:'
DO i = 1, SIZE(alea, 1)
WRITE (*, *) alea(i, :)
END DO
! recherche de la taille du tableau d'tat
CALL RANDOM_SEED(SIZE = n_alea)
WRITE(*, *) ' taille de la mmoire du gnrateur alatoire : ', n_alea
! rservation de mmoire pour deux tableaux d'tat
ALLOCATE(mem_alea(n_alea), stat = erreur_alloc)
IF(erreur_alloc /= 0 ) STOP
ALLOCATE(mem_alea2(n_alea), stat = erreur_alloc)
IF(erreur_alloc /= 0 ) STOP
! lecture et mmorisation du tableau d'tat courant avant la boucle
CALL RANDOM_SEED(GET = mem_alea)
WRITE(*, *) '- tableau d''tat du gnrateur avant la boucle:', mem_alea(:)
DO i = 1 , 3
! lecture et affichage du tableau d'tat courant puis tirage
CALL RANDOM_SEED(GET = mem_alea2)
WRITE(*, *) ' tableau d''tat du gnrateur :', mem_alea2(:)
CALL RANDOM_NUMBER(x)
WRITE (*, *) ' valeur tire: x = ',x
END DO
! rinitialisation avec le tableau d'tat mmoris avant la boucle
! pour repartir du mme tat et donc obtenir la mme srie
CALL RANDOM_SEED(PUT = mem_alea)
WRITE (*, *) '- puis rinitialisation l''tat avant la boucle '
DO i = 1 , 3
! lecture et affichage du tableau d'tat courant puis tirage
CALL RANDOM_SEED(GET = mem_alea2)
WRITE(*, *) ' tableau d''tat du gnrateur :', mem_alea2(:)
CALL RANDOM_NUMBER(x)
WRITE (*, *) ' valeur tire: x = ',x
END DO
END PROGRAM random_test

A.4

Reprsentation des nombres (cf. 2.2)

DIGITS(x)
EPSILON(x)
EXPONENT(x)
FRACTION(x)
HUGE(x)
KIND(x)
MAXEXPONENT(x)
MINEXPONENT(x)
NEAREST(x,s)

nombre de digits (bits en base 2) utiliss pour reprsenter la mantisse x


dans le type de x
plus petite valeur dont la somme avec 1 diffre de 1 dans le type de x
exposant (entier) de x dans la reprsentation de x sous la forme
FRACTION(x) * REAL(RADIX(x))**EXPONENT(x)
partie fractionnaire de x dans la reprsentation de x sous la forme
FRACTION(x) * REAL(RADIX(x))**EXPONENT(x)
plus grande valeur absolue reprsentable dans le type de x
type numrique dans lequel est reprsent x
valeur maximale de lexposant (entier) de RADIX(x) dans le type de x
valeur minimale de lexposant (entier) de RADIX(x) dans le type de x
nombre le plus proche de x exactement reprsentable dans le type de x (par
excs ou dfaut suivant le signe de s)

A.5. FONCTIONS OPRANT SUR DES TABLEAUX

PRECISION(x)
RADIX(x)
RANGE(x)
RRSPACING(x)
SCALE(x, i)
SELECTED_INT_KIND(r)
SELECTED_REAL_KIND(p,r)
SET_EXPONENT(x, i)
SPACING(a)
TINY(x)
BIT_SIZE(i)

143

nombre de chiffres dcimaux significatifs dans le type de x


base de la reprsentation des nombres dans le type de x (en gnral 2)
domaine de x, exprim en puissance entire de 10, soit
INT(MIN(LOG10(HUGE(x)) , -LOG10(TINY(x))))
inverse (Reciprocal) de la distance relative (Relative) entre deux nombres
de mme type que x autour de x (quantit presque indpendante de x pour
un type fix)
x * REAL(RADIX(x))**i
sous-type entier permettant de reprsenter les entiers de lintervalle
] 10r , 10r [
sous-type rel permettant de reprsenter les rels x tels que
10r < | x | < 10r avec p chiffres significatifs
FRACTION(x) * REAL(RADIX(x))**i
plus petite distance entre a et la valeur de mme type la plus proche
plus petite valeur absolue non nulle reprsentable dans le type de x
nombre de bits des entiers du mme type que lentier a i

a. Largument i peut aussi tre un tableau dentiers, mais la taille est celle du scalaire.

A.5

Fonctions oprant sur des tableaux (cf. 7.4)

ALL(array[,dim])

teste si tous les lments dun tableau boolen sont


vrais
ALLOCATED(array)
teste si un tableau est allou (rsultat boolen)
ANY(array[,dim])
teste si au moins un des lments dun tableau boolen
est vrai
COUNT(array[,dim])
compte les lments vrais dun tableau boolen
CSHIFT(array, shift [, dim])
dcalage circulaire de shift des lments dun tableau,
vers les indices croissants si shift<0, selon la dimension 1, ou dim sil est spcifi.
DOT_PRODUCT(vector_a, vector_b)
produit scalaire de deux vecteurs
EOSHIFT(array,shift[,boundary][,dim]) dcalage de shift des lments dun tableau avec perte
aux bords (remplacement par 0 ou boundary si largument est spcifi)
LBOUND(array[,dim])
vecteur des bornes infrieures des indices dun tableau
(scalaire si la dimension concerne est prcise)
MATMUL(matrix_a, matrix_b)
multiplication matricielle
MAXLOC(array[,mask])
tableau de rang 1 donnant la position de la premire
occurrence de la valeur maximum dun tableau
MAXVAL(array[,dim][,mask])
valeur maximum dun tableau
MERGE(tsource,fsource,mask)

fusion des tableaux tsource (si vrai) et fsource (si


faux) selon le masque mask
MINLOC(array[,mask])
tableau de rang 1 donnant la position de la premire
occurrence de la valeur minimum dun tableau
MINVAL(array[,dim][,mask])
valeur minimum dun tableau
PACK(array, mask [,vector])
range dans un tableau de rang 1 les lments de
array slectionns par le masque mask (conformant
avec tab). Si vector est fourni, le tableau rsultat
est si ncessaire complt par les lments terminaux
de vector pour obtenir un vecteur de mme tendue.
vector doit donc possder au moins autant dlments
que le masque en slectionne.

144

ANNEXE A. PROCDURES INTRINSQUES

PRODUCT(array[,dim][,mask])
RESHAPE(source,shape[,pad][,order])
SHAPE(array)
SIZE(array[,dim])
SPREAD(source,dim,ncopies)
SUM(array[,dim][,mask])
TRANSPOSE(matrix)
UBOUND(array[,dim])
UNPACK(vector, mask, field)

A.6

produit des valeurs dun tableau


restructuration du tableau source selon le profil shape
profil dun tableau
taille (nombre dlments) dun tableau [suivant la dimension dim ]
cration dun tableau de dimension suprieure par duplication (ncopies fois) du scalaire ou tableau source
selon la dimension dim
somme des valeurs dun tableau
transposition
vecteur des bornes suprieures des indices dun tableau
(scalaire si la dimension concerne est prcise)
dploie les lments du tableau vector de rang 1 dans
un tableau initialement rempli avec field selon le
masque mask conformant field

Manipulation de bits

Les fonctions intrinsques suivantes permettent la manipulation directe de bits sur les entiers :
BTEST(i, pos)
IAND(i, j)
IBCLR(i, pos)
IBITS(i, pos, len)
IBSET(i, pos)
IEOR(i, j)
IOR(i, j)
ISHFT(i, shift)
ISHFTC(i, shift)

NOT(i)

A.7

vrai si le bit pos de lentier i vaut 1


vrai si tous les bits de i et j sont gaux
rend un entier du type de i dont le bit pos a t mis zro.
rend un entier du type de i dont les len bits en commenant au bit pos
sont ceux de i complts par des zros gauche.
rend un entier du type de i dont le bit pso a t mis un.
rend un entier du type de i et j dont les bits sont obtenus par ou exclusif
entre ceux de i et j.
rend un entier du type de i et j dont les bits sont obtenus par ou inclusif
entre ceux de i et j.
rend un entier du type de i dont les bits sont obtenus par dcalage de
shift vers la gauche (la droite si shift ngatif) le remplissage tant
assur par des zros.
rend un entier du type de i dont les bits sont obtenus par dcalage de
shift vers la gauche (la droite si shift ngatif) le remplissage tant
assur par recyclage circulaire.
rend un entier du type de i dont les bits sont obtenus par inversion de
ceux de i.

Divers

PRESENT(a)
TRANSFER(source, mold [, size])

fonction valeur boolenne : vraie si largument optionnel


a de la procdure a t fourni, fausse sinon (cf. 6.5.1).
interprte la reprsentation binaire de source selon le
type spcifi par mold

Lusage de la fonction TRANSFER est susceptible de nuire la portabilit des codes 2 , car cette
fonction sappuie sur la reprsentation binaire des variables qui peut dpendre de lordinateur. Noter
que cette opration peut aussi tre ralise par criture puis relecture sur fichier texte externe au
format binaire (format B, cf. 5.4.1). Elle permet par exemple de considrer les 32 bits dune zone
de la mmoire codant un entier comme les 32 bits codant un rel ; la valeur numrique de ce rel
est videmment diffrente de celle de lentier ; les bits considrs peuvent mme reprsenter un rel
invalide ou une valeur spciale telle que Inf ou Nan.
2. Cette rinterprtation dun motif binaire selon un autre type constitue une opration de bas niveau, facile
coder en C avec des pointeurs par transtypage : float a; int i; int * p; p =&i; a = *((float *) p);. En
fortran, lassociation entre pointeurs de types diffrents est au contraire interdite.

145

A.8. POINTEURS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

PROGRAM t_transfer_int ! test de la fonction transfer entre entiers


IMPLICIT NONE
! pour reprsenter 100 => un octet suffit
INTEGER, PARAMETER :: ki1 = SELECTED_INT_KIND(2)
! pour reprsenter 10**4 => 2 octets suffisent
INTEGER, PARAMETER :: ki2 = SELECTED_INT_KIND(4)
INTEGER(kind=ki1), DIMENSION(2) :: ti
INTEGER(kind=ki2) :: j
INTEGER(kind=ki1), DIMENSION(:), ALLOCATABLE :: tk
INTEGER :: n
ti(1) = 3
ti(2) = 1
! recopie binaire du tableau de 2 entiers 8 bits sur un entier 16 bits
j = TRANSFER(ti,j)
WRITE(*,*) "ti(1) sur ", BIT_SIZE(ti(1)), "bits"
WRITE(*,*) "j sur ", BIT_SIZE(j), "bits"
WRITE(*,*) "affichage en binaire des 2 entiers ti(2) et ti(1) sur 8 bits chacun"
WRITE(*,'(A,B8.8,A,B8.8)') "ti(2)=",ti(2), " ti(1)= ",ti(1) ! ordre invers
WRITE(*,'(B8.8,B8.8,A)') ti(2:1:-1), " concatns (ordre inverse)"
WRITE(*,*) "affichage en binaire de l'entier j sur 16 bits "
WRITE(*,'(B16.16)') j
WRITE(*,*) "j =", j, " est gal ti(1) + ti(2)*2**8 =", ti(1) + ti(2)*2**8
! mme opration avec calcul du nombre d'lments de tk pour stocker j
n =SIZE(TRANSFER(j, tk)) ! en principe n = bit_size(j)/bit_size(tk(1))
ALLOCATE(tk(n)) ! l'allocation au vol ne fctne pas
tk = TRANSFER(j, tk) ! recopie bit bit de j dans la tableau tk
WRITE(*,*) "nb d'lments de tk ", SIZE(tk), "valeurs des lments ", tk(:)
DEALLOCATE(tk)
END PROGRAM t_transfer_int

produit laffichage suivant :


ti(1) sur 8 bits
j sur 16 bits
affichage en binaire des 2 entiers ti(2) et ti(1) sur 8 bits chacun
ti(2)=00000001 ti(1)= 00000011
0000000100000011 concatns (ordre inverse)
affichage en binaire de l'entier j sur 16 bits
0000000100000011
j = 259 est gal ti(1) + ti(2)*2**8 = 259
nb d'lments de tk 2 valeurs des lments 3 1

A.8

Pointeurs (cf. 11.1.1, p. 119)

ASSOCIATED(pointer [, target])
NULL([mold])

A.9

rend une valeur boolenne vraie si le pointeur pointer


est associ une cible ( la cible target si largument
optionnel est fourni).
rend un pointeur dsassoci du type du pointeur mold
si cet argument est prsent.

Accs lenvironnement fortran

partir de la norme fortran 2008, le module intrinsque ISO_FORTRAN_ENV (cf. 5.3.1, p. 41)
fournit deux fonctions dinterrogation sans argument qui renvoient une chane de caractres sur
lenvironnement de compilation :
COMPILER_OPTIONS() indique la liste des options du compilateur actives.
f2008
COMPILER_VERSION() indique la version du compilateur.
f2008

146

ANNEXE A. PROCDURES INTRINSQUES

Exemple dutilisation :

1
2
3
4
5
6
7
8

PROGRAM compiler_info
! standard fortran 2008 : emploi du module ISO_FORTRAN_ENV
! juin 2013: pas OK en gfortran 4.4, mais OK en gfortran 4.6
USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : compiler_version, compiler_options
IMPLICIT NONE
WRITE(*,*) "version du compilateur : ", compiler_version()
WRITE(*,*) "options du compilateur : ", compiler_options()
END PROGRAM compiler_info

Affichage obtenu :

1
2

f2003

version du compilateur : GCC version 4.6.3


options du compilateur : -mtune=generic -march=x86-64 -std=f2008

A.10

Accs lenvironnement systme

GET_ENVIRONMENT_VARIABLE(name [,value] [,length] [,status] [,trim_name])


sous-programme qui rcupre la valeur de la variable denvironnement name 3 dans la chane de
caractres value, sa longueur dans lentier length, ventuellement avec les blancs gauche si
trim_name vaut .false. Le statut de retour status vaut 1 si la variable demande nexiste pas,
-1 si la valeur est trop longue pour la chane value et 0 en labsence derreur ou davertissement.
GET_COMMAND_([command] [,length] [,status])
sous-programme qui rend dans la chane command la commande ayant lanc le programme et ventuellement le nombre de caractres de cette chane dans length. Largument optionnel status
vaut 0 quand lappel sest droul sans problme, -1 quand la chane passe est trop courte pour
hberger la ligne de commande, et un nombre positif en cas derreur.
COMMAND_ARGUMENT_COUNT()
fonction qui rend un entier contenant le nombre de paramtres 4 de la commande ayant lanc le
programme.
GET_COMMAND_ARGUMENT(number [,value] [,length] [,status])
sous-programme qui rend dans la chane value largument numro number 5 de la commande ayant
lanc le programme et ventuellement sa taille dans length.

Exemple daccs lenvironnement systme


On peut ainsi passer des paramtres sous forme de chanes de caractres au programme principal, de la mme faon quen C. Aprs avoir compil le programme suivant :

3. Cest lquivalent de la fonction getenv du langage C.


4. Cest dire argc -1 du langage C.
5. Cest le paramtre donn par argv[number] du langage C.

A.11. EXCUTION DUNE COMMANDE SYSTME

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

147

PROGRAM t_environ
IMPLICIT NONE
CHARACTER(len=20) :: nom, valeur, arg0, arg
CHARACTER(len=80) :: commande
INTEGER :: longueur, statut, n_param, i
WRITE(*,*) "rcupration d'une variable d'environnement"
nom(1:) = "SHELL"
CALL get_environment_variable(nom, valeur, longueur, statut)
IF (statut /= 0) STOP "erreur get_environment_variable"
WRITE(*,*) nom(1:5), "=", valeur(1:longueur)
CALL get_command(COMMAND=commande, LENGTH=longueur, STATUS=statut)
IF (statut /= 0) STOP "erreur get_command"
WRITE(*,*) "longueur de la ligne de commande", longueur
WRITE(*,*) "ligne de commande = |", commande(1:longueur), "|"
CALL get_command_argument(0, arg0, longueur, statut)
IF (statut /= 0) STOP "erreur get_command_argument"
WRITE(*,*) "commande ayant lanc ce programme=", arg0(1:longueur)
n_param = command_argument_count()
WRITE(*,*) "nb de paramtres de la commande = ", n_param
DO i=1, n_param
CALL get_command_argument(i, arg, longueur, statut)
IF (statut /= 0) STOP "erreur get_command_argument"
WRITE(*,*) "paramtre ", i, " de la commande=", arg(1:longueur)
END DO
END PROGRAM t_environ

Lexcution de la commande a.out test 12 "5 6" affiche :


1
2
3
4
5
6
7
8
9

f2008

rcupration d'une variable d'environnement


SHELL=/bin/bash
longueur de la ligne de commande
17
ligne de commande = |a.out test 12 5 6|
commande ayant lanc ce programme=a.out
nb de paramtres de la commande =
3
paramtre
1 de la commande=test
paramtre
2 de la commande=12
paramtre
3 de la commande=5 6

A.11

Excution dune commande systme

EXECUTE_COMMAND_LINE(command [,wait] [,exitstat] [,cmdstat], [,cmdmsg]) est un sousprogramme qui permet de passer la commande command (argument dentre de type chane de
caractres) au systme dexploitation. Tous ses autres arguments sont optionnels :
wait est un argument dentre de type boolen, vrai par dfaut, qui permet dautoriser une
excution asynchrone de la commande.
exitstat est un argument entier de vocation inout, qui, sauf si la commande est lance en
asynchrone, rcupre le statut de retour de la commande systme.
cmdstat est un argument de sortie entier qui vaut 0 si la commande sest excute sans erreur,
-1 si le processeur ne peut pas lexcuter et -2 si le processeur ne peut honorer lexcution
synchrone requise (wait=.true.) et une valeur positive pour les autres erreurs.
cmdmsg est un argument de type chane de caractres de vocation inout, qui, si cmdstat est
positif, contient un message dexplication.

148

f95

A.12

ANNEXE A. PROCDURES INTRINSQUES

Gestion du temps

DATE_AND_TIME([DATE,] [TIME,] [ZONE,] [VALUES])


sous-programme permettant daccder la date et lheure fournis par le systme dexploitation.
Les quatre arguments sont des arguments de sortie optionnels :
DATE : chane de 8 caractres recevant la date sous forme aaaammjj
TIME : chane de 10 caractres recevant le temps sous forme hhmmss.iii o iii reprsentent
les millisecondes
ZONE : chane de 5 caractres recevant le dcalage par rapport au temps universel sous la
forme +/-hhmm
VALUE : tableau de 8 entiers reprsentant successivement lanne, le mois, le jour, le dcalage
par rapport au temps universel exprim en minutes, lheure, les minutes, les secondes et les
millisecondes.

Exemple dutilisation de DATE_AND_TIME


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

MODULE util_time
IMPLICIT NONE
CONTAINS
REAL FUNCTION deltat(td, tf)
! calcul de la duree en secondes
! attention : incorrect si changement de date
INTEGER, DIMENSION(8), INTENT(in) :: td, tf
deltat = (tf(8) -td(8))/1000. + (tf(7) -td(7)) + &
60 * ( (tf(6) -td(6)) + 60 *(tf(5) -td(5)))
END FUNCTION deltat
SUBROUTINE affiche(t)
! affichage de la date suivie du temps
! en heures, minutes, secondes et millisecondes
INTEGER, DIMENSION(8), INTENT(in) :: t
WRITE(*,'(i2.2,a,i2.2,a,i4.4, a, i2.2,a,i2.2,a,i2.2,a,i3.3, a)') &
t(3),"/",t(2),"/",t(1), " ", &
t(5), "h", t(6), "'", t(7), '"', t(8), "ms "
END SUBROUTINE
END MODULE util_time
PROGRAM datetime ! test du sous-programme date_and_time
USE util_time
INTEGER, DIMENSION(8) :: debut, fin
CHARACTER(len=8) :: jour
CHARACTER(len=10) :: instant
INTEGER:: i, j
CALL DATE_AND_TIME(date=jour, time=instant)
WRITE(*,*) "date (AAAAMMJJ) : ", jour
WRITE(*,*) "heure (hhmmss.*): ", instant
CALL DATE_AND_TIME(values=debut)
WRITE(*,'(a)', advance="no") "debut "
CALL affiche(debut)
DO i=1, 1000000 ! ajuster < huge(i)
j = 1 - i
END DO
CALL DATE_AND_TIME(values=fin)
WRITE(*,'(a)', advance="no") "fin
"
CALL affiche(fin)
WRITE(*,*) "duree de la boucle", deltat(debut, fin), 's'
END PROGRAM datetime

Lexcution de ce code donne par exemple :

A.13. CARACTRES ET CHANES DE CARACTRES

1
2
3
4
5

149

date (AAAAMMJJ) : 20110824


heure (hhmmss.*): 135703.472
debut 24/08/2011 13h57'03"472ms
fin
24/08/2011 13h57'03"482ms
duree de la boucle 0.01 s

CPU_TIME(time)
sous-programme permettant daccder au temps du processeur exprim en secondes avec une rsolution de la microseconde : lorigine est arbitraire, seules les diffrences sont pertinentes. Ce
sous-programme permet notamment dvaluer des dures dexcution de code. Le paramtre est
un argument de sortie rel.
SYSTEM_CLOCK([count] [,count_rate] [,count_max])
sous-programme permettant daccder au temps exprim en nombre de tops dhorloge de frquence
COUNT_RATE modulo une valeur maximale COUNT_MAX. Les trois arguments sont des arguments de
sortie entiers optionnels.

A.13

Caractres et chanes de caractres

ACHAR(i)
CHAR(i [, kind])
IACHAR(c)
ICHAR(c)
NEW_LINE(a)
SELECTED_CHAR_KIND(name)

ie caractre (o i est compris entre 0 et 127) dans lordre de


lascii
ie caractre dans lordre du compilateur (qui inclut souvent
lordre ascii, mais peut aussi fournir des caractres nationaux,
comme nos caractres accentus)
position du caractre (entre 0 et 127) c dans lordre ascii
position du caractre c dans lordre du compilateur (qui inclut souvent lordre ascii, mais peut aussi fournir des caractres
nationaux, comme nos caractres accentus)
caractre de nouvelle ligne dans la variante de caractres de a
rend le numro de la variante de caractres dans laquelle la
chane name est donne ('DEFAULT', 'ASCII' ou 'ISO_10646')

ADJUSTL(string)
ADJUSTR(string)
LEN(string)
LEN_TRIM(string)
REPEAT(string,ncopies)
TRIM(string)

justification gauche de la chane string


justification droite de la chane string
longueur de la chane string
longueur de la chane string sans les blancs droite
duplique ncopies fois la chane string
suppression des blancs droite

LGE(string_a,string_b)

vrai si string_a est plac aprs string_b dans lordre lexicographique de lascii ou concide avec string_b
vrai si string_a est plac strictement aprs string_b dans
lordre lexicographique de lascii
vrai si string_a est plac avant string_b dans lordre lexicographique de lascii ou concide avec string_b
vrai si string_a est plac strictement avant string_b dans
lordre lexicographique de lascii

LGT(string_a,string_b)
LLE(string_a,string_b)
LLT(string_a,string_b)

INDEX(string,substring)
SCAN(string,set)

position de la sous-chane substring dans la chane string


repre un des caractres de la chane set dans la chane string

VERIFY(string,set)

vrifie que la chane string ne contient que des caractres de


la chane set (renvoie lentier 0), sinon donne la position du
premier caractre de string qui ne fait pas partie de lensemble set

150

ANNEXE A. PROCDURES INTRINSQUES

Codes ascii et iso-latin1


Les fonctions rciproques achar et iachar traduisent le codage ascii des caractres explicit
dans le tableau ci-aprs, qui indique le numro en octal, dcimal et hexadcimal de chaque caractre, soit sa reprsentation sil est imprimable soit son abrviation et ventuellement la squence
dchappement (commenant par une contre-oblique) qui le reprsente dans le langage C.
Oct

Dec

Hex

Char

Oct

Dec

Hex

Char

000
001
002
003
004
005
006
007
010
011
012
013
014
015
016
017
020
021
022
023
024
025
026
027
030
031
032
033
034
035
036
037
040
041
042
043
044
045
046
047
050
051
052
053
054
055
056
057
060
061
062
063

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
42
43
44
45
46
47
48
49
50
51

00
01
02
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F
10
11
12
13
14
15
16
17
18
19
1A
1B
1C
1D
1E
1F
20
21
22
23
24
25
26
27
28
29
2A
2B
2C
2D
2E
2F
30
31
32
33

NUL \0
SOH
STX
ETX
EOT
ENQ
ACK
BEL \a
BS \b
HT \t
LF \n
VT \v
FF \f
CR \r
SO
SI
DLE
DC1
DC2
DC3
DC4
NAK
SYN
ETB
CAN
EM
SUB
ESC
FS
GS
RS
US
SPACE
!
"
#
$
%
&
'
(
)
*
+
,
.
/
0
1
2
3

100
101
102
103
104
105
106
107
110
111
112
113
114
115
116
117
120
121
122
123
124
125
126
127
130
131
132
133
134
135
136
137
140
141
142
143
144
145
146
147
150
151
152
153
154
155
156
157
160
161
162
163

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

40
41
42
43
44
45
46
47
48
49
4A
4B
4C
4D
4E
4F
50
51
52
53
54
55
56
57
58
59
5A
5B
5C
5D
5E
5F
60
61
62
63
64
65
66
67
68
69
6A
6B
6C
6D
6E
6F
70
71
72
73

@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
[
\
]
^
&
`
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s

\\

151

A.13. CARACTRES ET CHANES DE CARACTRES

064
065
066
067
070
071
072
073
074
075
076
077

52
53
54
55
56
57
58
59
60
61
62
63

34
35
36
37
38
39
3A
3B
3C
3D
3E
3F

4
5
6
7
8
9
:
;
<
=
>
?

164
165
166
167
170
171
172
173
174
175
176
177

116
117
118
119
120
121
122
123
124
125
126
127

74
75
76
77
78
79
7A
7B
7C
7D
7E
7F

t
u
v
w
x
y
z
{
|
}
~
DEL

Plusieurs codages des caractres sur 8 bits permettent dtendre le code ascii en reprsentant
aussi les caractres dots de signes diacritiques (accents, cdille, ...) prsents dans les langages
europens. Le tableau suivant indique les caractres du codage iso-8859-1 (alphabet latin 1, pour
les langues de lEurope occidentale) qui sont imprimables et ne figurent pas dans le codage ascii.
Oct

Dec

Hex

Char

Description

240
241
242
243
244
245
246
247
250
251
252
253
254
255
256
257
260
261
262
263
264
265
266
267
270
271
272
273
274
275
276
277
300
301
302
303
304
305
306
307

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
AA
AB
AC
AD
AE
AF
B0
B1
B2
B3
B4
B5
B6
B7
B8
B9
BA
BB
BC
BD
BE
BF
C0
C1
C2
C3
C4
C5
C6
C7

NO-BREAK SPACE
INVERTED EXCLAMATION MARK
CENT SIGN
POUND SIGN
CURRENCY SIGN
YEN SIGN
BROKEN BAR
SECTION SIGN
DIAERESIS
COPYRIGHT SIGN
FEMININE ORDINAL INDICATOR
LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
NOT SIGN
SOFT HYPHEN
REGISTERED SIGN
MACRON
DEGREE SIGN
PLUS-MINUS SIGN
SUPERSCRIPT TWO
SUPERSCRIPT THREE
ACUTE ACCENT
MICRO SIGN
PILCROW SIGN
MIDDLE DOT
CEDILLA
SUPERSCRIPT ONE
MASCULINE ORDINAL INDICATOR
RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
VULGAR FRACTION ONE QUARTER
VULGAR FRACTION ONE HALF
VULGAR FRACTION THREE QUARTERS
INVERTED QUESTION MARK
LATIN CAPITAL LETTER A WITH GRAVE
LATIN CAPITAL LETTER A WITH ACUTE
LATIN CAPITAL LETTER A WITH CIRCUMFLEX
LATIN CAPITAL LETTER A WITH TILDE
LATIN CAPITAL LETTER A WITH DIAERESIS
LATIN CAPITAL LETTER A WITH RING ABOVE
LATIN CAPITAL LETTER AE
LATIN CAPITAL LETTER C WITH CEDILLA

152

310
311
312
313
314
315
316
317
320
321
322
323
324
325
326
327
330
331
332
333
334
335
336
337
340
341
342
343
344
345
346
347
350
351
352
353
354
355
356
357
360
361
362
363
364
365
366
367
370
371
372
373
374
375
376
377

ANNEXE A. PROCDURES INTRINSQUES

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255

C8
C9
CA
CB
CC
CD
CE
CF
D0
D1
D2
D3
D4
D5
D6
D7
D8
D9
DA
DB
DC
DD
DE
DF
E0
E1
E2
E3
E4
E5
E6
E7
E8
E9
EA
EB
EC
ED
EE
EF
F0
F1
F2
F3
F4
F5
F6
F7
F8
F9
FA
FB
FC
FD
FE
FF

LATIN CAPITAL LETTER E WITH GRAVE


LATIN CAPITAL LETTER E WITH ACUTE
LATIN CAPITAL LETTER E WITH CIRCUMFLEX
LATIN CAPITAL LETTER E WITH DIAERESIS
LATIN CAPITAL LETTER I WITH GRAVE
LATIN CAPITAL LETTER I WITH ACUTE
LATIN CAPITAL LETTER I WITH CIRCUMFLEX
LATIN CAPITAL LETTER I WITH DIAERESIS
LATIN CAPITAL LETTER ETH
LATIN CAPITAL LETTER N WITH TILDE
LATIN CAPITAL LETTER O WITH GRAVE
LATIN CAPITAL LETTER O WITH ACUTE
LATIN CAPITAL LETTER O WITH CIRCUMFLEX
LATIN CAPITAL LETTER O WITH TILDE
LATIN CAPITAL LETTER O WITH DIAERESIS
MULTIPLICATION SIGN
LATIN CAPITAL LETTER O WITH STROKE
LATIN CAPITAL LETTER U WITH GRAVE
LATIN CAPITAL LETTER U WITH ACUTE
LATIN CAPITAL LETTER U WITH CIRCUMFLEX
LATIN CAPITAL LETTER U WITH DIAERESIS
LATIN CAPITAL LETTER Y WITH ACUTE
LATIN CAPITAL LETTER THORN
LATIN SMALL LETTER SHARP S
LATIN SMALL LETTER A WITH GRAVE
LATIN SMALL LETTER A WITH ACUTE
LATIN SMALL LETTER A WITH CIRCUMFLEX
LATIN SMALL LETTER A WITH TILDE
LATIN SMALL LETTER A WITH DIAERESIS
LATIN SMALL LETTER A WITH RING ABOVE
LATIN SMALL LETTER AE
LATIN SMALL LETTER C WITH CEDILLA
LATIN SMALL LETTER E WITH GRAVE
LATIN SMALL LETTER E WITH ACUTE
LATIN SMALL LETTER E WITH CIRCUMFLEX
LATIN SMALL LETTER E WITH DIAERESIS
LATIN SMALL LETTER I WITH GRAVE
LATIN SMALL LETTER I WITH ACUTE
LATIN SMALL LETTER I WITH CIRCUMFLEX
LATIN SMALL LETTER I WITH DIAERESIS
LATIN SMALL LETTER ETH
LATIN SMALL LETTER N WITH TILDE
LATIN SMALL LETTER O WITH GRAVE
LATIN SMALL LETTER O WITH ACUTE
LATIN SMALL LETTER O WITH CIRCUMFLEX
LATIN SMALL LETTER O WITH TILDE
LATIN SMALL LETTER O WITH DIAERESIS
DIVISION SIGN
LATIN SMALL LETTER O WITH STROKE
LATIN SMALL LETTER U WITH GRAVE
LATIN SMALL LETTER U WITH ACUTE
LATIN SMALL LETTER U WITH CIRCUMFLEX
LATIN SMALL LETTER U WITH DIAERESIS
LATIN SMALL LETTER Y WITH ACUTE
LATIN SMALL LETTER THORN
LATIN SMALL LETTER Y WITH DIAERESIS

Annexe B

Ordre des instructions


Ce diagramme indique lordre respecter entre les diffrentes instructions dans une unit de
programme en fortran. Les instructions prsentes dans des colonnes diffrentes lintrieur dune
mme ligne du tableau peuvent tre insres dans un ordre quelconque.

PROGRAM, FUNCTION, SUBROUTINE, MODULE, BLOCK DATA


USE
IMPORT
IMPLICIT NONE
FORMAT, ENTRY

PARAMETER

IMPLICIT

PARAMETER et DATA

dfinition de types, blocs dinterfaces, dclarations

DATA

instructions excutables
CONTAINS

procdures internes ou de module


END
Noter, en particulier, que lon place dans lordre, dabord USE, puis IMPLICIT, ensuite les dclarations de types ou de variables, puis les instructions excutables. Enfin, linstruction CONTAINS qui
introduit les procdures internes se place juste avant la fin de lunit de programme qui lhberge.
En pratique, les instructions de formats sont soit places juste aprs les ordres dentressortie
qui les appellent, soit groupes en fin dunit de programme, surtout dans le cas o elles sont
utilises par plusieurs ordres dentressortie.
Concernant les dclarations de variables dans les procdures, une pratique saine consiste d-
clarer dabord les arguments de la procdure, en prcisant leur vocation (INTENT), puis les variables
locales.

153

Annexe C

La norme IEEE 754 de


reprsentation des flottants
C.1
C.1.1

Introduction
Reprsentation des rels en virgules flottante

Reprsenter un rel (non nul) en virgule flottante dans une base b consiste en donner une
approximation finie sous la forme :
0

e0

e0

r=sb m =sb
0

q
X

(C.1)

pi bi

i=0

o
s = 1 est le signe ;
e0 est un entier qualifi dexposant ;
m0 est le significande, appel abusivement la mantisse que lon peut dcomposer sur la base
b selon les q 0 + 1 poids entiers pi tels que 0 6 pi < b
Plusieurs dcompositions mantisseexposant tant possibles (de la mme faon quen dcimal, on
peut crire 1,2 100 ou 0,12 101 ), on choisit ici lexposant pour que 1 6 m0 < b (qui correspondrait lintervalle [1., 10.[ si on travaillait en dcimal). Cette reprsentation diffre donc de
celle introduite plus haut (cf. 2.2, p. 13), avec une mantisse m entre 1/b et 1 (qui correspondrait
lintervalle [.1, 1.[ si on travaillait en dcimal), choix qui tait plus en accord avec les fonctions
intrinsques FRACTION et EXPONENT. Ces deux reprsentations sont lies par e0 = e 1 et q 0 = q 1.
Dans le cas de la base 2 et en prenant en compte le choix dun premier bit p0 de m0 1,
lexpression (C.1) prend la forme :
r = (1) 2
s

e0

1+

q1
X
pi
i=1

q1

2i

e0

= (1) 2 (1 + f ) = (1) 2
s

1 X pi
+
2 i=1 2i+1

!
(C.2)

o f = m0 1 est la partie fractionnaire du significande sur q 0 = q 1 bits.


Chaque variante du type rel (dtermine via le paramtre de codage KIND) est caractrise
par :
un nombre M de bits ddis au stockage de la mantisse qui fixe la prcision relative des rels ;
un nombre E de bits ddis au stockage de lexposant qui fixe le domaine de valeurs couvert.
signe
1 bit

exposant
E bits
154

mantisse
M bits

C.2. LES CODES NORMAUX

C.1.2

155

Arithmtique tendue

Mais la norme IEEE-754-2008 permet aussi de reprsenter des rsultats doprations arithmtiques qui ne svaluent pas comme des rels, tels que :
 1./0. soit + affich +Inf
 -1./0. soit affich -Inf
 0./0. qui est indtermin, ou sqrt(-1.) qui est une opration invalide : il est cod comme
NaN soit Not-A-Number . NaN possde aussi une variante ngative. Enfin, les rsultats NaN
peuvent donner lieu des messages (signaling NaN) ou tre propags sans avertissement dans
les calculs (quiet NaN) : un bit particulier permet de dterminer ce comportement.
Larithmtique traditionnelle stend ces valeurs spciales de faon naturelle si on prcise
que ds quun NaN intervient dans une expression, le rsultat est aussi reprsent par un NaN. Par
exemple, Inf + Inf donne +Inf, mais Inf - Inf donne NaN. Enfin, le codage IEEE permet de
reprsenter un zro positif et un zro ngatif qui interviennent naturellement dans des
oprations arithmtiques tendues telles que 1./+Inf ou 1./-Inf.

C.2

Les codes normaux

Lexposant e0 cod sur E bits qui dtermine lintervalle couvert dfinissant ainsi le domaine, est
de signe a priori quelconque entre 2E1 + 1 et 2E1 : on lui ajoute 2E1 1 de faon stocker le
nombre sans signe e00 = e0 + 2E1 1, appel exposant biais, qui est un entier compris entre 0 et
2E 1. Mais on exclut les deux valeurs extrmes de lexposant pour rserver ces codes spciaux (o
les bits de lexposant e00 sont tous 0 ou tous 1) aux deux zros signs et larithmtique tendue
de la norme IEEE. Ainsi, pour les codes normaux, 1 6 e00 6 2E 2, donc 2E1 +2 6 e0 6 2E1 1.

C.2.1

Les nombres normaliss

En binaire, pour les nombres normaliss, le bit de plus fort poids de la mantisse m0 vaut donc 1.
On convient alors de ne pas le stocker pour gagner un bit sur la prcision de la reprsentation ; on
stocke donc la partie fractionnaire f de la mantisse sur M = q 0 = q 1 bits seulement. Mais le
nombre de bits de la mantisse donn par la fonction intrinsque DIGITS est M + 1 = q car il prend
en compte ce bit cach.
00
E1
Ainsi pour les flottants normaliss, r = (1)s 2e 2 +1 1.f o f est la partie fractionnaire
n n+1
de la mantisse. Dans chaque octave [2 , 2
[, il y a 2M nombres reprsents exactement, en
nM
progression arithmtique de raison 2
; cette raison double chaque changement doctave. Si le
successeur de 2n est 2n (1 + 2M ), son prdcesseur est 2n (1 2M 1 ).
Valeurs extrmes
Le plus grand rel normalis positif ainsi reprsentable, donn par la fonction HUGE,
est donc
Pi=M
obtenu pour e00 = 2E 2, soit e0 = 2E1 1 avec p0 = 1 et pi = 1 pour i > 0, soit m0 = i=0 2i =
E1
(1 2M 1 ). Si un calcul donne une valeur absolue suprieure
2(1 2M +1 ). Il vaut donc 22
HUGE(x), il y a thoriquement dpassement de capacit par valeur suprieure (floating overflow).
Le plus petit rel positif normalis ainsi reprsentable, donn par la fonction TINY, est donc
obtenu pour e00 = 1, soit e0 = 2E1 + 2 avec p0 = 1 et pi = 0 pour i > 1, soit f = 0. Il vaut
E1
donc 22 +2 . Si un calcul donne une valeur absolue non nulle mais infrieure TINY(x), il y a
thoriquement dpassement de capacit par valeur infrieure (floating underflow).
Le nombre doctaves de rels positifs est e00max e00min + 1, soit 2E 2.

C.2.2

Les nombres dnormaliss

Mais, quitte perdre en prcision, on peut aussi reprsenter des nombres de valeur absolue
infrieure la plus petite valeur ayant un exposant dcal e00 nul : on travaille alors en virgule
fixe. Si lexposant dcal e00 est nul, les M bits suivants reprsentent exactement la mantisse sans

156

ANNEXE C. LA NORME IEEE 754

bit cach 1 : on dfinit ainsi les nombres dnormaliss. Le plus petit nombre dnormalis positif
E1
(tous les bits 0 sauf le dernier) vaut donc 22 +2M .

10R

EPSILON(1.)
 - +HUGE(1.)

TINY(1.) 0 +TINY(1.)

HUGE(1.)
1

10R

dnormaliss

o R= RANGE(1.)

+10R

+1
 EPSILON(1.)/2

+10R

SPACING(X)

 -

NEAREST(X,-1)

NEAREST(X,+1)

Figure C.1 Reprsentation des rels. Mme si lchelle sapparente une chelle log, celle-ci
nest pas respecte afin de figurer le zro. De plus, successeur (NEAREST(X,1.))et prdcesseur
de X (NEAREST(X,-1.)) sont en gnral gale distance de X (progression arithmtique de raison
SPACING(X) dans chaque octave) sauf si X est la limite dune octave, cest dire une puissance
entire de 2 (dans ce cas le pas est deux fois plus faible du ct de zro).

C.3

Les codes spciaux

Les codes employs pour les valeurs spciales de larithmtique tendue sont caractriss par le
fait que tous leurs bits dexposant sont 1. On note aussi les deux zros signs avec tous les bits
dexposant 0.
+0
-0
quiet NaN > 0
signaling NaN > 0
quiet NaN < 0
signaling NaN < 0
+Inf
-Inf

C.3.1

signe
0
1
0
0
1
1
0
1

exposant
E bits 0
E bits 0
E bits 1
E bits 1
E bits 1
E bits 1
E bits 1
E bits 1

mantisse
M bits zro
M bits zro
1 suivi de (M-1) bits quelconques
0 suivi dau moins 1 bit 1
1 suivi de (M-1) bits quelconques
0 suivi dau moins 1 bit 1
M bits 0
M bits 0

Arithmtique IEEE et options de compilation

Il est cependant ncessaire de choisir les options de compilation adquates pour imposer le
respect de la norme IEEE (voir par exemple E.4.1 p. 168 pour ifort et E.3.1 p. 167 pour pgf95)
dans la propagation des drapeaux indiquant la sortie de larithmtique classique. On peut en effet
constater une grande diversit de comportement par dfaut entre plusieurs compilateurs sur le
simple cas dun calcul dont le rsultat devrait tre indtermin.
PROGRAM nan_indeterm
IMPLICIT NONE
REAL :: zero, infini, indet
zero = 0.
infini = 1./zero
indet = infini * zero ! en principe indtermin

C.4. LE CODAGE IEEE DES FLOTTANTS SUR 32 BITS ET 64 BITS

WRITE(*,*) " 0. ,
1./0.,
WRITE(*,*) zero, infini, indet
END PROGRAM nan_indeterm

157

(1./0.)*0."

diffrences de comportement suivant les compilateurs


et sensiblit aux options IEEE notamment
pgf90 et ifort sans option sont viter
=> "pgf90 -Kieee" et "ifort -fltconsistency"
pgf90 nan_indeterm.f90
0. ,
1./0.,
(1./0.)*0.
0.000000
Inf
0.000000
pgf90 -Kieee nan_indeterm.f90
0. ,
1./0.,
(1./0.)*0.
0.000000
Inf
NaN
ifort nan_indeterm.f90
0. ,
1./0.,
(1./0.)*0.
0.0000000E+00 Infinity
0.0000000E+00
ifort -fltconsistency nan_pgf.f90
(ou "-mp" mais "-mp1" est insuffisnt))
0. ,
1./0.,
(1./0.)*0.
0.0000000E+00 Infinity
NaN
g95 nan_indeterm.f90
0. ,
1./0.,
(1./0.)*0.
0. +Inf NaN
gfortran nan_indeterm.f90
0. ,
1./0.,
(1./0.)*0.
0.000000
+Infinity
NaN
nagfor nan_indeterm.f90
NAG Fortran Compiler Release 5.2(643)
Runtime Error: *** Arithmetic exception: Floating divide by zero - aborting
Abandon

C.4
C.4.1

Le codage IEEE des flottants sur 32 bits et 64 bits


Le codage IEEE des flottants sur 32 bits

Les rels par dfaut sont gnralement stocks sur 32 bits avec 8 bits dexposant et 23 bits plus
un bit 1 non stock pour la mantisse. Le dcalage de lexposant est de 127.
signe
s
1 bit

exposant biais
e00
8 bits
r = (1)s 2e

partie fractionnaire de la mantisse


f = m0 1
23 bits
00

127

1.f o f = m0 1

(C.3)

Pour des flottants sur 32 bits (cf. table C.1, p. 158), la plus petite valeur positive en normalis,
cest--dire le rsultat de la fonction TINY, vaut 2126 soit approximativement 1.175494E-38. La
plus grande valeur, cest--dire le rsultat de la fonction HUGE, est obtenue avec les 23 bits de la
mantisse 1 et le plus grand exposant (7 bits 1 et le dernier 0). Elle vaut 2+127 (2223 ) 2128 ,
soit approximativement 3.402823E+38. Quant la prcision relative, elle est caractrise par la
fonction EPSILON, lcart relatif maximal entre deux flottants successifs, soit 223 1.192093E-7.
Dans chaque octave, de 2n 2n+1 par exemple, il y a 223 , soit environ 8 millions de rels en
progression arithmtique de raison 2n23 . Pour conserver approximativement la prcision relative,
le pas double quand on progresse dune octave en sloignant de zro. Noter que le voisin gauche
de +1., soit NEAREST(+1.,-1.) est deux fois plus proche de +1. que son voisin de droite, soit
NEAREST(+1.,+1.). Enfin, le nombre doctaves 1 de rels positifs normaliss est de 28 2 = 254.
1. Le nombre total de rels normaliss non nuls sur 32 bits est donc 2 223 (28 2), soit 232 225 . Si on y ajoute

158

ANNEXE C. LA NORME IEEE 754

Table C.1 Codage IEEE de quelques valeurs remarquables sur 32 bits


0
1
0
0
0
0
0
0
0
0
0
0
0
f2008

00000000
00000000
00000001
11111110
01111111
01111111
01111111
10000000
10000000
01111111
01111110
00000000
11111111

00000000000000000000000
00000000000000000000000
00000000000000000000000
11111111111111111111111
00000000000000000000000
10000000000000000000000
11000000000000000000000
11111111111111111111111
00000000000000000000000
00000000000000000000001
11111111111111111111111
00000000000000000000001
00000000000000000000000

+0
-0
TINY(1.) 21127 1. = 2126
HUGE(1.) 2254127 2
1 = 2127127
1.5 = 2127127 (1 + 21 )
1.75 = 2127127 (1 + 21 + 22 )
2 223 = NEAREST(2.,-1.)
2
NEAREST(1.,+1.)=1+EPSILON(1.) = 1 + 223
NEAREST(1.,-1.) = 1 224
2127 222 = 2149 (plus petit dnormalis > 0)
+Inf

Pour vrifier le codage binaire, on peut utiliser le format binaire b (cf. 5.4.1, p. 48) des rels :
en criture, il permet de convertir un rel dcimal en binaire et en lecture de convertir du binaire
en rel affich en dcimal.
PROGRAM bin_real
! format B avec des rels = norme 2008
! accepte par gfortran et ifort, pas par g95
IMPLICIT NONE
REAL :: r0 = 1. ! rel par dfaut (32 bits)
CHARACTER(len=32) :: binreal
WRITE(*, *) "mantisse sur",DIGITS(r0),"bits (1 cach)"
! criture d'un rel en binaire
WRITE(*, *) r0
WRITE(*, "(a)") "seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm"
WRITE(*, "(b32.32)") r0
! lecture d'un rel saisi en binaire
!
"seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm"
binreal="00111111100000000000000000000000" ! 1.
READ(binreal, "(b32.32)") r0
WRITE(*, "(es16.9)") r0
END PROGRAM bin_real

C.4.2

Par exemple pour des rels sur 32


bits, le programme bin_real cicontre affiche :
mantisse sur 24 bits (1 cach)
1.
seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm
00111111100000000000000000000000
1.000000000E+00

Le codage IEEE des flottants sur 64 bits

Les rels en double prcision sont gnralement stocks sur 64 bits avec 11 bits dexposant et
52 bits plus un bit 1 non stock pour la mantisse. Le dcalage de lexposant est de 1023.
signe
s
1 bit

exposant biais
e00
11 bits
r = (1)s 2e

partie fractionnaire de la mantisse


f = m0 1
52 bits
00

1023

1.f o f = m0 1

(C.4)

2 223 rels dnormaliss et 2 zros, cela donne 232 224 + 2 valeurs normales, parmi les 232 codes disponibles. Au
contraire, tous les codes sur 32 bits reprsentent des entiers valides, qui sont donc trs lgrement plus nombreux
que les rels sur 32 bits !

C.4. LE CODAGE IEEE DES FLOTTANTS SUR 32 BITS ET 64 BITS

10

159

Avec 64 bits, le domaine stend : TINY vaut 22 +2 = 21022 2.2250738585072014 10308


10
alors que HUGE vaut 22 1 (2 252 ) = 21024 (1 253 ) 1.7976931348623157 10+308 . Mais la
prcision est aussi amliore avec EPSILON=252 2.220446049250313 1016 . Chaque octave
comporte 252 soit environ 4, 51015 rels en progression arithmtique et il y a 211 2, soit 2046
octaves de rels positifs normaliss.
Pour plus dinformations sur la norme IEEE-754, on pourra consulter le site wikipedia (2010)
et le chapitre 9 Arithmtique des ordinateurs de louvrage de Stallings (2003). On pourra
aussi sexercer sur les convertisseurs hexadcimal-IEEE en ligne sur le site Vickery (2009).

Annexe D

Correspondance entre la syntaxe


du fortran 90 et celle du langage C
Avertissement
Les correspondances de syntaxe mises en vidence ici ne signifient absolument pas des fonctionnalits quivalentes dans les deux langages. Par exemple, les chanes de caractres sont traites de
manire diffrente en fortran, o le type intrinsque existe et en C, o elles sont reprsentes par
des tableaux de caractres. Sans chercher lexhaustivit dans lanalogie, elles ont simplement pour
but daider le lecteur familier du langage C viter les erreurs de syntaxe en fortran.

D.1

Dclarations des types de base (cf. 2.1)


fortran 90
INTEGER :: var
REAL :: var
COMPLEX :: var
CHARACTER :: var
LOGICAL :: var

D.2

C89

complments C99

int var;
float var;
char var;

complex var ;
bool var ;

Oprateurs algbriques (cf. 3.1)

addition
soustraction
multiplication
division
lvation la puissance
reste modulo j

fortran 90
+
*
/
**
MOD(i,j) ou MODULO(i,j)
160

langage C
+
*
/
pow(x,y)
%

161

D.3. OPRATEURS DE COMPARAISON

D.3

Oprateurs de comparaison (cf. 3.2)

infrieur
infrieur ou gal
gal
suprieur ou gal
suprieur
diffrent de

D.4

C
<
<=
==
>=
>
!=

Oprateurs logiques (cf. 3.3)

fortran 90
ET
OU
NON
quivalence
OU exclusif

D.5

fortran 90
<
<=
==
>=
>
/=

.AND.
.OR.
.NOT.
.EQV.
.NEQV.

C
C89
&& (valuation minimale)
|| (valuation minimale)
!

C95
and
or
not

Oprations sur les bits (cf. A.6)

Les arguments des fonctions (en fortran) et les oprandes des oprateurs (en C) agissant bit
bit sont des entiers.

fortran 90
NOT(i)
IAND(i, j)
IOR(i, j)
IEOR(i, j)
ISHFT(i, j)
ISHFT(i, -j)

signification
ngation bit bit
et
ou (inclusif)
ou exclusif
dcalage gauche de j bits
dcalage droite de j bits

langage C
~i
i & j
i | j
i ^ j
i << j
i >> j

162

D.6

ANNEXE D. CORRESPONDANCE ENTRE LES SYNTAXES DU FORTRAN ET DU C

Structures de contrle (cf. chap. 4)


fortran 90
IF (expr. log.) THEN
bloc
ELSE
bloc
END IF
SELECT CASE (expr.)
CASE (slecteur)
bloc
CASE (DEFAULT)
bloc
END SELECT
DO entier = dbut, fin[, pas]
bloc
END DO
DO WHILE (expr. log.)
bloc
END DO
CYCLE
EXIT
GO TO tiquette-numr.
RETURN
STOP

D.7

C
if (expr. log.)
bloc
else
bloc
switch ( expr. entire) {
case slecteur :
bloc
break;
default :
bloc
}
for (expr1 ; expr2 ; expr3 )
bloc
while (expr. log.)
bloc
continue;
break;
goto tiquette;
return;
exit;

Pointeurs (cf. chap. 11)

dclarer des pointeurs


dclarer une cible
pointer vers
pointer vers
cible pointe
dissocier un pointeur
tester lassociation
tester lassociation
allouer un pointeur
dsallouer un pointeur
conversion implicite
interdit/dconseill
interdit/dconseill

fortran 90
REAL, POINTER:: ptr, pts
REAL, TARGET:: r
ptr => r
pts => ptr
ptr
ptr => null()
IF(ASSOCIATED(ptr))
IF(ASSOCIATED(ptr, pts))
ALLOCATE(ptr[...])
de plus, associe ptr
DEALLOCATE(ptr)
de plus, dsassocie ptr
pt_real = pt_int
pt_real => entier
pt_real => pt_entier

C
float *ptr, *pts;
float r;
ptr = &r;
pts = ptr;
*ptr
ptr = NULL;
if(ptr != NULL);
if(ptr == pts);
ptr=malloc(...);
ptr=calloc(...);
free(ptr);
ajouter ptr = NULL;
*pt_real = *pt_int
pt_real = &entier
pt_real = pt_entier

163

D.8. FONCTIONS MATHMATIQUES

D.8

Fonctions mathmatiques (cf. A.1, A.2 et A.4)

Les fonctions mathmatiques intrinsques du fortran sont utilisables sans faire appel un
quelconque USE, ni lier explicitement une bibliothque. linverse, pour utiliser les fonctions de la
bibliothque mathmatique en langage C, il est ncessaire dune part dinclure le fichier dentte
math.h et dautre part de lier la bibliothque libm.a. De plus, ces fonctions sont gnriques en
fortran, alors quen C, chaque type utilise une fonction spcifique 1 , do les variantes pour argument
entier (i), double (r), voire complexe (c) en C99, et les sous-variantes pour un argument de type
rel (double par dfaut) suffixes f pour les float, et l pour les long double.
fortran
ABS(a)
ACOS(a)
AIMAG(a)
ASIN(a)
ATAN(a)
ATAN2(a,b)
CEILING(a)
CONJG(a)
COS(a)
COSH(a)
EXP(a)
FLOOR(a)
LOG(a)
LOG10(a)
MOD(a,p)
MODULO(a,p)
NINT(a)
a**b
REAL(a)
SIGN(a,b)
SIN(a)
SINH(a)
SQRT(a)
TAN(a)
TANH(a)
NEAREST(a,s)
fortran 2008
ACOSH(a)
ASINH(a)
ATANH(a)
BESSEL_J0(a)
BESSEL_J1(a)
BESSEL_JN(n,a)
BESSEL_Y0(a)
BESSEL_Y1(a)
BESSEL_YN(n,a)
ERF(a)
ERFC(a)
GAMMA(a)
LOG_GAMMA(a)
HYPOT(a, b)

C89
abs(a) (i) fabs/f/l(a) (r)
acos/f/l(a) (r)
asin/f/l(a) (r)
atan/f/l(a) (r)
atan2/f/l(a,b)
ceil/f/l(a)
cos/f/l(a) (r)
cosh/f/l(a) (r)
exp/f/l(a) (r)
floor/f/l(a)
log/f/l(a) (r)
log10/f/l(a)
a%p si positifs
a%p si positifs
lrint/f/l(a)
pow/f/l(a,b) (r)
sin/f/l(a) (r)
sinh/f/l(a) (r)
sqrt/f/l(a) (r)
tan/f/l(a) (r)
tanh/f/l(a) (r)
C89 (r)
acosh/f/l(a)
asinh/f/l(a)
atanh/f/l(a)
j0/f/l(a)
j1/f/l(a)
jn/f/l(n,a)
y0/f/l(a)
y1/f/l(a)
yn/f/l(n,a)
erf/f/l(a)
erfc/f/l(a)
tgamma/f/l(a)
lgamma/f/l(a)
hypot/f/l(a,b)

C99
cabs(a) (z)
cacos/f/l(a)
cimag/f/l(a)
casin/f/l(a)
catan/f/l(a)

remarques
abs pour les entiers en C

(z)
(z)
(z)
(z)

norme C99

rsultat flottant en C
norme C99

conj/f/l(a) (z)
ccos/f/l(a) (z)
ccosh(a) (z)
cexp/f/l(a) (z)

rsultat flottant en C

clog/f/l(a) (z)
a%p

oprateur en C
oprateur en C
rsultat entier long en C
oprateur en fortran

cpow/f/l(a,b) (z)
creal/f/l(a,b)
copysign/f/l(a,b)
csin/f/l(a) (z)
csinh/f/l(a) (z)
csqrt(a) (z)
ctan/f/l(a) (z)
ctanh/f/l(a) (z)
nextafter/f/l(a,s)
C99 (z) avec tgmath.h
cacosh(a) acosh
casinh/f/l(a) asin
catanh/f/l(a) atanh
les fonctions de Bessel j0,
j1, jn, y0, y1 et yn ne sont
pas standard en C, y
compris dans les normes
C99 ou C2011

remarques
C99 + tgmath.h
C99 + tgmath.h
C99 + tgmath.h
J0 (a)
J1 (a)
Jn (n, a)
Y0 (a)
Y1 (a)
Yn (n, a)
R a t2
2
e
dt
R0
t2
2

dt

(a)
ln(|(a)|)

a2 + b2

1. En C99, il est cependant possible dimplmenter des fonctions mathmatiques gnriques pour les nombres
rels flottants grce au prprocesseur en incluant le fichier tgmath.h.

f2008

164

ANNEXE D. CORRESPONDANCE ENTRE LES SYNTAXES DU FORTRAN ET DU C

D.9

Formats (cf. 5.4.1)

La correspondance entre les spcifications de format en fortran et en C reste trs approximative.

B Les comportements des deux langages pour les entres-sorties sont assez diffrents : en particulier

en criture, lorsque la taille du champ de sortie prcise dans la spcification de format savre
insuffisante pour permettre lcriture, le C prend la libert dtendre cette taille (quitte ne pas
respecter la taille prvue) alors que le fortran refuse de dborder et affiche des caractres * en lieu
et place de la valeur crire.
B
Dautre part, le fortran donne la priorit la liste dentres/sorties sur le nombre de descripteurs
actifs du format, alors que le langage C cherche satisfaire en priorit les descripteurs actifs. En
particulier, si le nombre de descripteurs actifs est infrieur au nombre dentits coder ou dcoder,
le fortran r-explore le format, alors que dans le cas contraire, il ignore les descripteurs actifs
superflus. linverse, en C, si le nombre de descripteurs actifs est infrieur au nombre dlments
de la liste, seuls ceux qui correspondent un descripteur sont cods ou dcods, alors que dans
le cas contraire, les descripteurs actifs superflus provoquent des accs des zones mmoires non
rserves avec des consquences imprvisibles mais souvent plus graves en entre quen sortie.

entier en dcimal
entier en octal
entier en hexadcimal
flottant en virgule fixe
flottant en mantisse et exponentielle
gnral
chane de caractres

fortran
In
I0
On
O0
Zn
Z0
Fn.p
F0.p
En.p
Gn.p
G0
An

C
%nd
%d
%nO
%O
%nX
%X
%n.pf
%f
%n.pe
%n.pg
%g
%n.ps

D.10

Codage des valeurs numriques : domaine et prcision

D.10.1

Domaine des entiers (cf. 2.2.3)


fortran
HUGE(1)
HUGE(1_8)

D.10.2

langage C
Entiers sur 32 bits
2147483647 = 231 1 2 109
Entiers sur 64 bits
9223372036854775807 = 263 1 9 1018

INT32_MAX
INT64_MAX

Domaine et prcision des flottants (cf. 2.2.3)


fortran
HUGE(1.)
TINY(1.)
EPSILON(1.)
HUGE(1.D0)
TINY(1.D0)
EPSILON(1.D0)

langage C
Flottants sur 32 bits
3.402823 10+38
1.175494 1038
1.192093 107
Flottants sur 64 bits
1.7976931348623157 10+308
2.2250738585072014 10308
2.220446049250313 1016

FLT_MAX
FLT_MIN
FLT_EPSILON
DBL_MAX
DBL_MIN
DBL_EPSILON

Annexe E

Compilateurs et options de
compilation
Certains compilateurs fortran sont disponibles sur plusieurs plates-formes comme pgf95 de
Portland ou nagfor (ex-f95) de nag (The Numerical Algorithms Group). Dautres sont plus
spcifiques de certains systmes propritaires, comme xlf sur aix dibm, ou f90, celui de hp
issu de Compaq... lui-mme issu de Digital Equipment Corporation, dont la version pour
linux sur processeur alpha est libre dans le cadre dune licence particulire. Le compilateur ifort
dIntel sous linux (http://www.intel.com/cd/software/products/asmo-na/eng/compilers/
flin/index.htm) est aussi utilisable sans frais pour un usage non commercial.
Enfin, deux compilateurs fortran libres (sur le modle de g77) de la collection de compilateurs
gcc ont t dvelopps :
g95 (http://www.g95.org)
et gfortran (http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gfortran/)
disponibles pour plusieurs plates-formes dont Linux (sur processeurs 32 bits et 64 bits), Windows
et Macintosh OS X.

E.1

Compilateur xlf sous ibm-aix

Le compilateur fortran des machines ibm fonctionnant sous aix 1 ou sur processeur Powerpc sous linux est xlf 2 (voir Manuels Fortran IBM). Pour compiler du fortran 90 au format libre
(cf. 1.4.2, p. 8), il faut utiliser xlf90 ou xlf -qfree=f90. Pour respecter la convention de nommage
*.f90 des fichiers sources au format libre, on doit spcifier loption -qsuffix=f=f90 :
xlf90 -qsuffix=f=f90 <essai >.f90
ou
xlf -qfree=f90 -qsuffix=f=f90 <essai >.f90

E.1.1

Options du compilateur xlf conseilles

Il est conseill de demander au compilateur de signaler les constructions obsolescentes de for-


tran 90 par loption -qlanglvl=90pure :
xlf90 -qlanglvl=90pure -qsuffix=f=f90 <essai >.f90
1. aix est lunix dibm.
2. En 2013, la version 14 de xlf est disponible.

165

166

ANNEXE E. COMPILATEURS ET OPTIONS DE COMPILATION

De plus, au moins dans la phase de mise au point, on peut lui demander de vrifier le nondpassement des bornes des tableaux par loption -qcheck (version longue de loption -C), ainsi
que la compatibilit des arguments passs entre procdures par loption -qextchk.
Enfin, il est prudent de provoquer une interruption de lexcution dans les cas o les calculs en
virgule flottante aboutissent des rsultats non garantis 3 :
ENable : ncessaire pour permettre linterruption la suite dun des problmes suivants
INValid : opration invalide
OVerflow : dpassement de capacit vers le haut (quantit trop grande en valeur absolue pour tre
reprsente sur la machine, car lexposant serait trop grand et positif)
ZEROdivide : division par zro
Cette prcaution est assure en compilant avec loption -qflttrap, suivie des sous-options ncessaires : xlf90 -qflttrap=en:inv:ov:zero
Enfin, loption -qinit=f90ptr permet dimposer aux pointeurs un tat non associ leur
cration, au lieu de ltat indtermin (obtenu par dfaut).
Loption -F fichier.cfg permet de spcifier un fichier de configuration personnel (inspir de
/etc/xlf.cfg qui reprsente la configuration par dfaut) qui rassemble les options choisies.

E.2

Compilateur f95 ou nagfor de NAG

Le compilateur du Numerical Algorithms Group sappelait f95 mais comme le compilateur


gfortran est aussi appel f95, partir de la version 5.2, il sappelle maintenant nagfor (voir
Manuels Fortran NAG). La version 5.3 met en uvre lintgralit du standard 95, presque tout le
fortran 2003 et quelques lments du standard 2008.
Par dfaut, nagfor considre les fichiers sources de suffixes .f90, .f95 et leurs variantes majuscules comme crits au format libre (cf. 1.4.2, p. 8), alors que ceux de suffixes .f, .for .ftn
et leurs variantes majuscules sont supposs au format fixe (cf. 1.4.1, p. 7). Les options -free et
-fixed permettent de spcifier le type de format indpendamment de ces conventions. Dans le cas
du format fixe, on peut augmenter la longueur maximale des lignes de 72 132 caractres avec
loption -132.
Les fichiers sources de suffixe en majuscules sont par dfaut traits par le prprocesseur fpp,
alors que ceux dont le suffixe est en minuscules ne le sont pas par dfaut.
Les options -f95, -f2003 et -f2008 dfinissent le standard de rfrence (fortran 2008 par
dfaut). Les fonctionnalits de niveau suprieur au standard choisi sont simplement signales comme
extensions par des avertissements du compilateur.
Loption -kind= permet de spcifier la numrotation des variantes de type pour les entiers, les
boolens et les flottants :
-kind=sequential (par dfaut) les numrote en squence partir de 1 par taille croissante ;
-kind=byte les numrote avec le nombre doctets utiliss pour le stockage.
Un module f90_kind.f90 fournit un ensemble de variantes de type (KIND) prdfinis.
Loption -nomod empche la production du fichier de module de suffixe .mod.
Loption -convert=, suivie du format choisi, permet de prciser la conversion effectuer sur
les fichiers binaires (cf. note 9, p. 39) ; mais ces choix peuvent se faire plus finement, fichier par
fichier, avec les options de OPEN, ou, lexcution, via des variables denvironnement du type
FORT_CONVERTn , o n est le numro de lunit logique, comme pour gfortran (cf. E.6.1, p. 171)
et ifort.
Avec la version 5.3 est apparue loption -encoding= qui permet de prciser le codage du fichier
source, parmi ISO_Latin_1 (par dfaut), Shift_JIS et UTF_8. Ne pas confondre avec loption
encoding de OPEN pour les entres-sorties sur fichiers texte externes (cf. 5.3.2, p. 43) ni avec les
variantes de type pour les variables de type chane de caractres (cf. 8.1.3, p. 95).
3. Les noms des sous-options peuvent tre abrgs en ne conservant que la partie du mot-clef crite ici en
majuscules.

E.3. COMPILATEUR PGF95 DE PORTLAND

E.2.1

167

Options du compilateur nagfor conseilles

Les options suivantes sont conseilles pour forcer des vrifications complmentaires, au moins
dans la phase de mise au point des programmes :
-C=array signale les dpassements de bornes des tableaux et des chanes de caractres ;
-C=calls vrifie les rfrences aux procdures ;
-C=dangling signale les pointeurs indfinis ;
-C=do signale les boucles do dont le pas est nul ;
-C=recursion signale les rcursivits invalides ;
-nan initialise les variables de type REAL ou COMPLEX NaN (Not A Number), ce qui provoque un
arrt si elles sont utilises avant dtre dfinies.
Cet ensemble doptions peut tre slectionn globalement avec la syntaxe -C=all, laquelle il
est prudent dajouter -C=undefined 4 pour rechercher les variables non dfinies.
Loption -float-store interdit lutilisation de registres de capacit suprieure 64 bits pour
les calculs flottants : en effet lunit de calcul flottant (Floating Processor Unit) effectue bien souvent
les calculs dans des registres de 80 voire 128 bits permettant une prcision et un domaine tendus
pour reprsenter les rsultats intermdiaires. Cette option ne doit tre active qu titre de test car
elle dgrade les performances des programmes mme si elle contribue leur portabilit !
Enfin loption -gline permet de retracer lorigine dune erreur lexcution en indiquant les
lignes de code 5 o elle sest produite. Comme cette option est consommatrice de temps et de place,
on ne lactivera quen cas derreur lexcution et on relancera le programme ainsi recompil pour
analyser lerreur.

E.3

Compilateur pgf95 de Portland

Le groupe Portland commercialise un ensemble de compilateurs C, C++ et fortran ainsi que


des outils de dveloppement et de calcul parallle associs pour diverses plates-formes et systmes
dexploitation. Sous linux, avec des processeurs AMD64 ou IA32/EM64T, on peut utiliser le
compilateur pgf95 (voir Manuels Fortran PGI).
Par dfaut, les fichiers sources de suffixes .f90, .f95 et .f03 sont considrs comme crits au
format libre (cf. 1.4.2, p. 8), alors que ceux de suffixes .f, .for et .ftn sont supposs au format
fixe (cf. 1.4.1, p. 7). Les options -Mfreeform et -Mnofreeform permettent de spcifier le type de
format indpendamment de ces conventions. Enfin, loption -Mnomain spcifie lors de ldition de
lien que le programme principal nest pas en fortran (cf. chapitre 12, p. 129).

E.3.1

Options du compilateur pgf95 conseilles

Pour compiler des procdures rcursives, il est ncessaire de prciser loption -Mrecursive, car
loption par dfaut est -Mnorecursive. Par dfaut, les variables locales ne sont pas sauvegardes
dun appel lautre (option -Mnosave). Le stockage statique des variables locales peut tre vit
avec loption -Mrecursive.
Les options suivantes sont conseilles pour signaler aider crire un code robuste, au moins
dans la phase de mise au point des programmes :
-Mdclchk requiert que toutes les variables soient dclares (loption par dfaut est -Mnodclchk) ;
-Mstandard demande au compilateur de signaler les carts la syntaxe du fortran standard selon
la norme choisie ;
-Minform=inform choisit le niveau maximum dinformation (erreurs, avertissements et informations)
-Mbounds signale les dpassements de bornes des tableaux et des chanes de caractres.
4. Une procdure compile avec loption -C=undefined peut ne pas tre compatible avec une procdure compile
sans cette option. De plus, cette option est incompatible avec les fonctions rsultat allouable.
5. En remontant dans la hirarchie des appels de procdures.

168

ANNEXE E. COMPILATEURS ET OPTIONS DE COMPILATION

De plus, loption -Mallocatable=95 ou -Mallocatable=03 permet de choisir le comportement des affectations de variables allouables : allocation pralable ncessaire en fortran 95 ou
(r-)allocation implicite en fortran 2003 (cf. 7.5.4, p. 93).
Par ailleurs, loption -Mbyteswapio permet dintervertir lordre des octets dans les entressorties sur des fichiers binaires (conversion litte endian vers big-endian et rciproquement) (cf. note 9,
p. 39).
Enfin loption -Ktrap=fp force linterruption en cas de problme doprations en flottant (division par zro, opration invalide, dpassement de capacit) lexcution. On peut aussi activer
loption -Kieee pour respecter la norme IEEE 754 (cf. annexe C, p. 154) lors des calculs en
flottant, au prix ventuel dun moins bon temps de calcul.

E.4

Compilateur ifort dIntel

Sous linux, avec des processeurs intel ou compatibles, on peut utiliser le compilateur ifort
(voir Manuels Fortran Intel), disponible gratuitement sous conditions pour un usage non commercial.
Par dfaut, les fichiers sources de suffixes 6 .f90 sont considrs comme crits au format libre
(cf. 1.4.2, p. 8), alors que ceux de suffixes .f, .for et .ftn sont supposs au format fixe (cf. 1.4.1,
p. 7). Les options -free et -fixed permettent de spcifier le type de format indpendamment
de ces conventions. Les options -i8 et -r8 permettent de promouvoir respectivement les variables
entires par dfaut en 64 bits et les variables relles par dfaut en double prcision (64 bits). De plus
loption -fpconstant permet de promouvoir les constantes relles par dfaut en double prcision
si elles sont affectes des variables double prcision. Enfin, loption -nofor-main spcifie lors de
ldition de lien que le programme principal nest pas en fortran (cf. chapitre 12, p. 129).

E.4.1

Options du compilateur ifort conseilles

Le stockage statique des variables locales peut tre vit avec loption -automatic, -nosave ou
-auto. Pour compiler des procdures rcursives, il est ncessaire de prciser loption -recursive
(qui implique -automatic), car loption par dfaut est -norecursive.

Les options suivantes sont conseilles pour signaler des erreurs lexcution, au moins dans la
phase de mise au point des programmes :
-stand f90 ou -stand f95 ou -stand f03 demande au compilateur de signaler tous les carts
la syntaxe du fortran standard selon la norme choisie ;
B
Noter ce propos que malgr le choix de la norme 2003, le compilateur ifort ne met pas
en uvre lallocation automatique par affectation (cf. 7.5.4, p. 93) : il faut ajouter loption
-assume realloc_lhs.
-warn declarations ou -implicitnone signale les identifiants utiliss sans tre dclars (typage
implicite) ;
-warn uncalled signale les fonctions qui ne sont jamais appeles ;
-warn unused signale les variables dclares mais jamais utilises ;
-warn all demande dmettre tous les avertissements que le compilateur peut diagnostiquer (cela
implique notamment -warn declarations, -warn uncalled, -warn unused, ...)
-check bounds ou -CB signale les dpassements de bornes des tableaux et des chanes de caractres ;
-check format dtecte une inconsistance entre une valeur et son format de sortie ;
-check all ou -C permet de spcifier globalement toutes les vrifications du type -check
-diag-error-limit1 permet darrter la compilation la premire erreur.
-traceback ajoute dans le code objet des informations complmentaires permettant, en cas derreur grave, de retrouver la ligne de code, la procdure et le fichier source associs afin de
localiser lorigine de lerreur.
6. Contrairement dautres compilateurs, ifort nadmet ni le suffixe .f95 ni le suffixe .f03 pour des sources au
standard fortran 95 ou 2003.

E.5. COMPILATEUR G95

169

-assume byterecl permet dexprimer les longueurs des enregistrements (argument RECL de OPEN
et INQUIRE) des fichiers non-formats en octets, au lieu des mots longs de 4 octets par dfaut.
Enfin loption -ftrapuv qui initialise les variables alloues sur la pile des valeurs invalides
peut permettre de dtecter des dfauts dinitialisation.
Dautre part, loption -fltconsistency, ou -mieee-fp requiert des calculs en virgule flottante
plus portables et conformes la norme ieee (cf. exemple C.3.1, p. 156), au prix dune perte de
performances, de la mme faon que loption -ffloat-store de gfortran. Elle limite par exemple
certaines optimisations du compilateur affectant lordre des oprations et respecte la prcision des
calculs associ au type des variables.
Par ailleurs, lalignement des types drivs (sans attribut SEQUENCE ou BIND, cf. 9.1.1, p. 103)
par des octets de remplissage est conditionn par les options :
-noalign records pour viter le remplissage ;
-align records pour forcer lalignement sur des frontires de mots ;
-align recnbyte pour aligner sur un nombre n doctets, o n peut valoir 1, 2, 4, 8 ou 16.
Des variables denvironnement permettent de spcifier le contexte dexcution des programmes
compils avec ifort. Parmi celles-ci, on notera celle qui permet de dsigner lordre des octets (cf.
note 9, p. 39) dans la reprsentation des donnes binaires : F_UFMTENDIAN. Elle permet dindiquer
(sous diverses formes) la liste des numros dunits logiques pour lesquels les entres/sorties se
feront avec conversion entre little et big, sachant que le format par dfaut est little sur les
processeurs o ce compilateur fonctionne.

E.5

Compilateur g95

Le compilateur g95 (voir Vaught, 2009) est issu de gcc 7 , la collection de compilateurs du GNU,
capable de compiler les langages C, C++, Objective-C, Fortran, Java, et Ada. Plus prcisment,
il sappuie sur gcc, suit sa syntaxe et admet donc ses options gnrales, mais propose aussi des
options spcifiques pour le langage fortran.
Par dfaut, les fichiers sources de suffixes .f90, .f95, .f03 et leurs variantes majuscules sont
considrs comme crits au format libre (cf. 1.4.2, p. 8), alors que ceux de suffixes .f, .for et
leurs variantes majuscules sont supposs au format fixe (cf. 1.4.1, p. 7). Les options -ffree-form
et -ffixed-form permettent de spcifier le type de format indpendamment de ces conventions.
Dans le cas du format fixe, on peut prciser la longueur maximale des lignes avec les options
-ffixed-line-length-80 ou -ffixed-line-length-132.
Les fichiers sources de suffixe en majuscules sont par dfaut traits par le prprocesseur du C,
alors que ceux dont le suffixe est en minuscules ne le sont pas par dfaut.
Avec loption -fmod=, il est possible de fixer le rpertoire o seront crs les fichiers .mod
de module lors de la compilation. On pourra lassocier avec loption -I qui permet dajouter un
rpertoire au chemin de recherche des fichiers de module.
Loption -M permet laffichage des dpendances des fichiers objets et fichiers de module, en vue
de la rdaction du fichier makefile :
g95 -M <fichier.f90 > affiche les dpendances du fichier <fichier.o >.
Enfin, une liste de variables denvironnement (prfixes par G95_) permet dadapter lenvironnement dexcution des programmes compils par g95. Lavantage de tels rglages par rapport
aux options de compilation est quils peuvent tre modifis une fois lexcutable cr et ajusts a
posteriori lors de lexploitation. On peut connatre les valeurs de ces variables denvironnement en
lanant lexcutable produit par g95 avec loption --g95. Ces variables concernent notamment les
entres/sorties, avec, entre autres (cf. 5.2.1, p. 38) :
G95_STDIN_UNIT de type entier qui permet de choisir le numro de lunit logique prconnecte lentre standard ;
G95_STDOUT_UNIT de type entier qui permet de choisir le numro de lunit logique prconnecte la sortie standard ;
7. En fait, le dveloppement dun compilateur fortran 90 au sein de gcc est en cours sous le projet gfortran
(cf. E.6, p. 171). Mais un des anciens membres de lquipe de gfortran a entrepris un dveloppement en parallle
qui a abouti plus rapidement avec g95. Cependant g95 semble maintenant fig depuis aot 2010.

170

ANNEXE E. COMPILATEURS ET OPTIONS DE COMPILATION

G95_STDERR_UNIT de type entier qui permet de choisir le numro de lunit logique prconnecte la sortie derreur standard ;
G95_COMMA de type boolen qui permet de choisir la virgule comme sparateur dcimal
(cf. 5.3.2, p. 43) ;
G95_ENDIAN de type chane de caractres et de valeurs possibles BIG, LITTLE, SWAP ou NATIVE
(par dfaut), qui permet de choisir lordre des octets (cf. note 9, p. 39) dans la reprsentation
des donnes pour les lectures et critures de fichiers binaires.

E.5.1

Options du compilateur g95 conseilles

Le stockage statique des variables locales peut tre vit avec loption -fno-static.
Il est possible de demander au compilateur dinterdire tous les carts la syntaxe du fortran
standard avec loption -std=f95 8 ou -std=f2003. Cette option exclut lemploi des procdures
intrinsques non standard, telles que la fonction system qui permet de lancer des commandes
du systme dexploitation depuis le fortran. Mais des options 9 sont prvues pour autoriser
toutes ou partie seulement des extensions intrinsques tout en respectant le standard par
ailleurs.
Loption -Wimplicit-none permet de signaler toutes les variables non dclares. Loption
-fimplicit-none interdit lusage de variables non dclares.
Si on souhaite tre inform quune variable a t dclare, mais nest pas utilise 10 , il faut
prciser loption -Wunused.
linverse, loption -Wunset avertit quand on nattribue pas de valeur une variable, ce qui
est suspect si elle est utilise.

Afin de bnficier au mieux de lanalyse du code faite par le compilateur, il est utile de lui demander
la plupart des avertissements disponibles : on utilise cet effet loption -Wall qui regroupe les avertissements plus importants et on peut ajouter -Wextra pour activer notamment -Wmissing-intent
et -Wobsolescent.

Les options suivantes sont conseilles pour signaler des erreurs lexcution, au moins dans la
phase de mise au point des programmes :
-fbounds-check signale les dpassements de bornes des tableaux et des chanes de caractres ;
-ftrapv provoque une erreur lors dun dpassement de capacit dans les oprations daddition, de
soustraction et de multiplication.
-freal=nan initialise les variables scalaires relles et complexes (non explicitement initialises)
not a number, produisant des erreurs de calcul si on les utilise sans leur attribuer dautre
valeur.
-fpointer=null initialise les pointeurs scalaires (non explicitement initialiss) null()
-ftrace=full permet retrouver le numro de ligne dune ventuelle erreur arithmtique, mais
ralentit lexcution.
-ffloat-store interdit lutilisation de registres de capacit suprieure pour les calculs flottants :
en effet lunit de calcul flottant (Floating Processor Unit) effectue bien souvent les calculs
dans des registres de 80 voire 128 bits permettant une prcision et un domaine tendus pour
reprsenter les rsultats intermdiaires. Cette option ne doit tre active qu titre de test
car elle dgrade les performances des programmes mme si elle contribue leur portabilit !
8. On peut cependant dans ce cas autoriser certaines extensions relevant du standard 2003. En particulier lallocation de tableaux dynamiques arguments de procdures (cf. 7.5.3, p. 92) et les tableaux allouables dans les structures
(cf. 9.5, p. 106) en ajoutant loption -ftr15581.
9. Loption -fintrinsic-extensions permet daccder toutes les fonctions intrinsques de g95 alors que
-fintrinsic-extensions= permet de spcifier la liste explicite des fonctions intrinsques non-standard (par exemple
les fonctions GAMMA, ERF, ERFC... et aussi la fonction system) accepter en exigeant par ailleurs le respect dun
standard.
10. Ces avertissements peuvent paratre au premier abord superflus, en particulier dans la phase de mise au point
du code. Mais ils peuvent permettre de dcouvrir des erreurs de codage de faon assez subtile, comme dans cet
exemple, vcu par un tudiant : en signalant que, dans lexpression x**(1/3), la variable x est en fait inutilise, le
compilateur g95 a permis de dtecter une grossire erreur de codage dans le calcul de la racine cubique. La division
1/3 tant ici programme en entier, elle donne un exposant nul, rendant lexpression indpendante de x car x0 = 1.

E.6. COMPILATEUR GFORTRAN

171

-fone-error peut tre active pour arrter la compilation ds la premire erreur, vitant ainsi
lavalanche de messages concernant les erreurs provoques par exemple par une dclaration
inexacte.
G95_MEM_INIT=NAN cette variable denvironnement permet de choisir dinitialiser la mmoire alloue de faon dynamique, par exemple Not A Number, quitte ralentir lallocation.
En pratique, sur les postes clients linux de lUTES, des alias ou des fonctions du shell g95-mni
et g2003-mni ont t dfinis pour activer simplement les options conseilles.
Pour plus de dtails, consulter le manuel du compilateur, maintenant disponible en ligne
(Vaught, 2006), y compris traduit en franais (http://ftp.g95.org/G95Manual.fr.pdf).

E.6

Compilateur gfortran

Le compilateur gfortran fait partie de gcc 11 , la collection de compilateurs du GNU, capable de


compiler les langages C, C++, Objective-C, Fortran, Java, et Ada. Plus prcisment, il sappuie
sur gcc, suit sa syntaxe et admet donc ses options gnrales, mais propose aussi quelques options
spcifiques pour le langage fortran.
Les deux compilateurs gfortran et g95, bien que suivant un dveloppement spar, proposent
des fonctionnalits similaires et lon ne dtaillera donc pas ici celles de gfortran, laissant le lecteur
se reporter la documentation en ligne (Site gfortran, de la collection de compilateurs gcc).
Noter que les fichiers de module de gfortran comportent un numro de version li (mais
diffrent de) la version du compilateur. De plus, partir de la version 4.9, les fichiers de module
de gfortran sont compresss avec gzip.

E.6.1

Options du compilateur gfortran conseilles

Par dfaut, les variables locales sans lattribut SAVE des procdures ne sont pas stockes en
statique mais sur la pile, sauf si elles dpassent une taille spcifie en octets par loption
-fmax-stack-var-size (dfaut 32768). Loption -frecursive empche leur stockage en
mmoire statique.
Loption -fimplicit-none interdit le typage implicite des variables comme le fait linstruction IMPLICIT NONE.
Loption -std=f95, -std=f2003 ou -std=f2008 permet dexiger un code conforme la
norme fortran 95, fortran 2003 ou fortran 2008. Les carts la norme requise gnrent
des erreurs et les instructions obsolescentes sont signales par des avertissements. Cette option exclut lemploi des procdures intrinsques non standard, sauf si on ajoute loption B
-fall-intrinsics 12 qui autorise toutes les procdures intrinsques qui sont des extensions
la norme (comme GAMMA, ERF, ERFC... qui font partie du standard fortran 2008). Par ailleurs,
partir de la version 4.6, gfortran permet lallocation dynamique implicite par affectation
(cf. 7.5.4, p. 93) si le standard demand est 2003 ou 2008, mais il est possible de linhiber
avec loption -fno-realloc-lhs ou de lautoriser en standard 95 avec -frealloc-lhs.
Loption -fmax-errors=n peut tre active pour arrter la compilation ds la ne erreur, vitant ainsi lavalanche de messages concernant les nombreuses erreurs provoques par exemple
par une dclaration inexacte.
Loption -fbacktrace permet dafficher la hirarchie des appels avec les numros de ligne en
cas derreur lexcution.
Les options suivantes initialisent respectivement les entiers -finit-integer=<n >, les rels
et les complexes -finit-real=nan, par exemple Not a Number de signalisation.
11. En fait, cest le compilateur fortran 90 officiel de gcc et il a atteint un degr de dveloppement comparable
g95 (cf. E.5, p. 169). Il est maintenant distribu avec les outils de dveloppement dans la plupart des distributions
linux (http://gcc.gnu.org/wiki/GFortranBinaries). Noter quil est parfois accessible sous le nom f95.
12. Avec g95, il est possible de spcifier la liste des procdures non standard autorises, cf. E.5.1, p. 170.

172

ANNEXE E. COMPILATEURS ET OPTIONS DE COMPILATION

On conseille, pour la compilation, les options -Wall qui requirent des avertissements classiques
et -W pour des avertissements complmentaires. Pour la mise au point, -fbounds-check 13 ou (
partir de la version 4.5) -fcheck=bounds active la vrification des bornes des tableaux lexcution.
Noter que loption -Wconversion, qui signale les conversions implicites induites par les oprateurs (cf. 3.1.3, p. 22), peut savrer trop bavarde pour tre utilise systmatiquement, si on
ne simpose pas de rendre toutes ces conversions explicites pour viter dalourdir les codes. On
peut lajouter ponctuellement pour localiser les conversions implicites dans des codes sensibles aux
erreurs numriques de conversion.
Loption -ffloat-store de gcc a le mme effet (cf. exemple C.3.1, p. 156), quavec g95
(cf. E.5.1).
Si lon dispose dune version optimise de la bibliothque blas (Basic Linear Algebra Subroutines), comme par exemple OpenBlas (cf. http://xianyi.github.com/OpenBLAS/), il est
possible de dlguer les calculs de MATMUL cette bibliothque dans le cas des tableaux de taille
importante, avec loption -fexternal-blas. Le compilateur gnre alors un appel blas si la
taille des matrices est suprieure ou gale 30 par dfaut, seuil qui peut tre modifi via loption
-fblas-matmul-limit=n.
Loption -static impose une dition de liens statique, pour produire un excutable autonome ; en effet, de nombreux environnements fonctionnent aujourdhui par dfaut avec des bibliothques dynamiques partageables. Sil sagit simplement de produire un excutable embarquant
la version statique des objets issus de la bibliothque du fortran, on peut se contenter de loption
-static-libgfortran, qui produit cependant un excutable li dynamiquement, mais ne requiert
plus la bibliothque du fortran au chargement, comme on peut le vrifier avec ldd.
Avec loption -J, suivie du chemin dun rpertoire, il est possible de fixer le rpertoire o seront
crs les fichiers .mod de module lors de la compilation. On pourra lassocier avec loption -I
qui permet dajouter un rpertoire 14 la liste des chemins de recherche des fichiers de module
requis par linstruction USE. Cest une option ncessaire pour utiliser les fichiers de module dune
bibliothque fortran installe en dehors des rpertoires standard.
Il est possible de limiter ladjonction doctets de remplissage destins respecter des contraintes
dalignement dans les types drivs (cf. 9.1.1, p 103) avec loption -fpack-derived.
On notera que les variables denvironnement qui permettent dajuster le comportement de
lexcutable sont ici prfixes par GFORTRAN_ au lieu de G95_. De plus, le choix de lordre des octets
dans les fichiers binaires (cf. note 9, p. 39) peut se faire unit logique par unit logique grce la
variable GFORTRAN_CONVERT_UNIT, comme avec ifort (cf. E.4.1, p. 168).

E.7
E.7.1

Options de compilation contrlant le nombre doctets


des types numriques intrinsques
Options passant sur 64 bits les entiers par dfaut
processeur
32 bits
64 bits
32/64 bits
32/64 bits
32/64 bits
32/64 bits
64 bits (alpha)
64 bits (power PC)

compilateur
g95
g95
gfortran
nagfor (nag)
pgf95 (portland)
ifort (intel)
f90 (hp)
xlf (ibm)

option
-i8/-d8
par dfaut
-fdefault-integer-8
-double
-i8
-integer_size 64 ou -i8
-integer_size 64
-qintsize=8

13. partir de la version 4.5 -fbounds-check est un alias obsolescent de -fcheck=bounds.


14. Loption -I permet aussi de complter la liste des chemins de recherche des fichiers dentte pour le C.

173

E.8. QUIVALENCES DES OPTIONS ENTRE LES COMPILATEURS

E.7.2

Options passant sur 64 bits les rels par dfaut


processeur
32/64 bits
32/64 bits
32/64 bits
32/64 bits
32/64 bits
64 bits (alpha)
64 bits (power PC)

E.8

compilateur
g95
gfortran
nagfor (nag)
pgf95 (portland)
ifort (intel)
f90 (hp)
xlf (ibm)

option
-r8/-d8
-fdefault-real-8
-r8/-double
-r8
-real_size 64 ou -r8
-real_size 64
-qrealsize=8

quivalences approximatives des options entre les compilateurs

Ce tableau rcapitule les principales options dont les noms diffrent selon les compilateurs. Il ne
sagit que dun aide-mmoire grossirement simplifi pouvant aider migrer des applications dun
compilateur un autre : les correspondances sont parfois assez approximatives et on se rfrera
aux manuels respectifs pour sassurer dans le dtail de leffet de chaque option.
gfortran
-ffloat-store
-fmax-errors=1
-std=f95
-std=f2003
-realloc-lhs
-fckeck=bounds
-fimplicit-none
-static

g95
-ffloat-store
-fone-error
-std=f95
-std=f2003
-fbound-checks
-fimplicit-none

ifort
-fltconsistency
-diag-error-limit1
-std f95
-std f03
-assume realloc_lhs
-check bounds
-implicitnone
-nofor-main
-Bstatic

nagfor

-f95
-f2003
-C=array
-u
-Bstatic

pgfortran
-Kieee

-Mallocatable=03
-Mbounds
-Mdclchk
-Mnomain
-Bstatic

Bibliographie
Adams, Jeanne, Walter Brainerd, Richard Hendrickson, Richard Maine, Jeanne
Martin et Brain Smith, The Fortran 2003 Handbook : The Complete Syntax, Features and
Procedures, 712 pages (Springer, 2009), ISBN 978-1846283789.
Akin, Ed, Object-oriented programming via fortran 90/95, 360 pages (Cambridge University Press,
2003), ISBN 0-521-52408-3.
Cet ouvrage prsente les aspects programmation oriente objet du fortran 90/95 au travers de nombreux
exemples comments. Il comporte des tableaux synthtiques mettant en parallle les syntaxes du fortran,
du C++ et de matlab ainsi quune annexe rsumant succintement le langage fortran 90.

Chapman, Stephen J., Fortran 95/2003 for Scientists and Engineers, 974 pages (Mc Graw-Hill,
2007), 3e dition, ISBN 978-0-07-319157-7.
La troisime dition de ce livre est un des rares ouvrages qui prsente dlibrment le fortran du standard
2003, tout en distinguant explicitement par la prsentation les lments non disponibles dans le standard
fortran 95. Toutefois, linteroprabilit avec le C nest pas aborde. Contrairement Metcalf et al.
(2004), il peut tre abord par des dbutants car lapproche est progressive et assortie de nombreux
conseils, exemples et exercices.

Chivers, Ian et Jane Sleightholme, Introduction to Programming with Fortran With Coverage
of Fortran 90, 95, 2003, 2008 and 77, 619 pages (Springer, 2012), 2e dition, ISBN 978-0-85729232-2.
Clerman, Norman S. et Walter Spector, Modern fortran : Style and Usage, 360 pages (Cambridge University Press, 2011), ISBN 978-0521514538.
Comme son titre lindique, cet ouvrage prsente des rgles de bon usage du fortran 2003 aussi bien
dans lcriture du code (nommage, mise en page, ...) que dans sa documentation. Il sadresse donc un
public possdant dj une certaine exprience du langage.

1.3.2, 1.4.2
Corde, Patrick et Herv Delouis, Langage Fortran (F2003), Institut du Dveloppement et
des Ressources en Informatique Scientifique (IDRIS) CNRS, 2012, URL : http://www.idris.
fr/data/cours/lang/fortran/choix_doc.html.
Un des rares documents en franais prsentant les nouveauts du fortran 2003 par rapport au fortran 95,
en une srie de 246 transparents. Linter-oprabilit entre le fortran et le langage C et surtout les aspects
objet du fortran 2003 y sont tudis en dtail.

Corde, Patrick et Herv Delouis, Langage Fortran (F95-2), Institut du Dveloppement et


des Ressources en Informatique Scientifique (IDRIS) CNRS, 2013, URL : http://www.idris.
fr/data/cours/lang/fortran/choix_doc.html.
Une srie de 288 transparents issus des cours de lidris prsentant les aspects avancs du langage
fortran 95. Cette prsentation suppose une connaissance pralable des notions de base, prsentes dans la
partie (F95-1), Fouilloux et Corde (2013). Des exercices sont disponibles en ligne, au format .tar.gz

E.8
174

BIBLIOGRAPHIE

175

Delannoy, Claude, Programmer en Fortran 90 Guide complet, 413 pages (Eyrolles, 1997), ISBN
2-212-08982-1.
crit par un auteur bien connu pour le succs de ses nombreux ouvrages sur les langages de programmation, ce livre prsente le fortran 90 de faon progressive et concise. Il est accompagn dexemples et
dexercices corrigs, et peut constituer un trs bon manuel dapprentissage. Depuis 2015, on lui prfrera
la deuxime dition (Delannoy (2015)) qui couvre une partie des standards 2003 et 2008.

E.8
Delannoy, Claude, Programmer en Fortran : Fortran 90 et ses volutions Fortran 95, 2003
et 2008, 480 pages (Eyrolles, 2015), deuxime dition, ISBN 978-2-212-14020-0.
Deuxime dition de louvrage de 1997 (Delannoy (1997)), qui sarrtait fortran 95, cet ouvrage
aborde maintenant les standards 2003 et 2008 dans son annexe I , ainsi que la programmation oriente
objet avec fortran 2003 dans son annexe H.

E.8
Dubesset, Claude et Jean Vignes, Les spcificits du Fortran 90, 367 pages (ditions Technip,
1993), ISBN 2-7108-0652-5.
Cet ouvrage en franais sadresse avant tout ceux qui connaissent dj le fortran 77. Il prsente avec
beaucoup de prcision et de clart les apports de la norme fortran 90. Il est dot de prcieuses annexes
et notamment dun lexique et dun glossaire.

Fouilloux, Anne et Patrick Corde, Langage Fortran (F95-1), Institut du Dveloppement et


des Ressources en Informatique Scientifique (IDRIS) CNRS, 2013, URL : http://www.idris.
fr/data/cours/lang/fortran/choix_doc.html.
Une srie de 261 transparents rcemment rviss des cours de lidris prsentant les notions de base
du langage fortran 95. Les notions avances sont prsentes dans la partie (F95-2), Corde et Delouis
(2013). Des exercices sont disponibles en ligne, au format .tar.gz.

E.8
Lignelet, Patrice, Manuel complet du langage Fortran 90 et Fortran 95 : calcul intensif et gnie
logiciel, 314 pages (Masson, 1996), ISBN 2-225-85229-4.
Au del du langage fortran, cet ouvrage en franais dun auteur de nombreux ouvrages dans ce domaine,
aborde les questions de calcul numrique, de vectorisation et de gnricit.

Manuel Fortran DEC, Digital Fortran, Langage Reference Manual, Digital Equipment Corporation,
Maynard, Massachusetts, USA, 1997.
Le manuel papier du compilateur f90 de Digital Equipment Corporation, repris successivement par
Compaq, puis par hp. Trs bien prsent, il distingue clairement les extensions propritaires de la norme
du fortran 90.

Manuels Fortran IBM, XL Fortran for AIX, Langage Reference and Users Guide, IBM, 8200
Warden Avenue, Markham, Ontario, Canada, 2005, URL : http://publib.boulder.ibm.com/
infocenter/comphelp/. E.1
Manuels Fortran Intel, Intel Fortran Compiler Documentation, Intel Corporation, 2010,
URL : http://software.intel.com/sites/products/documentation/hpc/compilerpro/
en-us/fortran/lin/compiler_f/index.htm.
Site dintel qui prsente un manuel en ligne du compilateur ifort.

E.4
Manuels Fortran NAG, NAGWare Fortran 95 Compiler, Numerical Algorithms Group, The Numerical Algorithms Group Ltd, Wilkinson House, Jordan Hill Road, Oxford, OX2 8DR, UK, 2011,
URL : http://www.nag.co.uk/nagware/np.asp.
Site du Numerical Algorithms Group permettant daccder aux pages de manuel en ligne du compilateur nagfor (ex f95) et des modules associs.

176

BIBLIOGRAPHIE

E.2
Manuels Fortran PGI, PGI Fortran Compiler, The Portland Group, The Portland Group, STMicroelectronics, Two Centerpointe Drive, Suite 320, Lake Oswego, OR 97035, 2011, URL : http:
//www.pgroup.com/resources/docs.htm.
Site de The Portland Group, permettant daccder au manuel de rfrence du compilateur fortran
PGI au format pdf.

E.3
Markus, Arjen, Modern fortran in Practice, 253 pages (Cambridge University Press, 2012), ISBN
978-1-107-60347-9.
Marshall, A.C., J.S. Morgan et J. L. Schofelder, Fortran 90 Course Notes, The University
of Liverpool, 1997, URL : http://www.liv.ac.uk/HPC/F90page.html.
Le site de lUniversit de Liverpool propose une srie de cours de diffrents niveaux sur le fortran 90 :
les documents associs (transparents, notes, exercices, codes ...) sont accessibles via ftp lurl ftp:
//ftp.liv.ac.uk/pub/F90Course/.

Metcalf, Michael, Fortran 90/95/HPF information file, 2004, URL : http://www.fortran.


com/metcalf.htm.
Site dressant un inventaire des ressources sur fortran 90/95 (compilateurs, livres, cours, logiciels, ...).
M. Metcalf a maintenu ce site jusquen septembre 2004, date laquelle il a t fig, dans la perspective
de la norme fortran 2003.

Metcalf, Michael, John Reid et Malcolm Cohen, Fortran 95/2003 explained, 434 pages
(Oxford University Press, 2004), 3e dition, ISBN 0-19-852693-8.
Rdige par des promoteurs des nouveaux standards du fortran, la troisime dition de ce livre est un des
rares ouvrages qui aborde les apports du fortran 2003. Il constitue une rfrence majeure dans ce domaine.
Les apports de la norme fortran 2003 y sont prsents dans les 7 derniers chapitres, permettant ainsi
de les sparer de la norme fortran 95. Il aborde notamment linteroprabilit avec le C. Cette rfrence
nest cependant pas conseille pour dbuter.

E.8
Metcalf, Michael, John Reid et Malcolm Cohen, Modern Fortran explained, Numerical
Mathematics and Scientific Computation, 488 pages (Oxford University Press, 2011), 4e dition,
ISBN 978-019-960142-4.
La quatrime dition de ce classique est le premier ouvrage aborder la norme 2008 du fortran. Succdant
ldition Metcalf et al. (2004) sur le fortran 2003, cette version rvise comporte notamment un
chapitre sur les co-tableaux (coarrays) et un sur les nouveauts du fortran 2008. Cette rfrence nest
cependant pas conseille pour dbuter et rares sont encore les compilateurs honorer la norme 2008.

1.1, 4.5
Nyhoff, Larry R. et Sandfird C. Leestma, Fortran 90 for Engineers and Scientists, 1070
pages (Prentice-Hall, 1997), ISBN 0-13-6571209-2.
Un ouvrage volumineux mais trs bien illustr avec des applications concrtes dans le domaine du calcul
scientifique. Sa prsentation trs progressive permet de lutiliser pour dcouvrir le fortran 90 y compris
comme premier langage de programmation.

Olagnon, Michel, Traitement des donnes numriques avec Fortran 90, 244 pages (Masson,
1996), ISBN 2-225-85259-6.
Cet ouvrage ne prsente pas le langage fortran en tant que tel, mais des mthodes de traitement des
donnes (en particulier statistiques) mises en uvre en fortran 90. Cette approche pragmatique sappuyant sur de nombreux exemples permet daborder rapidement les applications tout en respectant les
rgles de bon usage du langage.

BIBLIOGRAPHIE

177

Press, William H., Saul A. Teukolsky, William T. Vetterling et Brain P. Flannery,


Numerical Recipes in Fortran 90, 551 pages (Cambridge University Press, 1996), 2e dition, ISBN
0-521-57439-0.
Une rfrence trs classique en analyse numrique, aussi disponible dans dautres langages (pascal, C et
C++). Bien la distinguer du manuel Numerical Recipes in Fortran 77 qui comporte la discussion des
algorithmes et leur mise en uvre en fortran 77 et constitue le volume 1 du trait. Le volume 2 prsente
les codes associs en fortran 90, mais aussi dans son premier chapitre (21) une trs prcieuse introduction
aux fonctionnalits du fortran 90. Noter enfin que les chapitres de cet ouvrage sont consultables en ligne :
http://www.library.cornell.edu/nr/

Site gfortran, de la collection de compilateurs gcc, Documentation de gfortran, Free Software Foundation, 2011, URL : http://gcc.gnu.org/onlinedocs/gfortran/. A, E.6
Stallings, W., Organisation et architecture de lordinateur, 829 pages (Pearson Education, 2003),
sixime dition, ISBN 9782744070075. 2.2, C.4.2
Vaught, Andy, Manuel de g95, 2006, URL : http://ftp.g95.org/G95Manual.pdf. E.5.1
Vaught, Andy, Documentation de g95, 2009, URL : http://www.g95.org/docs.html.
Le site du compilateur libre g95 do il est possible de tlcharger les binaires pour les diffrentes
architectures. Ce site comporte des liens vers la documentation. Il liste les bibliothques qui ont t
compiles avec succs avec g95.

E.5
Vickery, Christopher, IEEE-754 calculators, 2009, URL : http://babbage.cs.qc.edu/
IEEE-754/. C.4.2
wikipedia, The IEEE-754-2008 standard, 2010, URL : http://en.wikipedia.org/wiki/IEEE_
754. C.4.2

178

BIBLIOGRAPHIE

Index
Symboles
! commentaire . . . . . . . . . . . . . . . . . . . . . . . . . . . 8, 9
dlimiteur de chane . . . . . . . . . . . . . . . . . 17, 94
(/ constructeur de tableau . . . . . . . . . . . . . . . . 81
*
format libre dentre sortie . . . . . . . . 35, 47
oprateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
rptition dentre . . . . . . . . . . . . . . . . . . . . 36
unit logique standard . . . . . . . . . . . . . . . . 38
** lvation la puissance . . . . . . . . . . . . 21, 163
, sparateur
dcimal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
de donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
. sparateur dcimal . . . . . . . . . . . . . . . . . . . . . . 49
.AND. ET logique . . . . . . . . . . . . . . . . . . . . . . . . . 24
.EQV. quivalence logique . . . . . . . . . . . . . . . . . 24
.NEQV. OU exclusif . . . . . . . . . . . . . . . . . . . . . . . . 24
.NOT. ngation logique . . . . . . . . . . . . . . . . . . . . 24
.OR. OU logique . . . . . . . . . . . . . . . . . . . . . . . . . . 24
/
descripteur de contrle . . . . . . . . . . . . . . . . 49
oprateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
/) constructeur de tableau . . . . . . . . . . . . . . . . 81
// oprateur de concatnation . . . . . . . . . 25, 95
/= diffrent de . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
:
bornes dun tableau . . . . . . . . . . . . . . . . . . . 79
bornes dune sous-chane . . . . . . . . . . . . . . 96
descripteur de format . . . . . . . . . . . . . . 49, 50
section de tableau . . . . . . . . . . . . . . . . . . . . . 82
sparateur entre nom de la structure et structure de contrle . . . . . . . . . . . . . . . . . . . . .
26-31
:: dans les dclarations . . . . . . . . . . . . . . . . . . . . 16
; sparateur
dinstructions . . . . . . . . . . . . . . . . . . . . . . . . . . 8
de donnes . . . . . . . . . . . . . . . . . . . . . . . . 36, 50
< infrieur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
<= infrieur ou gal . . . . . . . . . . . . . . . . . . . . . . 23
== gal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
=>
association de pointeur . . . . . . . . . . . . . . . 119
renommage . . . . . . . . . . . . . . . . . . . . . voir USE
> suprieur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
>= suprieur ou gal . . . . . . . . . . . . . . . . . . . . . 23

[
%
&
"
]
_

constructeur de tableau . . . . . . . . . . . . . . . 6, 81
slecteur de champ . . . . . . . . . . . . . . . . . . . . . 104
continuation dinstruction . . . . . . . . . . . . . 8, 94
dlimiteur de chane . . . . . . . . . . . . . . . . . 17, 94
constructeur de tableau . . . . . . . . . . . . . . . 6, 81
variante de type
caractre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
numrique . . . . . . . . . . . . . . . . . . . . . . . . . 19, 20

A
ABS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138, 163
ABSTRACT INTERFACE . . . . . . . . . . . . . . . . . . . 74-76
accs
direct . . . . . . . . . . . . . . . . . . . . . . 40, 42, 44, 54
squentiel . . . . . . . . . . . . . . . . . . . . . . 40, 42, 44
stream . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40, 45
ACCESS, mot-clef de OPEN . . . . . . . . . . . . . . . . . . 42
ACHAR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98, 149
ACOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138, 163
ACOSH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
ACTION, mot-clef de OPEN . . . . . . . . . . . . . . . . . . 42
ADJUSTL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96, 149
ADJUSTR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97, 149
ADVANCE=, mot-clef de READ ou WRITE . 44, 45,
47, 50, 51
affectation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22, 114
AIMAG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140, 163
AINT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
alatoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
-align recnbyte, option de ifort . . . . . . . 169
-align records, option de ifort . . . . . . . . 169
ALL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88, 143
ALLOCATABLE . . . . . . . . . . . . . 16, 91, 92, 106, 130
ALLOCATE . . . . . . . . . . . 91, 92, 120, 122, 124, 126
ALLOCATED . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91, 143
allocation dynamique 16, 89, 91-93, 106, 122,
126, 130
An, format chane . . . . . . . . . . . . . . . . . . . . . . . . . . 48
ANINT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
ANY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88, 143
'APPEND', argument de POSITION dans OPEN . .
42, 46
ar, gestion des bibliothques statiques . . . . . . 4
argument
chane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

179

180

INDEX

BIT_SIZE . . . . . . . . . . . . . . . . . . 12, 14, 15, 18, 143


blancs
dplacement dans une chane . . . . . . . . voir
ADJUSTL, voir aussi ADJUSTR
dans le code source . . . . . . . . . . . . . . . . . . 8, 9
format
pour considrer nuls les . . . . . . . . voir BZ
pour dsigner les . . . . . . . . . . . . . . . . voir X
pour ignorer les . . . . . . . . . . . . . . . . voir BN
mot-clef de OPEN . . . . . . . . . . . . . voir BLANK
suppression dans une chane . . . voir TRIM
BLANK, mot-clef de OPEN . . . . . . . . . . . . . . . . . . . 43
bloc dinstructions . . . . . . 26, 28, 29, 31, 84, 89
BLOCK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16, 31
BN, format ignorer les blancs . . . . . . . . . . . . . . . 49
Bn.p, format binaire . . . . . . 12, 48, 52, 144, 158
boolen . . . . . . . . . . . . . . . . . . . . . . . . . 10, 17, 24, 69
bornes . . . . . . . . . . . . . . . . . . . . . . . . . . . voir tableau
boucle
avec compteur . . . . . . . . . . . . . . . . . . . . . . . . 29
implicite . . . . . . . . . . . . . . . . . . . . . . . . . . 51, 81
infinie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
WHILE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
B
bound procedure . voir procdure attache un
B'n' constante entire en binaire . . . . . . . . . . 17
type
BACK=
BTEST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
mot-clef de INDEX . . . . . . . . . . . . . . . . . . . . . 97 byterecl . . . . . . . . . . . . voir -assume byterecl
mot-clef de SCAN . . . . . . . . . . . . . . . . . . . . . . 97 BZ, format blanc=zro . . . . . . . . . . . . . . . . . . . . . 49
mot-clef de VERIFY . . . . . . . . . . . . . . . . . . . . 97
BACKSPACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
C
balise denregistrement . . . . . . . . . . . . . . . . . . . . 39 -C=all, option de nagfor . . . . . . . . . . . . . . . . 167
base . . . . . . . . . . . . . . . . . . . . . . . . . . 10, 12, 143, 154 c_char . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
BESSEL_J0, J0 (x) . . . . . . . . . . . . . . . . . . . . . . . . . 138 c_double . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
BESSEL_J1, J1 (x) . . . . . . . . . . . . . . . . . . . . . . . . . 138 c_f_pointer . . . . . . . . . . . . . . . . . . . . . . . . 130, 135
BESSEL_JN, Jn (x) . . . . . . . . . . . . . . . . . . . . . . . . 138 c_f_procpointer . . . . . . . . . . . . . . . . . . . . . . . . 130
BESSEL_Y0, Y0 (x) . . . . . . . . . . . . . . . . . . . . . . . . 138 c_float . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
BESSEL_Y1, Y1 (x) . . . . . . . . . . . . . . . . . . . . . . . . 138 c_funloc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
BESSEL_YN, Yn (x) . . . . . . . . . . . . . . . . . . . . . . . . 138 c_funptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
bibliothque . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4, 5 c_int . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
dynamique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 c_loc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118, 130
et interfaces . . . . . . . . . . . . . . . . . . . . . . . . . 112 c_ptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130, 135
et units logiques . . . . . . . . . . . . . . . . . . . . . 38 CALL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
fortran . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 caractres . . . . . . . . . . . . . . . 10, 94-101, 130, 149
intrinsque . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 CASE . . . . . . . . . . . . . . . . . . . . . . . voir SELECT CASE
mathmatique . . . . . . . . . . . . . . . . . . . . . . . 163 CEILING . . . . . . . . . . . . . . . . . . . . . . . . . 20, 140, 163
pour la prcision infinie . . . . . . . . . . . . . . . 19 chane de caractres . . . . . 10, 94-101, 130, 149
statique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
automatique . . . . . . . . . . . . . . . . . . . . . . . . . 100
big endian . . . . . . . . . 12, 39, 166, 168-170, 172 CHAR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98, 149
binaire
CHARACTER . . . . . . . . . . . . . . . . . . . . . . . . 10, 94, 130
base . . . . . . . . . . . . . . . . . . . . . . . . . . . voir base cible (dun pointeur) . . . . . . . . . . . . . . . . . 118-121
constante entire en . . . . . . . . . . . voir Zn
anonyme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
format . . . . . . . . . . . . . . . . . . . . . . . . . voir Bn.p
nomme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
BIND(C) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105, 130 CLASS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
bit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-19 CLASS IS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
de signe . . . . . . . . . 11, 13, 14, 154, 157, 158 CLOSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
manipulation de . . . . . . . . . . . . . . . . . . . . . 144 CMPLX (conversion vers le type) . . . . . . . . . . . 140
effectif . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58, 70
muet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58, 70
optionnel . . . . . . . . . . . . . . . . . . . . . 16, 69, 103
passage par mot-clef . . . . . . . . voir mot-clef
procdure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
ASCII . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
ASIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138, 163
ASINH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
'ASIS', argument de POSITION dans OPEN . 43
ASSOCIATED . . . . . . . . . . . . . . . . . . . . . . . . . 119, 145
association . . . . . . . . . . . . . . . . . . . . . . 118, 124, 145
-assume byterecl, option de ifort . . . . . 169
-assume realloc_lhs, option de ifort . . 93,
168
assumed-shape array . . . . . . voir tableau profil
implicite
ATAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138, 163
ATAN2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138, 163
ATANH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
automatique . . . . . . . . . . . . voir variable, tableau
avertissement la compilation . 4, 68, 166-168,
170-172

181

INDEX

codage
des caractres . . . . . . . . . . . . . . . . . 43, 46, 95
des entiers . . . . . . . . . . . . . . . . . . . . . . . . 10-12
des flottants . . . . . . . . . . . . . . . . . . . . . . . 12-13
norme IEEE . . . . . . . . . . . . . . . . . 154-159
comma . . . . . . . . . . . . . . . . . . . . . . . . . . voir DECIMAL
COMMAND_ARGUMENT_COUNT . . . . . . . . . . . 146, 147
commande . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
commentaire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7, 8
COMMON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
comparaison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
compilateur
g95 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165, 169
gfortran . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
ifort dintel . . . . . . . . . . . . . . 51, 165, 168
nagfor (ex-f95) de nag . . . . . . . . 165, 166
pgf95 de portland . . . . . . . . 51, 165, 167
xlf sur ibm . . . . . . . . . . . . . . . . . . . . . 51, 165
compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
de module . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
options de
avec g95 . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
avec gfortran . . . . . . . . . . . . . . . . . . . . . 171
avec ifort dintel . . . . . . . . . . . . . . . . 168
avec nagfor . . . . . . . . . . . . . . . . . . . . . . . 167
avec pgf95 de Portland . . . . . . . . . 167
avec xlf . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
spare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5, 66
COMPILER_OPTIONS() . . . . . . . . . . . . . . . . . . . . . 145
COMPILER_VERSION() . . . . . . . . . . . . . . . . . . . . . 145
COMPLEX (type) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
complexe . . . . . voir COMPLEX, voir aussi CMPLX
composante . . . . . . . . . . . . . . . . . . . . 102, 106, 130
concatnation . . . . . . . . . . . . . . . . . . . . . . . . . . 25, 95
conformants . . . . . . . . . . . . . . . . . . . . voir tableaux
CONJG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138, 163
constante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
constante symbolique . . . . . . . . . . . . . . . . . . . . . . 18
constructeur voir tableau, voir aussi structure
CONTAINS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62, 103
continuation dinstruction . . . . . . . . . . . . . . . 8, 94
CONTINUE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
conversion
de type . . . . . . . . . . . . . . . . . . . . . . 20, 114, 140
implicite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
-convert=, option de nagfor . . . . . . . . . . . . . 166
copie
profonde . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
superficielle . . . . . . . . . . . . . . . . . . . . . . . . . . 106
COS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138, 163
COSH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138, 163
COUNT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88, 143
CPU_TIME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
CSHIFT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87, 143
CYCLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30, 162

D
-d8, option de g95 . . . . . . . . . . . . . . . . . . . . . . . 173
DATE_AND_TIME . . . . . . . . . . . . . . . . . . . . . . . . . . 148
dc (decimal comma) . . . . . . . . . . . . . . . . . . . 36, 49
ddd, interface graphique du dboggueur gdb 5
DEALLOCATE . . . . . . . . . . . . . . . . . . . . . . . . . . 91, 120
dbogueur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
debugger . . . . . . . . . . . . . . . . . . . . . . voir dbogueur
dcalage des lments dun tableau . . . . . . . voir
CSHIfT et EOSHIFT
DECIMAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
DECIMAL, mot-clef de OPEN . . . . . . . . . . . . . . . . 43
dclaration . . . 16-17, 17, 19, 58, 62-65, 68, 69
darguments . . . . . . . . . . . . . . . . . . . . . . . 58, 69
dinterface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
dune fonction . . . . . . . . . . . . . . . . . . . . . . . . 61
de chane de caractres . . . . . . . . . . . . 94, 97
de cible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
de fonction . . . . . . . . . . . . . . . . . . . . . . . . 71, 73
de pointeur . . . . . . . . . . . . . . . . . . . . . 118, 119
de tableau . . . . . . . . . . . . . . 79, 80, 82, 89, 90
allouable . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
de type driv . . . . . . . . . . . . . . . . . . . 103, 104
deep copy . . . . . . . . . . . . . . . . . voir copie profonde
DEFAULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
deferred-shape array voir tableau profil diffr
dfinition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
dun type driv . . . . . . . . . . . . 102, 106, 153
'DELETE', argument de STATUS dans CLOSE 44
DELIM=, mot-clef de OPEN . . . . . . . . . . . . . . . . . . 43
dnormalis . . . . . . . . . . . . . . . . . . . . . . 13, 14, 156
dpassement
de bornes . . . . . . . . . . . . . . . . . . 166, 167, 170
de capacit . 15, 19, 22, 139, 155, 166, 170
descripteur
actif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
de contrle . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
-diag-error-limit, option de ifort . . 3, 168
DIGITS . . . . . . . . . . . . . . . . . . . . . . 14, 15, 142, 155
DIM fonction intrinsque . . . . . . . . . . . . . . . . . . 138
DIM= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85, 86-88
DIMENSION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16, 79
dimension . . . . . . . . . . . . . . . . . . . . . . . voir tableau
'DIRECT', argument de ACCESS dans OPEN . 42
DO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29, 162
DO WHILE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29, 162
domaine . . . . . . 12, 143, 154, 155, 159, 167, 170
DOT_PRODUCT . . . . . . . . . . . . . . . . . . . . . . . . . 86, 143
DOUBLE PRECISION . . . . . . . . . . . . . . . . . . . . . . . . 10
dp (decimal point) . . . . . . . . . . . . . . . . . . . . . . . . . 49
duplication dlments de tableaux . . . . . . . voir
SPREAD

E
dition de liens . . . . . . . . . . . . . . . . . . . . . . . 2, 4, 65
effet de bord . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

182

ELEMENTAL, attribut de procdure . . . . . . . . . . 78


ELSE IF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
ELSEWHERE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
En.p, format virgule flottante . . . . . . . . . . . . 48
encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . 67, 117
encoding
argument de INQUIRE . . . . . . . . . . . . . . . . . 46
argument de OPEN . . . . . . . . . . . . . . . . . . . . . 43
option de nagfor . . . . . . . . . . . . . . . . . . . . 166
END
DO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
FORALL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
FUNCTION . . . . . . . . . . . . . . . . . . . . . . . . 61, 153
IF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
INTERFACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
MODULE . . . . . . . . . . . . . . . . . . . . . . . . . . . 64, 153
PROGRAM . . . . . . . . . . . . . . . . . . . . . . . . . . . 3, 153
SELECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
SUBROUTINE . . . . . . . . . . . . . . . . . . . . . . 60, 153
TYPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
WHERE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
END= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34, 44
ENDFILE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
ENn.p, format ingnieur virgule flottante . 48
enregistrement . . . . . . . . . . . . . . . 38, 39-40, 43-51
entre standard . . . . . . . . . . voir units logiques
environnement . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
EOR= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34, 44
EOSHIFT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87, 143
EPSILON . . . . . . . . . . . . 15, 18, 142, 157-159, 164
ERF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138, 170, 171
ERFC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138, 170, 171
ERR= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
mot-clef de OPEN . . . . . . . . . . . . . . . . . . . . . . 42
erreur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
dexcution . . . . . . . . . . . . 3, 36, 39, 170, 171
de compilation . . . . . . . . . . . . . . . . . . . . . . . 3, 4
erreur standard . . . . . . . . . . . voir units logiques
error_unit (erreur standard) . . . . . . . . . . 38, 41
ESn.p, format scientifique virgule flottante . 48
espaces
dplacement dans une chane . . . . . . . . voir
ADJUSTL, voir aussi ADJUSTR
dans le code source . . . . . . . . . . . . . . . . . . 8, 9
suppression dans une chane . . . voir TRIM
tendue . . . . . . . . . . . . . . . . . . . . . . . . . . voir tableau
tiquette numrique . . . . . . . . . . . . 7, 32, 41, 162
EXECUTE_COMMAND_LINE . . . . . . . . . . . . . . . . . . 147
EXIST= mot-clef de INQUIRE . . . . . . . . . . . . . . . 45
EXIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30, 32, 162
EXP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138, 163
EXPONENT . . . . . . . . . . . . . . . . . . . . . . . . 15, 142, 154
exposant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12, 155
exposant biais . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
EXTENDS (type driv) . . . . . . . . . . . . . . . 105, 130
EXTERNAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16, 71

INDEX

F
f95 de nag . . . . . . . . . . . . . . . . . voir compilateur
-fall-intrinsics, option de gfortran . . 171
-fbacktrace, option de gfortran . . . . . . . . 171
-fblas-matmul-limit=
option de gfortran . . . . . . . . . . . . . . . . . . 172
-fbounds-check
option de g95 . . . . . . . . . . . . . . . . . . . . . . . . 170
option de gfortran . . . . . . . . . . . . . . . . . . 172
-fcheck=bounds, option de gfortran . . . . 172
-fdefault-integer-8, option de gfortran . .
172
-fdefault-real-8, option de gfortran . . 173
-fexternal-blas
option de gfortran . . . . . . . . . . . . . . 86, 172
-ffloat-store
option de g95 . . . . . . . . . . . . . . . . . . . . 22, 170
option de gfortran . . . . . . . . . 22, 169, 172
fichier
de module . . . . . . . . . . . . . . . . . . . . . . . . . . 5, 65
excutable . . . . . . . . . . . . . . . . . . . . . . . 2, 5, 65
externe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
format . . . . . . . . . . . . . . . . . . . . . . . . . . . 38, 39
interne . . . . . . . . . . . . . . . . . . . . . . . . 38, 51, 99
non-format . . . . . . . . . . . . . . . . . . . . . . . 38, 39
objet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2, 5, 65
source . . . . . . . . . 2, 3, 5-7, 65, 133, 165-169
FILE=, mot-clef de OPEN . . . . . . . . . . . . . . . . . . . 42
FILE_STORAGE_UNIT . . . . . . . . . . . . . . . . . . . . . . . 41
-fimplicit-none
option de g95 . . . . . . . . . . . . . . . . . . . . . . . . 170
option de gfortran . . . . . . . . . . . . . . . . . . 171
-finit-integer=, option de gfortran . . . 171
-finit-real=, option de gfortran . . . . . . . 171
-fintrinsic-extensions, option de g95 . 170
-float-store, option de nagfor . . . . . 22, 167
FLOOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20, 140, 163
-fltconsistency, option de ifort . . . . . . . 169
-fmax-errors=n, option de gfortran . . 3, 171
-fmax-stack-var-size=, option de gfortran
171
-fmode, option de g95 . . . . . . . . . . . . . . . . . . . . 169
FMT=
mot-clef de OPEN . . . . . . . . . . . . . . . . . . . . . . 44
mot-clef de READ . . . . . . . . . . . . . . . . . . . . . . 44
mot-clef de WRITE . . . . . . . . . . . . . . . . . 45, 54
Fn.p, format virgule fixe . . . . . . . . . . . . . . . . . 48
-fno-realloc-lhs, option de gfortran . . 93,
171
fonction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60, 61
-fone-error, option de g95 . . . . . . . . . . . 3, 171
FORALL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78, 88
FORM=, mot-clef de OPEN . . . . . . . . . . . . . . . . . . . 42
FORMAT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
format
binaire . . . . . . . . . . . . . . . . . . . . . . . . voir Bn.p

183

INDEX

chane . . . . . . . . . . . . . . . . . . . . . . . . . . . voir An
dcimal . . . . . . . . . . . . . . . . . . . . . . . . voir In.p
descripteur de . . . . . . . . . . . . . . . . . . . . . . . . . 48
fixe du code source . . . . 1, 7, 7-8, 166-169
hexadcimal . . . . . . . . . . . . . . . . . . . voir Zn.p
libre dentre sortie . . . . . 35, 37, 47, 81, 99
libre du code source . . . . . . 7, 8-9, 165-169
octal . . . . . . . . . . . . . . . . . . . . . . . . . . voir On.p
variable . . . . . . . . . . . . . . . . . . . . . . . . . . . 51, 99
'FORMATTED', argument de FORM dans OPEN 42
FORT_CONVERTn , compilateur nagfor . . . . . 166
-fpack-derived, option de gfortran 103, 172
-fpointer, option de g95 . . . . . . . . . . . 120, 170
FRACTION . . . . . . . . . . . . . . . . . . . . . . . . 15, 142, 154
-freal, option de g95 . . . . . . . . . . . . . . . . . . . . 170
-frealloc-lhs, option de gfortran . . 93, 171
-frecursive, option de gfortran . . . . . . . . 171
FSOURCE=, mot-clef de SPREAD . . . . . . . . . . . . . 87
-ftr15581, option de g95 . . . 92, 106, 122, 170
-ftrace=, option de g95 . . . . . . . . . . . . . . . . . 170
-ftrapv, option de g95 . . . . . . . . . . . . . . . 15, 170
fuite de mmoire . . . . . . . . . . . . . . . . . . . . . . . . . 120
FUNCTION . . . . . . . . . . . . 60, 61, 76, 100, 122, 153
fusion de tableaux . . . . . . . . . . . . . . . . voir MERGE

G
g95 . . . . . . . . . . . . . . . . . . . . . . . . . voir compilateur
G95_COMMA . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50, 170
G95_ENDIAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
G95_MEM_INIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
G95_STDERR_UNIT . . . . . . . . . . . . . . . . . . . . . . . . 170
G95_STDIN_UNIT . . . . . . . . . . . . . . . . . . . . . . . . . 169
G95_STDOUT_UNIT . . . . . . . . . . . . . . . . . . . . . . . . 169
GAMMA, (x) . . . . . . . . . . . . . . . . . . . . . 138, 170, 171
gdb, dboggueur . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
gnrique . voir procdure gnrique, interface
gnrique
GET_COMMAND . . . . . . . . . . . . . . . . . . . . . . . . 146, 147
GET_COMMAND_VARIABLE . . . . . . . . . . . . . 146, 147
GET_ENVIRONMENT_VARIABLE . . . . . . . . . 146, 147
gfortran . . . . . . . . . . . . . . . . . . . voir compilateur
GFORTRAN_CONVERT_UNIT, gfortran . . . . . . 172
Gn.p, format gnral . . . . . . . . . . . . . . . . . . . . . . . 48
GO TO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32, 162

H
hritage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
hexadcimal
constante entire en . . . . . . . . . . . voir Zn
format . . . . . . . . . . . . . . . . . . . . . . . . . voir Zn.p
HUGE . . . 12, 14, 15, 18, 142, 155, 157-159, 164
HYPOT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

I
-I, option de gfortran . . . . . . . . . . . . . . . . . . . 172
-i8, option de g95 . . . . . . . . . . . . . . . . . . . . . . . 172

IACHAR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98, 149


IAND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144, 161
IBCLR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
IBITS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
IBSET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
ICHAR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98, 149
IEEE (norme) . . . . . . . . . . . . . . 15, 154-159, 168
IEOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144, 161
IF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26, 162
ifort . . . . . . . . . . . . . . . . . . . . . . . voir compilateur
IF ... THEN . . . . . . . . . . . . . . . . . . . . . . . . . 26, 162
imaginaire (partie -) . . . . . . . . . . . . . . voir AIMAG
IMPLICIT NONE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
IMPORT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69, 131
IN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . voir INTENT
In.p, format dcimal . . . . . . . . . . . . . . . . . . . . . . 48
INCLUDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97, 149
indexation . . . . . . . . . . . . . . . . . . . . . . . voir tableau
Inf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
initialisation . . . . . . . . . . 17, 58, 78, 81, 103, 120
INOUT . . . . . . . . . . . . . . . . . . . . . . . . . . . voir INTENT
input_unit (entre standard) . . . . . . . . . . 38, 41
INQUIRE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45, 55
instruction . . . . . . . . . . . . 3, 5, 7-9, 57, 59-62, 64
daffectation . . . . . . . . . . . . . . . 17, 58, 84, 93
dentresortie . . . . . 35, 37, 38, 40, 41-47,
49-51, 80
de contrle . . . . . . . . . . . . . . . . . 26-34, 84, 88
de format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
excutable . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
ordre des . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
INT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20, 140
INT8, aussi INT16, INT32 et INT64 . . . . . . . . . 18
INTEGER . . . . . . . . . . . . . . . . . . . . . . . . 10-12, 15, 19
INTEGER_KINDS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
INTENT . . . . . . . . . . . . . . . . . . . . 16, 59, 78, 92, 131
INTERFACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63, 73
ASSIGNEMENT . . . . . . . . . . . . . . . . . . . . . . . . 114
OPERATOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
interface
abstraite . . . . . . . . . . . . . . . . . . . . . . . . . . 74-76
gnrique . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
intrinsque . . . . . . voir procdure, module, type
intrinsques
INTRINSIC
module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
procdure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
IOLENGTH=, argument de INQUIRE . . . . . . . . . 46
IOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144, 161
IOSTAT= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
mot-clef de OPEN . . . . . . . . . . . . . . . . . . . . . . 42
mot-clef de CLOSE . . . . . . . . . . . . . . . . . . . . . 44
mot-clef de READ . . . . . . . . . . . . . . . . . . . . . . 45
mot-clef de WRITE . . . . . . . . . . . . . . . . . . . . . 45
IOSTAT_END (fin de fichier) . . . . . . . . . 34, 41, 45

184

INDEX

IOSTAT_EOR (fin denregistrement) . . 34, 41, 45


IS_IOSTAT_END . . . . . . . . . . . . . . . . . . . . 34, 42, 45
IS_IOSTAT_EOR . . . . . . . . . . . . . . . . . . . . 34, 42, 45
ISHFT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144, 161
ISHFTC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
ISO_104646 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
ISO_C_BINDING (module) . . . 69, 118, 129-130
ISO_FORTRAN_ENV (module) 18, 34, 38, 41, 45,
69, 145

J
-J, option de gfortran . . . . . . . . . . . . . . . . . . . 172
J0 (x), J1 (x), Jn (x) . . . . voir BESSEL_J0/J1/JN
justification
droite . . . . . . . . . . . . . . . . . . . . voir ADJUSTR
gauche . . . . . . . . . . . . . . . . . . . voir ADJUSTL

K
'KEEP', argument de STATUS dans CLOSE . . 44
KIND 10, 13, 18, 18, 20, 129, 130, 142, 154, 166

L
LBOUND . . . . . . . . . . . . . . . . . . . . . . . . . . . 18, 85, 143
ld diteur de liens . . . . . . . . . . . . . . . . . . . . . . . 2, 4
ldd affichage des bibliothques dynamiques . 4
LEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
fonction . . . . . . . . . . . . . . . . . . . . . 97, 100, 149
paramtre de type . . . . . . . . . . . . . . . . 17, 94
LEN_TRIM . . . . . . . . . . . . . . . . . . . . . . . . 97, 100, 149
LGE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98, 149
LGT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98, 149
library . . . . . . . . . . . . . . . . . . . . . . . voir bibliothque
ligne
dentre-sortie . . . 35, 36, 38, 40, 47, 49, 98
dinstruction . . . . . . . . . . . . . . . . . . . . . . 7-9, 94
de commentaire . . . . . . . . . . . . . . . . . . . . . . . . 7
link . . . . . . . . . . . . . . . . . . . . . . voir dition de liens
liste chane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
liste dentre-sortie . . . . . . . . . . . . . . . . . . . . . . . . 40
little endian . . . . . . . 12, 39, 166, 168-170, 172
LLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98, 149
LLT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98, 149
Ln, format boolen . . . . . . . . . . . . . . . . . . . . . . . . 48
LOG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139, 163
LOG10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139, 163
LOG_GAMMA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
LOGICAL
fonction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10, 160
longueur dune chane . . . . . . . . . . . . . . 94, 96-100

-Mallocatable=, option de pgf95 . . . . 93, 168


mantisse . . . . . . . . . . . . . . . . . . 12, 48, 49, 142, 155
MASK= . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88, 143-144
masquage de variable . . . . . . . . . . . . . . . . . . . . . . 62
masque . . . . . . . . . . . . . . . . . . . . . . . . . . voir tableau
MATMUL . . . . . . . . . . . . . . . . . . . . . . . . . . 86, 143, 172
MAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
MAXEXPONENT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
MAXLOC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85, 143
MAXVAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86, 143
memory leak . . . . . . . . . . . . voir fuite de mmoire
MERGE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87, 143
-mieee-fp, option de ifort . . . . . . . . . . . . . . 169
MIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
MINEXPONENT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
MINLOC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85, 143
minuscule . . . . . . . . . . . . . . . . . . . . 3, 6, 7, 166, 169
MINVAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86, 143
MOD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139, 163
MODULE . . . . . . . . . . . . . . . . . . . . . . . . . . . 64-69, 153
module . . . . . . . . . . . . . . . . . . . . . . 19, 64, 103, 106
fichier de . . . . . . . . . . . . . . . . . . . . . . . . . . . 5, 65
intrinsque . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
MODULE PROCEDURE . . . . . . . . . . . . . . . . . . . . . . . 112
MODULO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139, 163
mot-clef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70, 103

N
nagfor de nag . . . . . . . . . . . . . . voir compilateur
NAME=, mot-clef de BIND . . . . . . . . . . . . . . . . . . 130
NaN, Not a Number . . . . . . . . . . . . . . . . . . . . 22, 155
NCOPIES=, mot-clef de SPREAD . . . . . . . . . . . . . 87
NEAREST . . . . . . . . . . . . . . . . 15, 142, 156-158, 163
'NEW', argument de STATUS dans OPEN . . . . . 42
NEW_LINE . . . . . . . . . . . . . . . . . . . . . . . . . 40, 98, 149
NEWUNIT=, mot-clef de OPEN . . . . . . . . . . . . 42, 45
NINT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20, 140, 163
-noalign records, option de ifort . 103, 169
NOPASS, attribut de PROCEDURE . . . . . . . . . . . 107
normalis . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14, 155
NOT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144, 161
NULL . . . . . . . . . . . . . . . . . . . . . . . . . . . 120, 145, 170
NULLIFY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

O'n' constante entire en octal . . . . . . . . . . . . 17


octal
constante entire en . . . . . . . . . . . voir On
format . . . . . . . . . . . . . . . . . . . . . . . . . voir On.p
od (octal dump) . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
'OLD', argument de STATUS dans OPEN . . . . . 42
M
-M, option de g95 . . . . . . . . . . . . . . . . . . . . . . 6, 169 On.p, format octal . . . . . . . . . . . . . . . . . . . . . 48, 52
-M, option de gfortran . . . . . . . . . . . . . . . . . . . . . 6 ONLY: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . voir USE
majuscule . . . . . . . . . . . . . . . . . . . . 3, 6, 7, 166, 169 OPEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
make . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 OPENED=, mot-clef de INQUIRE . . . . . . . . . . . . . 45
makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6, 169 oprateur

185

INDEX

cration d . . . . . . . . . . . . . . . . . . . . . . . 25, 112


standard du fortran . . . . . . . . . . . . . . . . . . . 21
surcharge d . . . . . . . . . . . . . . . . . . . . . . 25, 112
OPERATOR . . . . . . . . . . . . . . . . . . . . voir INTERFACE
OPTIONAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16, 69
options de compilation . . . . . . voir compilation
ORDER, mot-clef de RESHAPE . . . . . . . . . . . 86, 144
OUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . voir INTENT
output_unit (sortie standard) . . . . . . . . . 38, 41
overflow . . . . . . . . voir dpassement de capacit
overloading . . . . . . . . . . . . . . . . . . . . voir surcharge

P
PACK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86, 143
PAD=, mot-clef de RESHAPE . . . . . . . . . . . . . . . . . 86
PARAMETER . . . . . . . . . . . . . . . . . 16, 18, 89, 90, 94
partie entire . . . . voir CEILING, FLOOR, INT,
NINT
partie imaginaire . . . . . . . . . . . . . . . . . . voir AIMAG
partie relle . . . . . . . . . . . . . . . . . . . . . . . . voir REAL
PASS, attribut de PROCEDURE . . . . . . . . . . . . . 107
pgf95 . . . . . . . . . . . . . . . . . . . . . . . voir compilateur
point . . . . . . . . . . . . . . . . . . . . . . . . . . voir DECIMAL
POINTER . . . . . . . . . . . . . . . . . . . . . 16, 78, 118-128
pointeur . . . . . . . . . . . . . . 118-128, 130, 145, 162
porte . . . . . . . . . . . . . . . . . . . . . . . . . . 16, 31, 58, 65
POS=, mot-clef de INQUIRE, READ, WRITE 45, 46
POSITION=, mot-clef de OPEN . . . . . . . . . . . 42, 46
PRECISION . . . . . . . . . . . . . . . . . . . . . . . . 15, 15, 143
prcision numrique 12-15, 19, 21, 154-159, 168
prdcesseur . . . . . . . . . . . . . . . . . . . . . . . . . . 15, 142
PRESENT, fonction dinterrogation . . . . . 69, 144
PRINT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35, 45
priorit des oprateurs . . . . . . . . . . . . . . . . . . . . . 21
PRIVATE . . . . . . . . . . . . . . . . 16, 68, 103, 117, 130
PROCEDURE . . . . . . . . . . . . . . . . . . . . . . . . 74, 76, 112
procdure
attache un type . . . . . . . . . . . 1, 107-110
lmentaire . . . . . . . 18, 78, 96-98, 100, 138
externe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
gnrique . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
interface de . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
interne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
intrinsque . . . . . . . . . . . . . . 16, 18, 138, 170
pointeur de . . . . . . . . . . . . . . . . . . . . . . . . . . 126
pure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
rcursive . . . . . . . . . . . . . . . . . . . . . . . . . 76, 126
spcifique . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
standard . . . . . . . . . . . . . . . . . . . . . . . . 138, 170
PRODUCT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86, 144
produit matriciel . . . . . . . . . . . . . . . . . . . . . . . . . . 86
produit scalaire . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
profil . . . . . . . . . . . . . . . . . . . . . . . . . . . . voir tableau
diffr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
PROGRAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3, 153
PROTECTED . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16, 68

PUBLIC . . . . . . . . . . . . . . . . . . . . . . 16, 68, 103, 130


PURE, attribut de procdure . . . . . . . . . . . . . . . . 78

Q
quiet NaN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

R
-r8, option de g95 . . . . . . . . . . . . . . . . . . . . . . . 173
RADIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14, 143
RANDOM_NUMBER . . . . . . . . . . . . . . . . . . . . . . . . . . 140
RANDOM_SEED . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
rang . . . . . . . . . . . . . . . . . . . . . . . . . . . . . voir tableau
RANGE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11, 14, 143
range . . . . . . . . . . . . . . . . . . . . . . . . . . . voir domaine
READ
argument de ACTION dans OPEN . . . . . . . 42
instruction . . . . . . . . . . . . . . . . . . . . 35, 44-45
READWRITE
argument de ACTION dans OPEN . . . . . . . 42
REAL
fonction . . . . . . . . . . . . . . . . . . . . . 20, 140, 163
type . . . . . . . . . . . . . . . . . . . . . . . . . . 10, 19, 160
REAL32, aussi REAL64 et REAL128 . . . . . . . . . . 19
REAL_KINDS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
realloc_lhs . . . . . voir -assume realloc_lhs
REC=, mot-clef de READ ou WRITE . . . . . . . 44, 45
recherche
de caractres . . . . . . . . . . voir SCAN, VERIFY
de motif . . . . . . . . . . . . . . . . . . . . . . voir INDEX
RECL=, mot-clef OPEN . . . . . . . . . . . . . . . . . . . . . . 41
RECL=, mot-clef de OPEN . . . . . . . . . . . . . . . . . . . 43
record . . . . . . . . . . . . . . . . . . . . voir enregistrement
record marker . . . . . voir balise denregistrement
RECURSIVE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76, 78
relle (partie -) . . . . . . . . . . . . . . . . . . . . . voir REAL
registre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167, 170
REPEAT . . . . . . . . . . . . . . . . . . . . . . . . . . . 18, 98, 149
'REPLACE', argument de STATUS dans OPEN 42
RESHAPE . . . . . . . . . . . . . . . . . . . 18, 80, 81, 86, 144
reste . . . . . . . . . . . . . . . . . . . voir MODULO, voir MOD
RESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
RETURN . . . . . . . . . . . . . . . . . . . . . . . . . . . 33, 34, 162
'REWIND', argument de POSITION dans OPEN . .
42
REWIND, instruction de positionnement en dbut
de fichier . . . . . . . . . . . . . . . . . . . . . . . . . 46
RRSPACING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
run-time error . . . . . . . . . voir erreur dexcution

S
S, format signe plus selon processeur . . . . . . . 49
SAVE . . . . . . . . . . . . . . . . . . . . . . . 16, 17, 58, 76, 78
SCALE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
SCAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97, 149
scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . voir porte
'SCRATCH', argument de STATUS dans OPEN 42

186

section . . . . . . . . . . . . . . . . . . . . . . . . . . voir tableau


SELECT CASE . . . . . . . . . . . . . . . . . . . . . . . . . 27, 162
SELECT TYPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
SELECTED_CHAR_KIND . . . . . . . . . . . . . . . . . 95, 149
SELECTED_INT_KIND . . . . . . . . . . . . . . 18, 19, 143
SELECTED_REAL_KIND . . . . . . . . . . . . . 18, 19, 143
SEQUENCE . . . . . . . . . . . . . . . . . . 103, 105, 106, 130
'SEQUENTIAL', argument de ACCESS dans OPEN
42
SET_EXPONENT . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
shallow copy . . . . . . . . . . . voir copie superficielle
SHAPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18, 85, 144
SHAPE=, mot-clef de RESHAPE . . . . . . . . . . . . . . 86
SIGN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
signaling NaN . . . . . . . . . . . . . . . . . . . . . . . . 155, 171
signe
bit de . . . . . . . . . . . . . . . . . . . voir bit de signe
format dentre-sortie . . . . . . . . voir SP, SS
SIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139, 163
SINH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139, 163
SIZE, fonction dinterrogation pour les tableaux
18, 85, 144
SIZE, mot-clef de READ . . . . . . . . . . . . . . . . . . . . 44
sortie derreur standard . . voir units logiques
sortie standard . . . . . . . . . . . voir units logiques
SOURCE=
mot-clef de RESHAPE . . . . . . . . . . . . . . . . . . 86
mot-clef de SPREAD . . . . . . . . . . . . . . . . . . . . 87
sous-chanes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
sous-programme . . . . . . . . . . . . . . . . . . . . . . . 59, 60
SP, format signe plus . . . . . . . . . . . . . . . . . . . . . . 49
SPACING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15, 143
spcifique . . . . . . . . . . . voir procdure spcifique
SPREAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87, 144
SQRT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139, 163
SS, format sans signe plus . . . . . . . . . . . . . . . . . 49
statique
bibliothque . . . voir bibliothque statique
variable . . . . . . . . . . . . voir variable statique
STATUS=
mot-clef de CLOSE . . . . . . . . . . . . . . . . . . . . 44
mot-clef de OPEN . . . . . . . . . . . . . . . . . . . . . . 42
-std=f2003, option de g95 . . . . . . . . . . . . . . . 170
-std=f2003, option de gfortran . . . . . . . . . 171
-std=f2008, option de gfortran . . . . . . . . . 171
-std=f95, option de g95 . . . . . . . . . . . . . . . . . 170
-std=f95, option de gfortran . . . . . . . . . . . 171
STOP . . . . . . . . . . . . . . . . . . . . . . . . . . 33, 34, 78, 162
'STREAM', argument de ACCESS dans OPEN 42,
50
string . . . . . . . . . . . . . . . voir chane de caractres
structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102, 130
constructeur de . . . . . . . . . . . . . . . . . . . . . . 103
SUBROUTINE . . . . . . . . . . 57, 59, 60, 76, 100, 153
successeur . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15, 142
SUM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86, 144

INDEX

surcharge
doprateur . . . . . . . . . . . . . . . . . . . . . . 25,
de laffectation . . . . . . . . . . . . . . . . . . . . . . .
system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
SYSTEM_CLOCK . . . . . . . . . . . . . . . . . . . . . . . . . . . .

113
114
170
149

T
tableau
profil
diffr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
explicite . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
implicite . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
automatique . . . . . . . . . . . . . . . . . . . . . . . . . . 89
bornes dun . . . . . . . . . . . . . . . . . . 79, 85, 121
constructeur de . . . . . . . . . . . . . . . . . . . . . . . 81
de chanes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
dimensions dun . . . . . . . . . . . . . . . . . . . . . . . 79
dynamique . . . . . . . . . . . . . . . . . . . . . . . . 89, 90
et pointeurs . . . . . . . . . . . . . . . . . . . . . . . . . . 123
tendue dun . . . . . . . . . . . . . . . . . . . . . . . . . . 79
indexation de . . . . . . . . . . . . . 79-82, 85, 133
masque . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
pointeur sur un . . . . . . . . . . . . . . . . . . . . . . 121
profil dun . . . . . . . . . . . . . . . . . . . . 79, 85, 121
rang dun . . . . . . . . . . . . . . . . . . . . . . . . 79, 121
section de . . . . . . . . . . . . . . . . . . . . . . . . . 81, 93
non-rgulire . . . . . . . . . . . . . . . . . . . . . . . 82
rgulire . . . . . . . . . . . . . . . . . . . . . . . 82, 121
taille dun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
tableaux
conformants . . . . . . . . . . . . . . . . . . . . . . . . . . 79
tabulation
dans le code source . . . . . . . . . . . . . . . . . . . . . 6
dans les formats . . . . . . . . . . . . . . . . . . . . . . 49
taille . . . . . . . . . . . . . . . . . . . . . . . . . . . . voir tableau
TAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139, 163
TANH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139, 163
TARGET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16, 119
temps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
THEN . . . . . . . . . . . . . . . . . . . . . . . voir IF ... THEN
TINY . . . . . . . . . . . 14, 18, 143, 155, 157-159, 164
TLn, format tabulation vers la gauche . . . . . . 49
Tn, format tabulation . . . . . . . . . . . . . . . . . . . . . . 49
-traceback, option de ifort . . . . . . . . . . . . . 168
TRANSFER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18, 144
TRANSPOSE . . . . . . . . . . . . . . . . . . . . . . . . . . . 87, 144
TRIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18, 96, 149
TRn, format tabulation vers la droite . . . . . . . 49
TSOURCE=, mot-clef de SPREAD . . . . . . . . . . . . . 87
TYPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102-107
type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79, 111, 160
driv . . . 19, 102-107, 114, 117, 118, 123,
126, 130, 135
implicite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
interoprable . . . . . . . . . . . . . . . . . . . . . . . . 129
intrinsque . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

187

INDEX

variante de . 15, 18-19, 19, 23, 79, 95, 111 zro


TYPE IS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
division par . . . . . . . . . . . . . . . . . . . . . . . . . . 155
en entresortie . . . . . . . . . . . . . . . . 43, 48, 49
U
mise zro de bit . . . . . . . . . . . . . . . . . . . . 144
UBOUND . . . . . . . . . . . . . . . . . . . . . . . . . . . 18, 85, 144
norme IEEE . . . . . . . . . . . . . . . . . . . . 155, 156
underflow . . . . . . . voir dpassement de capacit
remplissage par . . . . . . . . . . . . . . . . . . 87, 144
'UNFORMATTED', argument de FORM dans OPEN
troncature vers . . . . . . . . . . . . . . . . . . . . . . . . 20
42
Zn.p, format hexadcimal . . . . . . . . . . . . . . 48, 52
Unicode . . . . . . . . . . . . . . . . . . . . . . . 43, 46, 95, 166
UNIT= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
mot-clef de CLOSE . . . . . . . . . . . . . . . . . . . . . 44
mot-clef de INQUIRE . . . . . . . . . . . . . . . . . . 45
mot-clef de OPEN . . . . . . . . . . . . . . . . . . . . . . 42
mot-clef de READ . . . . . . . . . . . . . . . . . . . . . . 44
mot-clef de WRITE . . . . . . . . . . . . . . . . . . . . . 45
units logiques . . . . . . . . . . . . . . 38, 41, 42, 44-46
entre standard . . . . . . . . . . . . . . . . . . 38, 169
sortie derreur standard . . . . . . . . . . 38, 170
sortie standard . . . . . . . . . . . . . . . . . . . 38, 169
'UNKNOWN', argument de STATUS dans OPEN 42
UNPACK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87, 144
USE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64, 78
=> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20, 68
ONLY: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
UTF-16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
UTF-32 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
UTF-8 . . . . . . . . . . . . . . . . . . . . . . . . . 43, 46, 95, 166

V
VALUE, attribut dargument . . . . . . . . . . . 16, 131
variable
automatique . . . . . . . 58, 167, 168, 170, 171
locale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
statique . . 16, 17, 58, 58, 65, 76, 167, 168,
170, 171
VERIFY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97, 149
visibilit . . . . . . . . . . . . . . . . . . . . . . . . 62-65, 68, 69

W
-Wall, option de g95 . . . . . . . . . . . . . . . . . . . . . 170
warning . . . . . . . . . . . . . . . . . . . . voir avertissement
-Wconversion, option de gfortran . . . 22, 172
-Wextra, option de g95 . . . . . . . . . . . . . . . . . . . 170
WHERE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84, 89
-Wimplicit-none, option de g95 . . . . . . . . . 170
WRITE
argument de ACTION dans OPEN . . . . . . . 42
instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

X
X, format espace . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
xlf . . . . . . . . . . . . . . . . . . . . . . . . . voir compilateur

Y
Y0 (x), Y1 (x), Yn (x) . . voir BESSEL_Y0/Y1/YN

Z
Z'n' constante entire en hexadcimal . 17, 95

You might also like