函數指針的使用,以及使用函數指針的好處


轉載博客,自己學習用

函數指針是指向函數的指針變量。 因而“函數指針”本身首先應是指針變量,只不過該指針變量指向函數。程序在編譯時,每一個函數都有一個入口地址,該入口地址就是函數指針所指向的地址。很多c++泛型算法以及linux庫函數經常見到函數指針的使用。。

函數指針的聲明:

bool (*pf)(int, int);
//pf指向一個函數,該函數的參數是兩個int,返回值是bool類型

函數指針的初始化

例如有這樣一個函數:bool cmp(int a, int b);
pf = cmp//注意cmp形參及返回值應與聲明的的函數指針的類型匹配

調用函數指針

bool b = pf(3,5);
等價於直接調用:bool b = cmp(3,5);

函數指針使用的好處:

單單用以上的調用的方法使用函數指針,除了使程序變得晦澀難懂別無意義。包括很多例程只是在闡明函數指針的使用方法,完全不符合函數指針的使用場合。那到底為什么還要使用函數指針呢!郁悶了很久,雖沒完全理解的很深入,還是有所收獲,總的來說,函數指針有兩個方面的應用。
(1)把指針函數當作形參傳遞給某些具有一定通用功能的模塊。並封裝成接口來提高代碼的靈活性和后期維護的便捷性。
一個經典的例子是泛型算法中的一個快速排序函數:

void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*));

參數:
1 待排序數組首地址

2 數組中待排序元素數量

3 各元素的占用空間大小

4 指向函數的指針,用於確定排序的規則
qsort設計時,底層開發者並不能確定調用者的需求,因此便采用函數指針的方法,在qsort內部通過函數指針調用傳遞過來的函數(這等同於在內部直接調用,但為了封裝成接口,供調用者使用,采用函數指針的方法更好,這種機制與形參傳遞變量類似)
這里通過比較一個比較low的冒泡排序來說明一下qsort內部函數指針的實現機制:

#include<iostream>
using namespace std;
void sort(int arr[], int size, bool(*cmp)(int,int));
bool up(int a, int b);
bool down(int a, int b);
int main()
{
    int arr[10];
    for (int i = 0;i < 10;++i)
        cin >> arr[i];

    sort(arr, 10,down);

    for (int i = 0;i < 10;++i)
        cout << arr[i] << " ";
    return 0;
}
void sort(int arr[],int size,bool(*cmp)(int,int))//簡單冒泡排序
{
    int temp;
    for (int i = 0;i < size-1; ++i)
    {
        for (int j = i;j < size-1;++j)
        {
            if (cmp(arr[i], arr[j + 1]))
            {
                temp = arr[i];
                arr[i] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}
bool up(int a, int b)
{
    if (a > b)
        return 1;
    else
        return 0;
}
bool down(int a, int b)
{
    if (a > b)
        return 0;
    else
        return 1;
}
!

調用者通過傳入相應的函數指針來決定排序的規則,這里只是一個簡單的例子,真正的函數指針的使用可以將實現同一功能的很多個模塊統一起來標識,這樣一來更容易后期的維護,系統結構更加清晰。或者歸納為:便於分層設計、利於系統抽象、降低耦合度以及使接口與實現分開
該冒泡排序的通用性是不是稍微強大了一丟丟。。。。(其實此個例程中,也可以通過一個變量來決定使用什么樣的排序規則,不過,我猜測,博大精深的庫中很多場合不是通過一個變量能解決的(僅僅猜測哈。。而且后期修改的話是不需要動sort函數框架的。。)
(2)另外,有些地方必須使用函數函數指針才能完成給定的任務,如linux系統中的異步信號中斷處理,當發生某一觸發信號時,需要調用相應的處理函數,此時需要使用函數指針來實現。

void (*signal(int signum,void(* handler)(int)))(int);  

參數一為信號條件,第二個參數為一個函數指針,它所指向的函數需要一個整型參數,無返回值。 
該函數的返回值也是一個函數指針,返回的指針所指向的函數有一個整型參數(一般不用)


---------------------
作者:Gouhailiang
來源:CSDN
原文:https://blog.csdn.net/gouhailiang/article/details/74170670
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM