for (;;) {
//Something to be done repeatedly
}
He visto que este tipo de cosas se usan mucho, pero creo que es bastante extraño ... ¿No sería mucho más claro decir while(true)
, o algo por el estilo?
Supongo que (como es la razón por la cual muchos programadores recurren al código críptico), ¿esto es un pequeño margen más rápido?
¿Por qué, y realmente vale la pena? Si es así, ¿por qué no simplemente definirlo de esta manera?
#define while(true) for(;;)
Ver también: ¿Cuál es más rápido: while (1) o while (2)?
c++
c
optimization
readability
infinite-loop
Chris Cooper
fuente
fuente
TRUE
?TRUE
tiene que ver con C? La macro estándar para un verdadero resultado boolen en C99 sigue siendotrue
. ¿De dónde vino elTRUE
?#define EVER ;;
aunque se ha utilizado en IOCCC .. :)#define while(TRUE)
declarar una macro que toma un argumento llamadoTRUE
que nunca se usa, por lo tanto, convierte cada ciclo while en su programa en un ciclo infinito?TRUE
proviene de los archivos de encabezado asociados con la API de Windows. No está relacionado con VS 6.0 de ninguna manera. Y, como dije antes, no tiene nada que ver con C o C ++. En C ++, el literal "verdadero" es justotrue
(también en VS 6.0), en C89 / 90 no existe tal cosa, y en C99 es macrotrue
. Esto se aplica a todos los compiladores C / C ++.Respuestas:
fuente
Prefiero
for(;;)
por dos razones.Una es que algunos compiladores producen advertencias sobre
while(true)
(algo así como "la condición del bucle es constante"). Evitar las advertencias siempre es algo bueno.Otra es que creo que
for(;;)
es más clara y más reveladora. Quiero un bucle infinito. Literalmente tiene no condición, no depende de nada. Solo quiero que continúe para siempre, hasta que haga algo para salir de eso.Mientras que con
while(true)
, bueno, ¿qué tiene que ver algo con algo? No estoy interesado en hacer un bucle hasta que verdadero se convierta en falso, que es lo que esta forma literalmente dice (bucle mientras que verdadero es verdadero). Solo quiero hacer un bucle.Y no, no hay absolutamente ninguna diferencia de rendimiento.
fuente
for(;;)
, obviamente se verá extraño. Pero te recomiendo que te acostumbres porque es un idioma común, y vas a toparte con él nuevamente. ;)for(;condition;)
. Eso es lo que un bucle while es para . Pero como dije, con un bucle infinito, realmente no quiero que el compilador compare ninguna condición. Ingenuamente, con unwhile
bucle, tendría que probartrue
cada iteración (obviamente, ni siquiera el compilador más tonto haría eso, pero es el principio lo que me molesta. Me sorprende que especifiques en exceso tu código), mientras que con unfor(;;)
literalmente estás diciendo "no hay condición para probar. Solo bucle". Me parece el equivalente más cercano a tu imaginarioloop {...}
while(true)
da una advertencia.Personalmente lo uso
for (;;)
porque no contiene ningún número, es solo una palabra clave. Yo prefiero awhile (true)
,while (1)
,while (42)
,while (!0)
, etc, etc.fuente
true
no es más un número mágico quefor
una palabra clave mágica o quefor(;;)
utiliza un infinito mágico implícito. (dewhile (42)
hecho es una abominación.)for(;;)
se analiza más rápido que los demás de todos modos#define LIFE 42
while (LIFE)
:)while(true)
no contiene ningún número también. y para (;;) no es una palabra clavePor Dennis Ritchie
Empecé a usarlo
for (;;)
porque así es como lo hace Dennis Ritchie en K&R, y cuando aprendo un nuevo idioma siempre trato de imitar a los tipos inteligentes.Esto es idiomático C / C ++. Probablemente sea mejor a largo plazo acostumbrarse si planea hacer mucho en el espacio C / C ++.
Su
#define
voluntad no funciona, ya que lo de ser #define tiene que parecer un identificador C.Todos los compiladores modernos generarán el mismo código para las dos construcciones.
fuente
while(TRUE)
, sospecho que el programador es un novato en C, o aprendí C de un libro For Dummies.Ciertamente no es más rápido en ningún compilador cuerdo. Ambos serán compilados en saltos incondicionales. La versión for es más fácil de escribir (como dijo Neil) y será clara si comprende la sintaxis de bucle.
Si tienes curiosidad, esto es lo que gcc 4.4.1 me da para x86. Ambos usan la instrucción x86 JMP .
compila a (en parte):
fuente
for_infinite
es más rápido; 2 caracteres menos paraputs
.yo prefiero
for (;;)
porque es el más consistente en diferentes lenguajes tipo C.En C ++
while (true)
está bien, pero en C depende de un encabezado para definirtrue
, pero tambiénTRUE
es una macro de uso común. Si lo usawhile (1)
, es correcto en C y C ++, y JavaScript, pero no en Java o C #, que requieren que la condición del bucle sea booleana, comowhile (true)
owhile (1 == 1)
. En PHP, las palabras clave no distinguen entre mayúsculas y minúsculas, pero el lenguaje prefiere las mayúsculasTRUE
.Sin embargo,
for (;;)
siempre es completamente correcto en todos esos idiomas.fuente
for (;;)
es mejor.while (1)
yfor (;;)
son expresiones comunes para los bucles infinitos en C. Cualquier persona que lea un programa en C que tiene problemas para entender bien es probable que tenga problemas con el resto del código. No vale la pena escribir código C que pueda leer fácilmente alguien que no conozca C.Personalmente prefiero el
for (;;)
idioma (que se compilará con el mismo código quewhile (TRUE)
.El uso
while (TRUE)
puede ser más legible en un sentido, he decidido usar elfor (;;)
idioma porque se destaca .Una construcción de bucle infinito debería notarse fácilmente o llamarse en código, y personalmente creo que el
for (;;)
estilo lo hace un poco mejor quewhile (TRUE)
owhile (1)
.Además, recuerdo que algunos compiladores emiten advertencias cuando la expresión controladora de un ciclo while es una constante. No creo que eso suceda demasiado, pero solo el potencial de advertencias espurias es suficiente para querer evitarlo.
fuente
He visto que algunas personas lo prefieren porque tienen un #definir en algún lugar como este:
Lo que les permite escribir esto:
fuente
FOREVER
definidafor(;;)
, pero eso no es mejor. Las macros IMO no deben usarse para 'inventar' un nuevo lenguaje.#define BEGIN {
y#define END }
. Incluso he visto#define DONKEYS_FLY (0)
para que puedan decirif DONKEYS_FLY ...
. ¿Quién dice que el software es aburrido?#define never while(0)
y#define always
¿Qué pasa (si su idioma lo admite):
fuente
goto
las numerosas desventajas, pero si el algoritmo que está tratando de implementar proviene de un diagrama de flujo, esta es la traducción más directa.goto
goto
es que no tiene que preocuparse de que alguien agregue unbreak
para hacer que su ciclo sea menos infinito. (a menos que ya estés dentro de otrowhile
o unfor
bucle, por supuesto ...)No hay diferencia en términos del código de máquina que se genera.
Sin embargo, solo para contrarrestar la tendencia, argumentaría que la forma while (TRUE) es mucho más legible e intuitiva que para (;;), y que la legibilidad y la claridad son razones mucho más importantes para las pautas de codificación que cualquier otra razón I ' He escuchado el enfoque for (;;) (prefiero basar mis pautas de codificación en razonamiento sólido y / o prueba de efectividad por mí mismo).
fuente
for(;;)
es la forma tradicional de hacer esto en C y C ++.while(true)
parece ser la convención en C # y Java y otros lenguajes. Su experiencia puede ser diferente.No solo un patrón bien conocido, sino un idioma estándar en C (y C ++)
fuente
while (true)
por la misma razón que lo hacenif (true)
.genera una advertencia con Visual Studio (la condición es constante). La mayoría de los lugares en los que he trabajado compilan compilaciones de producción con advertencias como errores. Entonces
se prefiere.
fuente
Ambos deberían ser iguales si su compilador optimiza su código. Para explicar lo que quiero decir con optimización, aquí hay un código de muestra escrito en MSVC 10:
Si lo compila en modo de depuración ( sin optimización (/ Od) ), el desmontaje muestra la clara diferencia. Hay instrucciones adicionales para la
true
condición en el interiorwhile
.Sin embargo, si construye su código en modo Release (con la velocidad de maximización predeterminada (/ O2) ) obtendrá la misma salida para ambos. Ambos bucles se reducen a una instrucción de salto.
Cualquier cosa que use no importa para un compilador decente con optimización de velocidad activada.
fuente
Es una cuestión de preferencia personal qué camino es más rápido. Personalmente, soy un touchtypist y nunca miro mi teclado, durante la programación, puedo tipear las 104 teclas de mi teclado.
Me parece más rápido escribir "while (TRUE)".
Agregué mentalmente algunas medidas de movimiento de los dedos y las totalicé. "for (;;)" tiene aproximadamente 12 anchuras de tecla de movimientos hacia atrás y cuarto (entre las teclas de inicio y las teclas, y entre las teclas de inicio y la tecla MAYÚS) "while (TRUE)" tiene aproximadamente 14 anchuras de teclas de movimientos hacia atrás y cuarto.
Sin embargo, soy mucho menos propenso a errores al escribir este último. Pienso mentalmente en palabras a la vez, por lo que me resulta más rápido escribir cosas como "nIndex" que acrónimos como "nIdx" porque tengo que deletrear mentalmente las letras en lugar de decirlas dentro de mi mente y dejar que mis dedos se auto -tipear la palabra (como andar en bicicleta)
(Mi referencia de TypingTest.com = 136 WPM)
fuente
time head -10 >/dev/null
, escriba cada 10 veces y mida los resultados. Apuesto a que serás más rápido afor(;;)
menos que hagas trampa. Estaba en aproximadamente el 14%.Todas buenas respuestas: el comportamiento debe ser exactamente el mismo.
SIN EMBARGO - Solo suponga que HIZO la diferencia. Supongamos que uno de ellos toma 3 instrucciones más por iteración.
¿Te debería importar?
SOLO si lo que haces dentro del bucle es casi nada , lo cual casi nunca es el caso.
Mi punto es que hay micro-optimización y macro-optimización. La microoptimización es como "cortarse el pelo para perder peso".
fuente
++i
mási++
?++i
yi++
potencialmente puede ser significativa si sei
trata de una instancia de una clase en lugar de una integrada y el compilador no aplica la optimización trivial. El consejo es adquirir un hábito para que no te atrape cuando sea necesario.++i
vsi++
es que no le cuesta nada hacer la "optimización". Es cierto, en la mayoría de los casos no hace absolutamente ninguna diferencia, pero son igualmente fáciles de escribir, entonces, ¿por qué no preferir el potencialmente más eficiente por defecto? Y supongo que lo mismo se aplica aquí. Si uno era un poco más rápido que el otro, ¿por qué no elegir el más rápido? ¿Qué perderíamos al hacerlo? Ambos son bastante fáciles de leer y escribir.No puedo imaginar que un compilador valioso generaría un código diferente. Incluso si lo hiciera, no habría forma de determinar sin probar el compilador particular que era más eficiente.
Sin embargo, sugiero que prefiera
for(;;)
por las siguientes razones:Varios compiladores que he utilizado generarán una advertencia de expresión constante para while (verdadero) con la configuración de nivel de advertencia adecuada.
en su ejemplo, la macro VERDADERO puede no estar definida como espera
Hay muchas posibles variantes de la infinita mientras bucle tales como
while(1)
,while(true)
,while(1==1)
etc .; asífor(;;)
es probable que resulte en una mayor consistencia.fuente
while(TRUE)
evalúa comowhile(0)
no es probable que se beneficiefor(;;)
.while(true)
debe preferirse en cualquier caso. En C ++bool
está reservado, y en C se define en C stdbool.h (lo que lo hace menos seguro en C).for(;;)
elimina toda dudaEs más claro que:
No es que esto se aplique si no lo está usando
Sleep()
.fuente
timerService.scheduleRepeating (50, [] () { /* lots of code */ });
El bucle "para siempre" es popular en los sistemas integrados como un bucle de fondo. Algunas personas lo implementan como:
Y a veces se implementa como:
Y otra implementación más es:
Un compilador de optimización debería generar el mismo código de ensamblaje o uno similar para estos fragmentos. Una nota importante: el tiempo de ejecución de los bucles no es una gran preocupación ya que estos bucles duran para siempre y se dedica más tiempo a la sección de procesamiento.
fuente
Supongo que while (true) es más legible que for (;;): parece que el programador pierde algo en for loop :)
fuente
La razón más importante para usar "for (;;)" es el miedo a usar "while (TRUE)" cuando haces programación exploratoria. Es más fácil controlar la cantidad de repeticiones con "for", y también, es más fácil convertir el bucle "for" en un infinito.
Por ejemplo, si está construyendo una función recursiva, puede limitar la cantidad de llamadas a la función antes de convertirla en un bucle infinito.
Cuando estoy seguro de mi función, la convierto en un bucle infinito:
fuente