函数指针和指针函数

函数指针

一、基本内容

   函数指针是指向函数的指针变量 .

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

posted on 2012-07-21 16:36  as_  阅读(1409)  评论(0编辑  收藏  举报

导航