函数作为参数"/>
【C/C++】函数作为参数
C++函数本身是可以作为参数传入函数的。
一、函数指针的定义
函数类型 (*自定义变量名)(形参1,形参2,...) ;int (*p)(int, int); // 定义一个指向函数的指针-->p,被指向的函数有两个整型参数并返回整型值。
上式可以看作这样:
int (*)(int, int) p;
其中,int (*)(int, int) 是变量类型, p是变量名。
例1:
#include<iostream>
using namespace std;int main()
{int add(int x, int y);int a = 2, b = 3, sum;// 定义一个指向函数的指针-->p,被指向的函数有两个整型参数并返回整型值。int(*p)(int x, int y);p = add; // p指向一个函数的起始地址,它相当于一个函数的"别名"。可以写成p = &add;sum = add(a, b);cout << "sum: " << sum << endl;sum = p(a, b);cout << "sum: " << sum << endl;sum = (*p)(a, b); // (*p)() == (*&add)() == add()cout << "sum: " << sum << endl;return 0;
}int add(int x, int y) {return (x + y);
}
函数输出:
sum: 5
sum: 5
sum: 5
函数名代表函数的入口地址。
函数指针,指向一个函数的起始地址,它相当于一个函数的别名,它的返回值是int型(不是指针)
p = add; // p = &add; (*p)() == (*&add)() == add()
注意:下面这三种写法是等价的。
int(*p)(int x, int y); p = add;int(*p)(int x, int y) = add;
int(*p)(int x, int y) = &add;
因为形参名可以不写,在代码中,也可以写成下面这样,也能得到同样的输出:
int(*p)(int, int); p = add;int(*p)(int, int) = add;
int(*p)(int, int) = &add;
二、函数作为形参的语法格式
例2:
#include<iostream>
using namespace std;// 其中: void (*)(int) 为形参的类型,func 为形参变量。
void foo(void (*func)(int),int j)
{func(j);
}void printnumber(int j)
{cout<<"j="<<j<<" "<<endl;
}int main()
{void (*func)(int i); // 声明一个函数的指针变量--func,该函数有一个int型的参数,无返回值。func = printnumber; // 将printnumber的地址赋给func。foo(func,1);//(1)foo(printnumber,1);//(2)// (1)、(2)两种写法是等价的。
}
个人觉得,可以将
void foo( void (*func)(int), int j)
看作
void foo( void (*)(int) func, int j)
例3:用typedef定义一类函数,Linux中最常用。
#include<iostream>
using namespace std;typedef void(*func)(int, int);
//这样func就可以代表一类函数;//使用这个定义
void runfunc(func p, int a, int b)
{p(a, b);
}void add(int a, int b)
{cout << a + b << endl;
}void sub(int a, int b)
{cout << a - b << endl;
}int main() {//函数作参数runfunc(add, 1, 2);runfunc(sub, 1, 2);return 0;
}
个人觉得,可以将
typedef void(*func)(int, int);
看作
typedef void(*)(int, int) func;
这样 func 就可以代表一类函数。
三、类成员函数指针的使用方法
例4:
#include<iostream>
using namespace std;class A {
public:void fun(int a){cout << a << endl;}
};int main()
{A a;void (A::*ptrfun)(int);ptrfun = &A::fun;(a.*ptrfun)(2);return 0;
}
如果 void fun(int a)
是普通函数,对普通函数指针进行赋值时,直接写成pfun = fun
。 但是,如果 void fun(int a)
是类的成员函数,对类的成员函数指针进行赋值时,必须写成pfun = &A::fun
。
这涉及到函数类型与函数指针类型。对于普通函数,当定义了一个函数指针,将函数名赋值给函数指针,函数类型会默认转换成函数指针。因此 pfun = fun
或者 pfun = &fun
都是可行的,只是 pfun = fun
中有一层默认的转换。
而对于类的成员函数,当定义了一个成员函数指针 ptrfun
,如果直接用 A::fun
进行赋值,编译器会将它理解为A中的静态成员,会产生编译错误,所以,这里的&是必须的。
不过,如果写成这样 ptrfun = &(A::fun)
;也会发生编译错误,因为,将 A::fun
作为一个整体,编译器就会将fun理解为A中的静态成员,所以,要将 &A::fun
作为一个整体,即使::的优先级较高。同样,对于调用方式也有类似的不同。对于普通函数,(*pfun)()和pfun()都是可以的。对于成员函数,只能是 (a.*ptrfun)()
。
四、使用类成员函数的指针作为参数
例5:
#include<iostream>
using namespace std;class A {
public:void fun(int a){cout << a << endl;}
};void test(A x, void (A::*pfun)(int), int y)
{(x.*pfun)(y);
}int main()
{void (A::*ptrfun)(int);ptrfun = &A::fun;A a;test(a, ptrfun, 3);return 0;
}
参考链接:
函数作为参数
函数参数与函数作为参数
将成员函数作为函数形参
C++typedef的详细用法
c++将函数作为函数参数(函数指针)
更多推荐
【C/C++】函数作为参数
发布评论