Quel est le terme pour boucle "while (true)" avec "break" à l'intérieur? [fermé]

24

Supposons que j'ai une boucle en C ++ ou C # qui va comme ceci:

while( true ) {
    doSomething();
    if( condition() ) {
        break;
    }
    doSomethingElse();
}

Ceci est communément appelé "boucle infinie". Pourtant, il n'est pas techniquement infini - il s'arrêtera une fois le contrôle passé break.

Quel est le terme pour une telle boucle - qui contient une instruction de contrôle de boucle "boucle pour toujours" et "pause" à l'intérieur?

acéré
la source
22
Je ne pense pas qu'il y ait un terme spécial.
ChrisF
2
Y a-t-il une garantie que le contrôle passera jamais par la rupture? Dans cet exemple, que se passe-t-il si condition()renvoie toujours faux? Je dirais que c'est une boucle infinie avec des ruptures conditionnelles.
JohnL
1
Même sans a break, la boucle n'est pas infinie ( kill, ctrl-alt-del, débrancher ...). Alors, pourquoi s'embêter avec les détails de la terminologie?
mouviciel
5
"Quel est le terme?" - "Ceci est communément appelé boucle infinie". Voilà votre réponse. Vous n'êtes clairement pas satisfait du terme, mais cela n'enlève pas le fait que les langues (naturelles) sont descriptives. Le «terme pour X» est tout ce que les gens utilisent, pas ce qu'ils devraient utiliser.
MSalters
5
Cette question semble être hors sujet parce que c'est une question "nommez cette chose". "Nommez cette chose" sont de mauvaises questions pour les mêmes raisons qui "identifient cette émission télévisée, film ou livre obscur par ses personnages ou son histoire" sont de mauvaises questions: vous ne pouvez pas les rechercher sur Google, elles ne sont en aucune façon pratiques, elles n'aide personne d'autre, et leur permettre ouvre la porte à la pose d'autres types de questions marginales. Voir blog.stackoverflow.com/2012/02/lets-play-the-guessing-game
gnat

Réponses:

24

En étudiant CS, ce professeur nous a enseigné qu'il existe des boucles de pré-vérification ( while(cond) {}), des boucles de post-vérification ( do {} while(cond);) et des boucles de vérification intermédiaire . (J'ai peut-être mal traduit cela en anglais, mais vous avez compris.)

C et C ++ n'ont pas ce dernier (ISTR Ada l'ayant, BICBW), donc votre construction est utilisée pour cela en C et C ++.

sbi
la source
1
Oui, Ada a ceci:loop ... exit when condition; ... end loop;
Keith Thompson
@Keith: Merci d'avoir confirmé! Cela fait presque 20 ans que j'ai fait du Ada.
sbi
1
Pour ce que ça vaut, je suis un programmeur professionnel depuis plus de 20 ans (et un amateur plus longtemps que cela), et je n'ai jamais entendu ces termes.
offby1
En ce qui concerne la traduction - je pense que "in" est généralement plus approprié lorsque "pre" et "post" sont utilisés, par exemple "pré-commande / post-commande / traversée de l'arborescence".
Oak
1
Le terme avec lequel j'ai grandi était «boucle à mi-sortie». J'ai travaillé dans deux langues différentes avec un support explicite pour les boucles de mi-sortie.
mjfgates
13

Le tout premier cours de CS à Stanford ( méthodologie de programmation de Mehran Sahami ) y fait référence en tant que boucle et demie . Et ce n'est pas nécessairement une mauvaise pratique de programmation. Considérez cet exemple sur la collecte des entrées utilisateur (tiré de The Art and Science of Java par Eric Roberts , où Roberts l'appelle également une boucle et demie ):

prompt user and read in the first value
while (value != sentinel) {
    process the data value
    prompt user and read in a new value
}

Et puis la même chose a résolu en utilisant la boucle et une demi- idée pour éviter le code en double:

while (true) {
    prompt user and read in a value
    if (value == sentinel) break;
    process the data value
}
ernes7a
la source
10

En l'absence d'un nom officiel, je l'appellerais la boucle brisée . L'ambiguïté de ce terme est voulue, car une rupture au milieu d'une boucle est un peu impure, presque comme un goto.

user281377
la source
Je dirais, bien pire qu'un goto. Je préfère de loin voir un goto qu'une condition faussement construite dans une boucle comme ça.
Brian Knoblauch
14
@Brian Quoi? La condition «vraie» le rend évident et les boucles comme celle-ci sont vraiment courantes. Par exemple, si vous voulez ajouter chaque ligne d'un fichier dans une liste, vous devez essayer de lire la ligne (faire quelque chose), arrêter si elle a échoué (si la condition est rompue), sinon l'ajouter à la liste et répéter (faire quelque chose autre).
Craig Gidney
7
Il n'y a rien de mal à rompre au milieu d'une boucle. Si vous devez effectuer une opération à chaque début de cycle, vous devrez soit dupliquer le code, soit insérer ces opérations dans la condition. L'une ou l'autre variante présente clairement des inconvénients. gotoavait également des applications valides, par exemple l'émulation d'un essai ... enfin un bloc en C.
Malcolm
1
Malcolm: Le problème possible est que lors de la lecture du code, il est plus difficile de voir quand et pourquoi la boucle est fermée. Des problèmes supplémentaires surviennent lorsque vous imbriquez deux ou plusieurs de ces boucles et que vous souhaitez sortir de la boucle externe en fonction d'une condition trouvée dans la boucle interne.
user281377
Disons que vous avez une boucle d'événements conduisant une application Xorg, comme (en pseudo-code :) while(XEventGet(&ev) != NULL){ ... }, vous allez naturellement vouloir vérifier les clés à l' intérieur de la boucle: if(ev.key == XK_q) break;. Faire ce qui suit while(XEventGet(&ev) != NULL && ev.key != XK_q){ ... }:, est moche et sans doute plus difficile à lire qu'une pause en milieu de boucle. De plus, que se passe-t-il si quelque chose doit être fait à la valeur avant de pouvoir être vérifié? Vous n'allez pas sérieusement mettre tout cela dans le cas de base de la boucle, n'est-ce pas?
Braden Best
8

Il n'y a pas de nom définitif. La boucle infinie est, je pense, le terme approprié. Aucune boucle n'est vraiment infinie, mais cela a le potentiel d'être effectivement infini car il est possible que la branche qui contient la rupture ne se produise jamais.

Si vous dites à quelqu'un de "créer une boucle infinie et d'utiliser une pause pour la condition X", il saura ce que vous voulez dire. Si quelqu'un examine votre code et ne dit rien de plus que "Je n'aime pas la boucle infinie que vous avez écrite", vous saurez de quoi ils parlent (sauf si vous en avez plus d'un, bien sûr).

Bryan Oakley
la source
1
Ce n'est pas une boucle infinie; il a une condition de terminaison bien définie, tout comme une whileboucle normale et la façon dont vous faites la preuve de la terminaison est exactement la même (trouver une métrique à diminution monotone est un excellent début).
Donal Fellows
8

C'est une boucle do-while avec le conditionnel au mauvais endroit.

Malfist
la source
2
Oui, il devrait être écrit: while (keep_going) {doSomething (); if (condition) {keep_going = false; } else {doSomethingElse (); }}
Stephen Gross
10
alors ... vous dites que si vous enseignez un cours d'informatique et que vous voulez décrire cela, vous diriez "et maintenant, nous allons en apprendre davantage sur la boucle * do-while avec le conditionnel au mauvais endroit "? Cela ressemble plus à une opinion religieuse qu'à un nom.
Bryan Oakley
5
@StephenGross Cet extrait de code est une suggestion horrible. Refactorisez pour mettre la condition réelle dans la définition de boucle, ou utilisez simplement breakou continue. Évitez les valeurs sentinelles à tout prix, ce n'est qu'un autre état arbitraire à suivre mentalement, qui masque le but du code.
Izkata
2
Les valeurs sentinelles sont des gotos retardés.
Winston Ewert
2
-1 pour être un weenie à sortie unique.
Donal Fellows
6

Je voterais pour "boucle inconditionnelle" , similaire à "saut inconditionnel". Il illustre exactement ce qui se passe (le code boucle inconditionnellement), sans mentir (contrairement à "boucle infinie").

tdammers
la source
1
Mais il a une condition de résiliation; que if/ breakau milieu fait partie du motif.
Donal Fellows
5

Quel est le terme pour une telle boucle - qui contient une instruction de contrôle de boucle "boucle pour toujours" et "pause" à l'intérieur?

C'est une boucle infinie avec une condition de rupture.

Je serais d'accord avec ammilind en ce que si vous vouliez lui donner un nom spécial, vous pourriez l'appeler une boucle partielle infinie

Ramhound
la source
1
Ce n'est pas du tout infini; le point où la condition de terminaison est vérifiée est juste à un endroit différent.
Donal Fellows
5

Sur Rosetta Code, ce modèle particulier est décrit comme une boucle «N plus un demi» . Bien que ce ne soit pas mon terme préféré, ce n'est pas terrible et c'est clairement un modèle qui est utile pour certains types de boucles. (Les alternatives consistent à dupliquer le code avant la condition - potentiellement délicat dans les programmes réels - ou à augmenter la profondeur d'imbrication du code après la condition tout en ajoutant une variable de condition de boucle; ni n'améliore la maintenabilité ou la compréhensibilité du code . La seule raison de rejeter de telles constructions est que si l'on insiste pour que les boucles soient breaklibres.)

Associés Donal
la source
4

Il n'y a pas de terme standard, mais je dirais que c'est une boucle partielle .

Cette boucle est utilisée lorsque vous souhaitez rompre uniquement après avoir exécuté une partie de la boucle une dernière fois (c'est-à-dire une exécution partielle). Il est utilisé lorsque vous ne trouvez pas de situation appropriée où vous voudrez peut-être rompre la boucle entière .

Dans ce cas, vous souhaitez rompre la boucle après au moins doSomething()une dernière exécution .

iammilind
la source
2

Je dois être d'accord avec sbi ici - j'aime le terme de boucle de vérification intermédiaire . Ce type de construction était plus populaire lorsque la programmation structurée a commencé à rouler et que de nombreux langages avaient un support syntaxique pour eux.

Cela dit, il est désormais largement connu que les whileboucles sont généralement plus faciles à maintenir, car il est plus facile de raisonner sur les invariants et ils gèrent souvent mieux le cas vide délicat.

Dans votre cas particulier, votre boucle est juste équivalente à

for(; doSomething(), !condition(); doSomethingElse()){}

donc je n'utiliserais la breakversion que si l'une doSomethingou l' autre doSomethingElseimpliquait plusieurs instructions et je préfère ne pas les ranger dans des fonctions séparées comme vous l'avez fait.

Cela dit, si votre boucle est plus compliquée qu'une itération (démarrer, vérifier, incrémenter), vous devriez envisager de la refactoriser en quelque chose de plus simple.

hugomg
la source
1

Je suppose que si nous allons essayer de trouver un terme pour cela, peut-être:

Boucle échappable

LarsTech
la source
-1. la question n'est pas de se faire un nom, c'est de savoir si un nom commun existe déjà. De plus, toutes les boucles sont "échappables", ce n'est donc pas un nom particulièrement efficace.
Bryan Oakley
@BryanOakley Une boucle infinie, par définition, ne devrait pas être cassable. Il ne devrait probablement pas y avoir de terme pour cela, à part une mauvaise programmation.
LarsTech
0

Ce n'est pas si mal dans tous les cas. Je me retrouve à écrire ce type de boucles avec certains types d'API. Disons, par exemple, que vous avez un objet boucle et que vous devez vérifier une condition assez profonde, comme ceci:

while (loop
    .getAExecutionModelFactory()
    .getActiveXexecutor()
    .getYCancelModelHandler()
    .getCurrentHandler()
    .isCancelled()) {
        // ... do something with the current Handler ....
        loop = ..... // prepare for next loop
}

Supposons maintenant que chaque méthode getXXX puisse potentiellement retourner null. Il serait alors toujours possible d'écrire une expression booléenne, bien qu'elle soit assez compliquée et illisible. Et puis nous devons refaire presque la même chose pour obtenir l'objet gestionnaire actuel. Dans de tels cas, je trouve plus facile d'écrire une while (true)boucle avec pause et de continuer.

Ingo
la source