Supongamos que tengo un bucle en C ++ o C # que dice así:
while( true ) {
doSomething();
if( condition() ) {
break;
}
doSomethingElse();
}
Esto se llama comúnmente "bucle infinito". Sin embargo, no es técnicamente infinito; se detendrá una vez que fluya el control break
.
¿Cuál es el término para tal bucle, que tiene una declaración de control de bucle "bucle para siempre" y "ruptura" dentro?
terminology
diente filoso
fuente
fuente
condition()
pasa si siempre devuelve falso? Yo diría que es un bucle infinito con saltos condicionales.break
, el bucle no es infinito (kill
, ctrl-alt-del, desconectar ...). Entonces, ¿por qué molestarse con los detalles de la terminología?Respuestas:
Al estudiar CS, este profesor nos enseñó que hay bucles de verificación previa (
while(cond) {}
), bucles de verificación posterior (do {} while(cond);
) y bucles de verificación media . (Podría haber traducido mal esto al inglés, pero entiendes la idea).C y C ++ no tienen este último (ISTR Ada lo tiene, BICBW), por lo que su construcción se usa para eso en C y C ++.
fuente
loop ... exit when condition; ... end loop;
El primer curso de CS en Stanford ( Metodología de programación de Mehran Sahami ) se refiere a esto como un ciclo y medio . Y no es necesariamente una mala práctica de programación. Considere este ejemplo sobre la recopilación de información del usuario (tomado de The Art and Science of Java por Eric Roberts , donde Roberts también lo llama a-loop-and-a-half ):
Y luego lo mismo se resolvió usando el bucle y una idea a medias para evitar el código duplicado:
fuente
Al no tener un nombre oficial, lo llamaría Broken Loop . La ambigüedad de este término es intencionada, ya que una ruptura en medio de un ciclo es un poco impura, casi como a
goto
.fuente
goto
también tenía aplicaciones válidas, por ejemplo, emulación de un intento ... finalmente bloquee en C.while(XEventGet(&ev) != NULL){ ... }
, que está naturalmente va a querer comprobar las claves dentro del ciclo:if(ev.key == XK_q) break;
. Hacer lo siguiente:while(XEventGet(&ev) != NULL && ev.key != XK_q){ ... }
es feo y podría decirse que es más difícil de leer que una pausa de medio ciclo. Además, ¿qué sucede si primero se debe hacer algo con el valor antes de que se pueda verificar? No vas a meter todo eso en el caso base del bucle, ¿verdad?No hay nombre definitivo. El bucle infinito es, creo, el término apropiado. No hay bucles realmente infinitos, pero esto tiene el potencial de ser efectivamente infinito ya que es posible que la rama que contiene la ruptura nunca ocurra.
Si le dice a alguien "cree un bucle infinito y use un descanso para la condición X" y sabrá a qué se refiere. Si alguien está revisando su código y no dice nada más que "No me gusta el bucle infinito que escribió", sabrá de qué está hablando (a menos que tenga más de uno, por supuesto).
fuente
while
bucle normal y la forma en que realiza la prueba de terminación es exactamente la misma (encontrar una métrica con disminución monotónica es un gran comienzo).Es un bucle do-while con el condicional en el lugar equivocado.
fuente
break
ocontinue
. Evite los valores centinela a toda costa, son solo otra parte arbitraria del estado a seguir mentalmente, que oculta el propósito del código.Yo votaría por el "bucle incondicional" , similar al "salto incondicional". Ilustra exactamente lo que está sucediendo (el código se repite incondicionalmente), sin mentir (a diferencia del "bucle infinito").
fuente
if
/break
en el medio es parte del patrón.Es un bucle infinito con una condición de interrupción.
Estoy de acuerdo con ammilind en que si quisieras darle un nombre especial, podrías llamarlo un bucle parcial infinito
fuente
En el Código de Rosetta, este patrón particular se describe como un bucle "N más una mitad" . Si bien no es mi término favorito, no es terrible y es claramente un patrón que es útil para algunos tipos de bucles. (Las alternativas son duplicar el código antes de la condición, potencialmente complicado en programas reales, o aumentar la profundidad de anidamiento del código después de la condición mientras se agrega una variable de condición de bucle; ni mejora la capacidad de mantenimiento ni la comprensión del código . La única razón para rechazar tales construcciones es si uno insiste en escribir bucles para que no tenga problemas
break
.)fuente
No hay un término estándar, pero lo diría como un bucle parcial .
Este bucle se usa cuando desea romper solo después de ejecutar alguna parte del bucle por última vez (es decir, ejecución parcial). Se usa cuando no encuentra una situación adecuada en la que desee romper todo el ciclo .
En este caso, desea romper el ciclo después de al menos ejecutarlo por
doSomething()
última vez.fuente
Tengo que estar de acuerdo con SBI aquí, me gusta el término del bucle de verificación de en medio . Este tipo de construcción fue más popular cuando la programación estructurada comenzó a funcionar y muchos lenguajes tenían soporte sintáctico para ellos.
Dicho esto, ahora se sabe que
while
se sabe bucles suelen ser más mantenibles, ya que es más fácil razonar sobre los invariantes y, a menudo, manejan mejor el complicado caso vacío.En su caso particular, su bucle es equivalente a
así que solo usaría la
break
versión sidoSomething
odoSomethingElse
involucrara varias declaraciones y prefiero no guardarlas en funciones separadas como lo hizo usted.Dicho esto, si su ciclo es más complicado que una iteración (inicio, verificación, incremento), entonces debería considerar refactorizarlo en algo más simple.
fuente
Supongo que si vamos a tratar de inventar un término para esto, tal vez:
fuente
Yo lo llamo lo que es, un "ciclo verdadero".
¿Ver también mientras es (cierto) una mala práctica de programación?
fuente
No es tan malo en todos los casos. Me encuentro escribiendo este tipo de bucles con cierto tipo de API. Digamos, por ejemplo, que tiene un objeto de bucle y necesita verificar alguna condición bastante profunda en él, así:
Ahora suponga que cada método getXXX podría devolver un valor nulo. Entonces aún sería posible escribir una expresión booleana, aunque bastante complicada e ilegible. Y luego tenemos que rehacer casi lo mismo para llegar al objeto controlador actual. En tales casos, me resulta más fácil escribir un
while (true)
bucle con pausa y continuar.fuente