我猜你对一些支持闭包机制的编程语言应该很熟悉吧?
不幸的是,C语言本身不支持像那样的闭包。
如果你坚持要使用闭包,你可以找到一些有用的库来模拟闭包在C语言中的实现。但是大多数这些库都比较复杂且与机器相关。
或者,如果你能改变
double ()(unsigned,unsigned)
的签名,你也可以改变主意,接受C风格的闭包。
在C语言中,一个函数除了传递给它的参数和它可以访问的静态变量之外,没有其他数据(或上下文)。
所以上下文必须由你自己传递。下面是一个使用额外参数的示例:
// first, add one extra parameter in the signature of function.
typedef double(function)(double extra, unsigned int,unsigned int);
// second, add one extra parameter in the signature of apply
void apply(double* matrix,unsigned width,unsigned height, function* f, double extra)
{
for (unsigned y=0; y< height; ++y)
for (unsigned x=0; x< width ++x)
matrix[ y*width + x ] = f(x, y, extra);
// apply will passing extra to f
}
// third, in constant_function, we could get the context: double extra, and return it
double constant_function(double value, unsigned x,unsigned y) { return value; }
void test(void)
{
double* matrix = get_a_matrix();
// fourth, passing the extra parameter to apply
apply(matrix, w, h, &constant_function, 1212.0);
// the matrix will be filled with 1212.0
}
一个double extra
足够吗?是的,但只在这种情况下。
如果需要更多的上下文,我们应该怎么办?
在C语言中,通用参数是void*
:我们可以通过传递上下文的地址来通过一个void*
参数传递任何上下文。
这里是另一个例子:
typedef double (function)(void* context, int, int );
void apply(double* matrix, int width,int height,function* f,void* context)
{
for (int y=0; y< height; ++y)
for (int x=0; x< width ++x)
matrix[ y*width + x ] = f(x, y, context);
}
double constant_function(void* context,int x,int y)
{
double* d = context;
return *d;
}
void test(void)
{
double* matrix = get_a_matrix();
double context = 326.0;
apply( matrix, w, h, &constant_function, &context);
}
(function,context)对,像&constant_function,&context这样的是C风格的闭包。
每个需要闭包的函数(F)都必须有一个上下文参数,该参数将作为上下文传递给闭包。
调用F的调用者必须使用正确的(f,c)对。
如果您可以更改函数的签名以适应C风格的闭包,那么您的代码将简单且与机器无关。
如果您不能(函数和应用程序不是由您编写的),请尝试说服作者更改该代码。
如果不可能,您别无选择,只能使用一些闭包库。