5. Structures de contrôle▲
5-1. Les tests▲
5-1-1. Le bloc IF▲
2.
3.
4.
5.
6.
7.
8.
[nom_bloc: ] IF
( exp1 )THEN
bloc1
[ELSE
IF
( exp2 )THEN
[nom_bloc]
bloc2
...
[ELSE
[nom_bloc]
blocn]]
END
IF
[nom_bloc]
- nom bloc une étiquette ;
exp
i une expression de typeLOGICAL
;- bloci une suite d'instructions Fortran.
En l'absence de clause ELSE
lorsque bloc1 est réduit à une seule instruction, la structure IF
se simplifie en :
IF
(exp
) instruction
Exemples
2.
3.
4.
5.
6.
7.
8.
9.
PROGRAM
structure_if
REAL
A,B,SUM
...
IF
(A.LT.
B) THEN
SUM = SUM + A
IF
(SUM >
0.) PRINT
*, SUM
END
IF
...
END
PROGRAM
structure_if
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
PROGRAM
structure_if
REAL
A,HRS
...
IF
(HRS.LE.
40.0) THEN
A = HRS*150.0
ELSE
IF
(HRS.LE.
50.) THEN
A = (HRS-40.0)*150.0*1.5
ELSE
A = (HRS-50.0)*150.0*2.0
END
IF
...
END
PROGRAM
structure_if
5-1-2. Le bloc SELECT-CASE▲
L'instruction SELECT
CASE
permet des branchements multiples qui dépendent de la valeur d'une expression scalaire de type entier, logique ou chaîne de caractères.
2.
3.
4.
5.
6.
7.
[ nom_bloc: ] SELECT
CASE
(expression)
[ CASE
(liste) [ nom_bloc ]
bloc1]
...
[ CASE
DEFAULT
[ nom_bloc ]
blocn]
END
SELECT
[ nom_bloc ]
- nom_bloc est une étiquette ;
- expression est une expression de type
INTEGER
,LOGICAL
ouCHARACTER
; - liste est une liste de constantes du même type que expression ;
- bloci est une suite d'instructions Fortran.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
PROGRAM
structure_case
integer
:: mois, nb_jours
logical
:: annee_bissext
...
SELECT
CASE
(mois)
CASE
(4, 6, 9, 11)
nb_jours = 30
CASE
(1, 3, 5, 7:8, 10, 12)
nb_jours = 31
CASE
(2)
!----------------------------------
fevrier: select
case
(annee_bissext)
case
(.true.
)
nb_jours = 29
case
(.false.
)
nb_jours = 28
end
select
fevrier
!----------------------------------
CASE
DEFAULT
print
*, ' Numéro de mois invalide'
END
SELECT
END
PROGRAM
structure_case
5-2. Les itérations▲
5-2-1. L'instruction GOTO▲
L'instruction GOTO
permet d'effectuer un branchement à un endroit particulier du code :
GOTO
étiquette
Cette instruction est à éviter, car elle peut générer des programmes illisibles et difficiles à corriger.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
PROGRAM
iteration_goto
REAL
diviseur, valeur, facteur
...
valeur = 0. ; diviseur = 360.
69 IF
(diviseur .NE.
0.) THEN
valeur = valeur + facteur / diviseur
diviseur = diviseur - 10.
GOTO
69
END
IF
...
END
PROGRAM
iteration_goto
Cet exemple peut être remplacé par une boucle itérative de type DO
WHILE
.
5-2-2. Les boucles DO▲
Il existe plusieurs types de boucles itératives qui sont toutes de la forme :
2.
3.
[ nom_bloc: ] DO
[contrôle_de_boucle]
bloc
END
DO
[ nom_bloc ]
- nom_bloc est une étiquette ;
- contrôle_de_boucle définit les conditions d'exécution et d'arrêt de la boucle ;
- bloc est une suite d'instructions Fortran.
5-2-2-a. 1re forme : DO indéxé▲
contrôle_de_boucle est de la forme :
variable = expr1, expr2 [,expr3]
avec :
- variable est une variable de type
INTEGER
; - expr1, expr2 et expr3 sont des expressions arithmétiques de type
INTEGER
.
Le nombre d'itérations est évalué avant le démarrage de la boucle.
2.
3.
4.
5.
6.
7.
8.
9.
10.
PROGRAM
iteration_do
INTEGER
i, somme, n
...
! affectation de n
somme=0
DO
i=1,n,2
somme=somme+i
END
DO
...
END
PROGRAM
iteration_do
5-2-2-b. 2e forme : DO WHILE▲
contrôle_de_boucle est de la forme :
WHILE
(expression)
avec expression de type scalaire logique.
Le corps de la boucle est exécuté tant que l'expression est vraie.
Remarque : pour pouvoir sortir de la boucle, il faut que expression puisse prendre la valeur .FALSE.
dans le bloc.
Exemple
Sommation de la série kitxmlcodeinlinelatexdvp\sum_{n\ge 1}1/n^2finkitxmlcodeinlinelatexdvp jusqu'à ce que le terme général soit inférieur à # fois la somme partielle courante :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
PROGRAM
iteration_while
INTEGER
:: n
DOUBLE
PRECISION
:: somme
DOUBLE
PRECISION
, PARAMETER
:: epsilon = 1.d-3
LOGICAL
:: fini
! Initialisation
n = 0
somme = 0.d0
fini = .FALSE.
DO
WHILE
(.not.
fini)
n = n+1
somme = somme + 1d0/n**2
fini = (1d0/n**2 .LT.
epsilon*somme)
END
DO
print
*,"Nombre d'itérations : "
, n
print
*,"Somme = "
, somme
END
PROGRAM
iteration_while
5-2-2-c. 3e forme : DO▲
Ce sont des boucles DO
sans contrôle_de_boucle. Pour en sortir, on utilise une instruction conditionnelle avec une instruction EXIT
.
bloc est de la forme :
2.
3.
bloc1
IF
(expression) EXIT
bloc2
avec :
- expression une expression de type
LOGICAL
; - bloci des séquences de code Fortran.
Notons que la condition IF
peut être remplacée par une instruction de type SELECT
CASE
.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
PROGRAM
iteration_exit
REAL
:: valeur
REAL
:: x, xlast
REAL
, PARAMETER
:: tolerance = 1.0e-6
valeur = 50.
x = 1.0 ! valeur initiale (diff. 0)
DO
xlast = x
x = 0.5 * (xlast + valeur/xlast)
IF
(ABS
(x-xlast)/x <
tolerance) EXIT
END
DO
END
PROGRAM
iteration_exit
5-2-2-d. Instruction CYCLE▲
bloci peut aussi contenir une instruction CYCLE
:
IF
(expression) CYCLE
CYCLE
permet d'abandonner le traitement de l'itération courante et de passer à la suivante.
Là aussi, l'instruction IF
peut être remplacée par une instruction de type SELECT
CASE
.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
PROGRAM
iteration_cycle
INTEGER
:: annee
DO
READ
(*,*) annee
IF
(annee .LE.
0) EXIT
! On élimine les années bissextiles.
IF
( ((annee/4*4 .EQ.
annee) .AND.
&
(annee/100*100 .NE.
annee)) .OR.
&
(annee/400*400 .EQ.
annee) ) CYCLE
PRINT
*,'Traitement des années non bissextiles'
...
END
DO
END
PROGRAM
iteration_cycle