elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a Git (Primera Parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Salida inesperada de este programa
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Salida inesperada de este programa  (Leído 2,937 veces)
SebaC

Desconectado Desconectado

Mensajes: 16


Ver Perfil
Salida inesperada de este programa
« en: 23 Mayo 2016, 23:58 pm »

Tengo este sencillo programa

Código
  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5. int i = 0;
  6. int arr[20];
  7.  
  8.    while(i < 20)
  9. {
  10. arr[i++] = i;
  11. printf("%d\n", arr[i]);
  12. }
  13.  
  14.    return 0;
  15. }

En el cual inicializo un array de enteros pero cuando imprimo el contenido me da números extraños que no corresponden a la variable i
Que pasa aquí?


En línea

AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.705


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Salida inesperada de este programa
« Respuesta #1 en: 24 Mayo 2016, 00:07 am »

Código
  1. arr[i++] = i;
Estas asignado e incrementando i
y despues imprimes el i no inicializado.

Tienes que incrementar en el printf o despues


En línea

SebaC

Desconectado Desconectado

Mensajes: 16


Ver Perfil
Re: Salida inesperada de este programa
« Respuesta #2 en: 24 Mayo 2016, 01:42 am »

y despues imprimes el i no inicializado.

Yo inicialice i a cero no entiendo porque dices eso
En línea

AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.705


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Salida inesperada de este programa
« Respuesta #3 en: 24 Mayo 2016, 01:52 am »

el i++ lo tienes dentro de los corchetes

i vale 0
asignas 0 a arr[0]
incrementas i y ahora vale 1
imprimes arr[1]
asignas 1 a arr[1]
incrementas i y ahora vale 2
....


Tu codigo tendria que estar asi
Código
  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5. int i = 0;
  6. int arr[20];
  7.  
  8.    while(i < 20)
  9. {
  10. arr[i] = i;
  11. printf("%d\n", arr[i]);
  12.                i++;
  13. }
  14.  
  15.    return 0;
  16. }

o bien

Código
  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5. int i = 0;
  6. int arr[20];
  7.  
  8.    while(i < 20)
  9. {
  10. arr[i] = i;
  11. printf("%d\n", arr[i++]);
  12. }
  13.  
  14.    return 0;
  15. }

¿Vez la diferencia?
En línea

geeke

Desconectado Desconectado

Mensajes: 93


Ver Perfil
Re: Salida inesperada de este programa
« Respuesta #4 en: 24 Mayo 2016, 02:10 am »

Código
  1. arr[i++] = i;

La variable i se está modificando en el lado derecho de la asignación y tambien se hace referencia a ella en la izquierda el estándar de C no permite esto porqué no hay punto de secuencia para mas info http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points
En línea

AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.705


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Salida inesperada de este programa
« Respuesta #5 en: 24 Mayo 2016, 02:54 am »

Yo estoy con que la asignacion es totalemente valida.

Con el codigo que el presento solo es necesario modificatr el printf esta es otra version valida.

Código
  1. #include <stdio.h>
  2.  
  3. int main(void) {
  4. int i = 0;
  5. int arr[20];
  6. while(i < 20) {
  7. arr[i++] = i;
  8. printf("%d\n", arr[i-1]);
  9. }
  10. return 0;
  11. }


Salida:

Código:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20


Se le podria agregar

Código
  1. printf("i actualmente vale %i",i);

Para ver cuando vale i al momento de imprimir el contenido del arreglo. O antes de la asignacion  del valor. O ambos aun mejor XD

Código
  1. #include <stdio.h>
  2.  
  3. int main(void) {
  4. int i = 0;
  5. int arr[20];
  6. while(i < 20) {
  7. printf("i actualmente vale %i\n",i);
  8. arr[i++] = i;
  9. printf("Asignacion del arreglo\n")
  10. printf("i actualmente vale %i\n",i);
  11. printf("%d\n", arr[i-1]);
  12. }
  13. return 0;
  14. }

Salida:

Código
  1. i actualmente vale 0
  2. Asignacion del arreglo
  3. i actualmente vale 1
  4. 1
  5. i actualmente vale 1
  6. Asignacion del arreglo
  7. i actualmente vale 2
  8. 2
  9. i actualmente vale 2
  10. Asignacion del arreglo
  11. i actualmente vale 3
  12. 3
  13. i actualmente vale 3
  14. Asignacion del arreglo
  15. i actualmente vale 4
  16. 4
  17. i actualmente vale 4
  18. Asignacion del arreglo
  19. i actualmente vale 5
  20. 5
  21. i actualmente vale 5
  22. Asignacion del arreglo
  23. i actualmente vale 6
  24. 6
  25. i actualmente vale 6
  26. Asignacion del arreglo
  27. i actualmente vale 7
  28. 7
  29. i actualmente vale 7
  30. Asignacion del arreglo
  31. i actualmente vale 8
  32. 8
  33. i actualmente vale 8
  34. Asignacion del arreglo
  35. i actualmente vale 9
  36. 9
  37. i actualmente vale 9
  38. Asignacion del arreglo
  39. i actualmente vale 10
  40. 10
  41. i actualmente vale 10
  42. Asignacion del arreglo
  43. i actualmente vale 11
  44. 11
  45. i actualmente vale 11
  46. Asignacion del arreglo
  47. i actualmente vale 12
  48. 12
  49. i actualmente vale 12
  50. Asignacion del arreglo
  51. i actualmente vale 13
  52. 13
  53. i actualmente vale 13
  54. Asignacion del arreglo
  55. i actualmente vale 14
  56. 14
  57. i actualmente vale 14
  58. Asignacion del arreglo
  59. i actualmente vale 15
  60. 15
  61. i actualmente vale 15
  62. Asignacion del arreglo
  63. i actualmente vale 16
  64. 16
  65. i actualmente vale 16
  66. Asignacion del arreglo
  67. i actualmente vale 17
  68. 17
  69. i actualmente vale 17
  70. Asignacion del arreglo
  71. i actualmente vale 18
  72. 18
  73. i actualmente vale 18
  74. Asignacion del arreglo
  75. i actualmente vale 19
  76. 19
  77. i actualmente vale 19
  78. Asignacion del arreglo
  79. i actualmente vale 20
  80. 20
En línea

geeke

Desconectado Desconectado

Mensajes: 93


Ver Perfil
Re: Salida inesperada de este programa
« Respuesta #6 en: 24 Mayo 2016, 05:36 am »

Yo estoy con que la asignacion es totalemente valida.

Con el codigo que el presento solo es necesario modificatr el printf esta es otra version valida.

Te invito a leer la página que proporcioné mas arriba al parecer no tomaste tiempo en leerlo, esa asignación provoca comportamiento indefinido por lo tanto no existe garantía de que el resultado sea lo esperado. Compila ese código con el nivel de advertencia -Wall luego me cuentas
En línea

engel lex
Moderador Global
***
Desconectado Desconectado

Mensajes: 15.514



Ver Perfil
Re: Salida inesperada de este programa
« Respuesta #7 en: 24 Mayo 2016, 05:54 am »

AlbertoBSD lo que dice JOWELL es cierto, los incrementos de ese tipo pueden generar comportamiento indefinido y diferentes compiladores pueden tomarlo en diferentes maneras


Código
  1. int add(int x, int y)
  2. {
  3.    return x + y;
  4. }
  5.  
  6. int main()
  7. {
  8.    int x = 5;
  9.    int value = add(x, ++x); // is this 5 + 6, or 6 + 6?  It depends on what order your compiler evaluates the function arguments in
  10.  
  11.    std::cout << value; // value could be 11 or 12, depending on how the above line evaluates!
  12.    return 0;
  13. }

Citar
C++ does not define the order in which function arguments are evaluated. If the left argument is evaluated first, this becomes a call to add(5, 6), which equals 11. If the right argument is evaluated first, this becomes a call to add(6, 6), which equals 12! Note that this is only a problem because one of the argument to function add() has a side effect.

Código
  1. int main()
  2. {
  3.    int x = 1;
  4.    x = x++;
  5.    std::cout << x;
  6.  
  7.    return 0;
  8. }

Citar
What value does this program print? The answer is: it’s undefined. If the ++ is applied to x before the assignment, the answer will be 1. If the ++ is applied to x after the assignment, the answer will be 2.

There are other cases where C++ does not specify the order in which certain things are evaluated, so different compilers will make different assumptions. Even when C++ does make it clear how things should be evaluated, some compilers implement behaviors involving variables with side-effects incorrectly. These problems can generally all be avoided by ensuring that any any variable that has a side-effect applied is used no more than once in a given statement.

http://www.learncpp.com/cpp-tutorial/33-incrementdecrement-operators-and-side-effects/
En línea

El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.
AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.705


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Salida inesperada de este programa
« Respuesta #8 en: 24 Mayo 2016, 14:10 pm »

Tienen razon, me dormi pensando en ese problema y me pregunte si estubiera compilando ese codigo que instruccion pondria primero y todas las formas llevan a un reaultado diferente.

Opciones:

Seleccionar la direccion la direccion de memoria para guardar el valor, incrementar i y copiar el valor a la direccion previamemte seleccionada.

Seleccionar la direccion de memoria, copiar el valor e incrementar i.

incrementar i, seleccionar la direccion y copiar el valor.

Copiar el valor a un registro interno, incrementar i y copiar el valor a la direccion de i actual.

Copiar el valor a un registro interno, seleccionar la direccion de memoria, incrementar i

En fin...


Conclusión

Colocar el incremento de i en una linea separada abajo del printf. O en el printf.


Muy didactico el topic parece sencillo, aunque mis primeras  respuesta no eran del todo correctas.

Falta ver que responde Sosar a todo esto.

Saludos.
En línea

SebaC

Desconectado Desconectado

Mensajes: 16


Ver Perfil
Re: Salida inesperada de este programa
« Respuesta #9 en: 24 Mayo 2016, 16:15 pm »

Ya decía yo que algo andaba mal en esa asignación, en síntesis aquí el orden de evaluación es indefinido  ;-)
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines