首页 > 解决方案 > 第 i 个元素返回 i 的函数数组

问题描述

昨天我的朋友挑战我用 C 语言编写一个函数,该函数将返回一个函数指针数组,其中第 i 个函数将返回 i。在 C++ 中很容易获得类似的效果,但我不确定如何在 C 中实现。

任何人都可以帮助我吗?

编辑。

我正在寻找的效果与此等效。

vector <function<int()>> get_functions(int n) {
    vector <function<int()>> functions;
    for (int i = 0; i < n; ++i) {
        functions.emplace_back([i]() {
            return i;
        });
    }
    return functions;
}


int main() {
    auto functions = get_functions(10);
    for (auto f:functions) {
        cout << f() << endl;
    }
    return 0;
}

编辑。

正如评论部分所问的那样,我提供了我对挑战的糟糕尝试。

typedef int (*fun_t)(void);

int fun() { return 0; }
int fun1() { return 1; }

fun_t *get_functions() {
    fun_t *functions = malloc(sizeof(fun_t) * 2);

    functions[0] = fun;
    functions[1] = fun1;

    return functions;
}

int main() {
    fun_t* funs=get_functions();
    for (int i = 0; i < 2; ++i) {
        printf("%d\n",funs[i]());
    }
    free(funs);
}

标签: c++function-pointers

解决方案


C++ 代码是作弊的。function<int()>不是函数指针;事实上,它根本就不是一个指针,它是一个类。

因此,等效的 C 代码看起来像这样:

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

// function<int ()>, simplified version just for this task
typedef struct {
    int (*code)(int);
    int ctx;
} function_int_t;

// function<int()>::operator()()    
int call(function_int_t fun) {
    return fun.code(fun.ctx);
}

// lambda body
int proto(int ctx) {
    return ctx;
}

function_int_t *get_functions(size_t n) {
    function_int_t *functions = calloc(n, sizeof *functions);
    if (!functions) {
        abort();  // hey, that's how C++ does it
    }
    for (size_t i = 0; i < n; i++) {
        functions[i] = (function_int_t){ proto, i };  // capture i
    }
    return functions;
}

int main(void) {
    size_t n = 10;
    function_int_t *functions = get_functions(n);
    for (size_t i = 0; i < n; i++) {
        printf("%d\n", call(functions[i]));
    }
    free(functions);
    return 0;
}

推荐阅读