2009-09-04 15 views
5

Parece que¿Alguna razón para reemplazar mientras (condición) con para (; condición;) en C++?

while(condition) { 
    //do stuff 
} 

es completamente equivalente a

for(; condition;) { 
    //do stuff 
} 

¿Hay alguna razón para utilizar este último en lugar de la antigua?

+3

Ambos códigos de muestra son correctos y hacen lo mismo. Pero no hay ninguna razón para usar la segunda declaración. Cuando hay una avatabilidad de sintaxis adecuada, ¿por qué quieres usar la segunda? Entonces, la única razón para usar la segunda declaración es conocer diferentes tipos de código y creo que solo debe usarse con fines educativos. –

+1

He visto este último en un proyecto y me gustaría saber las razones por las que podría haber aparecido. – sharptooth

+0

Las ideas de estilo de los pueblos difieren, a menudo bruscamente, y a menudo en formas que yo no esperaría. Alguien puede haber querido estandarizar la declaración para todos los bucles, por alguna razón que parecía tener sentido en ese momento. No hay diferencia funcional –

Respuesta

23

No hay buena razón hasta donde yo sé. Está intencionalmente engañando a las personas mediante el uso de un bucle for que no incrementa nada.

Actualización:

Basado en el comentario de la OP a la pregunta, puedo especular sobre cómo es posible que vea una construcción de este tipo de código real. He visto (y utilizados) esto antes:

lots::of::namespaces::container::iterator iter = foo.begin(); 
for (; iter != foo.end(); ++iter) 
{ 
    // do stuff 
} 

Pero eso es por lo que yo voy con dejar las cosas fuera de un bucle para. Quizás su proyecto tenía un ciclo que se parecía a eso al mismo tiempo. Si agrega un código que elimina elementos de un contenedor en el medio del ciclo, es probable que tenga que controlar cuidadosamente cómo se incrementa iter. Eso podría conducir a código que se parece a esto:

for (; iter != foo.end();) 
{ 
    // do stuff 

    if (condition) 
    { 
     iter = foo.erase(iter); 
    } 
    else 
    { 
     ++iter; 
    } 
} 

Sin embargo, eso no es excusa para no tomar las cinco segundos necesarios para convertirla en un bucle while.

1

si quiere hacer algo una cantidad limitada de veces, entonces "para" le permite especificar la restricción sin mezclarla con la lógica dentro de su ciclo.

4

Hasta donde yo sé, el compilador optimiza las dos declaraciones en el mismo código assember de todos modos ... así que no, no hay ninguna razón para hacerlo, solo preferencias personales.

2

En este caso, personalmente prefiero el primer ciclo, ya que es más fácil de escribir y leer.

Pero si tengo un bucle que se necesita una cierta declaración posterior, que haría uso de bucle de la siguiente manera:

for (; i < 10; i += 2) 
2

Puede haber pequeñas diferencias compilador depende del nivel de montaje, pero lo ideal tanto debe se comportan exactamente igual, y el primero es más legible. Entonces no, no reson para usar la última versión que no sea inconformismo.

2

Compilar ambos y comprobar el desensamblaje resultante, si son iguales (lo que probablemente sea). Elija el que encuentre más legible.

1

Al mantener la legibilidad a un lado durante un tiempo, generalmente no hay diferencia de rendimiento entre los diferentes bucles. Al menos no hay una diferencia significativa.

Para aplicaciones de escritorio, puede elegir según los criterios de legibilidad. Consulte las otras publicaciones, p. Al buscar el bucle, alguien piensa que el incrementor está declarado dentro del bucle.

Parece para aplicaciones web, p. las secuencias de comandos del lado del cliente puede haber una diferencia.

Comprobar este sitio: http://www.websiteoptimization.com/speed/10/10-2.html

ejecutar sus propios experimentos y pasar los resultados de palo de otra por las normas de legibilidad.

+0

Pregunta formulada explícitamente sobre C++ ... – DevSolar

+0

@sharptooth: ¿Y puedo sostener tu billetera mientras estás ejecutando esos experimentos? –

3

Es posible compilar

for(INIT; CONDITION; UPDATE) 
{ 
    BODY 
} 

en

{ 
    INIT 
    while(CONDITION) 
    { 
    BODY 
    UPDATE 
    } 
} 

UPDATE: El alcance adicional aparentemente redundante es jaula cualquier definición de variables en INIT, es decir, desde for(int i = 0; ...). ¡Gracias!

Básicamente es solo un reordenamiento de las expresiones. Así que no hay ninguna razón para preferir uno sobre el otro, por razones de rendimiento. Recomendaría while() si es posible, ya que es más simple. Si un constructo más simple expresa lo que quieres hacer, creo que es el que debes usar.

+3

Recuerde que la instrucción 'continue' tiene una semántica diferente en este último caso. – Juliano

+3

El alcance de INIT es diferente. –

+0

No solo es posible, también está definido en el estándar de esa manera, vea mi respuesta a un duplicado de esta pregunta aquí: http://stackoverflow.com/questions/885908/while-1-vs-for-is-here -a-speed-difference/887298 # 887298. –

1

puedo ver 2 razones, ninguno de los cuales me gustaría considerar:

  • sólo tenemos 1 construcción de lazo, pero entonces la objeción de Kristo stands
  • de escritura "para (; siempre;)", pero luego prefiere una macro LOOP_FOREVER si realmente quiere esto.
+2

Las macros son malvadas. ;-) – DevSolar

+0

'for (; EVER;)' == 'while (true)' :) – suszterpatt

+0

@suszterpatt Está leyendo "para siempre". @DevSolar: ¿qué hay de BOOST_FOREACH? – stefaanv

6

No. No. No.

Incluso si hubiera una diferencia de rendimiento microscópica, que tendría que ser un ajustador de rendimiento Jedi en fase terminal tenerlo importa lo suficiente como para cuidar.

+1

E incluso si hubiera alguna diferencia de rendimiento, el uso de este último todavía estaría trabajando en torno a un error del compilador (error al optimizar el ciclo while). –

+0

+1 para "sintonizador de rendimiento Jedi de etapa final" – DVK

+2

Debería ser sintonizador de rendimiento Sith. Como todas las optimizaciones de nivel de código como esta son malvadas. –

1

Realmente no hay diferencia en los idiomas C-ish entre un ciclo for (; cond;) y un ciclo while. En general, lo que hago en los lenguajes C-ish es comenzar a escribir el ciclo como un "para" y cambiarlo a un "while" si termino con ese formulario. Sin embargo, es un poco raro, ya que siempre está iterando a través de algo, y C le permite poner el código que desee en esa última área.

Sería diferente si C tuviera real (iteración pre calculada) para bucles.

2

Creo que los bucles "while" y "for" están pensados ​​para diferentes expresiones idiomáticas. La expresión idiomática de usar "mientras" es "hacer algo, mientras que ciertas condiciones son ciertas". El modismo para "para" es "iterar sobre un cierto rango de elementos" ...

Cada vez que leo un código, espero estos modismos (y creo que no estoy solo). Cuando veo "por" entiendo, alguien está iterando sobre cierto rango y no entiendo detalles. Cuando veo el ciclo for, usado para otro idioma (no el que espero), me confundo y tengo que entrar en detalles.

De todos modos, es muy subjetiva ...

8

Algunos compiladores advierten sobre las condiciones de bucle constante:

while (true) { /* ... */ } /* Warning! */ 
for (;;) { /* ... */ } /* No warning */ 

En el caso específico de un bucle infinito, podría elegir un bucle durante un tiempo bucle por esa razón. Pero si la condición no está vacía, realmente no veo ningún beneficio. Mi suposición de por qué apareció en el proyecto mencionado es que el código de alguna manera evolucionó a través del mantenimiento, pero originalmente fue escrito de una manera más convencional.

1

Es posible que desee utilizar un bucle do-while en lugar de un bucle for para que el código se procese al menos una vez antes de comprobar y cumplir (o no) las condiciones.

6

¿Hay alguna razón para usar la última en lugar de la anterior?

  1. un esfuerzo equivocado para impresionar a sus colegas que usted sabe que estas dos formas son equivalentes.
  2. Una maniobra insensata para garantizar la "seguridad en el trabajo" haciendo que su código sea tan confuso como sea posible para que nadie quiera cambiarlo.
  3. La tecla "w" en su teclado está rota.
  4. Comenzó su vida como un bucle for con inicializadores y condición de incremento, y cuando la lógica cambió, el desarrollador estaba demasiado ocupado para cambiarlo.
+2

+1 para # 3! (agregue más caracteres para que pase 15) –

1

Solía ​​escribir algunos códigos C/C++ bastante crípticos. Mirando hacia atrás, probablemente hacer esto en un bucle while:

ifstream f("file.txt"); 
char c; 
for(f.get(c); !f.eof(); f.get(c)) { 
    // ... 
} 

Creo que mi punto es que los bucles son generalmente más corto, pero menos legible, si no se utilizan en el sentido tradicional de bucle en un rango .

1

Esta pregunta ha sido respondida, el lenguaje tiene un constructo más natural para expresar lo que desea, debe usarlo. Por ejemplo, sin duda puedo escribir esto:

for (bool b = condition(); b; b = !b) { 
    /* more code */ 
} 

o:

while (condition()) { 
    /* more code */ 
    break; 
} 

en lugar de la más convencional:

if (condition()) { 
    /* more code */ 
} 

Pero por qué? C (y todos los idiomas) tienen modismos y la mayoría de ellos tienen sentido racional en términos de expresividad y expectativa de significado. Cuando te masturbas con la expresión idiomática, tu confusión con la sensibilidad de la persona que tiene que leer tu código.

Cuestiones relacionadas