Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: harofenix en 25 Diciembre 2014, 04:21 am



Título: Aprendiendo el uso basico de apuntadores ! no me da el resultado correcto
Publicado por: harofenix en 25 Diciembre 2014, 04:21 am
Que tal, apenas estoy aprendiendo el uso basico de apuntadores, hice este programita para calcular el promedio, sin embergo, me da mal el promedio, la pregunta es: que estoy haciendo mal ?

#include <stdio.h>
Código:
void SolicitudEingresoDeValores(float valor1, float valor2, float valor3, float valor4, float valor5);
float Promedio(float *val1, float *val2, float *val3, float *val4, float *val5);
/*declaracion de apuntadores*/
float *val1, *val2, *val3, *val4, *val5;

int main(int argc, char **argv)
{
float average;
float valor1 = 0, valor2 = 0, valor3 = 0, valor4 = 0, valor5 = 0;
SolicitudEingresoDeValores(valor1, valor2, valor3, valor4, valor5);
average = Promedio(val1, val2, val3, val4, val5);
printf("%10.2f \n", average);
return 0;
}

void SolicitudEingresoDeValores(float valor1, float valor2, float valor3, float valor4, float valor5)
{

printf("ingrese el primer valor: \n");
scanf("%f", &valor1); /*inicializo puntero*/
val1 = &valor1;
printf("ingrese el primer valor: \n");
scanf("%f", &valor2);/*inicializo puntero*/
val2 = &valor2;
printf("ingrese el primer valor: \n");
scanf("%f", &valor3);/*inicializo puntero*/
val3 = &valor3;
printf("ingrese el primer valor: \n");
scanf("%f", &valor4);/*inicializo puntero*/
val4 = &valor4;
printf("ingrese el primer valor: \n");
scanf("%f", &valor5);/*inicializo puntero*/
val5 = &valor5;

}
float Promedio(float *val1, float *val2, float *val3, float *val4, float *val5)
{

float promedio;
promedio = ( *val1 + *val2 + *val3 + *val4 + *val5 ) / 5;
return promedio;
}


Título: Re: Aprendiendo el uso basico de apuntadores ! no me da el resultado correcto
Publicado por: SrCooper en 25 Diciembre 2014, 19:04 pm
No soy ningún experto, pero probablemente esto se deba a que en la funcion de ingreso estas dando a los punteros una dirección de memoria local dentro de la función y cuando se sale de esta función la dirección se vuelve indeterminada (creo).

Para dar valor a los punteros deberías hacer lo siguiente:
Código
  1. *val1 = valor;
Con esto le estás indicando al programa que asigne el valor al puntero, no su dirección de memoria. Sin embargo para hacer esto antes tienes que haber reservado memoria para el puntero con la función malloc() y después tienes que liberarla con la función free().

El programa quedaría entonces así:
Código
  1. void SolicitudEingresoDeValores();
  2. float Promedio();
  3.  
  4. /* Declaracion de los punteros */
  5. float *val1, *val2, *val3, *val4, *val5;
  6.  
  7. int main(int argc, char **argv)
  8. {
  9. float average;
  10.  
  11. /* Reservamos espacio en la memoria para poder asignar valores a los punteros */
  12. val1 = malloc(sizeof(float));
  13. val2 = malloc(sizeof(float));
  14. val3 = malloc(sizeof(float));
  15. val4 = malloc(sizeof(float));
  16. val5 = malloc(sizeof(float));
  17.  
  18. SolicitudEingresoDeValores();
  19.  
  20. average = Promedio();
  21. printf("%f \n", average);
  22.  
  23. /* Una vez que lo hemos usado, liberamos este espacio */
  24. free(val1);
  25. free(val2);
  26. free(val3);
  27. free(val4);
  28. free(val5);
  29.  
  30. return 0;
  31. }
  32.  
  33. void SolicitudEingresoDeValores()
  34. {
  35.  /* Como cambia de valor, con una variable sera suficiente */
  36.  float valor;
  37.  
  38.  printf("ingrese el primer valor: \n");
  39.  scanf("%f", &valor);
  40.  *val1 = valor; // Asignamos el valor, no la direccion de memoria (pues es una variable local)
  41.  
  42.  printf("ingrese el segundo valor: \n");
  43.  scanf("%f", &valor);
  44.  *val2 = valor;
  45.  
  46.  printf("ingrese el tercer valor: \n");
  47.  scanf("%f", &valor);
  48.  *val3 = valor;
  49.  
  50.  printf("ingrese el cuarto valor: \n");
  51.  scanf("%f", &valor);
  52.  *val4 = valor;
  53.  
  54.  printf("ingrese el quinto valor: \n");
  55.  scanf("%f", &valor);
  56.  *val5 = valor;
  57. }
  58.  
  59. float Promedio()
  60. {
  61.  return ( *val1 + *val2 + *val3 + *val4 + *val5 ) / 5;
  62. }

Como ya has reservado espacio para los punteros, la función scanf() se podría usar simplemente así:
Código
  1. scanf("%f", val1);
sin necesidad de un variable local, poniendo como parámetros directamente los punteros. Por lo tanto la función quedaría así:
Código
  1. void SolicitudEingresoDeValores()
  2. {
  3.  printf("ingrese el primer valor: \n");
  4.  scanf("%f", val1);
  5.  
  6.  printf("ingrese el segundo valor: \n");
  7.  scanf("%f", val2);
  8.  
  9.  printf("ingrese el tercer valor: \n");
  10.  scanf("%f", val3);
  11.  
  12.  printf("ingrese el cuarto valor: \n");
  13.  scanf("%f", val4);
  14.  
  15.  printf("ingrese el quinto valor: \n");
  16.  scanf("%f", val5);
  17. }

Por supuesto aún se podrían mejorar muchas cosas, como utilizar arrays en lugar de punteros separados para poder realizar medias de un número variable de valores en cada programa. Sin embargo esto cumple con lo que querías en el programa original utilizando punteros.

Un saludo

PD: En la función malloc() se tiene que indicar el tamaño de la variable (en bytes). Para ello se utiliza la función sizeof().


Título: Re: Aprendiendo el uso basico de apuntadores ! no me da el resultado correcto
Publicado por: rir3760 en 25 Diciembre 2014, 20:23 pm
Que tal, apenas estoy aprendiendo el uso basico de apuntadores, hice este programita para calcular el promedio, sin embergo, me da mal el promedio, la pregunta es: que estoy haciendo mal ?
El problema principal en el programa es de diseño.

1) No necesitas de las variables "globales", ademas hay que evitar su uso siempre que sea posible.

2) La función "SolicitudEingresoDeValores" se debe modificar pasando las direcciones de la cinco variables con la intención de modificarlas dentro de la función:
Código
  1. void SolicitudEingresoDeValores(float *a, float *b, float *c, float *d, float *e)
  2. {
  3. printf("ingrese el primer valor: \n");
  4. scanf("%f", a);
  5.  
  6. printf("ingrese el primer valor: \n");
  7. scanf("%f", b);
  8.  
  9. printf("ingrese el primer valor: \n");
  10. scanf("%f", c);
  11.  
  12. printf("ingrese el primer valor: \n");
  13. scanf("%f", d);
  14.  
  15. printf("ingrese el primer valor: \n");
  16. scanf("%f", e);
  17. }

3) La función "Promedio" no requiere de punteros ya que no altera las variables, solo necesita sus valores para calcular el promedio:
Código
  1. float Promedio(float a, float b, float c, float d, float e)
  2. {
  3. return (a + b + c + d + e) / 5;
  4. }

4) Ambas funciones se utilizan en main de esa forma:
Código
  1. #include <stdio.h>
  2.  
  3. void SolicitudEingresoDeValores(float *a, float *b, float *c, float *d, float *e);
  4. float Promedio(float a, float b, float c, float d, float e);
  5.  
  6. int main(void)
  7. {
  8. float a, b, c, d, e;
  9.  
  10. SolicitudEingresoDeValores(&a, &b, &c, &d, &e);
  11. printf("%10.2f \n", Promedio(a, b, c, d, e));
  12.  
  13. return 0;
  14. }
  15.  
  16. /* ... */

Un saludo