本篇文章对指针函数、函数指针以及回调函数作详细的说明。函数指针和回调函数经常在程序编写中经常使用。

  • 指针函数

 返回指针值的函数称为指针函数。具体是指函数的返回值的类型是指针。

定义指针函数的一般形式如下:

int* pFunction(int para1, int para2)
  • 函数指针

函数指针是指向函数的指针变量。简明一点说就是:“函数指针”本身首先应是指针变量,只不过该指针变量指向的是函数。好比用一个指针指向整型变量、字符型、数组一样,只不过这里指向的是函数(实际上是函数的入口地址)。C在编译时,每个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。

函数指针的声明方法为:

返回值类型 (*指针变量名)([形参列表项]):

注意1:“返回值类型”说明函数返回类型,“(*指针变量)”中的括号不能省略,括号改变了操作符的优先级。后面的“形参列表项”表示指针变量指向的函数所带的参数列表。 

例如:

// 声明一个函数原型
int function(int para);
int (*pf)(int para);
// 将函数的入口地址赋值给指针pf
pf = function;
或使用如下方式也行:
pf = &function;

使用注意事项:

  1. 函数括号中的形参可有可无,但是形参类型必须与函数原型一致;
  2. 指向函数的指针变量没有++和--运算,用时需小心。

不过,在某些编译器中这是不能通过的。补充如下:

应该是这样的:

(1)定义函数指针类型

typedef int (*pf_t)(int);
// 函数指针变量声明、赋值
pf_t pf = function;

也就是说,赋给函数指针的函数应该和函数指针所指的函数原型保持一致。(强烈推荐)

函数指针的示例代码:

int maxFunction(int x, int y){
    return (x>y?x:y);
}
int testFunction(void){
    //声明一个函数指针变量
    int (*pf)(int, int);
    int a = 10;
    int b = 20;
    int c = 0;
    // 函数指针指向函数入口地址
    pf = maxFunction;
    c = (*pf)(a, b);    

}

更多的用法请参考如下网址

求求你,不要再纠结指针了(2)——函数指针

  • 回调函数

回调函数一个通过函数指针调用的函数。如果你把函数指针(地址)作为形参传递给另一个函数当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或在条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

简单的讲:回调函数是由别人的函数执行时调用你的函数。

以下是来自知乎作者常溪玲的解说:

你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。

在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做 触发回调事件,店员给你打电话叫做 调用回调函数,你到店里去取货叫做 响应回调事件

实现机制:

  1. 定义一个回调函数;
  2. 提供函数实现的一方在初始化的时候,将回调函数的函数指针进行登记注册;
  3. 当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。

回调函数示例代码如下:

// 回调函数
void vSumFunction(int a, int b){
    
    int c = 0;
    
    c = a + b;

    printf("Sum = %d\r\n", c);
}
// 声明函数指针
typedef void (*vSumFunction)(int a, int b);

// 调用函数
void GetCallBack(vSumFunction cb){

    // 调用回调函数
    cb(3, 4);    

}
// 函数调用
void TestCallBack(void)
{
    GetCallBack(vSumFunction);
}

回调函数使用场景:

  1. 代码重构
  2. 框架编程,并行工作。业务流程步骤。

回调函数总结:

回调与同步、异步并没有直接的联系,回调只是一种实现方式,既可以有同步回调,也可以有异步回调,还可以有事件处理回调和延迟函数回调,这些在我们工作中有很多的使用场景。所以其实并不是我们不认识回调函数,而是我们都萦绕在了这个“callback“ 这个词上,当你在一个函数中看到它是就会困惑,其实它只是一个形参名字而已

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐