void 指針的背后藏著什么? void是什么意思( 二 )


我們可以在main函數中使用這個函數指針來指向一個具體的函數(這個具體的函數定義需要和函數指針的定義一致):
void test1(int age){    printf(test1:%dn,age);}int main(void){        // 聲明一個intFunc類型的函數指針    intFunc f1 = test1;    // 執行f1函數指針所指向的代碼區    f1(8);    return 0;}最終運行結果如下圖所示,執行函數指針f1即執行了其所指向的具體的函數:

void 指針的背后藏著什么? void是什么意思


2.2 函數指針的基本使用【void 指針的背后藏著什么? void是什么意思】這里我們通過一個小案例來對函數指針做一個基本的使用介紹 。相信大部分的C#或Java程序員都很熟悉foreach,那么我們就來模擬foreach對int數組中的值進行不同的處理 。具體體現為for循環的代碼是復用的,但是怎么處理這些數據不確定,因此把處理數據的邏輯由函數指針指定 。
void foreachNums(int *nums,int len,intFunc func){    int i;    for(i=0;i<len;i++)    {        int num = nums[i];        func(num);    }}void printNum(int num){    printf(value=https://www.mduoduo.com/baikezatan/%dn,num);}在foreachNums函數中,我們定義了一個intFunc函數指針,printNum函數是滿足intFunc定義的一個具體的函數 。
下面我們在main函數中將printNum函數作為函數指針傳遞給foreachNums函數 。
    int nums[] = { 1,5,666,23423,223 };    foreachNums(nums,sizeof(nums)/sizeof(int),printNum);最終運行的結果如下圖所示:
void 指針的背后藏著什么? void是什么意思


通過函數指針,我們可以屏蔽各種具體處理方法的不同,也就是將不確定的因素都依賴于抽象,這也是面向抽象或面向接口編程的精髓 。
三、函數指針應用案例3.1 計算任意類型的最大值(1)定義函數指針及getMax主體:
typedef int (*compareFunc)(void *data1,void *data2);// getMax 函數參數說明:// data 待比較數據數組的首地址,uniteSize單元字節個數// length:數據的長度 。{1,3,5,6}:length=4// 比較data1和data2指向的數據做比較,// 如果data1>data2,則返回正數void *getMax(void *data,int unitSize,int length,compareFunc func){    int i;    char *ptr = (char*)data;    char *max = ptr;        for(i=1;i<length;i++)    {        char *item = ptr+i*unitSize;        //到底取幾個字節進行比較是func內部的事情        if(func(item,max)>0)        {            max = item;        }    }    return max;}這里可以看到,在getMax中到底取幾個字節去比較都是由compareFunc所指向的函數去做,getMax根本不用關心 。
(2)定義符合函數指針定義的不同類型的函數:
int intDataCompare(void *data1,void *data2){    int *ptr1 = (int*)data1;    int *ptr2 = (int*)data2;    int i1=*ptr1;    int i2=*ptr2;    return i1-i2;}typedef struct _Dog{    char *name;    int age;} Dog;int dogDataCompare(void *data1,void *data2){    Dog *dog1 = (Dog*)data1;    Dog *dog2 = (Dog*)data2;    return (dog1->age)-(dog2->age);}

推薦閱讀