现在的位置: 首页 > 综合 > 正文

函数指针(C++)

2017年11月21日 ⁄ 综合 ⁄ 共 2590字 ⁄ 字号 评论关闭

      函数指针就像是一个指针是该变量地址类似,只不过指向的变量变为指向的是函数。

      由于 int  nArray[10]实际就是一个指针指向一个具有10个int的数组。当我们解引用这个指针时,通过*(nArray + index) 或者nArray[index]。

      其实这个我们经常用到,数组名就是一个地址,也就是一个指针:nArray = int * nArray。 nArray[1] = *(nArray + 1)。

      于是基于数组名是一个地址的思想,那么函数名是否是一个入口地址呢?

       int  foo(); foo实际也是一个指向函数的指针,当函数被调用时(通过()操作符),函数指针被解引用。

      1.        int (*fPoo)() 与 int *fPoo()的区别

      由于优先级,int(*fPoo)() 可描述为:fPoo是一个指针,该指针指向一个函数,这个函数无参数,返回值为一个整型。而 int *fPoo()则可描述为:fPoo是一个函数,这个函数无参数,返回值为一个指向整型的指针。由此可以看出在int (*fPoo)() 中 fPoo “指向”任何函数只要能匹配(返回值,参数等)都可以。

      2.      ( a pointer to a function) 两个基本的情形。

     (1) 将函数赋给一个指向函数的指针。

                

#include <iostream>
using namespace std;

inline int foo(int nX){ return nX; }

inline void foo() { cout << "function pointer foo" << endl; }
inline void goo() { cout << "function pointer goo" << endl; }


int main()
{
    int (*pFoo)(int) = foo;
    void (*pFun)() = foo;   // pFoo 指向 foo
    pFun();
    pFun = goo;            // pFoo 现在指向 foo
    pFun();
    cout << pFoo(6);
    return 0;
}

由上面的代码写的很清楚,当然函数指针的使用要参数和返回类型进行匹配。

运行结果:

function pointer foo

function pointer goo

6

(2)  使用函数指针进行函数的调用。上面的代码也能说明这个情况就是通过函数指针进行的调用。

     当然这里的调用方式不唯一,这种是隐式的调用,pFoo(6);这种调用看似就像普通函数调用一样。

还有一种是显示调用, (*pFoo)(6);

3 为什么要使用一个指针指向函数。

      具体的应用需要具体的实现,需要看是否使用这种方法是比较不错的方法,举个例子:这个实例是在以前的一本书上看到过,类似的思想就是:当你在写一个函数执行一个任务时,例如排序,但是你想调用者自定义实现的任务的一部分(排序是升序或降序,也可先排奇数后排偶数等)

实例如下:

#include <iostream>
#include <algorithm>  // for swap

using namespace std;

template <class T>
void SelectSort(T *nArray, const int nSize, bool (*pCompare)(T, T));

template <class T>
bool Ascending(T nX, T nY);

template <class T>
bool Descending(T nX , T nY);

template <class T>
void PrintArray(T *nArray, const int nIndex);

int main()
{
    const int NUM = 6;
    float anArray[NUM] = { 23.2, 523.2, 224.15, 10.1, 262.6, -562.5 };

    SelectSort(anArray, NUM, Descending);
    cout << "Descending: " << endl;
    PrintArray(anArray, NUM);

    SelectSort(anArray, NUM, Ascending);
    cout << "Ascending: " << endl;
    PrintArray(anArray, NUM);

    return 0;
}

template <class T>
bool Descending(T nX , T nY)
{
    return nX > nY;
}

template <class T>
bool Ascending(T nX, T nY)
{
    return nX < nY;
}

template <class T>
void PrintArray(T *nArray, const int nIndex)
{
    for (int i = 0; i < nIndex; ++i)
        cout << nArray[i] << "\t";
    cout << endl;
}


template <class T>
void SelectSort(T *nArray, const int nSize, bool (*pCompare)(T, T))
{
    int i, j, nIndex;
    for (i = 0; i < nSize; ++i)
    {
        nIndex = i;
        for (j = i + 1; j < nSize; ++j)
        {
            if (pCompare(nArray[j], nArray[nIndex]))
                nIndex = j;
        }
        swap(nArray[i], nArray[nIndex]);
    }
}

运行结果: 正确(略)

当然这里不只是可以灵活实现升序和降序排,可以根据实际需要进行排序,通过此实例可以看出函数指针使得代码的reuse能力大大提高。

4. 函数指针与typedef

    函数指针的形式,让我们一看就不是很习惯特别是刚开始使用指针的人,从而,使用typedef定义新类型,使得函数指针如同普通变量一样。

    typedef    bool (*pFunTest)  (int   nX);

   解释:定义一个新类型:pFunTest, 这种类型就是指向函数的指针,而函数是带有一个形参和返回值为bool

   有两种方式使用它:

   (1)

          bool Ok(int   nX,   int    nY,    bool (*pFun) (int   nX)) ;         //  有点难看

   (2)

         bool Ok(int    nX, int  nY, pFunTest  pFun);                 //   nice !! !就像普通变量一样

以上属个人愚见,也是对函数指针的总结,难免有不足之处或理解不到位的地方。

  





抱歉!评论已关闭.