Quelqu'un peut-il me dire comment briser la boucle principale quand j'ai des boucles imbriquées?
Exemple *:
/*Main loop*/ for(int y = 0; y < 100; y+=10) { /*Sub loop*/ for (int x = 0; x < 100; x += 10) { if(x == 60) { //Break the main loop } } }
13 Réponses :
Utilisez un drapeau pour signaler la terminaison:
for(int y = 0; y < 100; y+=10) { bool flag = false; for(int x = 0; x < 100; x += 10) { if (x == 56) { flag = true; break; } } if(flag) break; }
C'est une façon verbeuse de le faire. Vous pouvez simplement vérifier le drapeau dans le pour code> boucle conditionnelle.
C'est une bonne chose à ce sujet, c'est qu'il est très facile de comprendre pour les autres programmeurs: zéro facteur surprise.
@Jon, je ne pense pas que ce soit un style propre d'avoir plus d'une condition à l'intérieur d'un.
Je préfère aller sur cette solution de contournement. (Bien sûr seulement si refactoring n'est pas bon choix)
@cjrh pensez-vous réellement? Pour moi, pour un, pensez que goto est beaucoup i> plus évident ici - sans parler plus efficacement.
@Fge: tbh, lorsque les boucles ont besoin de résiliation plus tôt que leurs limites suggérées, je soupçonne que cela devrait être une condition exceptionnelle i> si vous attrapez mon sens. De ce point de vue, goto et exceptions font exactement la même chose.
C'est fait avec des drapeaux comme ça à Pascal .. Je pensais que c # peut avoir quelque chose d'intelligent comme Java. Mais je vais l'utiliser .. J'ai essayé la déclaration Goto, mais cela n'a pas fonctionné correctement.
retour code> est souvent possible en mettant les boucles dans une fonction séparée. Li>
- Utilisez
goto code>. li>
- Utilisez un drapeau (laid) li>
ul>
Personne ne devrait jamais utiliser goto code> dans une langue de haut niveau.
IMO Drapeau-Break-Check-ChreeFlag-Break est encore plus laid que GoTo. Mais bien sûr, le refactoring est le choix préféré dans la mesure du possible.
GOTO CODE> est parfaitement légitime et c'est la meilleure utilisation pour cela, il est plus efficace que l'une des autres options présentées. Aucun programmeur ne devrait vivre par des règles telles que "N'utiliser jamais
goto code>", mais vous devez savoir quand b> à utiliser
goto code>.
@Aiabstract Ceci est exactement code> Le type de situation où
goto code> est la meilleure réponse. Arrêtez de régurgiter le
N'utilisez jamais goto code> déchets que vous avez été enseigné. Utilisez le bon outil dans la bonne situation.
@Rob: la bonne réponse est du refacteur. Je n'aime pas l'option I> Breakflag-Breakflag-Breakflag-Breakflag-Breakflag. Et ce n'est pas la régurgitation, c'est à propos de l'exactitude. :)
Souvent, il est préférable de mettre cela dans une fonction distincte et de faire un «retour»
Dans les vraies boucles imbriquées, je calcule quelque chose. Si je dois les transmettre à une méthode, ce sera vraiment laid!
Dépend de la façon dont vous le faites ... Souvent, ces choses deviennent désordonnées parce que les gens ont beaucoup de variables et les n'ont pas encapsulés dans une structure. Idéalement, vous vous retrouvez avec beaucoup de fonctions qui fonctionnent sur une structure. (OO simplifié).
Certaines personnes me timer pour suggérer l'utilisation de la relève code> goto code>, mais la rupture de plusieurs boucles est l'un des endroits qu'il peut être très utile (et efficace):
Ils sont terribles lorsqu'ils sont utilisés par de jeunes codeurs et entraînent un code spaghetti. En tant que développeur, vous devez utiliser les outils à votre disposition, et Goto est le moyen le plus efficace de sortir de plusieurs boucles imbriquées.
Je suis d'accord avec le préalable au sujet du code spaghetti, j'utilise toujours une pause ou un retour
+1 - Je suis avec vous - c'est l'un des rares endroits où goto rend les choses meilleures, pas pire. La restructuration pour éviter les boucles imbriquées serait idéale, mais si ce n'est pas une option, alors goto code> loin!
La solution simple de Hogan d'une variable booléenne supplémentaire est presque tout aussi efficace, et beaucoup plus maintenue et claire à d'autres programmeurs.
Je ne vois pas comment il est plus maintenu. S'il y avait plus de boucles impliquées, vous devez modifier plus de code, cela ne nécessite pas non plus une variable supplémentaire.
Pouvez-vous élaborer un peu? Vous avez décidé de poster une version mise à jour de votre code pour que nous puissions voir ce qui se passe.
/*Main loop*/ for(int y = 0; y < 100; y+=10) { bool makeMeBreak = false; /*Sub loop*/ for (int x = 0; x < 100; x += 10) { if(x == 56) { //Break the main loop makeMeBreak = true; break; } } if (makeMeBreak) break; }
Je ne comprends pas ce meme persistant qui dit que goto code>! p>
goto code> est considéré comme "nocif". Lorsqu'il est utilisé correctement, il est très puissant et c'est un tel cas. P>
Un jour, lorsque quelqu'un vous remet trois de trois décennies, un code de fortrain, poivré avec des gotos mal écrites et vous dit de réparer les bugs et de découvrir que c'est impossible i> au refacteur, vous comprendrez. Les meilleurs programmeurs peuvent faire de la magie avec goto. Le pire peut faire un grand mal.
Les meilleurs programmeurs peuvent utiliser goto code> sans causer de chagrin ce que ce soit et crée le code le plus efficace dans le processus.
+1, briser des boucles imbriquées est l'une des rares utilisations acceptables de goto imo. Beaucoup plus propre que d'utiliser un drapeau.
@cjrh et c'est pourquoi il a dit bien utilisé, c'est très puissant et c'est un tel cas. I>. Outil droit pour la bonne situation.
Je ne vois tout simplement pas pourquoi certaines personnes ici préféreraient utiliser un drapeau qu'un goto dans ce cas.
Je ne sais pas s'il y a un moyen de sortir des boucles imbriquées en C #, mais permettez-moi de suggérer une solution de contournement. P>
Vous pouvez lancer la boucle principale dans une fonction et revenir de cette fonction. Vous pouvez renvoyer false; code> pour indiquer une pause prématurée et
renvoyer true; code> pour indiquer que la boucle passait jusqu'à présent, si cela importe. P>
Il n'y a pas de bonne réponse générique. La «bonne façon» dépend du vrai problème. La meilleure façon peut être de mettre la boucle extérieure dans une fonction puis d'utiliser retour; code> pour sortir de celui-ci. Il pourrait être
x = 100; y = 100; code>. Cela pourrait être
fait = true; code>. Heck, il pourrait même être
goto code> (blindé). P>
Les drapeaux, comme suggéré dans les commentaires, sont probablement la meilleure méthode:
Ce n'est que si court car il n'y a aucun code après la boucle interne et après le si. Avec ce code, vous devez ajouter deux pauses et un chèque.
pas conseillé mais vous pouvez utiliser goto code>. Voir Ceci .
public class GotoTest1
{
static void Main()
{
int x = 200, y = 4;
int count = 0;
string[,] array = new string[x, y];
// Initialize the array:
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
array[i, j] = (++count).ToString();
// Read input:
Console.Write("Enter the number to search for: ");
// Input a string:
string myNumber = Console.ReadLine();
// Search:
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
if (array[i, j].Equals(myNumber))
{
goto Found;
}
}
}
Console.WriteLine("The number {0} was not found.", myNumber);
goto Finish;
Found:
Console.WriteLine("The number {0} is found.", myNumber);
Finish:
Console.WriteLine("End of search.");
// Keep the console open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/*
Sample Input: 44
Sample Output
Enter the number to search for: 44
The number 44 is found.
End of search.
*/
Depuis, comme vous l'avez mentionné, il n'y a pas d'étiquettes sur la commande Break code>, vous pouvez faire quelque chose comme ceci:
/*Main loop*/
bool fFound;
for(int y = 0; y < 100 && !fFound; y+=10)
{
/*Sub loop*/
for (int x = 0; x < 100; x += 10)
{
if(x == 56)
{
//Break the main loop
fFound = true;
break; //Break inner loop
}
}
}
Comme d'autres l'ont dit, la réponse "correcte" dépend du problème que vous résolvez. Si vous le pouvez, la rupture en pièces plus petites est la voie préférée. Quelque chose sur ce modèle:
object MainLoop () { object result = null; for(int y = 0; y < 100; y+=10) { result = SubLoop(y); if (result != null) { break; } } return result; } object SubLoop (int y) { object result = null; for (int x = 0; x < 100; x += 10) { if(x == 56) { result = objectInstance; break; } } return result; }
J'ai utilisé LINQ pour rassembler les objets intéressants, puis effectué les opérations sur les résultats de la requête LINQ. Enlevant ainsi des boucles imbriquées et remplaçant avec une boucle. P>
Si possible, placez-le à l'intérieur d'une méthode distincte que vous pouvez simplement revenir, ce qui sera court-circuiter les boucles.
ALLER À! Hé, attends - où vous allez? Bonjour?