De retour dans mes jours C/C++, codant une "boucle infinie" comme
while (true)
senti plus naturel et semblait plus évident pour moi par opposition à
for (;;)
Une rencontre avec PC-lint à la fin des années 1980 et les discussions sur les pratiques optimales qui ont suivi ont rompu avec cette habitude. J'ai depuis codé les boucles à l'aide de l'instruction de contrôle for
. Aujourd'hui, pour la première fois depuis longtemps et peut-être mon premier besoin d'une boucle infinie en tant que développeur C #, je suis confronté à la même situation. Est-ce que l'un d'eux est correct et l'autre non?
while(true)
{
}
Est-ce toujours ce que j'ai utilisé et ce que j'ai vu d'autres utiliser pour une boucle qui doit être cassée manuellement.
Le compilateur C # transformera les deux
for(;;)
{
// ...
}
et
while (true)
{
// ...
}
dans
{
:label
// ...
goto label;
}
Le CIL pour les deux est le même. La plupart des gens trouvent que while(true)
est plus facile à lire et à comprendre. for(;;)
est plutôt cryptique.
J'ai joué un peu plus avec .NET Reflector , et j'ai compilé les deux boucles avec l'option "Optimiser le code" dans Visual Studio.
Les deux boucles sont compilées dans (avec .NET Reflector):
Label_0000:
goto Label_0000;
Je pense que cela peut être plus facile à lire et est certainement la norme d'utilisation en C #:
while(true)
{
//Do My Loop Stuff
}
Gasp, utiliser:
while (!false)
{
}
OU comme jsight a souligné, vous voudrez peut-être vous assurer à deux reprises:
while (!false && true)
{
}
Avant que les gens me crient dessus, c’est tout le même code CIL, j’ai vérifié :)
Pour ressasser quelques vieilles blagues:
for (;;) {}
" - cela fera pleurer la déclaration.#define EVER ;;
".Si vous voulez aller à l'ancienne, goto est toujours supporté en C #:
STARTOVER:
//Do something
goto STARTOVER;
Pour une boucle vraiment infinie, c'est la commande incontournable. =)
Je pense que while (true)
est un peu plus lisible.
Dans les situations où j'avais besoin d'une vraie boucle infinie, j'ai toujours utilisé
while(true) {...}
Il semble exprimer mieux l'intention que les déclarations vides.
Personnellement, j'ai toujours préféré for(;;)
précisément parce qu'elle a la condition no (par opposition à while (true)
qui en a toujours une vraie). Cependant, il s’agit vraiment d’un problème de style très mineur, qui, selon moi, ne mérite pas d’être discuté de toute façon. Je n'ai pas encore vu de directives de style C # qui prescrivent ou interdisent l'une ou l'autre approche.
Le livre original K & R pour C, à partir duquel C # peut retracer son ascendance, recommandé
for (;;) ...
pour des boucles infinies. Il est sans ambiguïté, facile à lire et possède une longue et noble histoire.
Addendum (février 2017)
Bien sûr, si vous pensez que cette forme de boucle (ou toute autre forme) est trop cryptique, vous pouvez toujours ajouter un commentaire.
// Infinite loop
for (;;)
...
Ou:
for (;;) // Loop forever
...
Personnellement, je préfère l'idiome for (;;)
(venant d'un point de vue C/C++). Bien que je sois d’accord pour dire que la while (true)
est plus lisible dans un sens (et c’est ce que j’utilisais jadis, même en C/C++), j’ai commencé à utiliser l’idiome for
parce que:
Je pense que le fait qu’une boucle ne se termine pas (de façon normale) vaut la peine d’être appelé, et je pense que la for (;;)
le fait un peu plus.
Ce devrait être while(true)
pas while(1)
, donc while(1)
est incorrect en C #, oui;)
Même moi je dis aussi que celui ci-dessous est meilleur :)
while(true)
{
}
De toute façon, on pourrait dire que le fait d'avoir une boucle infinie est de toute façon une mauvaise pratique, car il faut une condition de sortie à moins que l'application ne s'exécute vraiment pour toujours. Cependant, s'il s'agit d'un missile de croisière, j'accepte une condition de sortie explicite qui pourrait ne pas être requise.
Bien que j'aime bien celui-ci:
for (float f = 16777216f; f < 16777217f; f++) { }
Je préfère un code légèrement plus "alphabétisé". Je suis beaucoup plus susceptible de faire quelque chose comme ça dans la pratique:
bool shouldContinue = true;
while (shouldContinue)
{
// ...
shouldContinue = CheckSomething();
}
La seule raison pour laquelle je dirais que for(;;)
est due aux limitations de CodeDom (les boucles ne peuvent pas être déclarées à l'aide de CodeDom et les boucles for sont considérées comme la forme plus générale de boucle d'itération).
C’est une raison assez vague de choisir cette option, à part le fait que l’implémentation de la boucle for
peut être utilisée aussi bien pour le code normal que pour le code généré par CodeDom. C'est-à-dire que cela peut être plus standard.
En note, vous pouvez utiliser des extraits de code pour créer une boucle while
, mais l'intégralité de la boucle doit être un extrait ...
Les deux ont la même fonction, mais les gens préfèrent généralement while(true)
. C'est facile à lire et à comprendre ...
Si vous utilisez le code-golf, je suggérerais for(;;)
. Au-delà, while(true)
a le même sens et semble plus intuitif. Quoi qu'il en soit, la plupart des codeurs comprendront probablement les deux variantes, ce qui importe peu. Utilisez ce qui est le plus confortable.
En termes de lisibilité du code, while(true)
, quelle que soit la langue choisie, a plus de sens. Pour ce qui est de la perception de l'ordinateur, il ne devrait y avoir aucune différence dans la société actuelle de compilateurs et d'interprètes très efficaces.
En cas de différence de performances, je suis certain que la conversion vers MSIL sera optimisée. Tu pourrais vérifier si tu le voulais vraiment.
Toute expression qui renvoie toujours la valeur true devrait convenir à la boucle while.
Exemple:
1==1 //Just an example for the text stated before
true