使用指针函数的程序方差和标准偏差

时间:2016-06-23 21:33:51

标签: c arrays function pointers variance

所以我试图制作一个标准偏差和方差函数,我无法弄清楚它为什么不起作用。我想在案例3中调用差异,在案例4中调用SD。其他一切都在程序中起作用。如果你看到任何看起来不正确的东西,请告诉我。

#include <stdio.h>
#include <math.h>
#define Max_Nums 20

void sortNums(float nums[], int size);
float meanValue(float nums[],int size);
float medianValue(float nums[], int size);
void var_stdDev(float nums[],int size,float *var,float *stdDev);
float sqrtf(float);

int main (void)

{   

    int NumValue = 0;
    float array[Max_Nums];
    int i=0;
    int choice=0;
    float avg=0;
    float median=0;

    printf("How many numbers do you wish to enter (Max of 20): ");
    scanf("%d",&NumValue);

    while (NumValue<1 || NumValue>Max_Nums)
    {
        printf("Invalid response. You must enter a value between 1 and 20.\n");
        scanf("%d",&NumValue);
    }
    printf("Enter %d real numbers: ",NumValue);

    for (i=0;i<NumValue;i++)
    {
        scanf("%f", &array[i]);
    }

    do
    {
        sortNums(array,NumValue);
        printf("-----Menu-----\n\a");
        printf("Enter 1 for mean value\n");
        printf("Enter 2 for median value\n");
        printf("Enter 3 for variance\n");
        printf("Enter 4 for standard deviation\n");
        printf("Enter 5 to exit the program\n");
        scanf("%d",&choice);

        switch(choice)
        {
            case 1:
                avg=meanValue(array,NumValue);
                printf("The mean is:%.2f\n",avg);
                break;
            case 2:
                median=medianValue(array,NumValue);
                printf("The median is:%.2f\n",median);
                break;
            case 3:
                //printf("The variance is:%.2f",variance);
                //break;
            case 4:
                //printf("The standard deviation is:%.2f\n");
                //break;
            case 5:
                printf("Exiting the program\n");
                break;
            default:
                printf("\nInvalid, try again");
                break;
        }
    }while (choice!=5);


return 0;
}

void sortNums(float nums[], int size)
{
    int x;
    int y;
    float z;

    for(x=0;x<(size-1);x++)
    {
        for(y=0;y<size-x-1;y++)
        {
            if(nums[y]>nums[y+1])
            {
                z=nums[y];
                nums[y]=nums[y+1];
                nums[y+1]=z;
            }
        }
    }
}

float meanValue(float nums[],int size)
{
    int i;
    float avg;
    float sum;

    for(i=0;i<size;i++)
    {
        sum+=nums[i];
    }
    avg = (sum/size);
    return avg;
}

float medianValue(float nums[], int size)
{
    float EvenMed;
    float Med;
    void sortNums(float nums[], int size);
    if (size%2==0)
    {
        EvenMed=(nums[size/2]+nums[size/2-1])/2;
        return EvenMed;
    }
    else
    {
        Med=nums[size/2];
        return Med;
    }

}

void var_stdDev(float nums[],int size,float *var,float *stdDev)
{
    int i;
    float sum;
    float meanValue(float nums[],int size);
    for(i=0;i<size;i++)
    {
        sum+=pow((nums[i]-meanValue,2);
    }
    *var=sum/(float)size;
    *stdDev=sqrt(*var);



} 

2 个答案:

答案 0 :(得分:2)

这一行错了:

    sum+=pow((nums[i]-meanValue,2);

这是试图从一个数字中减去一个函数指针,这没有任何意义。您需要调用 meanValue函数来获取均值,然后减去它。

此外,在添加sum之前,您尚未初始化{。}}。

void var_stdDev(float nums[],int size,float *var,float *stdDev)
{
    int i;
    float sum = 0;
    float mean = meanValue(nums, size);
    for(i=0;i<size;i++)
    {
        sum+=pow((nums[i]-mean,2);
    }
    *var=sum/(float)size;
    *stdDev=sqrt(*var);
} 

没有必要在meanValue内声明var_stdDev,文件顶部的声明贯穿整个目的。

medianValue()中,您声明为sortNums(),但您从未对其进行过调用,因此这些数字并未排序(您似乎并不了解它们之间的区别原型和电话)。

float medianValue(float nums[], int size)
{
    float EvenMed;
    float Med;
    sortNums(nums, size);
    if (size%2==0)
    {
        EvenMed=(nums[size/2]+nums[size/2-1])/2;
        return EvenMed;
    }
    else
    {
        Med=nums[size/2];
        return Med;
    }
}

答案 1 :(得分:0)

正如documentation解释的那样,OP的代码存在许多问题:

void var_stdDev(float nums[],int size,float *var,float *stdDev) {
    int i;
    // sum not initialize
    float sum;  
    // unneeded function declaration
    float meanValue(float nums[],int size);

    // missing code to find the mean

    for(i=0;i<size;i++) {
        // improper call to accumulate the average derivation from the mean
        sum+=pow((nums[i]-meanValue,2);
    }
    ...

推荐一种新的标准差计算方法

来自@Barmar

enter image description here

std = sqrt(n*sum_of_squares - sum_of_x*sum_of_x)/n

建议的改进:

使用double进行中间计算。 float可以减少存储空间,有时可以提高速度。然而,统计数据通常会减去导致精确度显着下降的值。使用double

由于四舍五入,选择数据集可能会导致一个很小的负数 - 即使数学上结果应该是&gt; = 0.0。在sqrt()之前查看签名非常好。

处理size == 0时的情况并且不执行0的运行时划分。

void var_stdDev2(const float x[], size_t size, float *var, float *stdDev) {
  double sumx = 0.0;
  double sumxx = 0.0;
  double std = 0.0; // Used when size == 0.0 - or set to NaN
  if (size > 0) {
    for (size_t i = 0; i < size; i++) {
      sumx += x[i];
      sumxx += 1.0 * x[i] * x[i];
    }
    double std = sumxx * size - sumx * sumx;
    std = std >= 0.0 ? sqrt(std) : 0.0;
    std /= size;
  }
  if (stdDev) *stdDev = (float) std;
  if (var) *var = (float) sqrt(std);
}

次要位:

在签名中使用const,因为函数不会修改nums[]

数组最好使用size_t而非int索引。