2011-11-07 16 views
5

Suponga que tiene dos bucles for anidados como este:¿Hay alguna manera de romper un ciclo superordenado en C?

int i, j; // Iterators 

for(i=0; i<100; ++i) { 
    /* do some stuff */ 
    ... 
    for(j=0; j<99; ++j) { 
     /* do more stuff */ 
     ... 
     if(someFunction(j,i) == 2) { 
      /* break out of both loops */ 
     } 
    } 
} 

¿Hay alguna forma (similar a la orden break; en un solo bucle) para poner fin a ambos bucles sobre el terreno?

+8

'goto' es útil. – Mat

+0

@Mat: ¿Es eso una broma? – Rob

+3

@robjb Dudo que lo sea. Este es uno de los casos donde 'goto' está perfectamente bien. El odio incondicional hacia 'goto' es incorrecto. – GSerg

Respuesta

13

Puede utilizar un goto como:

int i, j; // Iterators 

for(i=0; i<100; ++i) { 
    /* do some stuff */ 
    ... 
    for(j=0; j<99; ++j) { 
     /* do more stuff */ 
     ... 
     if(someFunction(j,i) == 2) { 
      goto done; 
     } 
    } 
} 
done: 

o utilizar otra variable para controlar las iteraciones del bucle:

int i, j; // Iterators 
int done = 0; 
for(i=0; i<100 && !done; ++i) { 
    /* do some stuff */ 
    ... 
    for(j=0; j<99 && !done; ++j) { 
     /* do more stuff */ 
     ... 
     if(someFunction(j,i) == 2) { 
      done = 1; 
     } 
    } 
} 
+0

+1 para ambas ideas, aunque a la gente no le gusta 'goto', es más rápido que agregar a los controles a cada ronda. (como en sus segundas opciones) – MByD

+0

! bandera hecha se verifica cada bucle que no es tan óptimo que parece –

+1

+1 para la segunda idea. Eso es lo que yo haría. 'goto' es más rápido, pero también es peligroso. Cosas extrañas pueden ocurrir si no le presta mucha atención mientras lo escribe. La verificación de la bandera se puede hacer solo en el bucle externo, agregar un 'break' justo después de 'done = 1;' y reducirá el costo computacional (Aunque es muy pequeño para las computadoras de hoy) – Victor

5

Nuestro buen amigo goto puede manejar eso para usted!

int i, j; // Iterators 

for(i=0; i<100; ++i) { 
    /* do some stuff */ 
    ... 
    for(j=0; j<99; ++j) { 
     /* do more stuff */ 
     ... 
     if(someFunction(j,i) == 2) { 
      /* break out of both loops */ 
      goto ExitLoopEarly; 
     } 
    } 
} 
goto ExitLoopNormal; 

ExitLoopEarly: 
.... 

ExitLoopNormal: 
... 
4

Eso podría ser una solución

function void loop() 
{ 
       int i, j; // Iterators 

      for(i=0; i<100; ++i) { 
       /* do some stuff */ 
       ... 
       for(j=0; j<99; ++j) { 
        /* do more stuff */ 
        ... 
        if(someFunction(j,i) == 2) { 
         return; 
        } 
       } 
      } 
} 
+0

Esto solo cubrirá algunos casos, ignorará cualquier valor que pueda usar dentro de los bucles. – MByD

+0

¿Qué quieres decir? Realmente no puedo entender que –

+0

digamos que tiene tres de tales bucles dobles en una función, y en esos bucles modifica algunas variables locales de la función, necesitará pasar (por referencia) cada variable que se usa en el lazo a la función. Goto o alguna bandera parecen mucho más razonables. – MByD

0

Puedes insertar dos lo ops en una función y para usar return

void foo(){ 
int i, j; // Iterators 

for(i=0; i<100; ++i) { 
    /* do some stuff */ 
    ... 
    for(j=0; j<99; ++j) { 
     /* do more stuff */ 
     ... 
     if(someFunction(j,i) == 2) { 
      return; 
     } 
    } 
} 
} 
Cuestiones relacionadas