1 #define _CRT_SECURE_NO_WARNINGS 1 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 void int_swap(const void *a, const void *b) 6 { 7 int tmp = *(int *)a; 8 *(int *)a = *(int *)b; 9 *(int *)b = tmp; 10 } 11 12 void char_swap(const void *a, const void *b) 13 { 14 char tmp = (char)*(int *)a; 15 (char)*(int *)a = (char)*(int *)b; 16 (char)*(int *)b = tmp; 17 } 18 19 void char_bubble(void(*pfun)(const void *a, const void *b), char arr[], int len) 20 { 21 int i = 0; 22 int j = 0; 23 for (i = 0; i < len - 1; i++) 24 { 25 for (j = 0; j < len - i - 1; j++) 26 { 27 if (arr[j] > arr[j + 1]) 28 { 29 pfun(&arr[j], &arr[j + 1]); 30 } 31 } 32 } 33 } 34 void int_bubble(void(*pfun)(const void *a, const void *b), int arr[], int len) 35 { 36 int i = 0; 37 int j = 0; 38 for (i = 0; i < len - 1; i++) 39 { 40 for (j = 0; j < len - i - 1; j++) 41 { 42 if (arr[j] > arr[j + 1]) 43 { 44 pfun(&arr[j], &arr[j + 1]); 45 } 46 } 47 } 48 } 49 50 void bubble(void(*pfun)(const void *a, const void *b), void *ptr, int len) 51 { 52 if (*((int*)ptr) >= 0 && *((int*)ptr) <= 9) 53 { 54 int_bubble(pfun, (int*)ptr, len); 55 } 56 else 57 { 58 char_bubble(pfun, (char*)ptr, len); 59 } 60 } 61 62 int main() 63 { 64 int arr1[] = { 1, 3, 2, 4, 5, 7, 6, 8, 10, 9 }; 65 char arr2[] = "acbdfe"; 66 int len = sizeof(arr1) / sizeof(arr1[0]); 67 int size = strlen(arr2); 68 int i = 0; 69 bubble(int_swap, arr1, len); 70 bubble(char_swap, arr2, size); 71 for (i = 0; i < len; i++) 72 { 73 printf("%d ", arr1[i]); 74 } 75 printf("\n"); 76 printf("%s\n", arr2); 77 system("pause"); 78 return 0; 79 }
回调函数是C语言的一种常用的高级应用,在库函数和应用程序中都有广泛的应用。
要点:
1.回调函数的调用方式
2.回调函数的完全形式的参数传递原则
3.C语言库函数的回调函数使用
回调函数的概念和作用
回调函数是程序中一种常用的函数调用方式。其特点是可以在下层软件模块(宏观上的被调用者)中,调用来自上层的软件模块(宏观上的调用者)中的函数,这和通常的调用顺序是相反的。
程序的调用方式 软件模块的关系,从总体上看,有上层软件模块和下层软件模块之分。一般有三种调用方式
1.简单的同步调用 上调下直接返回
2.带有回调的调用 双向调用
3.异步调用 一般基于消息或事件类似MFC的机制
带有回调的调用方式是一种双向调用模式,在这种方式中,下层模块的函数在被调用的时候,将会调用上层模块的某个函数,回调上层模块的函数至少有两个作用,一是监视下层模块函数的运行状态,二是干预下层模块函数的运行。
在C语言中回调函数的基础是函数类型的指针。
回调函数的作用 回调函数的表现形式是一个某种类型的函数指针,这个函数由上层的软件模块实现,将这个函数指针通过某种方式传递给下层的软件模块,由下层的软件模块在某个时刻调用这个函数。
函数指针的本质是一个函地址,在32位的系统中,本质是一个32位无符号整数。
函数指针由上层模块传递到下层模块的传递方式是可以通过函数的参数传递,也可以使用结构体的成员进行传递。
调用回调函数的时刻一般有两种:一种是在上层模块调用下层模块的函数中,直接调用回调函数:另一种是使用注册的方式,在某个事件发生的时候下层模块调用回调函数。
回调函数的语法:、
1.最简单的函数类型为:无参数、无返回值的函数。最简单的回调函数的格式是这种形式。其类型的定义如下所示:
typedef void (*T_SIMPLE_CALLBACK)(void);
注:回调函数可以是任意类型的函数指针,最简单的形式是无任何参数,也没有返回值得函数指针
2.完全形式的回调函数完全形式的回调函数可以按照如下方式实现,它包含两个无符号整数的参数,返回值也是无符号的整数。其类型的定义如下所示:
typedef unsigned int(*T_FULL_CALLBACK)(unsigned int para1,unsigned int para2);
注:1.典型的回调函数包含两个整数型参数和整数返回值,第一个参数由下层定义,第二个参数由上层定义,返回值是上层经过回调反馈给下层的
2.事实上,这种回调机制在一个系统的各个层次软件协同处理的时候很常用。例如,下层模块表示一个GUI系统,具有绘制界面的功能,上层将模块将回调函数的指针传递给下层,当界面产生“事件”的时候,调用回调函数执行上层软件模块所定制的行为