Publi

Preincremento y postincremento (x++ != ++x)

Hace unos días un alumno de clases particulares me preguntó la diferencia entre estos dos; me pareció una pregunta interesante ya que los únicos usos que había visto eran como única sentencia:

a++;
++a;

En este uso no hay diferencia, puesto que hagamos las cosas en el orden que las hagamos el resultado será igual; aunque en este ejemplo tampoco se tiene clara la idea del orden de las operaciones. Pero veamos otro ejemplo:

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>

int main(int argc, char *argv[])
{
  int a=10;
  int b;

  b=a++;
  printf("a=%d\nb=%d\n", a, b);
}

Vemos que estamos realizando un postincremento de a, o lo que es lo mismo, incrementamos la variable a después de las demás operaciones (asignar a b el valor de a).

Por lo tanto, si a vale 10, b tomará el valor 10 y tras eso a incrementará 1 pasando a valer 11.
Al ver la salida podemos observar:

$ ./prepost
a=11
b=10

En cambio podemos crear este programa también (igual que el anterior cambiando a++ por ++a),

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>

int main(int argc, char *argv[])
{
  int a=10;
  int b;

  b=++a;
  printf("a=%d\nb=%d\n", a, b);
}

Cuya salida es:

$ ./prepost2
a=11
b=11

En este caso, preincrementamos a. Antes de cualquier operación incrementamos la variable. Por tanto, si a vale 10, incrementamos esa variable pasando a valer 11 y luego asignamos ese valor a b.

La gran ventaja de esto es que con la experiencia suficiente nos ayuda a reducir el código que escribimos y optimizar la velocidad de nuestros programas. Además, a la hora de crear nuestros programas podremos ahorrar mucho código, sobre todo a la hora de lidiar con punteros de cadenas o imágenes donde, en ocasiones, podemos realizar tareas de forma más fácil.

Dejo algunos ejemplos más, aunque sencillos del uso de estos operadores:

Mareando un poco la perdiz

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>

int main(int argc, char *argv[])
{
  int a=10;
  int b=5;

  b=a++ + ++b;
  printf("a=%d\nb=%d\n", a, b);
}

Que da como salida:

$ ./prepost3
a=11
b=16

En este caso… cogemos a (que vale 10), luego incrementamos b (que valía 5 y pasa a valer 6), sumamos los dos valores (que da en total 16) y luego incrementamos a (que pasa a valer 11).

En un do-while

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int main(int argc, char *argv[])
{
  int a;

  a=0;
  do
    printf("Bucle a=%d\n", a);
  while (++a<5);
}

Cuya salida es:

$ ./preposw
Bucle a=0
Bucle a=1
Bucle a=2
Bucle a=3
Bucle a=4

En este caso, al finalizar cada iteración, incrementamos a y luego miramos si es menor que 5; por lo que, en la última vuelta del bucle, si a vale 4, incrementaremos su valor (pasando a ser 5) y luego veremos que ya no es menor que 5 por lo que saldremos del bucle.

En contraposición podemos hacer:

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int main(int argc, char *argv[])
{
  int a;

  a=0;
  do
    printf("Bucle a=%d\n", a);
  while (a++<5);
}

Cuya salida es:

$ ./preposw
Bucle a=0
Bucle a=1
Bucle a=2
Bucle a=3
Bucle a=4
Bucle a=5

En este caso, al verificar que a 5 antes de incrementar a. Cuando a vale 4, haremos la comparación, cuando todavía es menor que 5 e incrementaremos. Daremos otra vuelta más con a valiendo 5, donde, en la siguiente comparación (a ahora sí que saldrá del bucle, aunque si verificáramos el valor de a tras salir del bucle sería 6.

Contar caracteres a mano

Un ejemplo tonto más, para contar las letras de una cadena:

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main(int argc, char *argv[])
{
  int i=0;
  char *str="HOLA";

  // Con esto vale
  while (str[++i]!='\0');

  printf("Longitud: %d\n", i);
  }

Salida:

$ ./prepos
Longitud: 4

En este caso, dentro del while, primero incrementamos i, luego comparamos str[i] con ‘\0’ y si efectivamente tiene ese valor saldremos del bucle. No se crea un bucle infinito porque el incremento se produce (aunque sea en la misma sentencia de la comparación).
Hay que tener cuidado con este ejemplo, ya que si la cadena está vacía (es decir, que el primer carácter que encontremos sea \0) tal vez este método produzca resultados inesperados, ya que nunca llegamos a comparar el carácter 0 (incrementamos antes de comparar ese carácter). Una posible solución es inicializar i a -1.

Nota: Todo lo comentado aquí vale tanto con preincremento/postincremento como con predecremento/postdecremento (–a, a–), ya que son operaciones muy similares.

También podría interesarte....

There are 15 comments left Ir a comentario

  1. Pingback: Bitacoras.com /

  2. Santiago Valdarrama /
    Usando Google Chrome Google Chrome 8.0.552.237 en Windows Windows 7

    Como bien dices, ambos operadores funcionan de forma diferente, y efectivamente pueden ser utilizados para reducir la cantidad de código que escribes, pero esto muchas veces hace más daño de lo que ayuda.

    Menos código la gran mayoría de las veces redunda en una menor legibilidad. Usando operadores como estos, el código puede complicarse extremadamente haciéndolo bastante difícil de traducir incluso para ti mismo que eres el desarrollador.

    Yo no recomendaría el uso de los operadores ++ y — en sentencias donde se realicen asignaciones u otras operaciones. Por ejemplo:

    if (++a == 5)

    es completamente diferente a:

    if (a++ == 5)

    lo cual resulta bastante complicado de entender, y puede introducir errores innecesarios. El codigo deberia ser:

    a++;
    if (a == 5)

    o

    if (a == 5)
    // do whatever you want to do
    a++;

    Por ejemplo, aqui:

    http://blog.svpino.com/2011/01/java-tricky-java-identificadores.html

    Podras ver algo bien interesante con Java, pero que de la misma forma complica sobremanera la legibilidad del codigo.

    Gracias por tu articulo.

  3. admin / Post Author
    Usando Mozilla Firefox Mozilla Firefox 3.6 en Linux Linux

    @Santiago Valdarrama
    Gracias por el comentario Santiago. Es verdad que a veces lo podemos tomar como ofuscación y otras personas optarán por no usarlo, es más siempre podemos usarlo en una sentencia sin obtener valor; pero es importante conocer la potencia y las posibilidades de la programación.

  4. Pingback: BlogESfera.com /

  5. Pendejito Ramirez de los Rosarios /
    Usando Mozilla Firefox Mozilla Firefox 32.0 en Ubuntu Linux Ubuntu Linux

    Muchas grasias señorito, me acaba de salvar usted la vida con esto, ya que ahorita mismito tengo un examen que es bien huevon, wey, muchas grasias pueees.

  6. Pingback: Operador coma. Cómo incorporarlo a nuestro día a día con muchos ejemplos en C – Poesía Binaria /

  7. Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    That you’re allowed to place leaders, however is not one way links, except when they’re just authorised together with regarding niche.

  8. yitzchak kerrigan /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    I’d personally declare that will this is the a terrific article of an wonderful man or woman, i am just very happy to discover this specific. UFABETเว็บพนันบอลตรงดีที่สุดในเอเชีย

  9. MUZAMMIL SEO MUZAMMIL SEO /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    Wow, cool post. I’d like to write like this too – taking time and real hard work to make a great article… but I put things off too much and never seem to get started. Thanks though. 우리카지노

  10. seooo servicesss /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    Very efficiently written information. It will be beneficial to anybody who utilizes it, including me. Keep up the good work. For sure i will check out more posts. This site seems to get a good amount of visitors. sell my house fast indianapolis

  11. ghori92 /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    This is just the information I am finding everywhere. Thanks for your blog, I just subscribe your blog. This is a nice blog.. weight loss personal trainer in Casselberry

  12. jameel feeroc /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    You have performed a great job on this article. It’s very precise and highly qualitative. You have even managed to make it readable and easy to read. You have some real writing talent. Thank you so much. https://techannouncer.com/cybersecurity-threats-in-critical-infrastructure-protecting-key-sectors-from-cyber-attacks/

  13. MUZAMMIL SEO MUZAMMIL SEO /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    Awesome article! I want people to know just how good this information is in your article. It’s interesting, compelling content. Your views are much like my own concerning this subject. grandparents theme baby clothes

  14. seooo servicesss /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    Thank you a bunch for sharing this with all of us you actually realize what you are talking about! Bookmarked. Please also seek advice from my site =). We could have a hyperlink change contract between us! link mb66

  15. jameels feerock /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    I would like to say that this blog really convinced me to do it! Thanks, very good post. 来自印度的在线土耳其签证

Leave a Reply