1.0 基本含义
每个函数在内存的程序段都占用一段存储大单元,这段存储单元的首地址称为函数入口地址,指向这个函数入口地址的指针称为函数指针。
函数指针的抽象定义为 : 数据类型 (* 指针变量)(参数列表)
2. 实例1
如下是一个简单的求加减乘除的程序(参考《程序员面试笔记-C/C++、算法、数据结构篇》
int Add(int a, int b) { return a + b; }
int Minus(int a, int b) { return a - b; }
int Multi(int a, int b) { return a * b; }
int process(int a, int b, char operation)
{
switch (operation)
{
case '+': return Add(a, b);
case '-': return Minus(a, b);
case '*': return Multi(a, b);
default: return 0;
}
}
int main()
{
int a = 20, b = 10;
int res1 = process(a, b, '+');
int res2 = process(a, b, '-');
int res3 = process(a, b, '*');
cout << res1 << ' ' << res2 << " " << res3 << endl;
}
程序本身没任何问题。但不难看出程序的扩展性较差,如果要增加一个整数除法运算,不仅要编写整数除法函数,还要修改process函数,在switch添加一个分支。具体代码如下。
int Add(int a, int b) { return a + b; }
int Minus(int a, int b) { return a - b; }
int Multi(int a, int b) { return a * b; }
int Divide(int a, int b) { return a / b; }
int process(int a, int b, char operation)
{
switch (operation)
{
case '+': return Add(a, b);
case '-': return Minus(a, b);
case '*': return Multi(a, b);
case '/': return Divide(a, b);
default: return 0;
}
}
int main()
{
int a = 20, b = 10;
int res1 = process(a, b, '+');
int res2 = process(a, b, '-');
int res3 = process(a, b, '*');
int res4 = process(a, b, '/');
cout << res1 << ' ' << res2 << " " << res3 << " " << res4 << endl;
}
我们希望在增加函数运算时,只需添加运算函数本身,而无需修改process函数,这就需要在process函数中使用函数指针代替运算类型参数operation。
使用函数指针后程序如下
int Add(int a, int b) { return a + b; }
int Minus(int a, int b) { return a - b; }
int Multi(int a, int b) { return a * b; }
int Divide(int a, int b) { return a / b; }
int process(int a, int b, int (* func)(int a, int b))
{
return func(a, b);
}
int main()
{
int a = 20, b = 10;
int res1 = process(a, b, Add);
int res2 = process(a, b, Minus);
int res3 = process(a, b, Multi);
int res4 = process(a, b, Divide);
cout << res1 << ' ' << res2 << " " << res3 << " " << res4 << endl;
}
将process函数的第三参数修改为函数指针,在调用process函数时将任一整数运算函数的函数名作为参数传递给形参func。在process函数中,通过函数指针func调用其指向的函数。
修改后程序在扩展性方面的到了极大的改善。
函数指针最常见的用途就是参数参数传递,在主调函数中将函数名作为参数传递给被调函数参数列表的函数指针,从而在被调函数中能够根据参数值灵活地调用不同的函数。
2.1 简化超长的函数指针类型
在上面process的第三个参数中
int process(int a, int b, int (* func)(int a, int b));
发现其可读性较差,不简洁。这时候可用typedef 对其进行重定义类型别名。
修改后程序如下
int Add(int a, int b) { return a + b; }
int Minus(int a, int b) { return a - b; }
int Multi(int a, int b) { return a * b; }
int Divide(int a, int b) { return a / b; }
typedef int(* Func)(int, int);
int process(int a, int b, Func func)
{
return func(a, b);
}
int main()
{
int a = 20, b = 10;
int res1 = process(a, b, Add);
int res2 = process(a, b, Minus);
int res3 = process(a, b, Multi);
int res4 = process(a, b, Divide);
cout << res1 << ' ' << res2 << " " << res3 << " " << res4 << endl;
}
在 int (* func)(int a, int b)中指针func的类型是int (*)(int, int),因此用typedef关键字为该类型起一个别名。typedef int(* Func)(int, int)。将int (*)(int, int)命名为Func,这样在程序中就可以用Func代替int (*)(int, int)。