J'ai deux boucles imbriquées comme ceci:
for(...) {
for(...) {
}
}
Je sais qu'il existe une déclaration break
. Mais je suis confus quant à savoir si cela casse les deux boucles ou seulement celle dans laquelle elle s'appelait? Je dois casser les deux dès que je vois qu'il est insensé de répéter plusieurs fois.
break rompt une boucle, mais vous pouvez ajouter un contrôle à la boucle externe qui se rompt lorsque l’intérieur se casse.
bool dobreak = false;
for ( ..; !dobreak && ..; .. ) {
for ( ... ) {
if (...) {
dobreak = true;
break;
}
}
}
Si goto simplifie le code, alors ce serait approprié.
for (;;)
{
for (;;)
{
break; /* breaks inner loop */
}
for (;;)
{
goto outer; /* breaks outer loop */
}
}
outer:;
La déclaration break
vous permet uniquement de sortir de la boucle la plus profonde. Si vous ne voulez pas la surcharge de code, de mémoire et de performances d'une variable d'état dédiée, je vous recommande de refactoriser le code dans une fonction ou une méthode qui lui est propre et d'utiliser return
pour sortir de toutes les boucles:
void do_lots_of_work(void)
{
int i, j;
for(i=0; i<10 ; i++)
{
for(j=0;j< 10; j++)
{
..
..
if(disaster_struck())
return; /* Gets us out of the loops, and the function too. */
}
}
}
Autre que la variable flag ou goto déjà mentionnée, vous pouvez lancer une exception Objective-C:
@try {
for() {
for() {
@throw ...
}
}
}
@catch{
...
}
D'autres ont déjà expliqué comment définir un indicateur ou utiliser une variable goto
, mais je vous conseillerais de refactoriser votre code afin que la boucle interne devienne une méthode distincte. Cette méthode peut ensuite renvoyer un indicateur pour indiquer que la boucle externe doit break
. Si vous nommez vos méthodes de manière appropriée, ceci est beaucoup plus lisible.
for (int i = 0; i < 10; i++) {
if (timeToStop(i)) break;
}
-(bool) timeToStop: (int) i {
for (int j = 0; j < 10; j++) {
if (somethingBadHappens) return true;
}
return false;
}
Pseudocode, non testé, mais vous voyez l'idée.
Changer le compteur du top loop avant la pause
for(i=0; i<10 ; i++)
for(j=0;j< 10; j++){
..
..
i = 10;
break;
}
Une autre solution consiste à factoriser la deuxième boucle dans une fonction:
int i;
for(i=0; i<10 ; i++){
if !innerLoop(i) {
break;
}
}
bool innerLoop(int i)
int j;
for(j=0;j< 10; j++){
doSomthing(i,j);
if(endcondtion){
return false;
}
}
}
L'instruction break ne fera que sortir de la boucle dans la portée, qui est la boucle parente. Si vous souhaitez également vous échapper de la deuxième boucle, vous pouvez utiliser une variable booléenne située dans l'étendue des deux boucles.
bool isTerminated = false;
for (...)
{
if (!isTerminated)
{
for(...)
{
...
isTerminated = true;
break;
}
}
else
{
break;
}
}
Le moyen le plus simple est probablement d’utiliser une variable "flag"
for(i=0; i<10 && (done==false); i++)
for(j=0;j< 10; j++){
..
..
if(...){done=true; break;}
}
La déclaration de rupture sort de la boucle la plus interne. Un test et une instruction de rupture supplémentaires seraient nécessaires pour sortir de la boucle externe.
Si une pause est exécutée depuis un ensemble de boucles imbriquées, seule la boucle la plus interne dans laquelle la pause est exécutée est terminée. (Juste comme standard C)
Juste pour les sourires, pourquoi ne pas transformer cette vérification vrai/faux en une méthode et utiliser les instructions return
:
- (bool) checkTrueFalse: parameters{
for ( ...) {
for ( ... ) {
if (...) {
return true;
}
}
}
return false;
}
Exactement comme les derniers, généralement comme ceci:
for(i=0;i<a;i++){
for(j=0;j<a;j++){
if(Something_goes_wrong){
i=a;
break;
}
}
}