De nombreuses personnes ont l'air de ne pas trop savoir quelles boucles choisir, lorsqu'il faut utiliser des itérations dans un algorithme.
Je vais donc expliquer ici dans quel cas il est préférable d'utiliser un for, un while, ou un do.
Tout d'abord, il faut savoir que chaque boucle peu être paramétrée de façon a agir comme n'importe quelle autre boucle.
Vous pouvez n'utiliser que des for par exemple, mais syntaxiquement, ce n'est pas intéressant.
EquivalencesforLe code suivant utilisant for peut être écrit avec tous les types de boucles:
- Code:
-
for(i=0; i<5; i+=1) {
draw_text(16, 16*i, "TMY!")
}
- Code:
-
i=0
while(i<5) {
draw_text(16, 16*i, "TMY!")
i += 1
}
- Code:
-
i=0
if(i<5)
do {
draw_text(16,16*i, "TMY!")
i += 1
} until !(i<5)
- Code:
-
i=0
repeat(5) {
draw_text(16,16*i, "TMY!")
i += 1
}
On remarqueras qu'écrire un for avec un do est vraiment lourd syntaxiquement.
Avec les autres boucles on ajoute minimum 2 lignes de code.
while - Code:
-
for({};x<300;{})
x += 1
- Code:
-
while(x < 300)
x += 1
- Code:
-
if(x < 300)
do
x += 1
until !(x < 300)
- Code:
-
if(x < 300)
repeat(1000000000) { // Millemillemille
x += 1
if( !(x < 300) ) break
}
Dans ce cas, c'est le repeat qui n'est pas du tout adapté.
do - Code:
-
i = true
for({};i;{}) {
x = random(640)
y = random(480)
if(place_free(x, y))
i = false
}
- Code:
-
i = true
while(i) {
x = random(640)
y = random(480)
if(place_free(x, y))
i = false
}
- Code:
-
do
{
x = random(640)
y = random(480)
} until(place_free(x, y))
- Code:
-
repeat(1000000000) { // Miilleumillemille
x = random(640)
y = random(480)
if(place_free(x, y))
break
}
Ecrire un do avec une autre boucle est très fastidieux...
Pour le repeat, cela ressemble fortement au for, inutile donc tout réécrire.
Utiliser correctement forComme vu précédemment, il n'y a que deux façons de faire une boucle dont on connais le nombre d'itérations sans utiliser une syntaxe vraiment moche.
Si l'on veux répéter x fois un bout de code, il suffit d'utiliser repeat.
Si l'on veux connaitre l'iteration dans la boucle, il faudra utiliser une boucle for.
Exemple:
- Code:
-
for(i=0; i<10; i+=1)
draw_text(16, 16*i, "Iteration n" + string(i))
De plus la boucle for est très puissante, vous pouvez y initialiser plusieurs variables, vérifier plusieurs conditions, etc:
- Code:
-
for({i=0; j=0}; i<=j && j<1000; {i+=1; j+=i})
draw_text(2*j, 16*i, "OoooOOoOoOoOoOooo...")
Il est aussi de condenser du code, si vous aimez écrire du code incompréhensible:
- Code:
-
for(i=0; i<10; { draw_text(16, 16*i, i); i+=1 }) {}
Toutes les opérations de "balayage" se font avec des loop for imbriquées:
- Code:
-
for(i=0; i<10; i+=1)
for(j=0; j<10; j+=1)
{
draw_text(32*i, 32*j, "("+string(i)+";"+string(j)+")")
}
J'ai vu de nombreuses fois une utilisation de ce type:
- Code:
-
for({var i; i=0}; i<10; i+=1)
draw_text(16,16*i,i)
Cette syntaxe est inutile, car la variable i ne seras de toute façon détruite qu'en dehors du 'piece of code', et non pas a la fin du for.
Vous pouvez donc utiliser une syntaxe plus légère pour le même résultat:
- Code:
-
var i;
for(i=0; i<10; i+=1)
draw_text(16,16*i,i)
Utiliser correctement whileLe while s'utilise lorsque vous ne connaissez pas a l'avance le nombre d'itérations a effectuer.
Il est souvent utilisé pour le tirage de nombre aléatoires.
Exemple d'utilisation dans un démineur:
- Code:
-
find = false
while(!find) {
// on tire une cellule au hazard
xx = random(640) div 16
yy = random(480) div 16
// on regarde si elle est vide
if(emptyCell(xx, yy))
{
setCell(xx, yy, MINE) // on la remplie
find = true
}
}
Le while peut aussi être utilisé pour alléger les imbrications de if.
Dans ce cas on l'utiliseras un peu comme un label/goto:
- Code:
-
while(1)
{
if(!cond1) // goto label
break
toto()
if(!cond2) // goto label
break
blabla()
break
}
// label
Ce qui aurais donné avec des if:
- Code:
-
if(cond1) {
toto()
if(cond2) {
blabla
}
}
Avec deux conditions il vaux mieux utiliser des if, mais lorsqu'on se retrouve avec une dizaine de conditions le while permet d'éclaircir grandement le code.
Utiliser correctement doLe do est a utiliser a peu près dans les même cas que le while, a une chose près, c'est qu'il exécuteras toujours au moins une itération.
Son utilisation est plutôt rare, mais comme je l'ai montré plus haut, utiliser une autre boucle pour faire un do est vraiment très moche, alors n'oubliez pas cette boucle même si elle n'est pas fréquemment utilisée...