1 函数指针 是指向函数的指针变量 程序在编译时 每一个函数都有一个入口地址 该入口地址就是函数指针所指向的地址
函数指针有两个用途 调用函数和做函数的参数
int fun(int x){return 0;} /// 定义一个函数
int main()
{
int(*pf)(int x);///声明一个函数指针
pf=fun;/// 将函数首地址赋给指针 pf
cout<<fun<<endl;
printf("%x\n",fun);// 返回函数地址
cout<<pf<<endl;
}
或可以使用typedef 来定义函数指针
typedef int(*PF)(int x); 定义一个函数指针类型 PF pf 声明 pf 变量 pf=fun 赋值
通过函数指针调用函数的例子
int maxone(int x,int y)
{
int z;
z=(x>y)?x:y;
return z;
}
int main()
{
int i,a,b;
int(*p)(int ,int ); ///定义函数指针
cin>>a;
p=maxone;///给函数指针 p 赋值
for(i=0;i<2;i++)
{
cin>>b;
a=(*p)(a,b);/// 通过指针P 调用函数
}
cout<<"the max number is"<<a<<endl;
return 0;
}
函数指针作为参数
#include<iostream>
#include<cmath>
using namespace std;
double romb(double(*fun)(double),double a,double b,double eps)/// fun 就是一个函数指针
{
double y[9],h,p,q,ep,s,l;
int m,n,k,i;
h=b-a;
y[0]=h*((*fun)(a)+(*fun)(b))/2;/// 用函数指针来求取 a b 点的值
m=1;
n=1;
ep=eps+1;
while(ep>=eps&&m<=9)
{
p=0;
for(i=0;i<n;i++)
{
l=a+(i+0.5)*h;
p+=(*fun)(l);
}
p=(y[0]+h*p)/2;
s=1;
for(k=1;k<m;k++)
{
s*=4;
q=(s*p-y[k-1])/(s-1);
y[k-1]=p;
p=q;
}
ep=fabs(q-y[m-1]);
m++;
y[m-1]=q;
n*=2;
h/=2;
}
return q;
}
double fx(double x)
{
return sin(x);
}
int main()
{
printf("%f\n",romb(fx,0,3.1415926,0.0001));
return 0;
}
被积函数作为积分函数的参数 也就是函数作为参数 即函数指针。
操作系统中经常会使用回调函数 callBack 函数,实际上所谓回调函数 本质上是函数指针。回调函数就是一个通过函数指针调用的函数。假如把函数指针作为参数传递给另一个函数 当这个指针被
调用时 我们就说这是回调函数
2 指针函数 是指返回值为指针的函数 即本质是一个函数
int *func(int x,int y) // 定义了一个函数 返回一个指向整型数的指针 * 号表明这是一个指针型函数 即返回值是一个指针
下例中 month 为一指针数组 数组中的每个指针指向一个字符串常量 trans 需要一个整型变量作为实参 返回一个字符型指针 再判断m是否合法 这样指针p就可以指向对应的字符串常量 变量p保存的是一个地址 函数返回该变量
#include<iostream>
#include<cmath>
using namespace std;
char *month[]={"illegal month","January","February","March","April","May","June","July"
"August","September","October","November","December"};
char *trans(int m)
{
char *p;
if(m>=1&&m<=12)
p=month[m];
else
p=month[0];
return p;
}
int main()
{
int i;
cin>>i;
cout<<trans(i)<<endl;
}
3 返回函数指针的函数
#include<iostream>
using namespace std;
int add(int x,int y)
{
int i=x+y;
return i;
}
int (*funcptr())(int ,int )
{
return add;
}
int main()
{
int(*fptr)(int,int)=funcptr();
cout<<fptr(10,10)<<endl;
return 0;
}
第二个函数funcptr 是这个函数的函数名称,里面的括号 是它本身的参数括号符 即该函数没有参数 而它前面的* 表示返回的是一个指针,后面的() 表示这是一个函数指针,并且
该函数指针所指向的函数有两个int型的参数 最前面的int 表示该函数指针所指向的函数返回值为int型 然后在main函数里面定义了一个函数指针变量fptr 接收funcptr 返回的函数指针值
之后通过 fptr 调用函数add
typedef int(*RetFunptr)(int,int) RetFunptr fptr=funcptr();
4 函数指针实现重载 c语言
#include<iostream>
using namespace std;
typedef struct int_param
{
int param1;
int param2;
}INT_PARAM;
typedef struct double_param
{
double param1;
double param2;
}DOUBLE_PARAM;
typedef void *(*ADDFUNC)(void*);
void *int_add_func(void *wparam)
{
INT_PARAM*lparam=(INT_PARAM*)wparam;
int *res=new int;
*res=lparam->param1+lparam->param2;
return (void*)res;
}
void*double_add_func(void*wparam)
{
DOUBLE_PARAM*lparam=(DOUBLE_PARAM*)wparam;
double *res=new double;
*res=lparam->param1+lparam->param2;
return (void*)res;
}
void *add_func(ADDFUNC f,void *wparam)
{
return f(wparam);
}
int main()
{
INT_PARAM val1={2,2};
DOUBLE_PARAM val2={3.3,3.3};
void *res1=add_func(int_add_func,&val1);
int result1=*((int *)res1);
cout<<result1<<endl;
void *res2=add_func(double_add_func,&val2);
double result2=*((double*)res2);
cout<<result2<<endl;
delete res1;
delete res2;
return 0;
}
结构体中 int_param 中有两个int型数据,结构体中 double_param 中有两个double 型数据 程序要求对这两个函数求和
typedef void *(*ADDFUNC)(void*);
ADDFUNC f
通过ADDFUNC定义了一个函数指针f
void *add_func(ADDFUNC f,void *wparam)
{
return f(wparam);
}
add_func 是一个返回指针的函数 有两个参数,第一个是一个函数指针,第二个是 void* 参数 调用 add_func 时 f指向了一个参数和返回值都是void *的函数
在add_func 中通过f来调用 int_add_func 和 double_add_func
void *int_add_func(void *wparam)
{
INT_PARAM*lparam=(INT_PARAM*)wparam;
int *res=new int;
*res=lparam->param1+lparam->param2;
return (void*)res;
}
void*double_add_func(void*wparam)
{
DOUBLE_PARAM*lparam=(DOUBLE_PARAM*)wparam;
double *res=new double;
*res=lparam->param1+lparam->param2;
return (void*)res;
}
这两个函数传进来的参数 分别为 int_param 和 double——param 结构体变量中的指针 对传过来的参数求和后 保存在堆区上创建的res中 之后将res 返回
在main函数中 res1 res2 分别接收 int_add_func 和 double_add_func 返回的指针 在程序结束时 delete 释放堆上的内存
原文:https://www.cnblogs.com/guoyu1024/p/9029293.html