函数指针
函数指针的概念
在描述函数指针之前,我想先讲讲函数的概念。
试想这样一种场景,你在一个程序中编写了一个函数f,并且调用了这个函数f,如果对底层比较感兴趣的同学,可能会对这个过程中程序发生了什么有着强烈的好奇心
下面从程序编译后开始说起
如果对操作系统有了解的同学,可以知道,程序是在用户进程空间中执行的,一个程序可以看作一个进程。
一个简化的进程空间模型,可以看作由代码段,数据段,堆栈三个部分组成(当然还有其余部分,但我们主要讲这三个部分)
代码段主要存储整个程序的代码部分,一般来说是只读不可修改的
数据段主要用来存储整个程序的全局变量或静态变量
堆栈用来存储程序的局部变量和用来辅助函数调用
而一个程序编译之后,我们编写的函数就被存储在代码段。
而这个函数的函数名,就相当于代码段中这个函数代码区域的首地址
比如我们编写了这样一个函数
void f(){
//process
}
函数名f的含义如图所示
函数指针的用法
函数指针的声明
下面看看某个函数的声明
int func(int n, int m);
然后看看函数指针pfunc的声明
int (*pfunc)(int n, int m);
令这个函数指针指向函数func
pfunc = &func;
因为函数名本来就表示这个函数的入口地址,所以我们也可以这样写
pfunc = func;
最后我们利用函数指针调用函数
(*pfunc)(3,4)
最终返回结果为7.
函数指针作为参数传入函数
函数指针主要的用法如下
利用函数指针,我们可以实现一个函数作为另外一个函数的参数,这样能够使得我们的函数更加灵活。
要实现一个函数作为另外一个函数的参数,我们可以将函数指针作为函数的参数,声明如下:
int getRoot(float (*f1)(int n), float (*f2)(int n),int min , int max);
该函数实现了下面一个功能,在[min-max]区间中得到令函数f1(n) >= f2(n)的最接近的整数解,并将该解返回
该函数的第一个参数即为函数指针f1,该函数指针的声明为float (*f1)(int n);
第二个参数同样为函数指针,不过多叙述
讲完了函数指针作为一个函数getRoot的参数,接下来看看函数getRoot如何调用这个函数指针所指向的函数。
int getRoot(float (*f1)(int n), float (*f2)(int n),int min , int max){
//search root of equation f1 = f2 from section (min to max)
//precondition There is an integer where f1 is greater than f2
int result = min;
while(result <= max){
if(f1(result) - f2(result) >= 0){
return result;
}
else{
result++;
}
}
return 0;
};
可以看到,我们调用其他函数使用的是这个语句if(f1(result) - f2(result) >= 0),需要调用函数指针指向的函数,只需要正常使用这个函数就行
完整程序
#include<iostream>
#include<math.h>
//function pointer
using namespace std;
int getRoot(float (*f1)(int n), float (*f2)(int n),int min , int max){
//search root of equation f1 = f2 from section (min to max)
//precondition There is an integer where f1 is greater than f2
int result = min;
while(result <= max){
if(f1(result) - f2(result) >= 0){
return result;
}
else{
result++;
}
}
return 0;
};
float f1(int n){
return n*n;
} //prototype
float f2(int n){
return n + 6;
}
int main(){
//test function pointer
//
float (*pf1)(int n) = &f1;
float (*pf2)(int n) = &f2;
//f1(n):n*n
//f2(n):n+6
int n = getRoot(pf1,pf2,0,8);
cout << n;
//result:n = 3;
}