Es posible el uso de la break función para salir de varios anidada for bucles? Si es así, ¿cómo podría hacer esto? También puede controlar el número de bucles de la ruptura de las salidas?

  • En lugar de utilizar descanso o ir a salir de varios bucles anidados, puede encerrar esa lógica particular en una función y el uso de retorno a la salida de varios bucles anidados. Para mantener la estética de su código y se evitará el uso de goto que es una mala práctica de programación.
InformationsquelleAutor Faken | 2009-08-10

18 Comentarios

  1. 221

    AFAIK, C++ no soporta la nomenclatura de los bucles, como Java y otros lenguajes. Usted puede usar un goto, o crear un valor del indicador que se utilice. Al final de cada bucle de comprobar el valor del indicador. Si se establece a true, entonces usted puede salir de la iteración.

    • No tenga miedo de usar un goto si que es la mejor opción.
    • Soy un nuevo programador de C++ (y sin ningún tipo de programas formales de capacitación) así que después de leer sobre lo que la gente despotrica sobre goto. Estoy indeciso sobre su uso en el temor de mi programa sólo podría de repente explotar y matar a mí. Aparte de eso, cuando he utilizado para escribir programas en mi ti-83 (en la aburrida clase de matemáticas, por supuesto), las funciones básicas del editor de siempre requiere el uso de goto es.
    • Me parece recordar que la lectura que muchos compiladores de renunciar a la optimización de bucles cuando un goto está presente…
    • Dos tipos de programadores utilizan goto: los Malos programadores, y pragmático de los programadores. Los primeros son auto explicativas. El último, el que se alcanzarían si usted elige utilizar bien, utilizar lo que se llama un «mal» concepto cuando es el menor de dos males. Lea esto para un mejor entendimiento de algunos conceptos de C++ que usted puede ser que necesite para utilizar de vez en cuando (macros, goto, de preprocesador, matrices): parashift.com/c++-faq-lite/gran imagen.html#faq-6.15
    • No hay nada malo con el uso de goto. Es mal uso de un goto que es molesto.
    • Eso es correcto, salvo que la utilización de goto rara vez siempre es la mejor opción. ¿Por qué no poner los bucles en su propia función (inline, si usted está preocupado acerca de la velocidad) y return de esto?
    • en algún momento de nuestras funciones tienen muy grande marco de pila, y pasando de 9-10+ vars definitivamente nuestro código ilegible. Tomar un descanso y el uso de goto, en este caso hace el programa más sexy y más legible. Algunos algoritmos han sooo mucho el control de las rutas que hace ir más preferido, sobre todo del estado de mashines en bucle de partida rendimiento código crítico donde incluso un simple marco de pila pérdidas de más o de su rendimiento!
    • entre líneas las funciones no tienen un marco de pila
    • en línea es un compilador de sugerencia de palabras clave, no hay garantía de que va en línea de la función. En cualquier caso, debe escribir el código como si ellos no estaban en línea lo que significa pasar variables…. Estoy con @Петър Петров en que.
    • Por desgracia, yo terminé de ver con mis ojos cómo un marco de pila fue inicializado en llamar a una función en línea. Compilador de tener su decisión final sobre eso. Sólo la verdad entre líneas, es una cosa de la macro. De hecho, el compilador no lo vea 🙂 Y NO MOLESTAR a tirar! Es como llamar «goto» 10000 veces en una fila.
    • Si la función manipula 9-10+ variables dentro de un bucle, el rendimiento de la pena de que la creación del marco de pila es absolutamente insignificante.
    • La creación – y la corrección – un Marco de Pila es más caro que la comprobación de la bandera, a continuación, realizar un salto. if...goto muy a menudo se compila a je o jne local saltos par, mientras que el call / ret función semántica a menudo hace mucho saltos y errores de caché. Por lo tanto, no tenga miedo de usar goto es es el menor mal de dos en dos. Y nunca truse inline si quieres velocidad.

  2. 254

    No, no estropearlo con un break. Este es el último bastión para el uso de goto.

    • El MISRA C++ estándar de codificación permite el uso de goto para cubrir este tipo exacto de la situación.
    • Los verdaderos programadores no tienen miedo a usar goto. Hecho por 25 años, no se arrepiente — salvó un montón de tiempo de desarrollo.
    • Estoy de acuerdo. gotos son una necesidad si usted no tiene 8K píxeles de ancho, y es necesario llamar a una secuencia de 30 de Windows OS llama.
    • O un simple «retorno» al poner el código en una función.
  3. 54

    Otro enfoque para salir de un bucle anidado es el factor de ambos bucles en una función separada, y return de esa función cuando desee salir.

    Por supuesto, esto trae a colación el otro argumento de que si alguna vez explícitamente return de una función en otro lugar que en la final.

    • Eso es un C problema. Con la RIAA retorno precoz no es un problema de todos los problemas asociados con la devolución son manejados correctamente.
    • Entiendo que la correcta aplicación de la RIAA puede resolver el recurso de limpieza de problema en C++, pero he visto el argumento filosófico en contra de los principios de retorno continuar en otros entornos y lenguajes. Un sistema trabajé en donde el estándar de codificación de prohibido el retorno temprano tenía funciones llena de variables booleanas (con nombres como continue_processing) que controla la ejecución de los bloques de código más abajo en la función.
    • ¿Qué es la RIAA? Es que nada como RAII? =D
    • er sí, s/RIAA/RAII/g; 🙂
    • Depende de cómo muchos de los bucles que tiene y la profundidad del nido va… ¿quieres que la pastilla azul o pastilla roja?
  4. 53

    Sólo para añadir un una respuesta explícita el uso de expresiones lambda:

      for (int i = 0; i < n1; ++i) {
        [&] {
          for (int j = 0; j < n2; ++j) {
            for (int k = 0; k < n3; ++k) {
              return; //yay we're breaking out of 2 loops here
            }
          }
        }();
      }

    Por supuesto, este patrón tiene ciertas limitaciones y, obviamente, C++11, pero creo que es bastante útil.

    • Esto puede confundir al lector en el pensamiento del retorno hace que la función lambda es en volver, y no la lambda de sí mismo.
    • Si el bucle es tan complicado, que te olvidas de que estás en una lambda, es el momento de ponerlos en una función diferente, pero para los casos más sencillos, esto debería funcionar bastante bien.
    • Creo que esta solución es hermoso
    • Usted puede capturar la lambda en un RIIA plantilla que le da un nombre y se llama en dtor(aka ámbito gaurd). Esto no añadiría ninguna ganancia en el rendimiento, pero puede mejorar readabilty y reducir el riesgo de perder la llamada a la función entre paréntesis.
  5. 32

    romper será sólo la salida del bucle más profundo que la contiene.

    Puede utilizar goto para salir de cualquier número de bucles.

    De curso goto es a menudo Considera Perjudicial.

    es adecuado para utilizar la función de salto[…]?

    El uso de break y goto puede hacer que sea más difícil razonar sobre la corrección de un programa. Ver aquí para una discusión sobre este: Dijkstra no estaba loco.

    • Una buena respuesta en el que explica que «goto es perjudicial» meme está fuertemente ligado a la más generalizada «de control de flujo de la interrupción es perjudicial» de su declaración. Que no tiene sentido decir «goto es perjudicial», y luego dar la vuelta y recomendamos el uso de break o return.
    • y return tienen la ventaja sobre goto que usted no tendrá que buscar una etiqueta con el fin de encontrar a donde ir. Sí, debajo de ellos son algunas de las goto, pero una muy restringida. Ellos son mucho más fáciles de descifrar por un programador de coincidencia de patrón de cerebro de la libre goto. Así que la OMI son preferibles.
    • Cierto, pero no es todavía parte de la programación estructurada. Es mejor tolerado que un goto.
    • la Dijkstra enlace es obsoleto; esto parece estar funcionando: blog.plover.com/2009/07
    • No hay absolutamente nada malo con el uso de goto en esta situación. Bien situado goto es a pasos agigantados mejor y más fácil de leer que muchos de los retorcida soluciones propuestas.
  6. 22

    Aunque esta respuesta ya fue presentado, me parece un buen enfoque es hacer lo siguiente:

    for(unsigned int z = 0; z < z_max; z++)
    {
        bool gotoMainLoop = false;
        for(unsigned int y = 0; y < y_max && !gotoMainLoop; y++)
        {
            for(unsigned int x = 0; x < x_max && !gotoMainLoop; x++)
            {
                              //do your stuff
                              if(condition)
                                gotoMainLoop = true;
            }
        }
    
    }
    • que es buena pero no es tan fácil de leer, prefiero ir en ese caso
    • esto hace que el código «muy lento» porque el gotoMainLoop se comprueba cada ciclo
    • En este caso, mediante el real goto hace núcleo más legible y con mejor rendimiento.
  7. 18

    ¿Qué hay de esto?

    for(unsigned int i=0; i < 50; i++)
    {
        for(unsigned int j=0; j < 50; j++)
        {
            for(unsigned int k=0; k < 50; k++)
            {
                //Some statement
                if (condition)
                {
                    j=50;
                    k=50;
                }
            }
        }
    }
    • interesante enfoque, pero definitivamente me gusta la forma en que rece @inf.ig.sh maneja. for (unsigned int y = 0; y < y_max && !gotoMainLoop; y++).
  8. 15

    Un ejemplo de código con goto y una etiqueta para salir de un bucle anidado:

    for (;;)
      for (;;)
        goto theEnd;
    theEnd:
  9. 9

    Una buena manera de salir de varios bucles anidados es refactorizar el código en una función:

    void foo()
    {
        for(unsigned int i=0; i < 50; i++)
        {
            for(unsigned int j=0; j < 50; j++)
            {
                for(unsigned int k=0; k < 50; k++)
                {
                    //If condition is true
                    return;
                }
            }
        }
    }
    • …que no es una opción si tenemos que pasar 10-20 variables de pila encuadre de esta función.
    • a continuación, vaya para un lambda que es también mejor que usted puede definir exactamente donde usted lo necesita.
    • +1 para lambdas pero la revisión en el motor de juego de núcleo, donde incluso un marco de pila es todavía un cuello de botella. Siento decirte, pero lambdas no son tan ligero al menos en MSVC 2010.
    • A continuación, cambie el par de funciones en una clase, y la pila de variables en los miembros privados.
    • Esto sólo overcomplicates la ya compleja código 🙂 a Veces, goto es la única solución. O, si usted escribe complejos autómatas con «goto estado X» la documentación, luego, goto es en realidad lo que el código es leído como escrito en el documento. También, C# y vaya ambos tienen goto con un propósito: ninguna lengua es turing-completo sin un goto, y gotos son a menudo la mejor usa las herramientas de escritura intermedio traductor o de la asamblea-como código.
  10. 5

    goto puede ser muy útil para romper los bucles anidados

    for (i = 0; i < 1000; i++) {
        for (j = 0; j < 1000; j++) {
            for (k = 0; k < 1000; k++) {
                 for (l = 0; l < 1000; l++){
                    ....
                    if (condition)
                        goto break_me_here;
                    ....
                }
            }
        }
    }
    
    break_me_here:
    //Statements to be executed after code breaks at if condition
  11. 3

    La break declaración termina la ejecución de la más cercana adjuntando do, for, switch, o while declaración en la que aparece. El Control pasa a la instrucción que sigue a la terminación de la instrucción.

    de msdn.

  12. 2

    Yo creo que un goto es válido en esta circunstancia:

    Para simular un break/continue, te gustaría:

    Romper

    for ( ;  ;  ) {
        for ( ;  ;  ) {
            /*Code here*/
            if (condition) {
                goto theEnd;
            }
        }
    }
    theEnd:

    Continuar

    for ( ;  ; ) {
        for ( ;  ;  ) {
            /*Code here*/
            if (condition) {
                i++;
                goto multiCont;
            }
        }
        multiCont:
    }
    • En «continuar» no va a funcionar, porque el expresión de iteración del primer bucle no se ejecuta
    • Estoy suponiendo que el iterador para el primer bucle es i. Por lo tanto i++ antes de que el goto
  13. 0

    Otros lenguajes como PHP aceptan un parámetro para romper (es decir, romper 2;) para especificar la cantidad de bucle anidado niveles se quiere romper, C++, sin embargo, no. Usted tendrá que trabajar hacia fuera mediante un valor booleano que se establece a false antes del bucle, se establece en true en el bucle si desea descanso, además de un condicional después de romper el bucle anidado, comprobando si el booleano se establece en true y se rompen si sí.

  14. 0

    Sé que esto es viejo el post . Pero yo sugeriría un poco de lógica y sencilla respuesta.

    for(unsigned int i=0; i < 50; i++)
        {
            for(unsigned int j=0; j < conditionj; j++)
            {
                for(unsigned int k=0; k< conditionk ; k++)
                {
                    //If condition is true
    
                    j= conditionj;
                   break;
                }
            }
        }
    • Eso no es muy escalable solución como j = conditionj no funcionará si usted tiene un complejo predicado en lugar de j < conditionj.
  15. 0

    Romper cualquier número de bucles por un solo bool variable ver a continuación :

    bool check = true;
    
    for (unsigned int i = 0; i < 50; i++)
    {
        for (unsigned int j = 0; j < 50; j++)
        {
            for (unsigned int k = 0; k < 50; k++)
            {
                //Some statement
                if (condition)
                {
                    check = false;
                    break;
                }
            }
            if (!check)
            {
                break;
            }
        }
        if (!check)
        {
            break;
        }
    }

    En este código que se break; todos los bucles.

  16. -1
      while (i<n) {
        bool shouldBreakOuter = false;
        for (int j=i + 1; j<n; ++j) {
          if (someCondition) {
              shouldBreakOuter = true;
          }
        }
    
        if (shouldBreakOuter == true)
          break;
    
      }
  17. -2

    Se puede utilizar try…catch.

    try {
        for(int i=0; i<10; ++i) {
            for(int j=0; j<10; ++j) {
                if(i*j == 42)
                    throw 0; //this is something like "break 2"
            }
        }
    }
    catch(int e) {} //just do nothing
    //just continue with other code

    Si usted tiene que salir de varios bucles en una vez, a menudo es una excepción, de todos modos.

    • Me gustaría saber la razón por la que esta respuesta tanto abajo de los votos.
    • La solución se ha caído votos porque se utiliza una excepción para controlar el flujo de ejecución. Como el nombre sugiere, las excepciones sólo debe utilizarse en casos excepcionales.
    • No es esta una situación excepcional para que el idioma no es el suministro de una solución adecuada?
    • Las excepciones son lentos.
    • Sería válido si 1. mi programa es compilado con las excepciones de apoyo (nunca en mi caso) y 2. realmente FUE una excepción 3. Usted está dispuesto a poner con el horrible sobrecarga.
    • El impacto en el rendimiento de la banda es enorme para algo que no es un error irrecuperable el 99% del tiempo.
    • El lenguaje de proporcionar soluciones, tales como el uso de una condición de prueba, o el uso de un goto.
    • También, si otro se produjo una excepción de ese bloque de código, usted hubiera atrapado, pensando que es el control de flujo, y se obtendría de multiplicación/se manejan correctamente.

  18. -3

    Salir de un bucle es un poco extraño para mí, ya que la semántica de un bucle suelen indicar que se va a ejecutar un número determinado de veces. Sin embargo, no es malo en todos los casos; si usted está buscando algo en una colección y quiere romper después de encontrar, es útil. Salir de bucles anidados, sin embargo, no es posible en C++; es en otros idiomas mediante el uso de una etiqueta de salto. Puede utilizar una etiqueta y un goto, pero que podría dar la acidez en la noche..? Parece que la mejor opción, aunque.

    • No es extraño en absoluto. Si eres de iterar sobre una colección para buscar algo (y no tienen una forma más rápida de búsqueda), no hay punto de terminar el bucle. (como un ejemplo)

Dejar respuesta

Please enter your comment!
Please enter your name here