我想创建一个函数,该函数对一组数据执行由参数传递的函数。如何在C中将函数作为参数传递?
void funcA(void(*funcB)(int))
和void (*funcA())()
要typedef void funcB(); void funcA(funcB)
和funcB funcA()
?我没有看到上行空间。
我想创建一个函数,该函数对一组数据执行由参数传递的函数。如何在C中将函数作为参数传递?
void funcA(void(*funcB)(int))
和void (*funcA())()
要typedef void funcB(); void funcA(funcB)
和funcB funcA()
?我没有看到上行空间。
Answers:
宣言
具有函数参数的函数原型如下所示:
void func ( void (*f)(int) );
这说明该参数f
将是指向具有void
返回类型并且采用单个int
参数的函数的指针。以下函数(print
)是一个函数示例,func
由于它是正确的类型,因此可以作为参数传递给它:
void print ( int x ) {
printf("%d\n", x);
}
函数调用
使用函数参数调用函数时,传递的值必须是指向函数的指针。为此,请使用函数的名称(不带括号):
func(print);
会调用func
,将print函数传递给它。
功能体
与任何参数一样,func
现在可以使用函数体内的参数名称来访问参数的值。假设func
它将应用传递给数字0-4的函数。首先考虑一下循环直接调用print的样子:
for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
print(ctr);
}
由于func
的参数声明说这f
是指向所需函数的指针的名称,因此我们首先回想一下,如果f
是指针,则指向*f
该对象f
(即print
本例中的函数)。结果,只需将上面循环中所有出现的print替换为*f
:
void func ( void (*f)(int) ) {
for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
(*f)(ctr);
}
}
f
函数调用都可以f
照原样使用。最好像您一样这样做,以使参数f很明显是一个函数指针。但这经常会损害可读性。
typedef
for函数指针吗?抱歉,必须拒绝投票。
这个问题已经有了定义函数指针的答案,但是它们会变得非常混乱,特别是如果您要在应用程序中传递它们。为避免这种不愉快,我建议您将函数指针类型化为更易读的内容。例如。
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<int (char a)> functiontype2;
比上面的要好得多。
typedef
; 它更简单,不需要任何额外的库。
从C ++ 11开始,您可以使用功能库以简洁通用的方式进行此操作。语法例如是
std::function<bool (int)>
这里bool
是第一个参数为type的单参数函数的返回类型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();
}
根据ISO C11 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;
}
IncMultInt
?
typedef
。