如何在C中返回一个函数指针?

fdx2calv  于 2023-08-03  发布在  其他
关注(0)|答案(4)|浏览(125)

假设我想要一个增量函数,它接受一个参数f(它本身就是一个函数),并返回一个函数g,其属性是g(x)= f(x)+ 1。在Python中,代码如下:

def increment(f):
    def g(x):
        return f(x) + 1
    return g
def f(x):
    return 2 * x
print(increment(f)(5))

字符串
结果将是2 * 5 + 1 = 11我想在C中实现一个类似的递增函数。我不想使用lambdas(我认为只有C++才有)。如何继续?
我知道你不能在C中嵌套函数。我尝试使用函数指针,但增量函数的返回类型及其主体对我来说很困惑。任何关于函数指针的资料都是有帮助的。

i7uaboj4

i7uaboj41#

首先要认识到的是,g在python中并不是一个真正的函数指针,而是一个闭包。也就是说,它不仅是指向函数(__call__)的指针,而且是指向一些数据(在这种情况下是函数f)的指针。
你可以在C中通过为闭包g定义一个结构体来做同样的事情:

typedef struct {
    int (*f)(int);
    // maybe more fields here
} g_t;

字符串
然后在increment函数的等价物中构造此类型:

g_t increment(int (*f)(int)) {
    g_t closure;
    closure.f = f;
    // maybe init more fields here
    return closure;
}


最后,C没有成员函数,所以我们将g_t的调用操作符实现为一个自由函数:

int g_call(g_t self, int x) {
    return self.f(x) + 1;
}


把所有这些放在一起,我们得到:

int f(int x) {
    return 2 * x;
}

int main(void) {
    // print(increment(f)(5))
    printf("%d\n", g_call(increment(f), 5)); // 11
}

z18hc3ub

z18hc3ub2#

我不明白为什么你不能简单地有两个单独的函数,一个g(x)和一个f(x),然后调用它们。

#include <stdio.h>
int f(int x)
{
     return 2*x;
}
int g(int x)
{
     return f(x)+1;
}
int main()
{
     int n = g(10);
     printf("%d\n",n);
     return 0;
}

字符串
g(x)调用f(x)并返回结果。

llmtgqce

llmtgqce3#

C没有闭包/lambda。
因此,您不能按原样返回g
你的函数可以使用函数指针:

#include <stdio.h>

int increment(int (*f)(int), int x)
{
     return f(x)+1;
}

int twice(int x)
{
     return 2 * x;
}

int main()
{
     int n = increment(twice, 5);
     printf("%d\n", n);
     return 0;
}

字符串

epfja78i

epfja78i4#

在C中不能嵌套函数,一个函数不能产生一个函数。但是使用函数指针,你可以定义一个函数组合函数指针调用。

// compute y from x and combination of 3 functions pointers
int  calc_combine( int x, int (*f)(int), int (*g)(int), int (*h)(int) ) {
    return  (*h)( (*g)( (*f)(x) ) );
}

int  increment( int x ) {
    return  x + 1;
}
int  get_double( int x ) {
    return  2 * x;
}
int  square( int x ) {
    return  x * x;
}
int  same( int x ) {
    return  x;
}

int main() {
    printf( "increment(double(square(3)))=%d\n", calc_combine(3,square,get_double,increment) );
    printf( "increment(4)=%d\n", calc_combine(4,same,same,increment) );
    printf( "square(square(2))=%d\n", calc_combine(2,same,square,square) );
}

字符串

相关问题