所以我需要编写一些执行部分集成的代码。我有一个由示意表示的数值积分器
double integrate(double (*func)(double));
并且假设它工作正常,即对于函数double f(double x)
,integrate(f)
给出正确的结果。然而,我所拥有的是看起来像的功能
double f(double x, double y);
我只想对第一个变量执行积分,所以动态生成指向g(x)=f(x,1)
或h(x)=f(x,2)
等函数的指针,并将它们传递给积分。我想我想要的原型是在另一个中定义一个函数
double compute(double y){
double g(double x){
return f(x, y);
}
return integrate(g);
}
我知道它不是ANSI C的一部分,尽管GCC允许它(也许我不应该在意,然后就使用它(。那么,获得C18批准的标准方式是什么呢?如果唯一的可能性是将integrate
的代码复制到compute
的内部,我想我只会使用GCC扩展,即使我的LSP不断抱怨它,但我感兴趣的是";适当的";程序的外观。
使用基本C语言,即严格符合标准定义的代码,这里有三种方法。
定义一个对附加参数进行硬编码的函数:
double g1(double x) { return f(x, 1); }
…
integrate(g1);
定义一个从外部定义的对象获取附加参数的函数:
double y;
double g(double x) { return f(x, y); }
…
y = 1;
integrate(g);
修改integrate
以获取指向附加信息的指针,并使用该指针将信息传递给正在集成的函数:
double integrate(double (*func)(double, const void *))
struct MyData { double y; }; // This structure can contain whatever you want.
double g(double x, const void *p)
{
const struct MyData *data = p;
return f(x, data->y);
}
…
struct MyData data = { 1 };
integrate(g, &data);
使用GCC,您可以使用C标准之外的一个扩展,该扩展允许您在函数中定义函数:
double compute(double y)
{
double g(double x) { return f(x, y); }
return integrate(g);
}
这也可以在Clang中使用块扩展来完成,但这也需要修改integrate
以接受块。