【C++之函数指针】

【C++之函数指针】

首先了解一下基础知识:
学习过C语言之后我们知道,函数是C语言的基本组成单位。函数其实也有他自己 的地址,函数的地址存储在机器语言的内存的开始地址,使用cout来输出它的地址。
如果一个函数是doSomething(),那么doSomething就是函数的地址。

函数指针的申明:

方法一:声明与初始化分开
double c_Perimeter(double radius);
double (*pf)(double );
pf = c_Perimeter;

方法二:声明的同时进行初始化
double c_Perimeter(double radius);
double (*pf)(double ) = c_Perimeter;

可以看出相较与原函数:
1、函数指针的返回值类型没有发生改变;
2、形参的类型没有发生改变,但是省略形参的值;
3、c_Perimeter替换成了(*pf),这个括号不能省略,因为 () 的优先级高于 * 的优先级,将函数地址赋值给pf,这样pf就是一个函数指针了,有些类似于普通指针和普通变量之间的地址赋值关系。
注意:pf的特征标(形参)和返回值必须和原函数相同。

函数指针的实现:

#include <iostream>
#include <cmath>
using namespace std;

const double PI = 3.14159;

double c_Perimeter(double radius){
	double perimeter = 2 * PI * radius;
	cout <<"source value Address: "<< &perimeter << endl;
	return perimeter;
}


double c_Area(double radius){
	double area = PI * pow(radius, 2);
	cout <<"source value Address: "<< &area << endl;
	return area;
}

void calculate(double r, double(*pf)(double))
{
	double a = (*pf)(r);
	cout << "address: " << &a << endl;        //输出返回值的地址
	cout << "value: " << a << endl;           //输出了返回值
	cout << "address: " << pf << endl;        //验证pf是函数的地址
	cout << "value: " << (*pf)(r) << endl<<endl;    //输出了返回值
}

int main(void)
{
	cout << "address of c_Perimeter :" << c_Perimeter << endl;            //c_Perimeter 函数地址在
	cout << "address of calculate   :"  << calculate << endl <<endl;       //calculate函数地址
	calculate(1.0, c_Perimeter);
	calculate(1.0, c_Area);
	cin.get();
	return 0;
}

运行的结果
在这里插入图片描述

仔细的阅读上面的代码,读者应该可以收获很多:
1、首先我们输出了两个函数的地址,确认我们上面说的函数也有它自己的地址。
2、通过函数指针我们,我们也可以看出局部变量的生存期,在c_Perimeter函数中perimeter的地址为0x012FF6D4,然而接收变量的地址为:0x012FF7C4,原因是perimeter这个变量在返回时,拷贝了一个相同的临时变量到内存中,而c_Perimeter函数结束后perimeter就被释放掉了,a由内存中的临时变量拷贝过来,所以变量的地址已经发生了改变。
3、我们输出了函数指针的地址,与对应的函数地址是一样的,原因是pf = c_Perimeter;它们本身就是同一个人,哈哈。

#include <iostream>
#include <cmath>
using namespace std;

const double PI = 3.14159;

double* fun1(double a[], int x){
	cout << "source address :" << &a[x] << endl;
	return &a[x];
}


double* fun2(double a[], int x){
	cout <<"source address :"<< &a[x] << endl;
	return &a[x];
}

void calculate(double *arr, int x, double* (*pf)(double*, int))
{
	cout << "address: " << (*pf)(arr, x) << endl;
	cout << "value: " << *(*pf)(arr, x) << endl<<endl;
}

int main(void)
{
	double  arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	calculate(arr, 5, fun1);
	calculate(arr, 4, fun2);
	cin.get();
	return 0;
}

运行结果:
在这里插入图片描述
为了提高可读性,这里省略了数组的越界等可能存在的出错,相比较于前面的一段代码,我们在这里使用了指针。

这两部分的代码的重点在于如何通过函数指针来得到返回值和返回值的地址。

函数指针数组

在函数返回值参数类型都相同的情况下,若要对每一个函数执行,我们可以采用函数指针数组。
<返回值类型> (<指针名称>[<数组长度>])(<参数类型>);
例如:
double
(pf[3])(double) ;

#include <iostream>
#include <cmath>
using namespace std;

const double* f1(double* arr){
	return arr;
}

const double* f2(double arr[]){
	return arr+1;
}

const double* f3(double arr[]){
	return arr+2;
}

int main(void)
{
	double arr[3] = { 1, 2, 3 };
	const double* (*pf[3])(double*) = { f1, f2, f3 };
	cout << "原函数的地址:" << endl;
	cout << "address of f1 : " << f1 << endl;
	cout << "address of f2 : " << f2 << endl;
	cout << "address of f3 : " << f3 << endl << endl;
	for (int i = 0; i < 3; i++)
	{
		cout << "function address :" << pf[i] << endl;
		cout << "value address :" << pf[i](arr) << endl;
		cout << "value address :" << (*pf[i])(arr) << endl;
		cout << "value:" << *(*pf[i])(arr) << endl ;
		cout << "value:" << *pf[i](arr) << endl << endl;
	}
	cin.get();
	return 0;
}

运行结果:
在这里插入图片描述
解读以上的代码,我们简单的实现了函数指针数组,首先我们输出了函数本身的地址,大家可以探讨一下,为什么最后面输出值和地址有两种形式,哈哈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值