Pregunta

En C, ¿cuál es la diferencia entre usar ++ i y i ++ , y cuál debe usarse en el bloque de incremento de un para loop?

¿Fue útil?

Solución

  • ++ i incrementará el valor de i y luego devolverá el valor incrementado.

     i = 1;
     j = ++i;
     (i is 2, j is 2)
    
  • i ++ incrementará el valor de i , pero devolverá el valor original que i tenía antes de ser incrementado.

     i = 1;
     j = i++;
     (i is 2, j is 1)
    

Para un bucle for , cualquiera de los dos funciona. ++ i parece más común, tal vez porque eso es lo que se usa en K & amp; R .

En cualquier caso, siga las pautas " prefiera ++ i sobre i ++ " y no te equivocarás.

Hay un par de comentarios sobre la eficiencia de ++ i y i ++ . En cualquier compilador de proyectos que no sean estudiantes, no habrá diferencia de rendimiento. Puede verificar esto mirando el código generado, que será idéntico.

La pregunta de eficiencia es interesante ... aquí está mi intento de respuesta: ¿Hay alguna diferencia de rendimiento entre i ++ y ++ i en C?

Como en las notas de Freund , es diferente para un objeto C ++, ya que operator ++ () es una función y el compilador no puede saber cómo optimizar la creación de un objeto temporal para mantener el valor intermedio.

Otros consejos

i ++ se conoce como Incremento de publicación , mientras que ++ i se llama Pre Incremento.

i++

i ++ es un incremento posterior porque incrementa el valor de i en 1 una vez que finaliza la operación.

Veamos el siguiente ejemplo:

int i = 1, j;
j = i++;

Aquí el valor de j = 1 pero i = 2 . Aquí el valor de i se asignará a j primero y luego se incrementará i .

++i

++ i es un incremento previo porque incrementa el valor de i en 1 antes de la operación. Significa que j = i; se ejecutará después de i ++ .

Veamos el siguiente ejemplo:

int i = 1, j;
j = ++i;

Aquí el valor de j = 2 pero i = 2 . Aquí el valor de i se asignará a j después del incremento de i de i . De manera similar, ++ i se ejecutará antes de j = i; .

Para su pregunta ¿cuál debe usarse en el bloque de incremento de un ciclo for? la respuesta es, puede usar cualquiera ... no importa. Ejecutará su for loop mismo no. de veces.

for(i=0; i<5; i++)
   printf("%d ",i);

Y

for(i=0; i<5; ++i)
   printf("%d ",i);

Ambos bucles producirán la misma salida. es decir, 0 1 2 3 4 .

Sólo importa dónde lo estés utilizando.

for(i = 0; i<5;)
    printf("%d ",++i);

En este caso, la salida será 1 2 3 4 5 .

Por favor, no te preocupes por la " eficiencia " (velocidad, realmente) de cuál es más rápido. Tenemos compiladores en estos días que se encargan de estas cosas. Utilice el que tenga sentido utilizar, según lo que muestre más claramente su intención.

++ i incrementa el valor, luego lo devuelve.

i ++ devuelve el valor y luego lo incrementa.

Es una diferencia sutil.

Para un bucle for, use ++ i , ya que es un poco más rápido. i ++ creará una copia adicional que simplemente se tirará.

i ++ : En este escenario, primero se asigna el valor y luego se realiza el incremento.

++ i : En este escenario, primero se realiza el incremento y luego se asigna un valor

A continuación se muestra la visualización de la imagen y también aquí hay un buen video práctico que demuestra lo mismo.

ingrese la descripción de la imagen aquí

El motivo ++ i puede ser un poco más rápido que i ++ es que i ++ puede requerir una copia local del valor de i antes de que se incremente, mientras que ++ i nunca lo hace. En algunos casos, algunos compiladores lo optimizarán si es posible ... pero no siempre es posible, y no todos los compiladores hacen esto.

Intento no confiar demasiado en las optimizaciones de los compiladores, así que seguiría el consejo de Ryan Fox: cuando puedo usar ambas, uso ++ i .

El resultado efectivo de usar cualquiera de los dos es idéntico. En otras palabras, el bucle hará exactamente lo mismo en ambos casos.

En términos de eficiencia, podría haber una penalización relacionada con la elección de i ++ sobre ++ i. En términos de la especificación de idioma, el uso del operador de incremento posterior debe crear una copia adicional del valor en el que actúa el operador. Esto podría ser una fuente de operaciones adicionales.

Sin embargo, debe considerar dos problemas principales con la lógica anterior.

  1. Los compiladores modernos son geniales. Todos los buenos compiladores son lo suficientemente inteligentes como para darse cuenta de que está viendo un incremento entero en un bucle for, y optimizará ambos métodos al mismo código eficiente. Si usar post-incremento sobre pre-incremento realmente hace que su programa tenga un tiempo de ejecución más lento, entonces está usando un compilador terrible .

  2. En términos de complejidad operacional, los dos métodos (incluso si se está realizando una copia) son equivalentes. El número de instrucciones que se realizan dentro del bucle debe dominar significativamente el número de operaciones en la operación de incremento. Por lo tanto, en cualquier bucle de tamaño significativo, la penalización del método de incremento se verá superada por la ejecución del cuerpo del bucle. En otras palabras, es mucho mejor preocuparse por la optimización del código en el bucle en lugar del incremento.

En mi opinión, todo el problema simplemente se reduce a una preferencia de estilo. Si crees que el pre-incremento es más legible, entonces úsalo. Personalmente, prefiero el postincremento, pero probablemente sea porque fue lo que me enseñaron antes de saber algo sobre optimización.

Este es un ejemplo esencial de optimización prematura, y problemas como este tienen el potencial de distraernos de los problemas serios en el diseño. Sin embargo, aún es una buena pregunta que hacer, ya que no hay uniformidad en el uso o consenso en las "mejores prácticas".

Ambos incrementan el número. ++ i es equivalente a i = i + 1 .

i ++ y ++ i son muy similares pero no exactamente iguales. Ambos incrementan el número, pero ++ i incrementa el número antes de evaluar la expresión actual, mientras que i ++ incrementa el número después de evaluar la expresión.

Ejemplo:

int i = 1;
int x = i++; //x is 1, i is 2
int y = ++i; //y is 3, i is 3

++ i (Operación de prefijo): Incrementa y luego asigna el valor
(p. ej.): int i = 5 , int b = ++ i        En este caso, 6 se asigna a b primero y luego se incrementa a 7 y así sucesivamente.

i ++ (operación Postfix): asigna y luego incrementa el valor
(p. ej.): int i = 5 , int b = i ++        En este caso, 5 se asigna a b primero y luego a 6 y así sucesivamente.

La base de for loop: i ++ se usa principalmente porque, normalmente, usamos el valor de inicio de i antes de incrementar el bucle for. Pero dependiendo de la lógica de su programa, puede variar.

++ i : es pre-incremento y el otro es post-incremento.

i ++ : obtiene el elemento y luego lo incrementa.
++ i : incrementa i y luego devuelve el elemento.

Ejemplo:

int i = 0;
printf("i: %d\n", i);
printf("i++: %d\n", i++);
printf("++i: %d\n", ++i);

Salida:

i: 0
i++: 0
++i: 2

Asumo que ahora entiendes la diferencia en semántica (aunque honestamente me pregunto por qué la gente hace preguntas sobre "qué significa el operador X" sobre el desbordamiento de la pila en lugar de leer, ya sabes, un libro o un tutorial web o algo así.

Pero de todos modos, en cuanto a cuál usar, ignore las preguntas de rendimiento, que son poco probable importante incluso en C ++. Este es el principio que debe utilizar al decidir que utilizar:

Di lo que quieres decir en el código.

Si no necesita el valor antes del incremento en su declaración, no use esa forma del operador. Es un problema menor, pero a menos que esté trabajando con una guía de estilo que prohíba una versión a favor de la otra en conjunto (también conocida como una guía de estilo con cabeza de hueso), debe usar la forma que más exactamente expresa lo que estás tratando de hacer.

QED, use la versión previa al incremento:

for (int i = 0; i != X; ++i) ...

La diferencia se puede entender con este simple código de C ++ a continuación:

int i, j, k, l;
i = 1; //initialize int i with 1
j = i+1; //add 1 with i and set that as the value of j. i is still 1
k = i++; //k gets the current value of i, after that i is incremented. So here i is 2, but k is 1
l = ++i; // i is incremented first and then returned. So the value of i is 3 and so does l.
cout << i << ' ' << j << ' ' << k << ' '<< l << endl;
return 0;
  

La principal diferencia es

     
      
  • Publicación de i ++ ( Después del incremento ) y
  •   
  • ++ i Pre ( Antes del incremento )

         
        
    • publicar si i = 1 los incrementos de bucle como 1,2,3,4,n
    •   
    • pre if i = 1 el bucle se incrementa como 2,3,4,5,n
    •   
  •   

i ++ y ++ i

Este pequeño código puede ayudar a visualizar la diferencia desde un ángulo diferente al de las respuestas ya publicadas:

int i = 10, j = 10;

printf ("i is %i \n", i);
printf ("i++ is %i \n", i++);
printf ("i is %i \n\n", i);

printf ("j is %i \n", j);
printf ("++j is %i \n", ++j);
printf ("j is %i \n", j);

El resultado es:

//Remember that the values are i = 10, and j = 10

i is 10 
i++ is 10     //Assigns (print out), then increments
i is 11 

j is 10 
++j is 11    //Increments, then assigns (print out)
j is 11 

Preste atención a las situaciones anteriores y posteriores.

para bucle

En cuanto a cuál de ellos debe usarse en un bloque de incremento de un bucle for, creo que lo mejor que podemos hacer para tomar una decisión es usar un buen ejemplo:

int i, j;

for (i = 0; i <= 3; i++)
    printf (" > iteration #%i", i);

printf ("\n");

for (j = 0; j <= 3; ++j)
    printf (" > iteration #%i", j);

El resultado es:

> iteration #0 > iteration #1 > iteration #2 > iteration #3
> iteration #0 > iteration #1 > iteration #2 > iteration #3 

No sé sobre ti, pero no veo ninguna diferencia en su uso, al menos en un bucle for.

El siguiente fragmento de código C ilustra la diferencia entre los operadores pre y post incremento y decremento:

int  i;
int  j;

Operadores de incremento:

i = 1;
j = ++i;    // i is now 2, j is also 2
j = i++;    // i is now 3, j is 2

El precremento significa incremento en la misma línea. Post-incremento significa incremento después de que se ejecuta la línea.

int j=0;
System.out.println(j); //0
System.out.println(j++); //0. post-increment. It means after this line executes j increments.

int k=0;
System.out.println(k); //0
System.out.println(++k); //1. pre increment. It means it increments first and then the line executes

Cuando viene con operadores OR, AND, se vuelve más interesante.

int m=0;
if((m == 0 || m++ == 0) && (m++ == 1)) { //false
/* in OR condition if first line is already true then compiler doesn't check the rest. It is technique of compiler optimization */
System.out.println("post-increment "+m);
}

int n=0;
if((n == 0 || n++ == 0) && (++n == 1)) { //true
System.out.println("pre-increment "+n); //1
}

En matriz

System.out.println("In Array");
int[] a = { 55, 11, 15, 20, 25 } ;
int ii, jj, kk = 1, mm;
ii = ++a[1]; // ii = 12. a[1] = a[1] + 1
System.out.println(a[1]); //12

jj = a[1]++; //12
System.out.println(a[1]); //a[1] = 13

mm = a[1];//13
System.out.printf ( "\n%d %d %d\n", ii, jj, mm ) ; //12, 12, 13

for (int val: a) {
     System.out.print(" " +val); //55, 13, 15, 20, 25
}

En C ++ post / pre-incremento de la variable de puntero

#include <iostream>
using namespace std;

int main() {

    int x=10;
    int* p = &x;

    std::cout<<"address = "<<p<<"\n"; //prints address of x
    std::cout<<"address = "<<p<<"\n"; //prints (address of x) + sizeof(int)
    std::cout<<"address = "<<&x<<"\n"; //prints address of x

    std::cout<<"address = "<<++&x<<"\n"; //error. reference can't re-assign because it is fixed (immutable)
}

En breve:

++ i y i ++ funcionan igual si no los escribes en una función. Si usa algo como la función (i ++) o (++ i) puede ver la diferencia.

La función

(++ i) dice el primer incremento i en 1, luego de eso, coloque este i en la función con nuevo valor.

La función

(i ++) dice poner primero i en la función después de ese incremento i en 1.

int i=4;
printf("%d\n",pow(++i,2));//it prints 25 and i is 5 now
i=4;
printf("%d",pow(i++,2));//it prints 16 i is 5 now

La única diferencia es el orden de las operaciones entre el incremento de la variable y el valor que devuelve el operador.

Este código y su salida explican la diferencia:

#include<stdio.h>

int main(int argc, char* argv[])
{
  unsigned int i=0, a;
  a = i++;
  printf("i before: %d; value returned by i++: %d, i after: %d\n", i, a, i);
  i=0;
  a = ++i;
  printf("i before: %d; value returned by ++i: %d, i after: %d\n", i, a, i);
}

La salida es:

i before: 1; value returned by i++: 0, i after: 1
i before: 1; value returned by ++i: 1, i after: 1

Básicamente, ++ i devuelve el valor después de que se incrementa, mientras que ++ i devuelve el valor antes de que se incremente. Al final, en ambos casos, el i tendrá su valor incrementado.

Otro ejemplo:

#include<stdio.h>

int main ()
  int i=0;
  int a = i++*2;
  printf("i=0, i++*2=%d\n", a);
  i=0;
  a = ++i * 2;
  printf("i=0, ++i*2=%d\n", a);
  i=0;
  a = (++i) * 2;
  printf("i=0, (++i)*2=%d\n", a);
  i=0;
  a = (++i) * 2;
  printf("i=0, (++i)*2=%d\n", a);
  return 0;
}

Salida:

i=0, i++*2=0
i=0, ++i*2=2
i=0, (++i)*2=2
i=0, (++i)*2=2

Muchas veces no hay diferencia

Las diferencias son claras cuando el valor devuelto se asigna a otra variable o cuando el incremento se realiza en concatenación con otras operaciones donde se aplica la prioridad de operaciones ( i ++ * 2 es diferente de ++ i * 2 , pero (i ++) * 2 y (++ i) * 2 devuelve el mismo valor) en muchos casos son intercambiables. Un ejemplo clásico es la sintaxis de bucle for:

for(int i=0; i<10; i++)

tiene el mismo efecto de

for(int i=0; i<10; ++i)

Regla para recordar

Para no confundir a los dos operadores, adopté esta regla:

Asocie la posición del operador ++ con respecto a la variable i al orden de la operación ++ con respeto a la tarea

Dicho en otras palabras:

  • ++ antes i significa que el incremento se debe realizar antes en la asignación;
  • ++ después de i significa que el incremento debe realizarse después de asignación:

Puedes pensar en la conversión interna de eso como múltiples declaraciones ;

// case 1 :

i++;

/* you can think as,
 * i;
 * i= i+1;
 */

// case 2

++i;

/* you can think as,
 * i = i+i;
 * i;
 */

a = i ++ significa que contiene un valor actual de i a = ++ i significa que contiene un valor i incrementado

Aquí está el ejemplo para entender la diferencia

int i=10;
printf("%d %d",i++,++i);

salida: 10 12/11 11 (según el orden de evaluación de los argumentos de la función printf , que varía entre compiladores y arquitecturas)

Explicación: i ++ - > i se imprime, y luego se incrementa. (Imprime 10, pero i se convertirá en 11) ++ i - > i incrementa el valor e imprime el valor. (Imprime 12, y el valor de i también 12)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top