结论
对于一个已经定义的函数,函数名、函数地址、函数指针所指对象指向的都是函数的入口地址。
证明
先定义以下函数:
/**********************************************************
* 函数:FuncPointer
* 描述:证明函数指针与函数名关系
* 参数:无
* 返回:无
* 备注:
**********************************************************/
void FuncPointer(void)
{
cout << "调用FuncPointer函数" << endl;
cout << FuncPointer << endl;//输出函数名
cout << &FuncPointer << endl;//输出函数地址
cout << *&FuncPointer << endl;//输出函数地址指向对象
}
在main函数中:
int main()
{
FuncPointer();//函数名调用
(&FuncPointer)();//地址方式调用
(*&FuncPointer)();//间址方式调用(函数地址指向对象)
}
执行结果:
可以看出函数名、函数指针、函数指针指向对象的值相等,指向同一个入口地址值,通过这三种方式都可以调用函数。
函数指针的运用
通过上面可知,可以通过函数指针的形式调用函数,故如果函数地址值赋给一个指针变量,则可通过这个指针变量调用这个函数。那么问题来了,这个指针的类型如何定义?要把函数地址赋给这个指针变量,那么这个指针变量关联的类型必须和函数指针关联的类型一样。所以必须要先了解一下函数的类型。
函数类型
- 函数定义:类型 函数名(形式参数表);函数由三部分组成:(1)类型是函数的返回值类型,(2)函数名是调用函数的地址入口,(3)形式参数表传入函数需要的外部参数。当两个函数的(1)和(3)相同时,我们称这两个函数是同一类型的函数。如下两个函数f1和f2是同类型的函数。
float f1(float x)
{
return (4 / (1 + x * x));
}
float f2(float x)
{
return ((float)sqrt(1 + pow(x, 2)));
}
- 用typedef定义函数类型:typedef 类型 函数类型名 (函数参数表)
typedef float IntegralFunction(float x);
- 使用已定义的函数类型声明函数或者定义变量
IntegralFunction f1, f2;//声明f1,f2
- 函数指针定义
(1)函数类型 * 指针变量名;
(2)类型 (* 指针变量名)(形式参数表);
例如用以上定义的函数类型声明一个函数指针:
(1)IntegralFunction *p;
(2)float (*p)(float);
使用(2)定义指针变量是应该注意 *p两边的括号不能少,如果少了括号,变成float *p(float),p就变成了一个返回类型为 int * 的函数了。
函数指针的运用:
float f1(float x)
{
return (4 / (1 + x * x));
}
float f2(float x)
{
return ((float)sqrt(1 + pow(x, 2)));
}
/**********************************************************
* 函数:ComputeIntegral
* 描述:求定积分
* 参数:*func - 原函数地址
a - 积分下限
b - 积分上限
* 返回:积分结果
* 备注:
**********************************************************/
float ComputeIntegral(IntegralFunction *func, float a, float b)
{
const int EdValue = 1000;
int n = (int)((float)EdValue * (b - a));
int i;
float Tn,h;
h = (b - a) / n;
Tn = (h * (func(a) + func(b))) / 2;
for (i = 1; i < n; i++)
{
Tn += h * func(a + i * h);
}
return Tn;
}
/**************求函数积分***************/
typedef float IntegralFunction(float x);
IntegralFunction f1, f2;//声明f1,f2
float ComputeIntegral(IntegralFunction* func, float a, float b);
ComputeIntegral 函数是计算定积分大小,其中传入的函数指针*func方便同一类型的不同函数传入,计算不同的函数的定积分只需修改传入的函数指针即可。如下调用ComputeIntegral 函数,计算f1在0-1的定积分大小。
int main()
{
float a,b,result;
cout << "计算定积分" << endl;
cout << "输入积分下限" << endl;
cin >> a ;
cout << "输入积分上限" << endl;
cin >> b ;
result = ComputeIntegral(f1,a,b);
cout << "定积分的值:" << result << endl;
}
运行结果:
有了函数指针,可以将函数的地址作为一个函数参数传入其他的函数。这个函数可以通过传入的函数指针调用传入的函数以实现特定的功能。