简体   繁体   English

C函数未返回值

[英]C function not returning value

I've written a program for a class and am having a problem. 我已经为一个班级写了一个程序,遇到了问题。 The purpose of the program is to read a set of values into an array, calculate the average, and then find how many elements in that array are larger than that average. 该程序的目的是将一组值读入数组,计算平均值,然后查找该数组中有多少个元素大于该平均值。 The function prototypes were provided so that cannot be changed. 提供了功能原型,因此无法进行更改。 Also, we were instructed to initialize the array to size 10 and double the size whenever the number of read elements exceeds the current size, so that cannot be changed. 另外,还指示我们将数组初始化为大小10,并且每当读取的元素数超过当前大小时将大小加倍,因此无法更改。

The problem I'm running into is returning a value from the aboveaverage function. 我遇到的问题是从上述平均函数返回一个值。 It works properly within itself (I can put a printf to display count before return, but in the main function, the value being returned is 0. Is there anyone that can help with this please? It's getting frustrating. 它可以在自身内部正常工作(我可以在返回之前将printf放在显示计数中,但是在主函数中,返回的值为0。请问有人可以对此提供帮助吗?令人沮丧。

Also, the commented printf line was to check the value being returned by the function. 同样,注释的printf行将检查该函数返回的值。 I commented it out instead of deleting it so I wouldn't have to retype it every time. 我将其注释掉而不是删除它,因此不必每次都重新输入。

#include <stdio.h>
#include <stdlib.h>

double average(double *ptr, int size);
int aboveaverage(double *ptr, int size, double average);

int main(int argc, char* argv[])
{
    double *ptr, avg, above, temp;
    int size = 10, i, j;
    void *tmp;
    FILE *fp;

    avg = above = 0;

    if (argc != 2)
    {
        printf("Invalid number of arguments, 2 required\n");
        return 1;
    }

    fp = fopen(argv[1], "r");
    ptr = (double *)calloc(10, sizeof(double));
    printf("Allocated 10 doubles\n");

    for (i = 0;fscanf(fp, "%lf", &temp) != EOF; i++)
    {
        if (i >= size - 1)
        {
            size*=2;    
            tmp = realloc(ptr, size);
            if (tmp == NULL)
            {
                printf("Error with realloc, exiting\n");
                return 1;
            }
            printf("Reallocated to %d doubles\n", size);
        }
        ptr[i] = temp;
        j = i;
    }

    size = j + 1;
    avg = average(ptr, size);
    above = aboveaverage(ptr, size, avg);
    //printf("%d\n", above);

    printf("%d elements are above average of %lf\n", above, avg);

    free(ptr);

    return 0; 
}

double average(double *ptr, int size)
{
    double sum;
    int i;
    while (i < size)
    {
        sum+=ptr[i];
        i++;
    }

    return (sum / size);
}

int aboveaverage(double *ptr, int size, double avg)
{
    int count=0, temp;
    for (int i = 0; i < size; i++)
    {
        temp = (int)ptr[i];
        if (temp > avg)
        count++;
    }
    return count;
}

So other answers have already pointed out where the problem is and how exactly can it be fixed. 因此,其他答案已经指出了问题出在哪里以及如何解决。

printf("%d elements are above average of %lf\n", above, avg); 

You pass %d as the format string and then you pass a double. 您传递%d作为格式字符串,然后传递一个双精度。

This can be fixed by declaring above as int (since that is what your function returns too). 可以通过在上面声明为int来解决此问题(因为这也是您的函数返回的结果)。

But I would like to add as to why it is wrong and why are you getting a zero. 但是,我想补充一下为什么它是错误的,为什么会得到零。

So this is the issue with var args functions. 因此,这是var args函数的问题。 Since the prototype says nothing about the types of the arguments, you call to printf assumes that the second argument is of type double. 由于原型没有说明参数的类型,因此调用printf假定第二个参数的类型为double。

Now the calling convention says that the second argument (if it is float or double) should be passed in the SSE register (on windows in the XMM1 register). 现在调用约定说第二个参数(如果它是float或double)应该在SSE寄存器(在XMM1寄存器的窗口中)中传递。 But since the printf function sees that the format string is %d so it expects for the second argument to be int. 但是由于printf函数看到格式字符串为%d,因此它期望第二个参数为int。 Now int arguments are passed in the general purpose registers (on windows second is passed in rdx). 现在,将int参数传递给通用寄存器(在Windows中,第二个参数传递给rdx)。

As a result it gets a garbage value. 结果,它得到一个垃圾值。

I hope this helps you better understand the problem. 希望这可以帮助您更好地理解问题。

1 Important Mistake 1个重要错误

  • You never use the value returned by realloc() . 您永远不要使用realloc()返回的值。

You need 你需要

ptr = tmp;

right after checking that realloc() did not return NULL . 在检查realloc()没有返回NULL

The program above looks fine. 上面的程序看起来不错。

printf("%d elements are above average of %lf\\n", above, avg); printf(“%d元素高于%lf \\ n的平均值”,高于平均值);

Above line you are printing a double value with %d may be wrong. 您在行上方用%d打印一个双精度值可能是错误的。 Otherwise I see everything fine. 否则,我认为一切都很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM