函数指针有两种常用的用法,一种是作为结构体成员,另一种是函数指针作为函数的参数。这一篇分享的是函数指针作为函数的参数。

一、函数指针作为函数的参数

函数指针可以作为一个参数传递给另一个函数。这时函数指针的使用就像普通的常量和变量一样。当函数指针作为参数传递的时候,这时接收参数传递的函数通常需要根据这个指针调用这个函数。作为参数传递的函数指针通常表示回调函数(Callback Functions)

1、什么是回调函数?

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。

2、回调函数在实际中有什么作用?

先假设有这样一种情况:我们要编写一个库,它提供了某些排序算法的实现(如冒泡排序、快速排序等等),为了能让库更加通用,不想在函数中嵌入排序逻辑,而让使用者来实现相应的逻辑;或者,能让库可用于多种数据类型(int、float、string),此时,该怎么办呢?可以使用函数指针,并进行回调。

例如,在 C 语言的通用工具库 stdlib.h 中,有如下一个函数原型:

  1. void qsort(void *, size_t, size_t, int (comp*)(const void *, const void *))

这是在 C 通用工具库中声明的一个快速排序算法函数,其可以用来排序 int 类型、float 类型以及字符串数据,可以按从小到大的顺序也可以按从大到小的顺序排序。其关键在于函数指针 comp 指向的函数的具体实现。

二、举例说明

上一节我们使用函数指针作为结构体成员来实现四则运算,这里一节我们稍微修改一下代码,使用函数指针作为函数参数来实现四则运算。

设计如下函数:

  1. int calculate(int a, int b, fun_t operation)
  2. {
  3. int result;
  4. result = operation(a, b);
  5. return result;
  6. }

其中,fun_t 是一个函数指针,其定义为:

  1. typedef int (*fun_t)(int, int);

该函数指针fun_t指向一个带两个int类型的形参、int类型的返回值的函数。使用关键字typedefint (*)(int, int)进行重命名(封装)为fun_t。关于 typedef 与 define 的区别可查看往期笔记:【C 语言笔记】#define 与 typedef 的区别?

根据函数指针变量operation指向不同的运算函数可实现加法运算、减法运算、乘法运算、除法运算。

主函数代码如下:

  1. int main(void) {
  2. int result;
  3. int a = 192, b = 48;
  4. /* 两个数相加的操作 */
  5. result = calculate(a, b, add2);
  6. printf("加法运算: %d+%d = %d\n", a, b, result);
  7. /* 两个数相减的操作 */
  8. result = calculate(a, b, sub2);
  9. printf("减法运算: %d-%d = %d\n", a, b, result);
  10. /* 两个数相乘的操作 */
  11. result = calculate(a, b, mul2);
  12. printf("乘法运算: %d*%d = %d\n", a, b, result);
  13. /* 两个数相除的操作 */
  14. result = calculate(a, b, div2);
  15. printf("除法运算: %d/%d = %d\n", a, b, result);
  16. return 0;
  17. }

实现运算的 4 个函数很简单,如下:

  1. int add2(int a, int b) { return a + b; }
  2. int sub2(int a, int b) { return a - b; }
  3. int mul2(int a, int b) { return a * b; }
  4. int div2(int a, int b) { return a / b; }

程序运行结果为:

  1. 加法运算: 192+48 = 240
  2. 减法运算: 192-48 = 144
  3. 乘法运算: 192*48 = 9216
  4. 除法运算: 192/48 = 4

以上就是关于函数指针作为函数参数的笔记,如有错误欢迎指出!

所有源码如下:

  1. #include <stdio.h>
  2. typedef int (*fun_t)(int, int);
  3. int calculate(int a, int b, fun_t operation)
  4. {
  5. int result;
  6. result = operation(a, b); // 运算
  7. return result;
  8. }
  9. int add2(int a, int b) { return a + b; }
  10. int sub2(int a, int b) { return a - b; }
  11. int mul2(int a, int b) { return a * b; }
  12. int div2(int a, int b) { return a / b; }
  13. int main(void) {
  14. int result;
  15. int a = 192, b = 48;
  16. /* 两个数相加的操作 */
  17. result = calculate(a, b, add2);
  18. printf("加法运算: %d+%d = %d\n", a, b, result);
  19. /* 两个数相减的操作 */
  20. result = calculate(a, b, sub2);
  21. printf("减法运算: %d-%d = %d\n", a, b, result);
  22. /* 两个数相乘的操作 */
  23. result = calculate(a, b, mul2);
  24. printf("乘法运算: %d*%d = %d\n", a, b, result);
  25. /* 两个数相除的操作 */
  26. result = calculate(a, b, div2);
  27. printf("除法运算: %d/%d = %d\n", a, b, result);
  28. return 0;
  29. }

转自:https://cloud.tencent.com/developer/article/1451116