一、基本内容
函数指针是指向函数的指针变量。
因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上一致的。函数指针有两个用途:调用函数和做函数的参数。函数指针的说明方法为:
函数类型(指针变量名)(形参列表);
说明:
1. “函数类型”说明函数的返回类型,由于“()”的优先级高于“*”,所以指针变量名外的括号必不可少,后面的“形参列表”表示指针变量指向的函数所带的参数列表。例
int func(int x); /* 声明一个函数 */
int (*f) (int x); /* 声明一个函数指针 */
f=func; /* 将func函数的首地址赋给指针f */
赋值时函数func不带括号,也不带参数,由于func代表函数的首地址,因此经过赋值以后,指针f就指向函数func(x)的代码的首地址。
2. 函数括号中的形参可有可无,视情况而定 下面的程序说明了函数指针调用函数的方法:
#include<stdio.h>
int max(int x, int y)
{
return ((x > y) ? x : y);
}
void main()
{
int (*ptr)(int, int);
int a;
int b;
int c;
ptr = max;
scanf("%d, %d", &a, &b);
c = (*ptr)(a, b);
printf("a = %d, b = %d,max = %d", a, b, c);
}
ptr是指向函数的指针变量,所以可把函数max()赋给ptr作为ptr的值,即把max()的入口地址赋给ptr,以后就可以用ptr来调用该函数,实际上ptr和max都指向同一个入口地址,不同就是ptr是一个指针变量,不像函数名称那样是死的,它可以指向任何函数,就看你想怎么做了。在程序中把哪个函数的地址赋给它,它就指向哪个函数。而后用指针变量调用它,因此可以先后指向不同的函数,不过注意,指向函数的指针变量没有++和--运算,用时要小心,下面举例说明函数指针的灵活应用:
#include <stdio.h>
void filefunc()
{
printf("FileFunc\n");
}
void editfunc()
{
printf("EditFunc\n");
}
void main()
{
void (*funcp)();
funcp = filefunc;
(*funcp)();
funcp = editfunc;
(*funcp)();
}
二、应用
1.函数回调
函数指针通常用来实现回调,其基本用法如下:
1). 定义函数指针类型
// 定义一个原型为int Fun( int a )的函数指针
typedef int (*PTRFUN) ( int aPara );
2). 函数指针作为函数的参数传递
int CallBack( int a ) //定义回调函数
{
return ++a;
}
void Caller( PTRFUN cb ) // 定义回调者函数 void Caller( int (*cb) ( int ) ) 也可这样申明
{ //这里面对形参就可以传不同函数,实现回调函数的灵活应用
int nPara = 1;
int nRet = cb( nPara );
printf("nRet=%d\n",nRet);
}
void Test() // 使用回调
{
Caller( CallBack ); // 直接使用回调函数
PTRFUN cb = CallBack; // int (*cb) ( int ); cb = CallBack;
int nRet1 = cb( 99 ); // nRet1 = 100;
}
2.函数指针的指针使用 这里仅给出代码示例
typedef int (**PTRFUN) ( int aPara ); // 定义函数指针的指针
void PtrCaller( PTRPTRFUN cb ) // 函数指针的指针作为参数
{
int nRet = (*cb)(999); // nRet = 1000;
}
// void PtrCaller( PTRFUN* cb ) 指针申明
// void PtrCaller( int (**cb) ( int ) ) 原型申明
void Test()
{ // 使用函数指针的指针
PTRFUN cb = CallBack; //CallBack同前
PtrCaller( &cb );
}
3.函数指针数组的使用
PTRFUN fArray[10]; // 函数指针数组的定义
// int (*fArray[10]) ( int ); 原型定义
for ( int i = 0; i < 10; i++ ){
fArray[i] = CallBack; //CallBack同前
int nRet = fArray[i](i); // nRet = i+1;
}
4.在C++中函数指针的使用
代码示例
/typedef 返回类型(类名::*新类型)(参数表)
class CA
{
public:
char lcFun(int a){ return; }
};
CA ca;
typedef char (CA::*PTRFUN)(int);
PTRFUN pFun;
void main()
{
pFun = CA::lcFun;
ca.(*pFun)(2);
}
在这里,指针的定义与使用都加上了“类限制”或“对象”,用来指明指针指向的函数是那个类的这里的类对象也可以是使用new得到的。比如:
CA *pca = new CA;
pca->(*pFun)(2);
delete pca;
而且这个类对象指针可以是类内部成员变量,你甚至可以使用this指针。比如:
PTRFUN m_pfun;
void CA::lcFun2()
{
(this->*m_pFun)(2);
}
一句话,使用类成员函数指针必须有“->*”或“.*”的调用。
指针函数
指针函数是指函数的返回值类型是一个指针类型,即本质是一个函数。
我们知道函数都有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。其定义格式如下所示:
返回类型标识符 *函数名称(形式参数表)
{ 函数体 }
返回类型可以是任何基本类型和复合类型。返回指针的函数的用途十分广泛。事实上,每一个函数,即使它不带有返回某种类型的指针,它本身都有一个入口地址,该地址相当于一个指针。比如函数返回一个整型值,实际上也相当于返回一个指针变量的值,不过这时的变量是函数本身而已,而整个函数相当于一个“变量”。例如下面一个返回指针函数的例子:
#include<iostream>
using namespace std;
void main()
{
float *find(float(*pionter)[4],int n);
static float score[][4]={{60,70,80,90},{56,89,34,45},{34,23,56,45}};
float *p;
int i,m;
cout<<"Enter the number to be found:";
cin>>m;
p=find(score,m);
for(i=0;i<4;i++)
cout<<" "<<*(p+i);
}
float *find(float(*pionter)[4],int n) /*定义指针函数*/
{
float *pt;
pt=*(pionter+n);
return(pt);
}
PS:指针函数和函数指针的区别
这两个概念都是简称,指针函数是指带指针的函数,即本质是一个函数。我们知道函数都又有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。函数指针是指向函数的指针变量,因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。