Comment sortir d'une boucle à l'intérieur d'un switch?
Je suis en train d'écrire un peu de code qui ressemble à ceci:
while(true) {
switch(msg->state) {
case MSGTYPE: //...
break;
//... more stuff ...
case DONE:
break; //**HERE, I want to break out of the loop itself**
}
}
Est-il un moyen direct de le faire?
Je sais que je peux utiliser un drapeau, et la rupture de la boucle en mettant un saut conditionnel juste après le commutateur. Je veux juste savoir si C++ a un certain de construire pour cela.
- Pourquoi avez-vous besoin d'un saut conditionnel après le switch? Il vous suffit de changer tout de while(true) pour tout(drapeau)...
- Je suppose que c'est une version simplifiée qu'il a mis pour illustrer ce qu'il était en train de faire.
- Voir: Code Complet (2ème Édition). Voir aussi "la Programmation Structurée avec les instructions goto' par D E Knuth (pplab.snu.ac.kr/cours/adv_pl05/documents/p261-knuth.pdf).
- Pressman et al: on dirait qu'il pourrait être un tableau d'état de la machine, pour moi, avec un cas pour chaque etat - y compris un FAIT de l'etat dans lequel le code doit quitter. Cependant, cela pourrait peut-être être manipulés par des "
while (msg->state != DONE)
" pour la boucle de contrôle. - Oui, exactement. J'irais même plus loin et séparer les préoccupations de la boucle de la condition d'arrêt de la boucle elle-même (l'extrait à une méthode).
- Si vous êtes l'un de ces programmeurs qui produisent, qui sont des fonctions de plusieurs pages, vous trouverez
goto
attrayant et, parfois, la seule propre moyen de sortir. Si vous avez tendance à organiser votre code dans des petites fonctions qui ne sont qu'à quelques lignes de long et de faire une seule chose à chaque, vous n'aurez plus jamais ce problème. (Soit dit en passant votre code sera plus facile à lire, aussi.) - Si se sent comme obtenir un conseil pour arrêter de fumer quand tout ce que vous voulez savoir, c'est comment se rendre à la plus proche station de métro.
- Eh bien, si vous ne pouvez pas voir la station de métro en face de vous, en raison de toute la fumée, que le conseil pourrait ne pas être si mauvais que ça.
:)
- Parfois, il est pratique de retour d'appel à partir d'un cas. Pas joli, mais qui fonctionne.
- Vous pouvez toujours utiliser des if-else, sauf si vous avez de trop nombreux cas..!
Vous devez vous connecter pour publier un commentaire.
Prémisse
Le code suivant doit être considéré comme une mauvaise forme, indépendamment de la langue ou de la fonctionnalité souhaitée:
Arguments À L'Appui,
La
while( true )
boucle est médiocre parce que c':while(true)
pour des boucles qui ne sont pas infinies, nous perdons la capacité de communiquer de façon concise lorsque des boucles n'ont réellement aucune condition d'arrêt. (On peut le dire, cela s'est déjà produit, de sorte que le point est sans objet.)Alternative à "Aller À"
Le code suivant est une meilleure forme:
Avantages
Pas de drapeau. Pas de
goto
. Pas d'exception. Facile à changer. Facile à lire. Facile à fixer. En outre, le code:Le deuxième point est important. Sans savoir comment le code fonctionne, si quelqu'un m'a demandé de faire la boucle principale de laisser les autres threads (ou processus) ont un peu de temps CPU, deux solutions me viennent à l'esprit:
Option #1
Facilement insérer la pause:
L'Option n ° 2
Remplacer exécuter:
Ce code est plus simple (donc plus facile à lire) qu'une boucle avec un intégré à
switch
. LeisValidState
méthode ne doit déterminer si la boucle doit continuer. Le cheval de bataille de la méthode doit être placé dans leexecute
méthode, qui permet à des sous-classes pour remplacer le comportement par défaut (une tâche difficile à l'aide d'un intégré àswitch
etgoto
).Exemple Python
Revanche la réponse suivante (pour un Python question) qui a été posté sur StackOverflow:
Code
Contre:
Code
Ici,
while True
résultats trompeurs et un code trop complexe.while(true)
devrait être nocif me parait bizarre. Il y a des boucles de que vérifier avant de l'exécuter, il y a ceux que l'enregistrement par la suite, et il y a ceux que l'enregistrement dans le milieu. Puisque ceux-ci n'ont pas de construction syntaxique en C et C++, vous aurez à utiliserwhile(true)
oufor(;;)
. Si vous considérez que c'est faux, vous n'avez pas assez réfléchi pour les différents types de boucles encore.while(true) {string line; std::getline(is,line); if(!is) break; lines.push_back(line);}
bien sûr, je pourrais le transformer à un préconditionnés en boucle (à l'aide destd::getline
comme condition de la boucle), mais cela a des inconvénients, sur son propre (line
devrait être une variable en dehors de la boucle du champ d'application). Et si je le faisais, j'aurais à poser: Pourquoi nous avons trois boucles de toute façon? On peut toujours transformer le tout en un préconditionnés en boucle. Utiliser ce qui convient le mieux. Siwhile(true)
s'adapte, puis l'utiliser.continue
dans votre code python est totalement inutile. L'initialisation dechoice
avec une certaine valeur factice est la source d'erreurs de la partie.Vous pouvez utiliser
goto
.goto
. L'OP est clairement mentionné sans l'aide de drapeaux. Pouvez-vous imaginer une meilleure façon, compte tenu de l'OP de la limitation? 🙂goto
semble être une solution idéale. Il serait améliorée si leswhile
boucle ont été également l'unique constituant de fonction ou de méthode.goto
réponse. Je suis heureux de l'avoir fait, mais, si je ne dois pas. +1Une autre solution consiste à utiliser le mot-clé
continue
en combinaison avecbreak
, c'est à dire:Utiliser le
continue
déclaration à la fin de chaque cas étiquette où vous souhaitez que la boucle pour continuer et utiliser lebreak
déclaration à la finition de cas, les étiquettes qui doit mettre fin à la boucle.Bien entendu, cette solution ne fonctionne que si aucun autre code à exécuter après l'instruction switch.
:(
:(
Sinon très propre mise en œuvre.Un neatish façon de le faire serait de mettre ceci en fonction:
Éventuellement (mais les "mauvaises pratiques"): comme l'a déjà suggéré que vous pourriez utiliser un goto, ou lever une exception à l'intérieur de l'interrupteur.
Autant que je sache, il n'y a pas de "double saut" ou similaire construire en C++. Le plus proche serait un
goto
- qui, alors qu'il a une mauvaise connotation de son nom, existe dans la langue pour une raison, car il est utilisé avec soin et parcimonie, c'est une option viable.Vous pourriez mettre votre basculer dans une autre fonction comme ceci:
Même si vous n'aimez pas goto, n'utilisez pas une exception à la sortie d'une boucle. L'exemple suivant montre comment laide, il pourrait être:
Je voudrais utiliser
goto
comme dans cette réponse. Dans ce casgoto
va rendre le code plus clair que toute autre option. J'espère que cette question sera utile.Mais je pense que l'utilisation de
goto
est la seule option ici à cause de la chaîne dewhile(true)
. Vous devriez envisager la refonte de votre boucle. J'avais suppose que la solution suivante:Ou même les éléments suivants:
goto
, ne pas utilisez une exception à la sortie d'une boucle:"?Il n'y a pas de C++ construire pour sortir de la boucle dans ce cas.
Soit utiliser un drapeau à l'interruption de la boucle ou (le cas échéant) de l'extrait de votre code dans une fonction et l'utilisation
return
.Vous pouvez éventuellement utiliser goto, mais je préfère de définir un indicateur qui arrête la boucle. Puis sortir de l'interrupteur.
Pourquoi ne pas simplement corriger la condition dans ta boucle while, à l'origine du problème à disparaître?
Non, C++ ne possède pas de construire pour cela, étant donné que le mot "pause" est déjà réservé pour la sortie de l'interrupteur du bloc. À l'inverse, un do..while() avec une sortie de drapeau pourrait suffire.
Je pense;
La façon la plus simple de le faire est de mettre un simple SI avant de faire le COMMUTATEUR , et que SI testez votre condition pour sortir de la boucle .......... aussi simple qu'il peut être
La
break
mot-clé en C++ ne prend fin qu'à la plus imbriquée enfermant itération ouswitch
déclaration. Ainsi, vous ne pouviez pas sortir de lawhile (true)
boucle directement à l'intérieur de laswitch
de la déclaration; toutefois, vous pouvez utiliser le code suivant, qui, je pense, est un excellent modèle pour ce type de problème:Si vous avez besoin de faire quelque chose quand
msg->state
est égal àDONE
(notamment l'exécution d'une routine de nettoyage), placez ce code immédiatement après lafor
boucle; c'est à dire si vous avez actuellement:Ensuite utiliser à la place:
Il me stupéfie comment simple c'est compte tenu de la profondeur des explications... Voici tout ce dont vous avez besoin...
LOL!! Vraiment! C'est tout ce dont vous avez besoin! Une variable supplémentaire!
J'ai eu le même problème et résolu à l'aide d'un drapeau.
Si je me souviens syntaxe C++, vous pouvez ajouter une étiquette à
break
états, tout comme pour lesgoto
. Donc, ce que vous voulez serait facilement écrit: