简体   繁体   English

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

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

Basically, I have a C function that prints out certain numbers and I also want the function to return 2 values. 基本上,我有一个C函数,可以打印出某些数字,并且我还希望该函数返回2个值。 I have tried this out using struct but I did not do this correctly and I am not sure how to proceed. 我已经使用struct进行了尝试,但是我没有正确执行此操作,并且不确定如何继续。 I have read other questions and I understand that using a pointer would be better but I am not sure how to. 我已经阅读了其他问题,并且我知道使用指针会更好,但是我不确定该如何做。

My C code is as follows: 我的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;
}

Ultimately, I would like to call only one function that is able to print out the array and return predict_label and prob_estimates . 最终,我只想调用一个能够打印出数组并返回predict_labelprob_estimates

I am actually calling this function in python via ctypes and my python function is included bellow. 我实际上是通过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

First you need to define your structure: 首先,您需要定义您的结构:

struct re_val{
    float predict_label;
    float prob_estimates;
};

And then you need to return a struct re_val from your function: 然后,您需要从函数中返回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;
}

So the full example would be: 因此,完整的示例将是:

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;
}

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

This is generally done with structures. 这通常是通过结构完成的。 To initialise it on the stack, do something like this. 要将其初始化在堆栈上,请执行以下操作。

#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;
}

See this link Are there any downsides to passing structs by value in C, rather than passing a pointer? 查看此链接在C中通过值传递结构而不是传递指针是否有不利之处? ; ; specifically, the prototype could have been static void c_func(const struct sample *const x, struct re_val *const rv); 具体来说,原型可能是static void c_func(const struct sample *const x, struct re_val *const rv); where rv pointer is filled, especially where re_val is a large structure or one wants it to be potentially allocated on the heap. 其中rv指针已填充,特别是re_val是一个大型结构,或者希望将其潜在地分配在堆上时。

There are different ways to pass information out of a function, such as, 有多种方法可以将信息从函数中传递出去,例如,

  • returning on the stack, as here. 返回堆栈,如此处所示。 Usually this is good for structures which the memory imprint is trivial. 通常,这对于内存标记比较琐碎的结构是有利的。 div , strtod64 ; divstrtod64 ;
  • passing a pointer to the data that's to be filled. 传递一个指向要填充数据的指针。 fread , fscanf , snprintf , sprintf , strfmon , strncat , strncpy , strptime , strftime , asctime_r , ctime_r , localtime_r ; freadfscanfsnprintfsprintfstrfmonstrncatstrncpystrptimestrftimeasctime_rctime_rlocaltime_r ;
  • keeping a static struct -- this method not re-entrant and overwrites the same data multiple times. 保持static struct -此方法不可重入并多次覆盖相同的数据。 It is not thread-safe. 它不是线程安全的。 asctime , ctime , gmtime , localtime , strtok ; asctimectimegmtimelocaltimestrtok ;
  • having a type associated with the state that one needs to pass to do operations, FILE * : fopen / fclose , regex_t : regcomp / regfree , or global, errno : perror ; FILE *fopen / fcloseregex_tregcomp / regfree或全局的errnoperror具有与状态相关的类型。
  • returning an heap-allocated pointer which the user must free. 返回用户必须释放的堆分配指针。 For example, asprintf . 例如, asprintf

This answer is an alternative to using structs - which is of course valid - you can return multiple value by reference/via a pointer. 这个答案是使用结构的替代方法-这当然是有效的-您可以通过引用/通过指针返回多个值。 And answers the main question whether it is possible to return mulitple value from a single function. 并回答主要问题,是否可以从单个函数返回多个值。

#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;
}

The function sum_diff assigns uses the arguments a , b , sum and diff . sum_diff分配的函数使用参数absumdiff a and b are input arguments and sum and diff are the output arguments. ab是输入参数, sumdiff是输出参数。 Notice that the function checks whether sum and diff are not NULL, this allows the caller to optionally get the difference or sum. 请注意,该函数检查sum和diff是否为NULL,这使调用方可以选择获取差值或sum。 This might be handy with more computational intensive calculations. 这可能需要更多的计算密集型计算。

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

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