web-dev-qa-db-fra.com

Pour vs en programmation C?

Il y a trois boucles en C: for, while et do-while. Quelle est la différence entre eux?

Par exemple, il semble que presque toutes les déclarations while peuvent être remplacées par des déclarations for, non? Alors, quel est l’avantage d’utiliser while?

70
user355546

Une boucle while évaluera toujours la condition en premier.

while (condition) {
  //gets executed after condition is checked
}

Une boucle do/while sera toujours exécutée le code dans le bloc do{} en premier et ensuite évaluer la condition.

do {
  //gets executed at least once
} while (condition); 

Une boucle for vous permet d'initier une variable de compteur, une condition de vérification et d'incrémenter votre compteur sur une seule ligne.

for (int x = 0; x < 100; x++) {
   //executed until x >= 100
}

À la fin de la journée, toutes les boucles sont encore actives, mais elles offrent une certaine souplesse quant à la manière dont elles sont exécutées.

Voici une bonne explication du raisonnement derrière l'utilisation de chaque type de boucle différent qui peut aider à clarifier les choses. Merci clyfe

La principale différence entre les for 's et la while 's est une question de pragmatique: nous utilisons habituellement for quand il y a un nombre connu d'itérations, et utilisez les constructions while lorsque le fichier Le nombre d'itérations n'est pas connu dans avance. La while vs do ... while La question est aussi de pragmatique, le second exécute les instructions une fois au début, et ensuite il se comporte juste comme le tout simple.


Les boucles sont particulièrement agréables car elles sont concises. Pour cela, boucle

for (int x = 0; x < 100; x++) {
   //executed until x >= 100
}

pour être écrit comme une boucle while, vous devrez faire ce qui suit.

int count = 0;
while (count < 100) {
  //do stuff
  count++;
}

Dans ce cas, il y a juste plus de choses à suivre et le count++; risque de se perdre dans la logique. Cela pourrait être gênant en fonction de l'endroit où count est incrémenté, et si oui ou non elle devrait l'être avant ou après la logique de la boucle. Avec une boucle for, votre variable compteur est toujours incrémentée avant la prochaine itération de la boucle, ce qui ajoute une certaine uniformité à votre code.


Par souci d'exhaustivité, il est probablement utile de parler ici des instructions break et continue qui s'avéreront utiles lors du traitement de la boucle.

break mettra instantanément fin à la boucle en cours et aucune autre itération ne sera exécutée.

//will only run "do stuff" twice
for (int x = 0; x < 100; x++) {
  if (x == 2) {
    break;
  }
  //do stuff
}

continue mettra fin à la itération actuelle et passera à la suivante.

//will run "do stuff" until x >= 100 except for when x = 2
for (int x = 0; x < 100; x++) {
  if (x == 2) {
    continue;
  }
  //do stuff
}

Notez que dans une boucle for, 'continue' évalue l'expression 'part3' de 'for (part1; part2; part3)'; au contraire, dans une boucle while, il saute simplement pour réévaluer la condition de la boucle.

150
Robert Greiner

Si la vitesse et les performances suscitent de vives préoccupations, la meilleure approche consiste à vérifier le code généré par le compilateur au niveau de l’Assembly.

Par exemple, le code suivant montre que le "do-while" est un peu plus rapide. Ceci parce que l'instruction "jmp" n'est pas utilisée par la boucle "do-while".

BTW, dans cet exemple spécifique, le pire des cas est donné par la boucle "pour". :))

int main(int argc, char* argv[])
{
    int i;
    char x[100];

    // "FOR" LOOP:
    for (i=0; i<100; i++ )
    {
        x[i] = 0;
    }

    // "WHILE" LOOP:
    i = 0;
    while (i<100 )
    {
        x[i++] = 0;
    }

    // "DO-WHILE" LOOP:
    i = 0;
    do
    {
        x[i++] = 0;
    }
    while (i<100);

    return 0;
}

// BOUCLE "POUR":

    010013C8  mov         dword ptr [ebp-0Ch],0
    010013CF  jmp         wmain+3Ah (10013DAh)

  for (i=0; i<100; i++ )
  {
      x[i] = 0;
    010013D1  mov         eax,dword ptr [ebp-0Ch]  <<< UPDATE i
    010013D4  add         eax,1
    010013D7  mov         dword ptr [ebp-0Ch],eax
    010013DA  cmp         dword ptr [ebp-0Ch],64h  <<< TEST
    010013DE  jge         wmain+4Ah (10013EAh)     <<< COND JUMP
    010013E0  mov         eax,dword ptr [ebp-0Ch]  <<< DO THE JOB..
    010013E3  mov         byte ptr [ebp+eax-78h],0
    010013E8  jmp         wmain+31h (10013D1h)     <<< UNCOND JUMP
  }

// "WHILE" LOOP:

  i = 0;
  010013EA  mov         dword ptr [ebp-0Ch],0
  while (i<100 )
  {
      x[i++] = 0;
    010013F1  cmp         dword ptr [ebp-0Ch],64h   <<< TEST
    010013F5  jge         wmain+6Ah (100140Ah)      <<< COND JUMP
    010013F7  mov         eax,dword ptr [ebp-0Ch]   <<< DO THE JOB..
    010013FA  mov         byte ptr [ebp+eax-78h],0
    010013FF  mov         ecx,dword ptr [ebp-0Ch]   <<< UPDATE i
    01001402  add         ecx,1
    01001405  mov         dword ptr [ebp-0Ch],ecx
    01001408  jmp         wmain+51h (10013F1h)      <<< UNCOND JUMP
  }

// BOUCLE "DO-WHILE":

i = 0;
.  0100140A  mov         dword ptr [ebp-0Ch],0
  do
  {
      x[i++] = 0;
    01001411  mov         eax,dword ptr [ebp-0Ch]   <<< DO THE JOB..
    01001414  mov         byte ptr [ebp+eax-78h],0
    01001419  mov         ecx,dword ptr [ebp-0Ch]   <<< UPDATE i
    0100141C  add         ecx,1
    0100141F  mov         dword ptr [ebp-0Ch],ecx
    01001422  cmp         dword ptr [ebp-0Ch],64h   <<< TEST
    01001426  jl          wmain+71h (1001411h)      <<< COND JUMP
  }
  while (i<100);
15
psanzani

Par souci de lisibilité

10
hoang

Ils sont tous interchangeables. vous pouvez choisir un type et ne rien utiliser que cela pour toujours, mais en général, un est plus pratique pour une tâche donnée. C'est comme dire "pourquoi avoir switch, vous pouvez simplement utiliser un tas d'instructions if" - vrai, mais s'il est courant de vérifier une variable pour un ensemble de valeurs, c'est pratique et beaucoup plus facile à lire s'il existe une fonctionnalité de langage pour faire ça

10
Michael Mrozek

Si vous voulez qu'une boucle s'exécute tant qu'une condition est vraie et non pour un certain nombre d'itérations, il est beaucoup plus facile de comprendre pour quelqu'un d'autre:

while (cond_true)

que quelque chose comme ceci:

for (; cond_true ; )
8
Justin Ethier

N'oubliez pas qu'une boucle for est essentiellement une boucle fantaisie while. Ils sont la même chose.

while <some condition is true> {
   // do some stuff
   // possibly do something to change the condition
}


for ( some var, <some condition is true>; increment var ) {

}

L'avantage d'une boucle for est qu'il est plus difficile de créer accidentellement une boucle infinie. Ou plutôt, c'est plus évident quand vous en faites une parce que vous mettez généralement la boucle var dans l'instruction initiale. 

Une boucle while est plus claire lorsque vous ne faites pas de schéma d'incrémentation standard. Par exemple:

int x = 1;
while( x != 10 ) {
  if ( some condition )
     x = 10;
  else 
     x += 5;
}
5
Armstrongest

Un malentendu courant avec les boucles whilefor que j'ai vues est que leur efficacité est différente. Les boucles While et les boucles for sont _/tout aussi efficaces. Je me souviens que mon professeur d’informatique au lycée m’a dit que les boucles for sont plus efficaces pour les itérations lorsque vous devez incrémenter un nombre. Ce n'est pas le cas.

Les boucles For sont simplement syntaxiquement sucréeswhile et rendent le code d’itération plus rapide à écrire.

Lorsque le compilateur prend votre code et le compile, il le traduit en une forme plus facile à comprendre et à exécuter par l'ordinateur (Assemblage). Au cours de cette traduction, les différences subtiles entre les syntaxes while et for sont perdues et deviennent exactement les mêmes.

4
Cam

Vous devriez utiliser une telle boucle, qui correspond le mieux à vos besoins ... Par exemple:

for(int i = 0; i < 10; i++)
{
    print(i);
}

//or

int i = 0;
while(i < 10)
{
    print(i);
    i++;
}

Évidemment, dans une telle situation, "pour" est plus beau que "tant que" . Et "faire tant que" devraient être utilisés lorsque certaines opérations doivent être effectuées avant le moment où la condition de votre boucle sera vérifiée.

Désolé pour mon mauvais anglais).

4
abespalov

Une for suggère une itération fixe en utilisant un index ou des variantes de ce schéma.

while et do... while sont des constructions que vous utilisez quand une condition doit être vérifiée à chaque fois (à l'exception d'une construction semblable à l'index, voir ci-dessus). Ils diffèrent lorsque la première exécution du contrôle de condition est effectuée.

Vous pouvez utiliser l'une ou l'autre construction, mais ils ont leurs avantages et leurs inconvénients en fonction de votre cas d'utilisation.

3
Pieter

J'ai remarqué il y a quelque temps qu'une boucle For génère généralement plusieurs instructions machine de plus qu'une boucle while. Cependant, si vous regardez de près les exemples, qui reflètent mes observations, la différence est deux ou trois instructions machine, qui ne méritent guère d’être considérées.

Notez également que l'initialiseur d'une boucle WHILE peut être éliminé en l'insérant dans le code, e. g.:

static int intStartWith = 100;

Le modificateur static insère la valeur initiale dans le code en enregistrant (tambour) un instruction MOV. Plus important encore, le fait de marquer une variable pendant que static le déplace en dehors du cadre de la pile. Si l'alignement des variables le permet, il peut également produire un code légèrement plus petit, car l'instruction MOV et ses opérandes prennent plus de place qu'une valeur entière, booléenne ou caractère (ANSI ou Unicode).

Toutefois, si les variables sont alignées sur des limites de 8 octets, un paramètre par défaut commun, un int, un bool ou un code intégré dans TCHAR coûte le même nombre d'octets qu'une instruction MOV.

3
David A. Gray

Ils sont tous les mêmes dans le travail qu'ils font. Vous pouvez faire les mêmes choses en utilisant n'importe lequel d'entre eux. Mais pour la lisibilité, la convivialité, la commodité, etc., ils diffèrent.

2
rahmivolkan

Une différence entre while et do-while est que while vérifie la condition de boucle et, le cas échéant, le corps est exécuté et la condition vérifiée à nouveau. Le do-while vérifie la condition après l'exécution du corps, ainsi avec do-while le corps est exécuté au moins une fois.

Bien sûr, vous pouvez écrire une boucle while en tant que do-while et vv, mais cela nécessite généralement un peu de duplication de code.

2
muksie

Les boucles for (au moins en considérant C99) sont supérieures aux boucles while car elles limitent la portée de la ou des variables incrémentées.

Les boucles Do While sont utiles lorsque la condition dépend de certaines entrées. Ce sont les trois types de boucle les plus rarement utilisés.

2
helpermethod

Entre pour et pendant: while n'a pas besoin d'initialisation ni d'instruction update, elle peut donc sembler meilleure, plus élégante; for peut avoir des instructions manquantes, une ou deux, c'est donc la plus souple et la plus évidente si vous avez besoin d'initialisation, de conditions de boucle et de "mise à jour" avant la boucle. Si vous n'avez besoin que de la condition de boucle (testée au début de la boucle), alors while est plus élégant.

Entre pour/while et do-while : dans do-while, la condition est évaluée à la fin de la boucle. Plus confortable si la boucle doit être exécutée au moins une fois.

2
ShinTakezou

WHILE est plus flexible. FOR est plus concis dans les cas où il s’applique.

FOR est idéal pour les boucles qui ont un compteur, comme

for (int n=0; n<max; ++n)

Vous pouvez accomplir la même chose avec un WHILE, bien sûr, comme d'autres l'ont fait remarquer, mais maintenant, l'initialisation, le test et l'incrément sont répartis sur trois lignes. Peut-être trois lignes largement séparées si le corps de la boucle est grand. Cela rend plus difficile pour le lecteur de voir ce que vous faites. Après tout, bien que "++ n" soit une troisième pièce très commune du FOR, ce n’est certainement pas la seule possibilité. J'ai écrit beaucoup de boucles où j'écris "n + = incrément" ou une expression plus complexe.

FOR peut également bien fonctionner avec des objets autres qu'un comptoir, bien sûr. Comme

for (int n=getFirstElementFromList(); listHasMoreElements(); n=getNextElementFromList())

Etc.

Mais FOR tombe en panne lorsque la logique de "la prochaine fois dans la boucle" devient plus compliquée. Considérer:

initializeList();
while (listHasMoreElements())
{
  n=getCurrentElement();
  int status=processElement(n);
  if (status>0)
  {
    skipElements(status);
    advanceElementPointer();
  }
  else
  {
    n=-status;
    findElement(n);
  }
}

En d’autres termes, si le processus d’avancement peut être différent en fonction des conditions rencontrées lors du traitement, une instruction FOR n’est pas pratique. Oui, parfois, vous pouvez le faire fonctionner avec des expressions assez compliquées, en utilisant le ternaire?: Opérateur, etc., mais cela rend généralement le code moins lisible que plus lisible.

En pratique, la plupart de mes boucles passent soit par un tableau, soit par une structure. Dans ce cas, j'utilise une boucle FOR; ou lisez un fichier ou un ensemble de résultats à partir d'une base de données, auquel cas j'utilise une boucle WHILE ("while (! eof ())" ou quelque chose du genre.

2
Jay

Une particularité du do while est qu'il vous faut un point-virgule après la fin. Il est souvent utilisé dans les définitions de macro pour exécuter plusieurs instructions une seule fois tout en limitant l'impact de la macro. Si les macros sont définies en tant que blocs, des erreurs d'analyse peuvent survenir.

Une explication parmi d'autres

2
LB40

Ils sont à peu près les mêmes sauf pour la boucle do-while. La boucle for est utile lorsque vous avez un type de variable counter. Cela le rend évident. La boucle while est utile dans les cas où un drapeau est vérifié, comme indiqué ci-dessous:

while (!done) {
   if (some condtion) 
      done = true;
}
2
fastcodejava

Les instructions while et for peuvent toutes deux être utilisées pour la lecture en boucle dans la programmation. Cela dépendra du programmeur si la boucle while ou for est utilisée. Certains sont à l'aise avec la boucle while et d'autres avec la boucle for.

Utilisez n'importe quelle boucle que vous aimez. Cependant, la boucle do...while peut être quelque peu délicate en programmation C .

0
Ranjit Bhatta

/*while boucle

5 dollars

1 chocolat = 1 dollars

while my money is greater than 1 bucks 
  select chocolate
  pay 1 bucks to the shopkeeper
  money = money - 1
end

venir à la maison et ne peut pas aller tout en magasin parce que mon argent = 0 dollars * /

#include<stdio.h>
int main(){
  int money = 5;

  while( money >= 1){   
    printf("inside the shopk and selecting chocolate\n");
    printf("after selecting chocolate paying 1 bucks\n");
    money = money - 1 ;  
    printf("my remaining moeny = %d\n", money);
    printf("\n\n");
  }

  printf("dont have money cant go inside the shop, money = %d",  money);

  return 0;
} 

argent infini

while( codition ){ // condition will always true ....infinite loop
  statement(s)
}

veuillez visiter cette vidéo pour une meilleure compréhension https://www.youtube.com/watch?v=eqDv2wxDMJ8&t=25s

/*for loop

5 dollars

for my money is greater than equal to 1 bucks   0      money >= 1
  select chocolate
  pay 1 bucks to the shopkeeper
  money = money - 1  1-1 => 0
end

* /

#include<stdio.h>
int main(){

  int money = 5;
  for( ; money >= 1; ){     0>=1  false 
    printf("select chocolate \n");
    printf("paying 1 bucks to the shopkeeper\n");
    money = money - 1;    1-1 = 0
    printf(" remaining money =%d\n", money);
    printf("\n\n");
  }

  return 0;
}

Pour une meilleure compréhension, consultez la page https://www.youtube.com/watch?v=_vdvyzzp-R4&t=25s .

0
sandeep bairwa