Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Schrödinger en 13 Mayo 2013, 19:24 pm



Título: Creando una función para hallar la media y la desviación
Publicado por: Schrödinger en 13 Mayo 2013, 19:24 pm
Quiero hacer un programa que genere N floats uniformemente distribuidos en un intervalo dado y que calcule la media y la dispersión mediante una función. El código es el siguiente:

Código:
#include <stdio.h>
#include <stdlib.h>
#define DEBUG
int N;
FILE *fout;

void med_var(float *serie, int Numero, float *Media, float *Varianza)
{
  int i;
  for(i=0;i<Numero;i++)
    {
      *Media+=serie[i];
    }
  *Media=*Media/Numero;
  for(i=0;i<Numero;i++)
    {
      *Varianza+=serie[i]*serie[i];
    }
  *Varianza=*Varianza/Numero;
  *Varianza=*Varianza-(*Media)*(*Media);
  printf("Media=%f, Varianza=%f\n",*Media,*Varianza);
}

float frandom(double min, double max)
{
  return min+(max-min)*(rand()/((double)RAND_MAX+1));
}

main(argc,argv)
int argc;
char **argv;
{
  switch(argc)
    {
    case 2:
      sscanf(argv[1],"%d",&N);
      break;
    default:
      N=100;
    }
  int i;
  float med,var,data[N];

  printf("%d\n",N);
 
  fout=fopen("datos.dat","wt");

  for(i=0;i<N;i++)
    {
      data[i]=frandom(-2,5);
    }

#ifdef DEBUG
  for(i=0;i<N;i++)
    {
      printf("data[%d]=%f\n",i,data[i]);
    }
#endif

  med_var(data,N,&med,&var);

  fprintf(fout,"\n%d %f %f",N,med,var);
  fclose(fout);
}

Compila sin problemas pero los valores para la media y la varianza son incorrectos. El caso es que en una versión anterior del programa en la cual N no estaba pillado de la consola al menos la media funcionaba.

¿Alguna pista?


Título: Re: Creando una función para hallar la media y la desviación
Publicado por: rir3760 en 14 Mayo 2013, 02:19 am
El problema se debe a la declaración de la variable "data":
Código
  1. int N;
  2.  
  3. /* ... */
  4.  
  5. float med,var,data[N];
Un array declarado en esa forma se conoce como array de longitud variable o VLA, los dolores de cabeza surgen por el soporte variado de estos en los distintos estándares de C:

A) En C90 los VLAs no son validos.
B) En C99 los VLAs son validos.
C) En C11 los VLAs son validos pero su soporte es opcional.

Para que el programa funcione correctamente debes verificar que tu compilador soporte el estándar C99 (y por supuesto que se compile en ese modo).

Por ello es mejor, en mi opinión, reservar memoria de forma dinámica. Mas o menos así:
Código
  1. int N;
  2.  
  3. /* ... */
  4.  
  5. /* 1) Declaracion del puntero */
  6. float med,var,*data;
  7.  
  8. /* 2) Reserva de memoria */
  9. data = malloc(N * sizeof *data);
  10.  
  11. /* ... */
  12.  
  13. /* Cuando ya no sea necesaria la memoria se libera */
  14. free(data);

Por ultimo tienes que cambiar la definicion de la funcion main.

Un saludo


Título: Re: Creando una función para hallar la media y la desviación
Publicado por: leosansan en 14 Mayo 2013, 15:41 pm
Quiero hacer un programa que genere N floats uniformemente distribuidos en un intervalo dado y que calcule la media y la dispersión mediante una función
...............................................................

Compila sin problemas pero los valores para la media y la varianza son incorrectos. El caso es que en una versión anterior del programa en la cual N no estaba pillado de la consola al menos la media funcionaba.

¿Alguna pista?

El problema radica, con permiso de rir, en que no inicializas las  variables *media=0 y *varianza=0 antes de los correspondientes for. A mí, con esta pequeñísima corrección, me ha funcionado bien, creo.

Saluditos!. ......  
(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Creando una función para hallar la media y la desviación
Publicado por: rir3760 en 14 Mayo 2013, 16:50 pm
El problema radica, con permiso de rir, en que no inicializar las  variables *media=0 y *varianza=0 antes de los correspondientes for.
Tienes razón, no era un problema sino dos (el uso del VLA y las dos variables sin inicializar).

¿O son tres? Lo menciono porque:

1) Debido a que la definición de la función main omite el tipo de retorno no se puede compilar como C99 (no seria valido).

2) La declaración del array "data" requiere compilar como C99.

...

Un saludo


Título: Re: Creando una función para hallar la media y la desviación
Publicado por: leosansan en 14 Mayo 2013, 17:04 pm
Tienes razón, no era un problema sino dos (el uso del VLA y las dos variables sin inicializar).

¿O son tres? Lo menciono porque:

1) Debido a que la definición de la función main omite el tipo de retorno no se puede compilar como C99 (no seria valido).

2) La declaración del array "data" requiere compilar como C99.

...


Ya sé que main debería ser declarado como int y que el uso de VLAs da problemas al no estar implementado en algunos compiladores, sin embargo en ese caso lo mejor es cambiar de compilador a uno más "funcional". En mi caso con Code::Blocks no he tenido problema alguno ni con main ni con los VLAs, que utilizo frecuentemente sin problemas.

Vamos que si el compilador "no tira" por falta de implementación de ciertas funcionalidades del C99 sencillamente cambiaría de compilador.

Saluditos!. .....
(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)