Массив функций, где i-й элемент возвращает i - PullRequest
0 голосов
/ 09 сентября 2018

Вчера мой друг попросил меня написать функцию на C, которая бы возвращала массив указателей на функции, где i-я функция возвращала бы i. Подобный эффект легко получить в C ++, но я не уверен, как это сделать в C.

Может ли кто-нибудь помочь мне с этим?

Edit.

Эффект, который я ищу, эквивалентен этому.

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

1 Ответ

0 голосов
/ 09 сентября 2018

Код 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...