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 ;
expi 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) instructionExemples
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,LOGICALouCHARACTER; - 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 étiquetteCette 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) CYCLECYCLE 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


