函數指針

函數指針

函數與數據項類似,也有地址,函數的地址是存儲其機器語言代碼的內存的開始地址。函數的地址,可通過函數名來獲取。對於一個函數:

bool isEven(int n),

那麼,該函數的地址就是isEven。而聲明指向該函數的指針時,必需表現出與指定函數的返回類型以及函數的參數類型,對於上面的函數,其指針類型應該是:

bool (*func)(int);

其中func是指向函數的指針,bool表明func指向函數的返回值,(int)表明func指向函數的參數型。

因此:

bool isEven(int n);

bool (*func)(int);

func=isEven;

其中func是函數的指針,(*func)就是函數isEven(),所以isEven(4)和(*func)(4)是一樣的。


下面是一個應用函數指針的例子:

下面函數實現的功能是對一個給定數組進行重新排序,保證所有奇數都在數組的前部,所有偶數都在數組的後部

#include <iostream>
//判斷n是否爲奇數,如果是奇數返回0,不是奇數返回1
bool isEven(int n)
{
    return (n & 1) == 0;
}
<span style="font-size:18px;">//對數組pData中的數據進行重新排序,保證所有奇數都在數組前部,所有偶數都在數組的後部,</span><span style="font-family: Helvetica; -webkit-text-stroke-width: initial;"><span style="font-size:14px;">length是數組的長度,</span></span>
<span style="font-size:18px;">//函數Reorder的第三個參數是一</span><span style="font-family: Helvetica; -webkit-text-stroke-width: initial;"><span style="font-size:14px;">個函數指針形式</span></span>
<span style="font-size:18px;">void Reorder(int *pData, unsigned int length, bool (*func)(int))
{
    if(pData == NULL || length == 0)
        return;
    
    int *pBegin = pData;//指向數組第一個元素
    int *pEnd = pData + length - 1;//指向數組最後一個元素
    
    while(pBegin < pEnd)
    {
        //  判斷指針pBegin所指向的數的奇偶性,若爲奇數,則將pBegin向後移動,直到指向一個偶數
        while(pBegin < pEnd && !(*func)(*pBegin))
            pBegin ++;
        
        // </span><span style="font-size:14px;"><span style="font-family: Helvetica; -webkit-text-stroke-width: initial;">判斷指針pEnd所指向的數的奇偶性,若爲偶數,則將pEnd向前移動,直到指向一個奇數</span>
</span><span style="font-size:18px;">
        while(pBegin < pEnd && (*func)(*pEnd))
            pEnd --;
        </span>
<span style="font-size:18px;"><span style="white-space:pre">	</span>//將pBegin所指向的偶數和pEnd所指向的奇數互換位置
        if(pBegin < pEnd)
        {
            int temp = *pBegin;
            *pBegin = *pEnd;
            *pEnd = temp;
        }
    }
}


void ReorderOddEven_2(int *pData, unsigned int length)
{
    Reorder(pData, length, isEven);//調用Reorder函數,注意第三個參數isEven是函數指針,指向isEven()函數
}



int main(int argc, const char * argv[]) {
    
    int a[]={2,1,4,3,7,8,5};
    ReorderOddEven_2(a,7);
    for (int i=0; i<7; i++) {
        std::cout<<"a["<<i<<"]="<<a[i]<<std::endl;
    }
    
    
    return 0;
}
</span>

運行結果:a[]={5,1,7,3,4,8,2,0};


用函數指針作爲參數的好處是,可以很方便的對上述函數功能進行擴展,比如上面要求的是對數組中元素進行重排,保證奇數在偶數前面,這時候,我們用函數isEven()進行判斷;那麼當改變要求時,比如讓所有正數在前負數在後、讓能被三整除的數在前,不能被三整除的數在後;那麼上面函數的主體並不用改變,只要在添加額外判定函數new(),並讓

<span style="font-size:18px;"> Reorder(pData, length, new);</span>
就可以了。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章