笨蛋C++07 - 函数指针

130 阅读3分钟

函数指针

如果未提到函数指针。则对C或者C++函数的讨论都是不完整的。我们将大致介绍一下这个主题。

与数据项相似。函数也有地址。函数的地址是存储其机器语言代码的内存的开始地址。通常,这些地址对用户而言。既不重要。也没有什么用处。但是对于程序而言。却很有用。比如:可以编写将另外一个函数的地址作为参数的函数。这样第一个函数将能够找到第二个函数,并且运行他。与直接调用另外一个函数相比。这种方法很笨拙。但是他允许在不同的时间传递不同的函数地址。这就意味着可以在不同的时间使用不同的函数。

函数指针的基础知识

首先通过一个例子来阐释这一个过程。假设要设计一个名为estimate()的函数。估算编写指定行数代码所需要的时间。并且希望不同的程序员都能够使用该函数。对于所有的用户来说。estimate()中的一部分代码都是相同的。但是该函数允许每一个程序员提供自己的算法来估算时间。为了实现这种目标。采用的机制是,将程序员使用的算法函数的地址传递给estimate()。为此,必须能够完成下面的工作:

  • 获取函数指针
  • 声明一个函数指针
  • 使用函数指针来调用函数

获取函数的地址

获取函数的地址很简单。只要使用函数名,后面不带有参数就好了。也就是说,如果think是一个函数,那么think就是这个函数的地址。要将函数名作为参数进行传递。必须传递函数名。一定要区分传递的是函数的地址还是函数的值

process(think) //address
process(think()) //return value of think to thought

声明函数的指针

声明某种数据类型的指针时。必须指定指针指向的类型。同样,声明指向函数的指针时。也必须指定指针指向的函数类型。这意味着声明应该指定函数的返回类型。以及函数的特征标志。也就是说,声明应该像函数原型那样指出有关函数的信息。比如:

  • 定义函数
double pam(int); //prototype
  • 定义函数指针
double pam(int);
double (*pf)(int);
pf=pam; // pf指向pam

pam()的特征标识和返回类型必须与pf相同。如果不相同,编译器将拒绝这种赋值。

使用指针来调用函数

现在进入最后一步,就是使用指针来调用被指向的函数。线索来自指针声明,前面讲过:(*pf)扮演的角色与函数名相同的时候。因此使用(*pf)的时候,只要把它看作函数名就可以了。

double pam(int);
double (*pt)(int);
pf=pam;
double x=pam(4);
double y=(*pf)(5);

实际上,C++也允许使用函数名那样使用pf;

double y=pf(5);

第一种格式虽然不好看,但是代码给出了强有力的提示---代码正在使用函数指针。