繁体   English   中英

在C中,从函数返回2个变量

[英]In C, return 2 variables from a function

基本上,我有一个C函数,可以打印出某些数字,并且我还希望该函数返回2个值。 我已经使用struct进行了尝试,但是我没有正确执行此操作,并且不确定如何继续。 我已经阅读了其他问题,并且我知道使用指针会更好,但是我不确定该如何做。

我的C代码如下:

struct re_val
{
    double predict_label;
    double prob_estimates;
    predict_label = 5.0;
    prob_estimates = 8.0;
};

int c_func(const char* dir, double a, double b, double c, double d)
{
    double x[] = { a, b, c, d };

    printf("x[0].index: %d \n", 1);
    printf("x[0].value: %f \n", x[0]);

    printf("x[1].index: %d \n", 2);
    printf("x[1].value: %f \n", x[1]);

    printf("x[2].index: %d \n", 3);
    printf("x[2].value: %f \n", x[2]);

    printf("x[3].index: %d \n", 4);
    printf("x[3].value: %f \n", x[3]);

    return re_val;
}

最终,我只想调用一个能够打印出数组并返回predict_labelprob_estimates

我实际上是通过ctypes在python中调用此函数,并且下面包含了我的python函数。

calling_function = ctypes.CDLL("/home/ruven/Documents/Sonar/C interface/Interface.so")
calling_function.c_func.argtypes = [ctypes.c_char_p, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double]
calling_function.c_func.restype =  ctypes.c_double
y = calling_function.c_func("hello",1.1, 2.2, 3.1, 4.2)
print y

首先,您需要定义您的结构:

struct re_val{
    float predict_label;
    float prob_estimates;
};

然后,您需要从函数中返回struct re_val

struct re_val c_func(const char* dir, float a, float b, float c, float d )
{
    /* ... all that stuff ... */

    struct re_val r;
    r.predict_label = 5.0f;
    r.prob_estimates = 8.0f;   
    return r;
}

因此,完整的示例将是:

struct re_val{
    float predict_label;
    float prob_estimates;
};

struct re_val c_func(const char* dir, float a, float b, float c, float d )
{

    /* ... all that stuff ... */

    struct re_val r;
    r.predict_label = 5.0f;
    r.prob_estimates = 8.0f;   
    return r;
}

int main(void)
{
    struct re_val r = c_func("",1.0f,2.0f,3.0f,4.0f);
    printf("predict_label=%.1f\n",r.predict_label);
    printf("predict_label=%.1f\n",r.prob_estimates);
    return 0;
}

在这里尝试: http : //rextester.com/WRROW32352

这通常是通过结构完成的。 要将其初始化在堆栈上,请执行以下操作。

#include <stdio.h>  /* printf */
#include <assert.h> /* assert */

struct sample {
    float x[4];
};

struct re_val {
    float predict_label, prob_estimates;
};

/** Returns the re_val of x. */
static struct re_val c_func(const struct sample *const x) {
    struct re_val rv;
    float a;
    assert(x); /* Debug warn if called with null. */
    rv.predict_label = (x->x[0] + x->x[1]) * 5.0f;
    a = x->x[2] + x->x[3];
    if(a < 0.01f) a = 0.01f;
    rv.prob_estimates = 1.0f / a;
    return rv;
}

/** Prints the re_val. */
static void print(const struct re_val *const rv) {
    assert(rv);
    printf("# prediction label\tprobability estimates\n%g\t%g\n",
        rv->predict_label, rv->prob_estimates);
}

int main(void) {
    const struct sample x = { { 0.1f, 0.2f, 1.0f, 100000.0f } };
    const struct re_val rv = c_func(&x);
    print(&rv);
    return 0;
}

查看此链接在C中通过值传递结构而不是传递指针是否有不利之处? ; 具体来说,原型可能是static void c_func(const struct sample *const x, struct re_val *const rv); 其中rv指针已填充,特别是re_val是一个大型结构,或者希望将其潜在地分配在堆上时。

有多种方法可以将信息从函数中传递出去,例如,

  • 返回堆栈,如此处所示。 通常,这对于内存标记比较琐碎的结构是有利的。 divstrtod64 ;
  • 传递一个指向要填充数据的指针。 freadfscanfsnprintfsprintfstrfmonstrncatstrncpystrptimestrftimeasctime_rctime_rlocaltime_r ;
  • 保持static struct -此方法不可重入并多次覆盖相同的数据。 它不是线程安全的。 asctimectimegmtimelocaltimestrtok ;
  • FILE *fopen / fcloseregex_tregcomp / regfree或全局的errnoperror具有与状态相关的类型。
  • 返回用户必须释放的堆分配指针。 例如, asprintf

这个答案是使用结构的替代方法-这当然是有效的-您可以通过引用/通过指针返回多个值。 并回答主要问题,是否可以从单个函数返回多个值。

#include<stdio.h>

void sum_diff(double a, double b, double* sum, double*diff)
{
    if (sum) // Only assign when we have a valid reference
        *sum = a + b;
    if (diff)
        *diff= a - b;
}

int main() {

    double diff, sum;
    double a = 4, b = 3;

    sum_diff(a, b, &sum, &diff);

    fprintf(stdout, "The sum of %lf and %lf is %lf\n", a, b, sum);
    fprintf(stdout, "The difference of %lf and %lf is %lf\n", a, b, diff);

    return 0;
}

sum_diff分配的函数使用参数absumdiff ab是输入参数, sumdiff是输出参数。 请注意,该函数检查sum和diff是否为NULL,这使调用方可以选择获取差值或sum。 这可能需要更多的计算密集型计算。

暂无
暂无

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

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