函数指针
一、基本内容
函数指针是指向函数的指针变量 .
因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,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,b,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 (**PTRPTRFUN) ( 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:指针函数和函数指针的区别
这两个概念都是简称,指针函数是指带指针的函数,即本质是一个函数。我们知道函数都又有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。函数指针是指向函数的指针变量,因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。