Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: SDCC en 26 Abril 2018, 21:40 pm



Título: Problema con uso del incremento de una variable.
Publicado por: SDCC en 26 Abril 2018, 21:40 pm
Muy buenos dias,tardes o noches,durante un problema que realizaba sobre archivos me tope con un error un tanto extraño y que me hizo retomar este tema basico sobre el incremento en postfijo y prefijo.Tengo muy presentes las dos diferencias entre escribir el incremento en postfijo y prefijo pero a la hora de yo realizar varios postfijos o prefijos en una sentencia como la funcion printf() me topo con que los datos que arroja son algo raros y no termino de realizar una conexion entre los incrementos de la variable y los valores arrojados.
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main()
  5. {
  6.  
  7. int i=0;
  8.  
  9. printf("%d %d %d %d %d %d", ++i, i++, ++i, i++, ++i, i++);
  10.  
  11. }
  12.  
  13.  

El problema anterior no es el problema original, sin embargo es un pedazo de codigo que en esencia es el mismo problema que tengo en archivos y que ya pude solucionar de otra forma pero que sin embargo sigo sin entender la razon del resultado.


Título: Re: Problema con uso del incremento de una variable.
Publicado por: engel lex en 26 Abril 2018, 22:02 pm
el incremento prefijo y postfijo tienen su juego debido a su forma de funcionamiento... muchas veces pueden tomarse como "comportamiento indefinido"

 la variable no necesariamente se evalúa de izquierda a derecha o de izquierda a derecha... esto no sigue un standard peculiar


un articulo en inglés sobre los puntos de secuencia, que es quien "define" esto
https://en.wikipedia.org/wiki/Sequence_point (https://en.wikipedia.org/wiki/Sequence_point)


Título: Re: Problema con uso del incremento de una variable.
Publicado por: SDCC en 26 Abril 2018, 22:12 pm
Muchas gracias por tu respuesta,ahora entiendo que es lo que ocurre.


Título: Re: Problema con uso del incremento de una variable.
Publicado por: JPS en 30 Abril 2018, 14:17 pm
Mmm, no me ha quedado muy claro..., soy nuevo.

Código
  1. /*
  2. https://en.wikipedia.org/wiki/Sequence_point
  3.  
  4. Los puntos de secuencia también entran en juego cuando la misma variable se modifica más de una vez
  5. en una sola expresión. Un ejemplo frecuentemente citado es la expresión C i=i++ , que aparentemente
  6. le asigna a i su valor anterior e incrementa i . El valor final de i es ambiguo, ya que, dependiendo
  7. del orden de evaluación de la expresión, el incremento puede ocurrir antes, después o intercalado con
  8. la asignación. La definición de un idioma particular puede especificar uno de los comportamientos
  9. posibles o simplemente decir que el comportamiento no está definido . En C y C ++, la evaluación de
  10. dicha expresión produce un comportamiento indefinido. [4] Otros lenguajes, como C # , pueden definir
  11. la precedencia de la asignación e incrementar el operador de tal forma que se garantice el resultado
  12. de la expresión i=i++.
  13. */
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17.  
  18. int main()
  19. {
  20.  
  21. /*Puntos de secuencia en diferentes expresiones*/
  22. int i=0;
  23. printf("  i   = %d\n",i);
  24. printf("++i   = %d\n",++i);
  25. printf("  i++ = %d\n",i++);
  26. printf("++i   = %d\n",++i);
  27. printf("  i++ = %d\n",i++);
  28. printf("++i   = %d\n",++i);
  29. printf("  i++ = %d\n",i++);
  30. printf("++i   = %d\n",++i);
  31. printf("  i++ = %d\n",i++);
  32. printf("++i   = %d\n",++i);
  33. printf("  i++ = %d\n",i++);
  34. printf("  i   = %d\n\n",i);
  35.  
  36. printf("Reiniciamos i = 0\n\n");
  37. i=0;
  38.  
  39. /*Puntos de secuencia en una misma expresion*/
  40. printf("  i   = %d\n++i   = %d\n  i++ = %d\n++i   = %d\n  i++ = %d\n++i   = %d\n  i++ = %d\n++i   = %d\n  i++ = %d\n++i   = %d\n  i++ = %d\n  i   = %d\n\n",i,++i,i++,++i,i++,++i,i++,++i,i++,++i,i++,i);
  41.  
  42. return 0;
  43. }
  44.  

Resultados:

Código:
  i   = 0
++i   = 1
  i++ = 1
++i   = 3
  i++ = 3
++i   = 5
  i++ = 5
++i   = 7
  i++ = 7
++i   = 9
  i++ = 9
  i   = 10

Reiniciamos i = 0

  i   = 10
++i   = 10
  i++ = 8
++i   = 10
  i++ = 6
++i   = 10
  i++ = 4
++i   = 10
  i++ = 2
++i   = 10
  i++ = 0
  i   = 10


--------------------------------
Process exited after 0.02101 seconds with return value 0
Presione una tecla para continuar . . .

En la primera lista de números se ve un comportamiento esperado en los operadores de incremento.... ¿Porque están cada uno en una expresión (printf) única para cada uno; aunque todos hagan referencia a la misma variable?

En la segunda lista de números se observa un comportamiento inesperado y parece errático; pero sin embargo, se puede apreciar una progresión descendente: 10, 8, 6, 4, 2, 0. Frente a otra progresión permanente de 10.

En definitiva; aunque muestre una especie de patrón. ¿Hay que considerarlo errático y ambiguo? ya que todas las evaluaciones a la misma variable se efectuan en la misma expresión (printf) y... ¿es algo que se debe de evitar?



Título: Re: Problema con uso del incremento de una variable.
Publicado por: MAFUS en 30 Abril 2018, 15:15 pm
Has leído el artículo del link?

En él se explica porqué ocurre y en qué otros casos puede suceder.

Básicamente habla de los puntos de secuencia que son situaciones en la que C asegura que todos los cálculos previos están hechos. Si hay expresiones que dependen de unas de otras y no ha habido puntos de secuencia, puedes encontrar resultados aleatorios como en el ejemplo ya que, para hacer código más eficiente puede ejecutar esa serie de instrucciones en tiempos diferentes a los que has programado.


Título: Re: Problema con uso del incremento de una variable.
Publicado por: 6666 en 30 Abril 2018, 18:15 pm
El operador sufijo/prefijo solo funcionan en variables. Para solucionar eso se usa la sobrecarga de operadores, deberías leer sobre el operador 'operator'


Título: Re: Problema con uso del incremento de una variable.
Publicado por: JPS en 30 Abril 2018, 19:24 pm
Gracias Mafus y 6666.

Si lo leí... en parte... pero no lo logré entender del todo, supongo que por la densidad de contenido. Tengo que dedicarle más tiempo y también le echaré un ojo a eso de sobrecarga de operadores para ampliar conocimientos.