2010-08-22 25 views
14

Duplicar posibles:
Difference between i++ and ++i in a loop?Postfix y operador de incremento prefijo en un bucle for

Puede alguien explicar lo que es la diferencia entre los que:

for(unsigned col = 0; col < n; ++col, num_to_fill >>= 1U) 
{ 

    for(unsigned row = num_to_fill; row < (1U << n); row += (num_to_fill * 2)) 
    { 
     std::fill_n(&output[col][row], num_to_fill, 1); 
    } 
} 

y

for(unsigned col = 0; col < n; col++, num_to_fill >>= 1U) 
{ 

    for(unsigned row = num_to_fill; row < (1U << n); row += (num_to_fill * 2)) 
    { 
     std::fill_n(&output[col][row], num_to_fill, 1); 
    } 
} 

Cuando col=0, En ej.1 Output[col][row] habrá output[1][row] y ej.2 En Output[col][row] habrá output[0][row]. ¿Estoy en lo cierto?

Pregunta 2: ¿Usaría en lugar de /= 2 hace alguna diferencia?

+1

Si no recuerdo mal, en este caso no hace ninguna diferencia. Hace una diferencia al usar la variable como un 'Valor-R' como:' a = b ++; 'o' a = ++ b; ' –

+0

Las respuestas para esa pregunta son en su mayoría incorrectas, Greg. Responden lo que son post e incremento previo, ** no ** cómo funcionan en un bucle - de hecho, muchos de ellos son engañosos en el sentido de que aplican que sí hace una diferencia porque usan una sintaxis engañosa para sus bucles ('int i = 0; foreach (randomOtherThing en randomOtherThings) '...) – Stephen

+0

Ok. ¿Qué hay de la 2da pregunta? – Ahmed

Respuesta

19

No hace ninguna diferencia en el valor de col dentro del ciclo - suponiendo que col es un valor primitivo. Si col fuera una clase, los operadores de prefijo y postfix '++' podrían estar sobrecargados para hacer dos cosas diferentes, aunque yo consideraría que es una mala práctica. Consideremos el siguiente ejemplo:

#include <iostream> 

using namespace std; 

int main() { 
    for(int i = 0; i < 10; i++) { 
     cout << i << endl; 
    } 

    cout << endl; 

    for(int i = 0; i < 10; ++i) { 
     cout << i << endl; 
    } 

} 

Ambos simplemente imprima 0 a 9, a pesar del hecho de que usted pre-incremento en uno, y post incremento en la otra. El incremento de i ocurre al final de cada ejecución del ciclo, ya sea que use o no el incremento previo o posterior. Creo que el pre-incremento es más eficiente, ya que, y puedo estar equivocado aquí, el compilador no necesita usar una variable temporal 1., pero esto solo se notará si hace un bucle durante mucho tiempo (y por supuesto 'More computing sins are committed in the name of efficiency than for any other single reason')

en cuanto a la pregunta 2:.

pregunta 2: ¿Quieres utilizando >> = 1U en lugar de =/2 hace ninguna diferencia?

Unlikely. El cambio de bit sería más rápido si el compilador no se optimizara, pero es probable que su compilador optimice esto en un cambio de bit.

Como nota al margen, por lo general se encuentran haciendo unsigned variableName (es decir, dejar caer el int) mala práctica - a pesar de C++ le mete en un int en cualquier lugar uno se encuentra, es menos legible para mí.

1.: Stephen en los comentarios (un diferente Stephen;)) señala que - "Pre-incremento es más eficiente para iteradores contenedores biblioteca estándar, pero no es diferente para los tipos primitivos, ya que la copia de un número entero es más barato que copiar un iterador más grande (en particular std :: set y std :: iteradores de mapa) ".

+0

That fue exhaustivo – Ahmed

+1

El preincremento es más eficiente para los iteradores de contenedor de biblioteca estándar, pero no es diferente para los tipos primitivos, ya que copiar un entero es más barato que copiar un iterador más grande (en particular std :: set y std :: map iterators). p.s. No soy el 'Stephen' que produjo esta respuesta –

+0

@Stephen Gracias, otros Stephen. Incluiré tu respuesta. Y luego crédito 'Stephen', por supuesto: p. – Stephen

1

No hay diferencia para unsigned. Sin embargo, habría una diferencia para las clases con operator++ sobrecargado, ya que llamaría a sus diferentes sobrecargas (por lo general, el operador de posfijo crea una copia de la clase, lo que significa que puede ser más lento).

¿Utilizaría >> = 1U en vez de/= 2?

Probablemente no. Su semántica es la misma para unsigned, y los compiladores generalmente los tratan por igual y pueden cambiar uno en otro si es más rápido.

+0

Me pregunto por qué el escritor de códigos lo usó. – Ahmed

+0

Puede describir mejor la operación general. Por ejemplo, si la variable que se está dividiendo (o desplazando) es algún tipo de vector de bits, en el que la división aritmética es un concepto sin sentido, pero el cambio es significativo. –

Cuestiones relacionadas