函数指针的使用详解

函数指针是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);

然后只需要在动态库中调用此函数,而这个函数的真实实现由应用层完成,应用层将函数地址和参数传递给动态库即可,通过这种解耦合的方法,当业务需求发生更改时,就无需再次改动动态库。

以上。

你可能感兴趣的:(c++学习)