Je programme en Java depuis plusieurs années maintenant, mais je suis récemment retourné à l'école pour obtenir un diplôme officiel. J'ai été assez surpris d'apprendre que, lors de ma dernière mission, j'ai perdu des points pour avoir utilisé une boucle comme celle ci-dessous.
do{
//get some input.
//if the input meets my conditions, break;
//Otherwise ask again.
} while(true)
Maintenant, pour mon test, je suis juste en train de rechercher des entrées de console, mais on m'a dit que ce type de boucle est déconseillé parce que l'utilisation break
s'apparente à goto
, nous ne le faisons tout simplement pas.
Je comprends parfaitement les pièges de goto
et son cousin Java break:label
, et j'ai le bon sens de ne pas les utiliser. Je me rends également compte qu'un programme plus complet fournirait d'autres moyens d'évasion, par exemple pour simplement mettre fin au programme, mais ce n'était pas une raison que mon professeur a citée, alors ...
Qu'est-ce qui ne va pas do-while(true)
?
la source
break
est probablement bien intentionnée, mais en fait mal comprise. Vous pouvez peut-être éduquer votre professeur à ce sujet;) D'après mon expérience, les professeurs ne connaissent pas grand-chose à l'art de la programmation.do {} while (true)
c'est équivalent àwhile(true) {}
et ce dernier est de loin la forme la plus conventionnelle et beaucoup plus claire.break
, il devrait essayer de programmer dans un langage sans lui. Cela ne prend pas trop de boucles avant que vous ne le souhaitiez!Réponses:
Je ne dirais pas que c'est mauvais - mais je chercherais normalement au moins une alternative.
Dans les situations où c'est la première chose que j'écris, j'essaie presque toujours au moins de la refactoriser en quelque chose de plus clair. Parfois, cela ne peut pas être aidé (ou l'alternative est d'avoir une
bool
variable qui n'a rien de significatif, sauf indiquer la fin de la boucle, moins clairement qu'unebreak
déclaration), mais cela vaut au moins la peine d'essayer.Comme exemple d'utilisation plus claire
break
qu'un indicateur, considérez:Maintenant, forçons-le à utiliser un drapeau:
Je considère ce dernier comme plus compliqué à lire: il y a un
else
bloc supplémentaire , ilactOnInput
est plus en retrait, et si vous essayez de comprendre ce qui se passe lors destestCondition
retourstrue
, vous devez regarder attentivement le reste du bloc pour vérifier qu'il y a n'est pas quelque chose après leelse
bloc qui se produirait, qu'ilrunning
ait été définifalse
ou non.La
break
déclaration communique plus clairement l'intention et permet au reste du bloc de poursuivre ce qu'il doit faire sans se soucier des conditions antérieures.Notez que c'est exactement le même type d'argument que les gens ont à propos de plusieurs instructions de retour dans une méthode. Par exemple, si je peux déterminer le résultat d'une méthode dans les premières lignes (par exemple parce qu'une entrée est nulle, ou vide, ou zéro), je trouve plus clair de renvoyer cette réponse directement que d'avoir une variable pour stocker le résultat , puis un bloc entier d'autres codes, et enfin une
return
déclaration.la source
while (true)
AFAIK rien, vraiment. Les enseignants sont allergiques
goto
, car ils ont entendu quelque part que c'était vraiment mauvais. Sinon, vous écririez simplement:C'est presque la même chose.
C'est peut-être plus propre (car toutes les informations de bouclage sont contenues en haut du bloc):
la source
Douglas Crockford a fait une remarque sur la façon dont il souhaitait que JavaScript contienne une
loop
structure:Et je ne pense pas que Java serait pire pour avoir une
loop
structure non plus.Il n'y a rien d' intrinsèquement mauvais avec des
while(true)
boucles, mais il est une tendance pour les enseignants de les décourager. Du point de vue de l'enseignement, il est très facile de demander aux élèves de créer des boucles sans fin et de ne pas comprendre pourquoi la boucle ne s'échappe jamais.Mais ce qu'ils mentionnent rarement, c'est que tous les mécanismes de boucle peuvent être répliqués avec des
while(true)
boucles.est le même que
et
est le même que:
et
est le même que:
Tant que vous pouvez configurer vos boucles d'une manière qui fonctionne, la construction que vous choisissez d'utiliser n'a pas d'importance. Si cela se trouve dans une
for
boucle, utilisez unefor
boucle.Une dernière partie: gardez vos boucles simples. S'il y a beaucoup de fonctionnalités qui doivent se produire à chaque itération, mettez-la dans une fonction. Vous pouvez toujours l'optimiser après l'avoir fait fonctionner.
la source
for
boucles lorsque descontinue
instructions sont impliquées, mais elles ne constituent pas une extension majeure.for (;;) {
plus? (Prononcé "pour toujours"). C'était très populaire auparavant.En 1967, Edgar Dijkstra a écrit un article dans un magazine spécialisé expliquant pourquoi goto devrait être éliminé des langages de haut niveau pour améliorer la qualité du code. Tout un paradigme de programmation appelé "programmation structurée" en est sorti, bien que tout le monde ne soit certainement pas d'accord pour dire que goto signifie automatiquement un mauvais code.
Le nœud de la programmation structurée est essentiellement que la structure du code devrait déterminer son flux plutôt que d'avoir des gotos ou des ruptures ou continue de déterminer le flux, dans la mesure du possible. De même, avoir plusieurs points d'entrée et de sortie dans une boucle ou une fonction est également déconseillé dans ce paradigme.
Évidemment, ce n'est pas le seul paradigme de programmation, mais souvent il peut être facilement appliqué à d'autres paradigmes comme la programmation orientée objet (ala Java).
Vos professeurs ont probablement été formés et essaient d'enseigner à votre classe que nous éviterions au mieux le "code spaghetti" en nous assurant que notre code est structuré et en suivant les règles implicites d'une programmation structurée.
Bien qu'il n'y ait rien de fondamentalement "mauvais" avec une implémentation qui utilise break, certains considèrent qu'il est beaucoup plus facile de lire du code où la condition pour la boucle est explicitement spécifiée dans la condition while (), et élimine certaines possibilités d'être trop délicat. Il y a certainement des pièges à utiliser une condition while (true) qui semble apparaître fréquemment dans le code par des programmeurs novices, comme le risque de créer accidentellement une boucle infinie, ou de rendre le code difficile à lire ou déroutant inutilement.
Ironiquement, la gestion des exceptions est un domaine où des écarts par rapport à la programmation structurée seront certainement attendus à mesure que vous progressez dans la programmation en Java.
Il est également possible que votre instructeur s'attende à ce que vous démontriez votre capacité à utiliser une structure de boucle ou une syntaxe particulière enseignée dans ce chapitre ou cette leçon de votre texte, et bien que le code que vous avez écrit soit fonctionnellement équivalent, vous n'avez peut-être pas démontré la compétence particulière que vous étiez censé apprendre dans cette leçon.
la source
La convention Java usuelle pour la lecture des entrées est la suivante:
Et la convention C ++ habituelle pour lire les entrées est:
Et en C, c'est
ou si vous êtes convaincu que vous connaissez la longueur de la plus longue ligne de texte de votre fichier, vous pouvez le faire
Si vous testez pour voir si votre utilisateur a entré une
quit
commande, il est facile d'étendre l'une de ces 3 structures de boucle. Je vais le faire en Java pour vous:Donc, bien qu'il y ait certainement des cas où
break
ougoto
est justifié, si tout ce que vous faites est de lire un fichier ou la console ligne par ligne, vous ne devriez pas avoir besoin d'unewhile (true)
boucle pour l'accomplir - votre langage de programmation vous a déjà fourni avec un idiome approprié pour utiliser la commande d'entrée comme condition de boucle.la source
while (true)
boucle au lieu d'une de ces boucles d'entrée conventionnelles, vous oubliez peut-être de vérifier la fin du fichier.while
conditionnel. Dans la dernière condition Java, cela devient déjà assez lourd, et si vous avez dû faire une manipulation approfondie pour décider de continuer ou non, cela peut devenir assez long. Vous pouvez le diviser en une fonction distincte, et cela pourrait être mieux. Mais si vous le voulez dans une seule fonction, et qu'il y a un travail non trivial à faire avant de décider de continuer, c'estwhile(true)
peut-être mieux.gets()
n'est pas une convention commune. Il est très propice aux débordements de tampon.fgets(buffer, BUFFER_SIZE, file)
ressemble beaucoup plus à la pratique standard.fgets
.Ce n'est pas une chose si terrible, mais vous devez prendre en compte les autres développeurs lors du codage. Même à l'école.
Vos collègues développeurs devraient pouvoir voir la clause de sortie de votre boucle, lors de la déclaration de boucle. Tu n'as pas fait ça. Vous avez caché la clause de sortie au milieu de la boucle, ce qui rend plus de travail pour quelqu'un d'autre qui vient et essaie de comprendre votre code. C'est la même raison pour laquelle des choses comme la «pause» sont évitées.
Cela étant dit, vous verrez toujours des choses comme ça dans BEAUCOUP de code dans le monde réel.
la source
while (true)
il est assez évident qu'il y aura unbreak
ou à l'return
intérieur, ou qu'il fonctionnera pour toujours. Être simple est important, maiswhile(true)
n'est pas particulièrement mauvais en soi. Les variables qui ont des invariants complexes sur les itérations de boucle seraient un exemple de quelque chose qui cause beaucoup plus d'angoisse.C'est ton arme, ta balle et ton pied ...
C'est mauvais parce que vous demandez des ennuis. Ce ne sera pas vous ou l'une des autres affiches de cette page qui avez des exemples de boucles while courtes / simples.
Le problème commencera à un moment très aléatoire dans le futur. Cela peut être causé par un autre programmeur. Il peut s'agir de la personne qui installe le logiciel. Ce pourrait être l'utilisateur final.
Pourquoi? J'ai dû découvrir pourquoi une application LOC 700K commencerait progressivement à graver 100% du temps CPU jusqu'à ce que chaque CPU soit saturé. C'était une boucle while (true) incroyable. C'était gros et méchant, mais cela se résumait à:
Il n'y avait pas de dernière branche else. Si la valeur ne correspond pas à une condition if, la boucle continue de fonctionner jusqu'à la fin du temps.
Bien sûr, le programmeur a accusé les utilisateurs finaux de ne pas avoir choisi une valeur attendue par le programmeur. (J'ai ensuite éliminé toutes les instances de while (true) dans le code.)
À mon humble avis, ce n'est pas une bonne programmation défensive d'utiliser des constructions comme while (true). Il reviendra vous hanter.
(Mais je me souviens que les professeurs se sont classés si nous ne commentions pas chaque ligne, même pour i ++;)
la source
C'est mauvais dans le sens où les constructions de programmation structurées sont préférées aux instructions break et continue (quelque peu non structurées). Ils sont, par comparaison, préférés à "goto" selon ce principe.
Je recommanderais toujours de rendre votre code aussi structuré que possible ... même si, comme le souligne Jon Skeet, ne le rendez pas plus structuré que cela!
la source
D'après mon expérience, dans la plupart des cas, les boucles ont la condition "principale" de continuer. C'est la condition qui doit être écrite dans l'opérateur while () lui-même. Toutes les autres conditions qui peuvent rompre la boucle sont secondaires, moins importantes, etc. Elles peuvent être écrites comme des
if() {break}
instructions supplémentaires .while(true)
est souvent déroutant et moins lisible.Je pense que ces règles ne couvrent pas 100% des cas mais probablement seulement 98% d'entre eux.
la source
Bien que ce ne soit pas nécessairement une réponse à pourquoi ne pas utiliser
while (true)
, j'ai toujours trouvé cette déclaration de l'auteur comique et accompagnant une explication succincte de pourquoi faire tout au lieu de faire tout.En ce qui concerne votre question: il n'y a pas de problème inhérent avec
... si vous savez ce que vous faites et assurez-vous que cela
exit_time
sera évalué à un moment donnétrue
.Les enseignants vous découragent d'utiliser
while(true)
car jusqu'à ce que et à moins que vous ne sachiez exactement ce que vous faites, c'est un moyen facile de faire une erreur critique.la source
exit_time = false; while(!exit_time) { execute_stuff(); }
etdo { execute_stuff(); } while(! exit_time );
sont à la fois beaucoup plus clair que d'avoir unif( condition ) { break; }
à la fin d'une boucle avec unwhile(true)
. Les coupures sont des courts-circuits aux boucles - parfaitement bien lorsqu'il est utilisé comme court-circuit au milieu d'une boucle, mais vous devez simplement évaluer une condition dans l'instruction while par rapport à une coupure à la fin d'une boucle.Vous pouvez simplement utiliser un indicateur booléen pour indiquer quand terminer la boucle while.
Break
etgo to
étaient des raisons pour lesquelles les logiciels étaient trop difficiles à maintenir - la crise des logiciels (tm) - et devraient être évités, et peuvent facilement l'être aussi.C'est une question de savoir si vous êtes pragmatique ou non. Les codeurs pragmatiques pourraient simplement utiliser la pause dans cette situation simple.
Mais il est bon d'avoir l'habitude de ne pas les utiliser, sinon vous pouvez les utiliser hors d'habbit dans des situations inappropriées, comme dans les boucles imbriquées compliquées où la lisibilité et la maintenabilité de votre code deviennent plus difficiles à utiliser
break
.la source
if (running)
dans la boucle, indentant tout le reste du code quand tout ce que je veux, c'est de quitter la boucle est définitivement moins clair pour moi qu'une simple instruction break qui indique exactement ce que je veux faire. Vous semblez considérer l'utilisation de la pause comme une mauvaise habitude de façon axiomatique - je n'y pense pas en tant que telle.Peut-être que je n'ai pas de chance. Ou peut-être que je manque simplement d'expérience. Mais chaque fois que je me souviens avoir traité d'
while(true)
avoir à l'break
intérieur, il était possible d'améliorer le code appliquant la méthode d'extraction à while-block , qui a conservé lewhile(true)
mais (par coïncidence?) Transformé tous lesbreak
s enreturn
s.D'après mon expérience, les
while(true)
pauses (c'est-à-dire avec retours ou lancers) sont assez confortables et faciles à comprendre.la source
Je pense que oui c'est assez mauvais ... ou du moins, pour de nombreux développeurs. C'est symptomatique des développeurs qui ne pensent pas à leurs conditions de boucle. Par conséquent, il y a des erreurs.
la source
Il n'y a pas de problème majeur
while(true)
avecbreak
instructions, mais certains peuvent penser que cela diminue légèrement la lisibilité du code. Essayez de donner aux variables des noms significatifs, évaluez les expressions au bon endroit.Pour votre exemple, il semble beaucoup plus clair de faire quelque chose comme:
Cela est particulièrement vrai si la boucle do while devient longue - vous savez exactement où la vérification pour voir s'il y a une itération supplémentaire se produit. Toutes les variables / fonctions ont des noms appropriés au niveau de l'abstraction. le
while(true)
déclaration ne vous dit que le traitement n'est pas à l'endroit que vous pensiez.Peut-être que vous voulez une sortie différente la deuxième fois dans la boucle. Quelque chose comme
me semble alors plus lisible
Encore une fois, avec un exemple trivial, les deux sont tout à fait lisibles; mais si la boucle est devenue très grande ou profondément imbriquée (ce qui signifie que vous devriez probablement déjà avoir refactorisé), le premier style peut être un peu plus clair.
la source
J'utilise quelque chose de similaire, mais avec une logique opposée, dans beaucoup de mes fonctions.
la source
C'est plus une question d'esthétique, beaucoup plus facile à lire du code où vous savez explicitement pourquoi la boucle s'arrêtera juste dans la déclaration de la boucle.
la source
Je dirais qu'en général, la raison pour laquelle ce n'est pas considéré comme une bonne idée est que vous n'utilisez pas la construction à son plein potentiel. De plus, j'ai tendance à penser que beaucoup d'instructeurs de programmation n'aiment pas que leurs étudiants arrivent avec des «bagages». Je veux dire par là que je pense qu'ils aiment être la principale influence sur le style de programmation de leurs étudiants. Alors peut-être que c'est juste une bête noire de l'instructeur.
la source
Pour moi, le problème est la lisibilité.
Une instruction while avec une condition vraie ne vous dit rien sur la boucle. Cela rend le travail de compréhension beaucoup plus difficile.
Quoi de plus facile à comprendre à partir de ces deux extraits?
la source
Je suppose qu'utiliser break pour votre professeur, c'est comme casser une branche d'arbre pour obtenir le fruit, utilisez d'autres astuces (inclinez la branche) pour obtenir le fruit et la branche est toujours en vie. :)
la source
1) Rien de mal à un
do -while(true)
2) Votre professeur a tort.
NSFS !!:
3) La plupart des enseignants sont des enseignants et non des programmeurs.
la source
Cela peut être mauvais si votre boucle s'exécute sur un thread d'arrière-plan, donc lorsque vous fermez votre application en terminant un thread d'interface utilisateur, ce morceau de code continuera à s'exécuter. Comme d'autres l'ont déjà dit, vous devez toujours utiliser une sorte de chèque pour fournir un moyen d'annulation.
la source