for (;;) {
//Something to be done repeatedly
}
J'ai beaucoup vu ce genre de chose utilisé, mais je pense que c'est plutôt étrange ... Ne serait-il pas beaucoup plus clair à dire while(true)
, ou quelque chose du genre ?
Je suppose que (comme c'est la raison pour laquelle beaucoup de programmeurs ont recours au code cryptique), c'est une petite marge plus rapide?
Pourquoi, et en vaut-il vraiment la peine? Si tel est le cas, pourquoi ne pas simplement le définir de cette façon:
#define while(true) for(;;)
Voir aussi: Quel est le plus rapide: while (1) ou while (2)?
c++
c
optimization
readability
infinite-loop
Chris Cooper
la source
la source
TRUE
???TRUE
a à voir avec C? La macro standard pour le résultat boolen vrai dans C99 est toujourstrue
. D'oùTRUE
vient le?#define EVER ;;
a été utilisée dans IOCCC cependant .. :)#define while(TRUE)
déclarer une macro qui prend un argument appeléTRUE
qui n'est jamais utilisé, transformant donc chaque boucle while de votre programme en une boucle infinie?TRUE
provient des fichiers d'en-tête associés à l'API Windows. Il n'est en aucun cas lié à VS 6.0. Et, comme je l'ai déjà dit, cela n'a rien à voir avec C ou C ++. En C ++, le "vrai" littéral est justetrue
(dans VS 6.0 également), en C89 / 90 il n'y a rien de tel du tout, et en C99 c'est macrotrue
. Cela s'applique à tous les compilateurs C / C ++.Réponses:
la source
Je préfère
for(;;)
pour deux raisons.La première est que certains compilateurs produisent des avertissements sur
while(true)
(quelque chose comme "la condition de boucle est constante"). Éviter les avertissements est toujours une bonne chose à faire.Un autre est que je pense que
for(;;)
c'est plus clair et plus révélateur. Je veux une boucle infinie. Cela n'a littéralement aucune condition, cela ne dépend de rien. Je veux juste que ça continue pour toujours, jusqu'à ce que je fasse quelque chose pour m'en sortir.Alors qu'avec
while(true)
, eh bien, qu'est-ce qui est vrai a à voir avec quoi que ce soit? Je ne suis pas intéressé par la boucle jusqu'à ce que true devienne faux, ce que dit littéralement cette forme (boucle alors que true est vrai). Je veux juste faire une boucle.Et non, il n'y a absolument aucune différence de performance.
la source
for(;;)
, cela vous semblera évidemment étrange. Mais je vous conseille d' essayer de s'y habituer car il est un idiome commun, et vous allez courir en elle à nouveau. ;)for(;condition;)
. C'est ce qu'une boucle while est pour . Mais comme je l'ai dit, avec une boucle infinie, je ne veux pas vraiment que le compilateur compare n'importe quelle condition. Naïvement, avec unewhile
boucle, il faudrait testertrue
chaque itération (évidemment, même le compilateur le plus stupide ne le ferait pas, mais c'est le principe qui me dérange. Cela me semble trop spécifier votre code), alors qu'avec unfor(;;)
vous dites littéralement "il n'y a aucune condition à tester. Juste une boucle". Je le trouve l'équivalent le plus proche de votre imaginaireloop {...}
while(true)
donne un avertissement.Personnellement, j'utilise
for (;;)
parce qu'il n'y a pas de chiffres, c'est juste un mot-clé. Je préfère àwhile (true)
,while (1)
,while (42)
,while (!0)
etc , etc.la source
true
n'est pas plus un nombre magique qu'unfor
mot clé magique ou quifor(;;)
utilise un infini magique implicite. (while (42)
est en effet une abomination.)for(;;)
est analysé plus rapidement que les autres de toute façon#define LIFE 42
while (LIFE)
:)while(true)
ne contient aucun numéro aussi. et pour (;;) n'est pas un motÀ cause de Dennis Ritchie
J'ai commencé à utiliser
for (;;)
parce que c'est ainsi que Dennis Ritchie le fait en K&R, et lorsque j'apprends une nouvelle langue, j'essaie toujours d'imiter les gars intelligents.C'est du C / C ++ idiomatique. Il est probablement préférable à long terme de s'y habituer si vous prévoyez de faire beaucoup dans l'espace C / C ++.
Votre
#define
volonté de travail pas, puisque la chose étant # define'd doit ressembler à un identifiant C.Tous les compilateurs modernes généreront le même code pour les deux constructions.
la source
while(TRUE)
, je soupçonne que le programmeur est un débutant en C, ou a appris le C à partir d'un livre For Dummies.Ce n'est certainement pas plus rapide dans un compilateur sensé. Ils seront tous deux compilés en sauts inconditionnels. La version for est plus facile à taper (comme l'a dit Neil) et sera claire si vous comprenez la syntaxe de la boucle for.
Si vous êtes curieux, voici ce que me donne gcc 4.4.1 pour x86. Les deux utilisent l' instruction JMP x86 .
compile en (en partie):
la source
for_infinite
est plus rapide; 2 caractères de moins àputs
.Je préfère
for (;;)
parce que c'est le plus cohérent dans différents langages de type C.En C ++,
while (true)
c'est bien, mais en C vous dépendez d'un en-tête à définirtrue
, maisTRUE
c'est aussi une macro couramment utilisée. Si vous utilisez,while (1)
c'est correct en C et C ++ et JavaScript, mais pas en Java ou C #, qui nécessitent que la condition de boucle soit un booléen, tel quewhile (true)
ouwhile (1 == 1)
. En PHP, les mots-clés sont insensibles à la casse mais le langage préfère la capitalisationTRUE
.Cependant,
for (;;)
est toujours tout à fait correct dans toutes ces langues.la source
for (;;)
est meilleure.while (1)
etfor (;;)
sont des idiomes courants pour des boucles infinies en C. Quiconque lit un programme C qui a du mal à comprendre l'un ou l'autre aura probablement des problèmes avec le reste du code. Cela ne vaut pas la peine d'écrire du code C qui peut être facilement lu par quelqu'un qui ne connaît pas C.Je préfère personnellement l'
for (;;)
idiome (qui compilera avec le même code quewhile (TRUE)
.L'utilisation
while (TRUE)
peut être plus lisible dans un sens, j'ai décidé d'utiliser l'for (;;)
idiome car il se démarque .Une construction de boucle infinie devrait être facilement remarquée ou appelée dans le code, et je pense personnellement que le
for (;;)
style le fait un peu mieux quewhile (TRUE)
ouwhile (1)
.Aussi, je rappelle que certains compilateurs émettent des avertissements lorsque l'expression de contrôle d'une boucle while est une constante. Je ne pense pas que cela arrive trop souvent, mais juste le potentiel d'avertissements fallacieux est suffisant pour que je veuille l'éviter.
la source
J'ai vu que certaines personnes la préfèrent parce qu'elles ont un #define quelque part comme ceci:
Ce qui leur permet d'écrire ceci:
la source
FOREVER
définiefor(;;)
, mais ce n'est pas mieux. Les macros de l'OMI ne doivent pas être utilisées pour «inventer» une nouvelle langue.#define BEGIN {
et#define END }
. J'ai même vu#define DONKEYS_FLY (0)
pour qu'ils puissent direif DONKEYS_FLY ...
. Qui a dit que le logiciel était ennuyeux?#define never while(0)
et#define always
Qu'en est-il (si votre langue le prend en charge):
la source
goto
les nombreux inconvénients, mais si l'algorithme que vous essayez d'implémenter provient d'un organigramme, c'est la traduction la plus directe.goto
goto
c'est que vous n'avez pas à vous soucier que quelqu'un ajoute unbreak
pour rendre votre boucle moins infinie. (sauf si vous êtes déjà dans une autrewhile
ou unefor
boucle bien sûr ...)Il n'y a aucune différence en termes de code machine généré.
Cependant, juste pour renverser la tendance, je dirais que le formulaire while (TRUE) est beaucoup plus lisible et intuitif que pour (;;), et que la lisibilité et la clarté sont des raisons beaucoup plus importantes pour les directives de codage que toutes les raisons pour lesquelles je '' J'ai entendu parler de l'approche for (;;) (je préfère fonder mes directives de codage sur un raisonnement solide et / ou une preuve d'efficacité moi-même).
la source
for(;;)
est la manière traditionnelle de faire cela en C et C ++.while(true)
semble être la convention en C # et Java et dans d'autres langages. Votre kilométrage peut varier.Pas seulement un modèle bien connu, mais un idiome standard en C (et C ++)
la source
while (true)
pour la même raison qu'ils le fontif (true)
.génère un avertissement avec Visual Studio (la condition est constante). La plupart des endroits où j'ai travaillé compilent des versions de production avec des avertissements comme des erreurs. Alors
est préféré.
la source
Les deux doivent être identiques si votre code est optimisé par le compilateur. Pour expliquer ce que j'entends par optimisation, voici un exemple de code écrit dans MSVC 10:
Si vous le construisez en mode Débogage ( sans aucune optimisation (/ Od) ), le démontage montre la différence claire. Il y a des instructions supplémentaires pour l'
true
état à l'intérieurwhile
.Cependant, si vous créez votre code en mode Release (avec Maximize Speed (/ O2) par défaut ), vous obtenez la même sortie pour les deux. Les deux boucles sont réduites à une instruction de saut.
Celui que vous utiliserez n'a pas d'importance pour un compilateur décent avec l'optimisation de la vitesse.
la source
C'est une question de préférence personnelle qui est le plus rapide. Personnellement, je suis un touchtypist et je ne regarde jamais mon clavier, pendant la programmation - je peux toucher les 104 touches de mon clavier.
Je trouve plus rapide de taper "while (TRUE)".
J'ai ajouté mentalement quelques mesures de mouvement des doigts et les ai totalisées. "for (;;)" a environ 12 largeurs de touches de mouvements en arrière et en quatrième (entre les touches d'accueil et les touches, et entre les touches d'accueil et la touche SHIFT) "tandis que (TRUE)" a environ 14 largeurs de touches de mouvements en arrière et Quatrième.
Cependant, je suis beaucoup moins sujet aux erreurs lors de la saisie de ce dernier. Je pense mentalement en mots à la fois, donc je trouve plus rapide de taper des choses comme "nIndex" que des acronymes comme "nIdx" parce que je dois en fait épeler mentalement le lettrage plutôt que de le dire dans mon esprit et laisser mes doigts s'auto -tapez le mot (comme faire du vélo)
(Mon benchmark TypingTest.com = 136 WPM)
la source
time head -10 >/dev/null
, tapez chaque 10 fois et mesurez les résultats. Je parie que vous serez plus rapide àfor(;;)
moins de tricher. J'étais à environ 14%.Toutes les bonnes réponses - le comportement doit être exactement le même.
TOUTEFOIS - Supposons simplement que cela ait fait une différence. Supposons que l'un d'eux prenne 3 instructions supplémentaires par itération.
Devez-vous vous en soucier?
UNIQUEMENT si ce que vous faites à l'intérieur de la boucle n'est presque rien , ce qui n'est presque jamais le cas.
Mon point est, il y a la micro-optimisation et la macro-optimisation. La micro-optimisation, c'est comme «se faire couper les cheveux pour perdre du poids».
la source
++i
plusi++
?++i
eti++
peut être potentiellement significative sii
est une instance d'une classe plutôt qu'une instance intégrée et que le compilateur n'applique pas l'optimisation triviale. Le conseil est d'acquérir une habitude pour qu'elle ne vous surprenne pas quand cela compte.++i
vsi++
est que cela ne vous coûte rien pour faire "l'optimisation". Certes, dans la plupart des cas, cela ne fait absolument aucune différence, mais ils sont tout aussi faciles à taper, alors pourquoi ne pas préférer le plus efficace par défaut? Et je suppose que la même chose s'applique ici. Si l'un était un peu plus rapide que l'autre, pourquoi ne pas opter pour le plus rapide? Que perdrions-nous en le faisant? Les deux sont assez faciles à lire et à taper.Je ne peux pas imaginer qu'un compilateur valable générerait un code différent. Même si c'était le cas, il n'y aurait aucun moyen de déterminer sans tester le compilateur particulier qui était plus efficace.
Cependant, je vous suggère de préférer
for(;;)
pour les raisons suivantes:un certain nombre de compilateurs que j'ai utilisés généreront un avertissement d'expression constante pour while (true) avec les paramètres de niveau d'avertissement appropriés.
dans votre exemple, la macro TRUE peut ne pas être définie comme prévu
il existe de nombreuses variantes possibles de l'infini en boucle tels que
while(1)
,while(true)
,while(1==1)
etc .; ilfor(;;)
en résultera probablement une plus grande cohérence.la source
while(TRUE)
évalue commewhile(0)
n'est pas susceptible d'en bénéficierfor(;;)
.while(true)
devrait être préféré dans tous les cas. En C ++bool
est réservé, et en C défini en C stdbool.h (ce qui le rend moins sûr en C).for(;;)
supprime tout doute.Est un plus clair que:
Non pas que cela s'applique si vous n'utilisez pas
Sleep()
.la source
timerService.scheduleRepeating (50, [] () { /* lots of code */ });
La boucle «pour toujours» est populaire dans les systèmes embarqués en tant que boucle d'arrière-plan. Certaines personnes l'implémentent comme:
Et parfois, il est implémenté comme:
Et encore une autre implémentation est:
Un compilateur d'optimisation doit générer le même code d'assembly ou un code similaire pour ces fragments. Une note importante: le temps d'exécution des boucles n'est pas un gros problème car ces boucles durent indéfiniment, et plus de temps est passé dans la section de traitement.
la source
Je suppose que while (true) est plus lisible que for (;;) - il semble que le programmeur manque quelque chose dans la boucle for :)
la source
La raison la plus importante d'utiliser "for (;;)" est la peur d'utiliser "while (TRUE)" lorsque vous faites de la programmation exploratoire. Il est plus facile de contrôler le nombre de répétitions avec "for", et aussi, plus facile de convertir la boucle "for" en une boucle infinie.
Par exemple, si vous construisez une fonction récursive, vous pouvez limiter le nombre d'appels à la fonction avant de la convertir en une boucle infinie.
Lorsque je suis sûr de ma fonction, je la convertis en une boucle infinie:
la source