La dernière forme de boucle permet de fixer à l'avance le nombre d'itérations à réaliser. Juste avant l'exécution, le compilateur calcule le nombre d'étapes à effectuer. On peut ainsi ré-écrire while_1 (partie 6.2) comme la boucle qui repète n fois le cumul dans somme du terme i courant et de la somme calculée à présent:
-- Boucle for_1 for i in 1..n loop somme := somme + i; end loop;
On lit:
``pour les valeurs de i qui vont de
i = 1 à i = n,
calculer somme := somme + i''.
Sémantique:
Les instruction entre loop et end loop
sont exécutées succésivement pour
chacune des valeurs de l'intervalle de repétition (ici,
l'intervalle est 1..n).
Une fois la dernière itération finie,
le contrôle du programme passe à l'instruction après
le end loop.
Dans cet exemple, l'instruction somme := somme + i est
exécutée pour
des valeurs de i = 1, 2, 3 ...jusqu'à i = n. Elle est donc
exécutée n fois. De manière générale, le corps de
la boucle est exécuté (fin - debut + 1) fois, si
debut est la valeur initiale donnée à l'indice de la boucle
et fin est sa valeur finale. La syntaxe d'une boucle for
suit le schéma:
for identificateur in [ reverse ]
intervalle loop |
sequence_instructions |
end loop |
Déclaration implicite de l'indice
L'identificateur i (qui peut, biensûr, s'appeler autrement)
utilisé comme indice d'une
boucle for est toujours déclaré implicitement
par le compilateur.
Cela veut dire qu'il n'est pas nécessaire de
déclarer i parmi les identificateurs du programme.
Le fait d'etre l'indice de la boucle fait qu'il est
considéré
en tant qu'identificateur
constant et de même type que celui de l'intervalle de
repétition (donné ici par 1..n, de type integer).
De plus, une fois la boucle finie, la liaison pour
i cesse d'être active. Par conséquent, i ne peut
pas être modifiée
par les instructions
du corps de la boucle (car il est implicitement déclaré
en tant que constante),
et il ne peut pas être utilisé en dehors de celle-ci non
plus (car, une fois dehors, il n'est plus déclaré).
Valeurs de l'intervalle
On peut écrire des boucles dont les valeurs de l'intervalle changent dans l'ordre décroissant:
for i in reverse 1..n loop ... end loop;
De même, l'intervalle d'itération peut être nul (si par exemple, dans le code précédent, n est 0 ou négatif). Dans ce cas, le corps de boucle n'est jamais exécuté. Enfin, l'intervalle de repétition est calculé une fois pour toutes avant de commencer la première itération (plutôt que d'être ré-évalué avant chacune d'entre elles). Ainsi, il est impossible de changer le nombre d'itérations dynamiquement dans la boucle. Dans l'exemple:
n:= 5; for i in 1..n loop ... n := 20; end loop;
les actions dans le corps sont exécutées 5 fois malgré l'affectation n:= 20.