函數指針的使用詳解

函數指針是C++中經常用到的指針類型,對業務解耦合有着重要的意義,學習函數指針,首先應該學習數組類型,兩者在定義上大同小異,所以,先來回顧一下數組類型的用法吧!

1 數組類型

數組類型的使用主要涉及三個定義:

  1. 如何定義一個數組類型
  2. 如何定義一個數組指針類型
  3. 如何定義一個指向數組類型的指針變量

我在代碼中詳細註釋了數組類型、數組指針類型以及指向數組類型的指針變量的定義方法,如下:

#include <stdio.h>
#include <string.h>
#include "stdlib.h"

int main()
{
    //定義一個數組 int array[10]
    //定義一個數組類型
    typedef int (MyArrayType)[10];
    //用這個類型定義一個變量
    MyArrayType array0;//相當於 int array[10];
    array0[0] = 2;

    //定義一個數組指針類型
    int array1[10];
    typedef int (*PMyArrayType)[10];
    PMyArrayType pmyArray;
    pmyArray = &array1;
    (*pmyArray)[0] = 3;


    //定義一個指向數組類型的指針變量
    int array2[10];
    int (*pMyArray)[10]; //告訴編譯器分配四個字節的內存
    pMyArray = &array2;
    (*pMyArray)[0] = 4;

    //打印結果
    printf("數組類型輸出:%d\n", array0[0]);
    printf("數組指針類型輸出:%d\n", array1[0]);
    printf("指向數組類型指針變量輸出:%d\n", array2[0]);

    return 0;
}

輸出結果如下圖:
在這裏插入圖片描述

2 函數指針

同數組類型相似,函數指針也是三個定義:

  1. 如何定義一個函數類型
  2. 如何定義一個函數指針類型
  3. 如何定義一個指向函數的指針變量

同上,代碼中詳細註釋了這三種定義方法及它們的使用方法,如下:

#include <stdio.h>
#include <string.h>
#include "stdlib.h"

//test是函數名,函數名是函數首地址,函數名就是函數指針
//對函數地址取多少次地址結果都還是函數地址
int test(int a)
{
    printf("a=%d\n",a);
    return 0;
}
int main()
{
    //定義一個函數類型
    typedef int (MyFuncType)(int);
    MyFuncType *myfunc = test;
    printf("輸出函數類型:");
    (*myfunc)(2);
    //定義函數指針類型
    typedef int (*PMyFuncType)(int);
    PMyFuncType pmyFunc = test;
    printf("輸出函數指針類型:");
    (*pmyFunc)(3);
    //定義一個指向函數的指針變量
    int (*PmyFunc)(int); //告訴編譯器分配四個字節
    PmyFunc = test;
    printf("輸出指向函數指針類型指針變量:");
    (*PmyFunc)(4);

    return 0;
}

輸出結果如下圖:
在這裏插入圖片描述

3 函數指針作函數參數

函數指針作函數參數是函數指針最重要的使用,通過一段代碼來學習,如下:

#include <stdio.h>
#include <string.h>
#include "stdlib.h"

int add(int a, int b)
{
    int c;
    c = a + b;
    return c;
}

int MyPrint(int (*pMyAdd)(int,int))
{
    printf("函數指針作函數參數:%d\n", pMyAdd(2,3));
}

//聲明一個函數指針類型
//函數指針作函數參數不光把函數的入口地址給了被調函數,同時作了接口的約定
typedef int (*PMyFuncType)(int,int);
int MyPrint1(PMyFuncType pMyFunc)
{
    printf("函數指針作函數參數:%d\n", pMyFunc(7,8));
}
int main()
{
    //定義一個函數指針變量
    int (*pAdd)(int,int);
    pAdd = add;
    //MyPrint方法
    MyPrint(pAdd);
    //MyPrint1方法
    MyPrint1(pAdd);
    return 0;
}

輸出結果如下圖:
在這裏插入圖片描述
函數指針作函數參數最重要的目的就是解耦合,即將寫任務和調用任務的人分開,它的使用一般有兩種情況,稱爲函數指針的正反向調用。

  1. 正向調用:應用程序EXE調用動態庫
  2. 反向調用:動態庫反向調用應用程序,在動態庫中通過函數指針實現業務模型的抽象

以動態庫爲例重點說明一下反向調用的使用方法,主要分爲兩步:

  1. 動態庫提前定義業務模型接口
  2. 提前把應用層的函數入口地址注入到動態庫

比如在動態庫中抽象一個加密模型,如下:

typedef int (*EncData)(unsigned char *inData, int inDataLen, unsigned char *outData, int outDataLen, void *Ref, int RefLen);

然後只需要在動態庫中調用此函數,而這個函數的真實實現由應用層完成,應用層將函數地址和參數傳遞給動態庫即可,通過這種解耦合的方法,當業務需求發生更改時,就無需再次改動動態庫。

以上。

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