Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C中从函数返回多个类型?_C_Function_Struct_Return Value - Fatal编程技术网

如何在C中从函数返回多个类型?

如何在C中从函数返回多个类型?,c,function,struct,return-value,C,Function,Struct,Return Value,我有一个C语言的函数,它计算数组的平均值。在同一个循环中,我创建了一个t值数组。我的当前函数返回平均值。如何修改它以同时返回t数组 /* function returning the mean of an array */ double getMean(int arr[], int size) { int i; printf("\n"); float mean; double sum = 0; float t[size];/* this is static allo

我有一个C语言的函数,它计算数组的平均值。在同一个循环中,我创建了一个t值数组。我的当前函数返回平均值。如何修改它以同时返回t数组

/* function returning the mean of an array */
double getMean(int arr[], int size) {
   int i;
   printf("\n");
   float mean;
   double sum = 0;
   float t[size];/* this is static allocation */
    for (i = 0; i < size; ++i) {
        sum += arr[i];
        t[i] = 10.5*(i) / (128.0 - 1.0);
        //printf("%f\n",t[i]);
   }
   mean = sum/size;
   return mean;
}
返回数组平均值的函数*/ 双getMean(整数arr[],整数大小){ int i; printf(“\n”); 浮动平均值; 双和=0; 浮动t[size];/*这是静态分配*/ 对于(i=0;i 想法:
我需要在函数中定义结构吗?这对标量类型和数组类型有效吗?有更干净的方法吗?

在C函数中只能返回1个对象。因此,如果无法选择,则必须创建一个结构以返回2个值,类似于:

typedef struct X{
     double mean;
     double *newArray;
} X;
但是,在您的情况下,还需要使用
malloc
动态分配
t
,否则,返回的数组将在堆栈中丢失


另一种方法是让调用者分配新数组,并将其作为指针传递给您,这样,您仍将只返回平均值,并用计算值填充给定数组。

最常见的方法是让调用者为您要返回的值提供存储。您只需在函数中设置另一个参数
t
,即可:

double getMean(double *t, const int *arr, size_t size) {
   double sum = 0;
   for (size_t i = 0; i < size; ++i) {
        sum += arr[i];
        t[i] = 10.5*(i) / (128.0 - 1.0);
   }
   return sum/size;
}
您可以编写例如
sizeof numbers/sizeof*numbers
,而不是幻数
5



另一种方法是在函数中使用
malloc()。哪种方法更合适取决于您的课程的其他部分。

遵循的建议可能是最佳选择。但是,如果存在可以预期的最大数组大小,也可以将数组包装在
结构中,而不需要动态分配。这允许代码创建新的
struct
s,而无需解除分配

可以在
get\u mean()
函数中创建
mean\u数组
结构,分配正确的值,然后返回到调用函数。调用函数只需提供一个
mean_数组
结构即可接收返回值

#include <stdio.h>
#include <assert.h>

#define MAX_ARR  100

struct mean_array {
    double mean;
    double array[MAX_ARR];
    size_t num_elems;
};

struct mean_array get_mean(int arr[], size_t arr_sz);

int main(void)
{
    int my_arr[] = { 1, 2, 3, 4, 5 };

    struct mean_array result = get_mean(my_arr, sizeof my_arr / sizeof *my_arr);

    printf("mean: %f\n", result.mean);
    for (size_t i = 0; i < result.num_elems; i++) {
        printf("%8.5f", result.array[i]);
    }
    putchar('\n');

    return 0;
}

struct mean_array get_mean(int arr[], size_t arr_sz)
{
    assert(arr_sz <= MAX_ARR);
    struct mean_array res = { .num_elems = arr_sz };
    double sum = 0;

    for (size_t i = 0; i < arr_sz; i++) {
        sum += arr[i];
        res.array[i] = 10.5 * i / (128.0 - 1.0);
    }
    res.mean = sum / arr_sz;

    return res;
}
在回答OP在评论中提出的几个问题时:

size\u t
是用于数组索引的正确类型,因为它保证能够保存任何数组索引。你可以用
int
来代替;但是要小心,因为访问或甚至形成指向数组第一个元素之前的位置的指针会导致未定义的行为。通常,数组索引应该是非负的。此外,在一些实现中,
size\u t
可能是比
int
更宽的类型
size\u t
保证保存任何数组索引,但
int
没有这样的保证

关于此处使用的
for
循环语法,例如,
for(size_t i=0;i
:此处
i
用循环范围声明。也就是说,
i
的生存期在循环体退出时结束。从C99开始,这就成为可能。在可能的情况下,限制变量范围是一种很好的做法。我默认使用此选项,以便我必须主动选择使循环变量在循环体之外可用


如果循环作用域变量或
size\t
类型导致编译错误,我怀疑您可能是在C89模式下编译的。这两个特性都是在C99中引入的。如果您使用的是gcc,旧版本(例如,我相信GCC4.x)默认为C89。您可以使用
gcc-std=c99
gcc-std=c11
进行编译,以使用最新的语言标准。我建议至少启用警告:
gcc-std=c99-Wall-Wextra
,以便在编译时捕获许多问题。如果您在Windows中工作,也可能会遇到类似的困难。据我所知,MSVC与C89兼容,但对以后的C语言标准的支持有限。

我指的是C标准的含义。自动存储持续时间意味着变量在其作用域内的执行时间正好有效。创建一个包含两个字段的结构,一个数组和一个double。对您来说,理解函数中声明的任何内容在完成后都不会出现也很重要。您需要在函数之前分配它,并发送到函数(结构)。不相关,但在没有很好理由的情况下不要使用
float
,因为它的精度非常有限。请始终使用
double
@TonyTannous或返回调用者在完成操作时必须释放的已分配对象。@Sjoseph不要让负面投票阻止你提问:)这只是表明问题格式不正确的一种方式,请阅读“如何提问部分”了解未来的问题。下面的答案很简单,但也很优雅。只需添加,以免混淆OP,即通过引用发送到函数的任何内容,并在其内部进行修改,然后从外部可以看到更改。因此,您可能只需要将存储发送到函数,而不需要结构。别忘了在函数中分配数组。@TonyTannous调用者应该提供输出数组。是的,如果大小改变,我只想在内部执行。。。但这也是一个简单的解决方案+1.@TonyTannous我认为让调用者提供内存是惯用的C方式。优点是任何对象都可以工作,自动、静态、分配。。。当然,有时您更希望在函数内部分配数组,并让调用方释放它。@FelixPalmen,当我从主函数调用此函数时
#include <stdio.h>
#include <assert.h>

#define MAX_ARR  100

struct mean_array {
    double mean;
    double array[MAX_ARR];
    size_t num_elems;
};

struct mean_array get_mean(int arr[], size_t arr_sz);

int main(void)
{
    int my_arr[] = { 1, 2, 3, 4, 5 };

    struct mean_array result = get_mean(my_arr, sizeof my_arr / sizeof *my_arr);

    printf("mean: %f\n", result.mean);
    for (size_t i = 0; i < result.num_elems; i++) {
        printf("%8.5f", result.array[i]);
    }
    putchar('\n');

    return 0;
}

struct mean_array get_mean(int arr[], size_t arr_sz)
{
    assert(arr_sz <= MAX_ARR);
    struct mean_array res = { .num_elems = arr_sz };
    double sum = 0;

    for (size_t i = 0; i < arr_sz; i++) {
        sum += arr[i];
        res.array[i] = 10.5 * i / (128.0 - 1.0);
    }
    res.mean = sum / arr_sz;

    return res;
}