web-dev-qa-db-fra.com

Pourquoi utiliser une boucle for au lieu d'une boucle while?

Doubles possibles:
Itérer avec une boucle for ou une boucle while?
Boucles en C - pour () ou while () - qui est le meilleur?

Quand faut-il utiliser une boucle for au lieu d'une boucle while

Je pense que les boucles suivantes sont identiques, à l'exception de leur syntaxe. Si oui, alors pourquoi en choisir un sur l’autre?

int i;
for (i = 0; i < arr.length; i++) {
  // do work
}

int i = 0;
while (i < arr.length) {
  // do work
  i++;
}
67
Ziggy

Dans votre cas, vous ne gagnez pas grand chose en plus d’une ligne de code en moins dans la boucle for.

Cependant, si vous déclarez la boucle comme ceci:

for(int i = 0; i < x; i++)

Vous parvenez à conserver i dans la portée de la boucle, au lieu de la laisser échapper au reste du code.

De plus, dans une boucle while, vous avez la déclaration de variable, la condition et l'incrémentation à 3 endroits différents. Avec la boucle for, il s’agit d’un seul endroit pratique et facile à lire.

Dernière pensée:
Une autre note importante. Il y a une différence sémantique entre les deux. Les boucles While, en général, sont censées avoir un nombre indéfini d’itérations. (c’est-à-dire jusqu’à ce que le fichier ait été lu, peu importe le nombre de lignes qu’il contient), et les boucles for devraient avoir un nombre plus précis d’itérations. (Parcourez tous les éléments d'une collection, que nous pouvons compter en fonction de la taille de la collection.)

100
jjnguy

Il y a une raison de choisir for sur while: Lisibilité.

En utilisant une boucle for, vous indiquez expressément que votre intention est d'effectuer un type d'opération nécessitant une initialisation, une opération "étape" et une condition d'achèvement.

Avec while, par contre, vous dites seulement que vous avez besoin de la condition d'achèvement.

85
Reed Copsey

J'utilise 'while' lorsque je n'ai pas nécessairement besoin d'un compteur, par exemple lorsque vous lisez un fichier et que vous attendez d'atteindre EOF. Dans ce cas, "pour" peut ne pas être la meilleure alternative. Lorsque vous parcourez les éléments d'un tableau, je préfère utiliser «pour», car il traduit mieux l'intention.

35
Otávio Décio

La différence notable entre une boucle for () et une boucle while () est la suivante: une instruction "continue" dans une boucle while () se branche en haut de la boucle, tandis qu'une dans une boucle for () passe à la troisième partie de la clause for () [celle qui suit la condition, habituellement utilisée pour renverser des variables].

27
supercat

En tant qu'enseignant, j'ai réfléchi à cette question sous différentes formes. ma suggestion se résume toujours à

  • for- Les boucles servent à compter. décompter, décompter.
  • Les constructions while/do-while s'appliquent à toutes les autres conditions. c!=EOF, diff<0.02, etc . Les itérateurs/énumérateurs sont des compteurs très appropriés pour les boucles for.

c'est-à-dire que votre int=0; while( ... ) est hideux à mes yeux.

16
Captain Giraffe

Pourquoi choisir Coca-Cola plutôt que Pepsi?

Entre une boucle WHILE et FOR, vous pouvez les utiliser de manière interchangeable. Pour être puriste, vous pouvez prendre votre décision en fonction de la nature des conditions. Si vous effectuez une boucle basée sur le nombre, une boucle FOR aurait le plus de sens.

for( cur = 0; cur < myList.Length; cur++ ){
    doSomething( myList[cur] );
}

Si vous effectuez une boucle basée sur la logique, alors un WHILE serait l’implémentation la plus propre.

Iterator i = myObject.getIterator();
while( i.hasNext() ){
    doSomething( i.next() );
}
15
Babak Naffas

Comme vous le dites, les raisons sont sémantiques et esthétiques plutôt que la performance (leur code compilé a tendance à être très similaire).

Cela dit, for est habituel dans les cycles comportant un nombre connu d'itérations, alors que while implique que la condition n'est pas nécessairement corrélée à ce que vous faites dans le cycle, ou que vous ne savez pas au début combien d'itérations Il y aura.

7
Piskvor

Généralement, je préfère toujours les boucles, même dans les cas où la boucle n’a rien à voir avec le comptage, car elle localise la maintenance de la boucle à un seul endroit. Lorsque quelqu'un d'autre se présente et décide d'ajouter/de modifier la boucle, s'il utilise une boucle FOR, la personne qui effectue la modification peut généralement être sûre de cela, tant qu'elle ne joue pas avec les éléments contenus dans la ou les expressions FOR. , ils ne vont pas briser l'itération dans la boucle.

Cependant, quelque chose comme une boucle while nécessite que le programmeur analyse complètement le corps de la boucle et comprenne comment il itère, afin de s'assurer qu'il conserve le code de maintenance de la boucle non modifié et dans le bon ordre lors de ses modifications.

Par conséquent, je seulement utilise WHILE dans les cas où je n’ai effectivement besoin que de la partie centrale du FOR.

7
Billy ONeal

Ils sont fonctionnellement identiques, cependant, on peut affirmer que la boucle for est moins sujette aux erreurs, car toutes les fonctionnalités de la boucle se trouvent ensemble. Si vous avez plusieurs lignes séparant la déclaration de i, la déclaration de durée et l'itérateur d'index, vous pouvez oublier ou être dérouté par son utilisation. Tout cela est subjectif bien sûr.

4
Matthew Vines

Ils compileront généralement vers le même résultat final. Je préfère pour ou pour chacun la plupart du temps. L'écriture 

for (;x<5;x++){ 
    //do work 
} 

n'est pas si sinistre, mais écrire

while(x<5){
    x++
    //do work
}

au lieu de 

while(x<5){
    //do work
    x++
}

pourrait dérouter certaines personnes et causer des erreurs inattendues.

3
gtrak

Dans un langage comme Pascal, les constructions for et while ont des applications différentes. Vous écririez une boucle for en Pascal comme suit:

for i := 1 to 5 do
begin
{ some code here }
end

Donc, vous déclarez explicitement que i est incrémenté de 1. Aucune condition de terminaison n'est explicitement spécifiée ici. Ainsi, vous pouvez utiliser une boucle for uniquement aux endroits où vous savez que la boucle s'exécutera pendant un certain nombre de fois prédéterminé avant le début de l'exécution de la boucle. D'autre part, vous pouvez spécifier une condition de fin explicite dans le cas d'une boucle while.

i:=0;
while (i<>5) do
begin
{ some code here }
i:=i+1;
end

Ainsi, une boucle while est beaucoup plus flexible. Plus tard, lorsque C a été développé, bien que for et While soient pris en charge, la signification de la construction for a changé et vous pouvez ajouter des conditions de terminaison explicites à l'aide d'opérateurs booléens. Ainsi, la puissance de while et for dans les langages C et C est la même et devient donc davantage un problème de lisibilité qu'un problème d’utilisabilité.

3
Anand

Au début de la programmation, une structure de données prédominante était le tableau linéaire (ou vecteur) et un motif répétitif devait parcourir et utiliser chaque élément du tableau. Ce scénario était si habituel que les langages incluaient une syntaxe spécifique pour ce modèle: la boucle for. Mis à part cet héritage historique, vous pouvez utiliser la boucle while bien (de nos jours, avec des langages fonctionnels comme F #, vous préférez utiliser List.map ou List.fold ;-)

3
Edgar Sánchez

C'est principalement une question de lisibilité. Généralement, utilisez les boucles for lorsque vous avez une plage de valeurs définie à parcourir. Utilisez les boucles while lorsque vous n'itérez pas ou ne savez pas quand votre condition de sortie sera vraie.

Du point de vue de Java, je trouve les boucles très utiles pour les collections:

for (Object o : objects){
    o.process();
}

est beaucoup plus facile à lire que:

int i=0;
while(i < objects.size()){
    objects.get(i).process();
    i++;
}
3
dpatchery

En jetant un coup d'œil sur les autres (très bonnes) réponses, il y a un point que je n'ai pas vu se faire comprendre. (Si cela s'est fait, je l'ai manqué et je m'excuse.)

Je vais vous donner deux extraits de code apparemment identique sémantiquement.

Extrait # 1:

for (int a = 0; a < arr.length; a++) {
  /* do some work here */
}

Extrait # 2:

int b = 0;
while (b < arr.length) {
  // do work
  b++;
}

On dirait qu'ils font la même chose, non? Maintenant, laissez-moi ajouter une seule ligne à chaque extrait et voyons ce qui se passe:

Extrait # 3:

for (int c = 0; c < arr.length; c++) {
  /* do some work here */
}
printf("%d\n", c);

Extrait # 4:

int d = 0;
while (d < arr.length) {
  // do work
  d++;
}
printf("%d\n", d);

Ainsi, lorsque je compile un fichier indésirable avec ces quatre extraits incorporés (plus un peu de colle pour que arr.length signifie quelque chose), j'obtiens l'erreur suivante:

$ clang junk.c
junk.c:20:17: error: use of undeclared identifier 'c'
        printf("%d\n", c);
                       ^
1 diagnostic generated.

Il s'avère que l'utilisation de la boucle for vous permet de donner plus de localité à vos variables de compteur factices, etc. Cela vous donne une plus grande marge de manœuvre pour réutiliser des noms de variables sans risque de collision (bien qu'au risque d'accroître l'ombrage potentiel).

Il existe une différence sémantique entre les boucles for et while. Avec les boucles for, le nombre d'itérations est prédéfini, alors qu'avec les boucles while, il n'est pas nécessaire.

Certaines langues (telles que Ada) l'appliquent en faisant en sorte que la boucle for devienne une constante du corps de la boucle. Par conséquent, il serait illégal de dire, par exemple:

for i in values'range loop
   ...
   i := i + 1;   -- this is illegal, as i is a constant within the loop body
end if;

Cette différence sémantique, cependant, n’est pas aussi claire avec la plupart des langages, qui ne considèrent pas le compteur de boucles for comme une constante.

1
Schedler

Choisissez-en un, puis copiez-le/collez/ajustez-le dans vos projets. Moins de décisions, moins de dactylographie, un codage plus rapide. Différence de performance négligeable.

De plus, je ne suis pas avec Justin en gardant i dans la portée de la boucle, ET j'utilise aussi var aL = array.length hors de la boucle. Ensuite, utilisez i et aL dans le constructeur de boucle for afin de ne pas recalculer la longueur du tableau sur chaque hit (avec une création var à répétition;)). Encore neg. vraiment les performances (voir la première partie de ma réponse), à ​​moins que de très grands tableaux volent autour. Si vous connaissez la longueur du tableau en amont, lancez-le d'abord avec sa longueur fixe (aide légère pour l'allocation de mémoire sur des navigateurs de mauvaise qualité;) s'il s'agit du côté client et que vous avez beaucoup de données).

js exemple

<script>
var i=0;
var myArray = ["D","R","Y"];//literal style will do for now;)
var aL=myArray.length; //or use 3 if known upfront
for(i;i<aL;i++){/*always do DRY things here*/}
</script>

assurez-vous également que, lorsqu'une condition est remplie, demandez-vous "Ai-je encore besoin de terminer la boucle?" Sinon, n'oubliez pas de vous échapper le plus tôt possible.

1
fullstacklife

En règle générale, la différence entre une boucle while et une boucle for est liée à la syntaxe et non aux performances. Cela dit, il semble que cette question ait déjà été posée pour Java: Java pour la boucle par rapport à la boucle while. Différence de performance?

1
simeonwillbanks

Tout simplement:

Une boucle 'pour' a tendance à être utilisée pour un usage itératif. Vous devez parcourir un tableau, vous avez besoin des nombres de 1 à 100 (ou d’autres plages) pour diverses raisons.

Une boucle 'while' a tendance à être une boucle conditionnelle. Vous voulez continuer à faire quelque chose jusqu'à ce qu'une contition soit fausse. En supposant que vous ayez une classe appelée "Toast" et que vous vouliez faire cuire le pain grillé jusqu'à ce qu'il soit toasté, vous obtiendriez quelque chose comme ce qui suit:

while (!toast.isToasted) cook(toast);

Vous pouvez presque toujours (je ne peux pas penser à un exemple où vous ne pouvez pas le faire) écrire une boucle for en tant que boucle while et une boucle while en tant que boucle for, mais choisir celle qui convient le mieux en premier est généralement la mienne. points ci-dessus.

1
Anthony

Trucs connexes:

Dans la nouvelle langue Go de Google , ils ont décidé de ne pas inclure l'instruction while. Au lieu de cela, ils vous permettent d’écrire une instruction pour qui n’a que la clause condition. Donc l'équivalent de 

while (a < b) { ... }

est simplement

for a < b { ... }
1
Samuel Jack

La lisibilité est un point très important, mais il fonctionne dans les deux sens. Je vais convertir une boucle for en une boucle while, même lorsque j'utilise une variable de compteur ou qu'elle serait autrement "naturelle", alors que c'est plus lisible. Ceci est courant lorsque vous avez une expression longue ou complexe dans l'une des trois parties ou dans plusieurs compteurs de (ce qui est lié à la complexité).

Knuth's loop-and-half fonctionne également mieux, dans plusieurs langues, comme une boucle infinie avec une pause, plutôt que comme une boucle for.

Cependant, il existe une différence sémantique très importante:

for (int i = 0; i < arr.length; i++) {
  if (filter(arr[i])) continue;
  use(arr[i]);
}

int i = 0;
while (i < arr.length) {
  if (filter(arr[i])) continue;
  use(arr[i]);
  i++;
}
1
Roger Pate

Lisibilité. Et du vieux VB 6 jours de wend chaque fois que je vois un moment, je veux pleurer.

Il y a des cas où les boucles sont bonnes à utiliser. L'appel d'une fonction sur un objet qui retourne true/false mais itère une valeur à l'intérieur de cet objet.

Exemple: un DataReader en C #:

List<string> strings = new List<string>();
while(DataReader.Read())
{
  strings.Add(DataReader["foo"].ToString());
}

Une boucle for vous permet d'encapsuler votre travail dans une fonction, ce qui permet une meilleure gestion de la mémoire. De plus, s'il y a une erreur dans votre boucle while, cela pourrait dégénérer en une boucle incontrôlable qui menace toute vie:

bool keepGoing = true;
while(keepgoing)
{
   try
   {
     //something here that causes exception, fails to set keepGoing = false;
     keepGoing = false;
   }
   catch(Exception)
   {
    //Do something, but forget to set keepGoing.
    //maybe there is always an exception...
   }

}

Je pense aussi que c'est juste une pratique générale. Un peu comme dans la construction. Vous utilisez des clous pour mettre des plats de toiture sur les poteaux. Vous "pourriez" utiliser des vis, ils feraient le même travail, mais ce n'est tout simplement pas une pratique courante.

Personne ne dit que c'est faux, nous disons simplement "s'il vous plaît pliez-vous sous la pression de vos pairs pour que le monde du codage fonctionne".

1
Ryan Ternier

car ce dernier peut être un liner: while (++ i <arr.length) {// fonctionne}

0
Devrim

C'est juste ma logique que nous utilisons généralement pour boucle lorsque nous connaissons le nombre exact de nos itérations et nous utilisons une boucle while lorsque nous voulons généralement vérifier une condition. Sinon, ils ont tous deux le même comportement.

0
Prateek

Utilisez for-loop quand c'est approprié. La solution while présente des inconvénients syntaxiques (plus longs) et vous devez vérifier que vous incrémentez i avant tout appel continu dans la boucle.

0
Karel Petranek

Préférence. Pour moi, toute la logique de bouclage est intégrée à l'instruction for. Vous n'avez donc pas à déclarer la variable compteur ni à effectuer les opérations d'incrémentation/décrémentation dans la boucle réelle. En outre, vous pouvez déclarer le compteur/index local à l'instruction for.

0
Wix

Une des raisons est que la condition d'un moment peut être une chaîne.

En outre, si nous ajoutons 'Do' au mélange, nous pouvons utiliser une boucle do while lorsque nous voulons que l'opération soit exécutée au moins une fois, quel que soit son état actuel.

0
Mild Fuzz

Une boucle while, définie comme

while(condition)

représente ce modèle de programmation:

1:
if(!condition) goto 2;
...
goto 1;
2:

Considérant qu’une boucle for, définie comme

for(var i = seed; condition; operation)

représente ce motif:

var i = seed
1:
if(!condition) goto 2;
...
operation;
goto 1;
2:

Les deux modèles sont si couramment utilisés qu'ils ont été nommés et intégrés dans des langages.

Si vous devez définir un compteur pour contrôler votre boucle, utilisez une boucle for. Sinon, utilisez une boucle while.

0
Chris Johnson

Les boucles sont souvent plus faciles à paralléliser. Comme le programme peut dire à l'avance le nombre d'itérations qui seront effectuées et la valeur de l'itérateur à tout moment, la parallélisation à l'aide d'une API telle que OpenMP est triviale. Bien sûr, si vous prenez des pauses, continue et change d'itérateur manuellement, cet avantage disparaît.

0
Rob