我想创建一个函数来执行由一组数据上的参数传递的函数。如何在C中将函数作为参数传递?
宣言
带函数参数的函数原型如下所示:
void func ( void (*f)(int) );
这表明参数f
将是一个指向具有void
返回类型并且采用单个int
参数的函数的指针。以下函数(print
)是一个函数的示例,可以作为参数传递给func
,因为它是正确的类型:
void print ( int x ) {
printf("%d\n", x);
}
功能调用
使用函数参数调用函数时,传递的值必须是指向函数的指针。使用函数的名称(不带括号):
func(print);
会调用func
,将打印功能传递给它。
功能体
与任何参数一样,func现在可以在函数体中使用参数的名称来访问参数的值。假设func将应用它传递给0-4数字的函数。首先考虑一下直接调用print的循环:
for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
print(ctr);
}
由于func
的参数声明说f
是指向所需函数的指针的名称,我们首先回想一下,如果f
是一个指针,那么*f
就是f
指向的东西(在这种情况下是函数print
)。因此,只需用*f
替换上面循环中每次出现的print:
void func ( void (*f)(int) ) {
for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
(*f)(ctr);
}
}
来自http://math.hws.edu/bridgeman/courses/331/f05/handouts/c-c++-notes.html
这个问题已经有了定义函数指针的答案,但是它们会变得非常混乱,特别是如果你要在应用程序中传递它们。为了避免这种不愉快,我建议你将函数指针键入为更可读的东西。例如。
typedef void (*functiontype)();
声明一个返回void并且不带参数的函数。要创建指向此类型的函数指针,您现在可以执行以下操作:
void dosomething() { }
functiontype func = &dosomething;
func();
对于返回int并获取char的函数,您可以这样做
typedef int (*functiontype2)(char);
并使用它
int dosomethingwithchar(char a) { return 1; }
functiontype2 func2 = &dosomethingwithchar
int result = func2('a');
有些库可以帮助将函数指针转换为可读的类型。 boost function图书馆很棒,值得付出努力!
boost::function<int (char a)> functiontype2;
比上面好多了。
从C ++ 11开始,您可以使用functional library以简洁和通用的方式执行此操作。语法是,例如,
std::function<bool (int)>
其中bool
是一个单参数函数的返回类型,其第一个参数是int
类型。
我在下面列出了一个示例程序:
// g++ test.cpp --std=c++11
#include <functional>
double Combiner(double a, double b, std::function<double (double,double)> func){
return func(a,b);
}
double Add(double a, double b){
return a+b;
}
double Mult(double a, double b){
return a*b;
}
int main(){
Combiner(12,13,Add);
Combiner(12,13,Mult);
}
但有时候,使用模板功能会更方便:
// g++ test.cpp --std=c++11
template<class T>
double Combiner(double a, double b, T func){
return func(a,b);
}
double Add(double a, double b){
return a+b;
}
double Mult(double a, double b){
return a*b;
}
int main(){
Combiner(12,13,Add);
Combiner(12,13,Mult);
}
将函数的地址作为参数传递给另一个函数,如下所示
#include <stdio.h>
void print();
void execute(void());
int main()
{
execute(print); // sends address of print
return 0;
}
void print()
{
printf("Hello!");
}
void execute(void f()) // receive address of print
{
f();
}
我们也可以使用函数指针将函数作为参数传递
#include <stdio.h>
void print();
void execute(void (*f)());
int main()
{
execute(&print); // sends address of print
return 0;
}
void print()
{
printf("Hello!");
}
void execute(void (*f)()) // receive address of print
{
f();
}
你需要通过function pointer。语法有点麻烦,但是一旦你熟悉它就会非常强大。
函数可以作为函数指针“传递”,如6.7.6.3p8所述:“参数声明为''函数返回类型''应调整为''指向函数返回类型的'',如6.3.2.1所述。“例如,这个:
void foo(int bar(int, int));
相当于:
void foo(int (*bar)(int, int));
它不是真正的功能,但它是一段本地化的代码。当然,它不会仅仅通过代码传递结果。如果传递给事件调度程序以便稍后运行它将无效(因为结果是现在计算的,而不是在事件发生时)。但它确实将您的代码本地化到一个地方,如果这就是您要做的全部。
#include <stdio.h>
int IncMultInt(int a, int b)
{
a++;
return a * b;
}
int main(int argc, char *argv[])
{
int a = 5;
int b = 7;
printf("%d * %d = %d\n", a, b, IncMultInt(a, b));
b = 9;
// Create some local code with it's own local variable
printf("%d * %d = %d\n", a, b, ( { int _a = a+1; _a * b; } ) );
return 0;
}