将函数作为具有不同长度参数的指针传递给另一个函数?

时间:2014-12-04 21:32:59

标签: c function nested

在file1.h

// find the root of a function of one variable
double rootfind(double (*fp)(double), double start, double end);

在file2.h中

// a function of multiple variables
double myfun(double a, double b);

double test();

在file2.c

double myfun(double a, double b)
{
    return (a+3.0)*(a-1.0)*(a-1.0)*b;
}

double test()
{
    double b, start, end;

    start = -4.0;
    end = 4.0/3.0;

    b = 2.0;

    // How do I use the rootfinding function to find the root of myfun
    // where b is set as a constant in this function?
    // How do i find the root of myfun(x,2.0)?
}

我想保持rootfind函数的通用性,而不是传递额外的参数。我也不想对嵌套函数使用gcc扩展。

3 个答案:

答案 0 :(得分:2)

您询问的是标准C90 / C99不支持的闭包。如果您计划这样做,您必须:

  • 使用您提到的GCC扩展程序。
  • 使用C ++的std::bind功能。
  • 使用库(例如GCC附带的libffi)来分配可写入和运行的内存(在运行时为新的一个参数函数创建机器代码)。
  • 编写一个顶级静态函数,以您希望的方式工作。
  • 使用在运行时从C代码编译的动态加载模块。

大多数人可能看起来令人困惑/恐吓,因为在C中做你想做的事真的没有好办法。这主要是因为它非常危险(主要的安全漏洞) )在C中运行时重写函数。


顶级静态函数的示例(将其放在main函数的上方):

static myfun_single_b = 2.0;

static double myfun_single(double a) {
    return myfun(a, myfun_single_b);
}

我们在这里使用static关键字的原因是变量的名称和函数的名称不会与其他源文件中的其他函数/变量名冲突。

答案 1 :(得分:1)

您可以编写包装函数:

static double wrapper(double a) {
    return myfun(a, 3.0);
}

并使用rootfind()。你可以通过从文件范围变量获取myfun()的第二个参数的值来使它更通用(即支持第二个参数的不同值为myfun()): / p>

static double b;

static double wrapper(double a) {
    return myfun(a, b);
}

您甚至可以通过文件范围函数指针使包装器调用为两个arg函数来进一步概括:

static double b;
static double (*wrapped)(double, double);

static double wrapper(double a) {
    return (*wrapped)(a, b);
}

关于你可以执行的间接限制,但它提供了相当大的自由度。

答案 2 :(得分:1)

如果你可以修改rootfind,修复它的正确方法是在函数指针中添加一个context参数,比如

double rootfind(double (*fp)(double, void *), double start, double end, void *context);

然后,您可以创建一个包含第二个参数b的上下文结构,并通过上下文参数传递指向它的指针。

这样,避免了全局状态和运行时代码生成。 rootfind函数也是通用的。