C语言 函数指针 | 作为函数参数 作为结构体成员

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

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

函数指针可以作为一个参数传递给另一个函数。这时函数指针的使用就像普通的常量和变量一样。当函数指针作为参数传递的时候,这时接收参数传递的函数通常需要根据这个指针调用这个函数。作为参数传递的函数指针通常表示回调函数(Callback Functions)。
回调函数已在之前一篇文章中有所介绍,下面我再举其他例子进行介绍。

什么是回调函数

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

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

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

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

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

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

举例说明

使用函数指针作为函数参数来实现四则运算。

设计如下函数:

int calculate(int a, int b, fun_t operation)
{
     
 int result;
 result = operation(a, b); // 运算
 return result;
}

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

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

该函数指针fun_t指向一个带两个int类型的形参、int类型的返回值的函数。使用关键字typedef对int (*)(int, int)进行重命名(封装)为fun_t。关于typedef与define的区别可百度。

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

主函数代码如下:

int main(void)
{
     
 int result;
 int a = 192, b = 48;

 /* 两个数相加的操作 */
 result = calculate(a, b, add2);
 printf("加法运算: %d+%d = %d\n",a, b, result);
 
 /* 两个数相减的操作 */
 result = calculate(a, b, sub2);
 printf("减法运算: %d-%d = %d\n",a, b, result);
 
 /* 两个数相乘的操作 */
 result = calculate(a, b, mul2);
 printf("乘法运算: %d*%d = %d\n",a, b, result);
 
 /* 两个数相除的操作 */
 result = calculate(a, b, div2);
 printf("除法运算: %d/%d = %d\n",a, b, result);
 
 return 0;
}

实现运算的4个函数很简单,如下:
int add2(int a, int b)
{
     
 return a+b;
}

int sub2(int a, int b)
{
     
 return a-b;
}

int mul2(int a, int b)
{
     
 return a*b;
}

int div2(int a, int b)
{
     
 return a/b;
}

程序运行结果为:
C语言 函数指针 | 作为函数参数 作为结构体成员_第1张图片

2、函数指针作为结构体成员

函数指针在C语言中的意义

在C语言程序中,数据结构和算法是两个基本的元素。C语言的基本数据类型、结构体、数组和联合体是数据结构的代表;C语言中的函数则是算法的代表。只有将数据结构和算法有机结合才能构成具有一定功能的程序。

函数指针的应用

函数指针在嵌入式中的应用非常广泛,常常把函数指针作为结构体的成员、作为函数的参数等。如在物联网操作系统RT-Thread内核源码中,有如下代码:
1、函数指针作为结构体成员
C语言 函数指针 | 作为函数参数 作为结构体成员_第2张图片
2、函数指针作为函数的参数
C语言 函数指针 | 作为函数参数 作为结构体成员_第3张图片

举例说明

建立一个结构体,用于四则运算(根据函数指针的指向可以选择加法运算、减法运算、乘法运算、除法运算),如

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

// 包含了数据和算法的结构体
struct Source
{
     
 int a;        // 数据a
 int b;        // 数据b
 fun_t operation;  // 算法operation
};

主函数内可以进行如下操作:

struct Source data;
int result;
data.a = 200;
data.b = 100;
/* 两个数相加的操作 */
data.operation = add2;  
result = data.operation(data.a, data.b);
printf("加法运算: %d+%d = %d\n",data.a, data.b, result);

函数指针data.operation指向加法函数add2,则调用data.operation就可以进行加法运算。同理,有:
/* 两个数相减的操作 */
data.operation = sub2;
result = data.operation(data.a, data.b);
printf("减法运算: %d-%d = %d\n",data.a, data.b, result);
 
/* 两个数相乘的操作 */
data.operation = mul2;
result = data.operation(data.a, data.b);
printf("乘法运算: %d*%d = %d\n",data.a, data.b, result);
 
/* 两个数相除的操作 */
data.operation = div2;
result = data.operation(data.a, data.b);
printf("除法运算: %d/%d = %d\n",data.a, data.b, result);

运行结果:

C语言 函数指针 | 作为函数参数 作为结构体成员_第4张图片

你可能感兴趣的:(C语言,c语言,c++)