zoukankan      html  css  js  c++  java
  • 函数指针和指针函数

    函数指针

    一、基本内容

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

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

  • 相关阅读:
    iphone开发之iphone解析xml&json1
    php中mb_convert_encoding 和 iconv 的区别
    Xcode开发 字符串用法
    iphone tableView的使用(zz)
    今天你抛弃了ASP.NET了吗?问题篇
    用代码初始化ViewController的View
    xcode 4.3 调试的时候显示汇编,怎么办?
    Show image from SQL image field
    provider: SQL 网络接口, error: 26 定位指定的服务器/实例时出错
    Dymanic Add Section For WebConfig
  • 原文地址:https://www.cnblogs.com/biyeymyhjob/p/2602434.html
Copyright © 2011-2022 走看看