今天上课的时候,老师给我们详细的讲了函数指针的用法。记得大一的时候上C语言的时候,只知道有函数指针这个概念,但是后来都一直没用到。但好像也有用到,每次在编程时,调用c库的qsort函数的时候,可以看到qsort的最后一个参数就是个函数指针,但是当时都不怎么的在意,就知道怎么用就可以了。今天在老师系统的讲之后,以后再遇到的话,应该就没有问题!今天下课回来后,我也去翻了下《c专家编程》和《C和指针》这两本书,发现C和指针里面在高级指针话题那章有讲到函数指针,并且也讲到了他们的应用----回调函数和转移表。由于时间关系,下次再仔细的看看吧。不过我发现这两本书还是非常的好!对于C语言的进阶非常有帮助,没事了可以翻一翻,看一看!
回归正题吧,我们一般用冒泡函数都是对整型或者浮点型进行排序,但是如果我们遇到对字符的排序呢?为了让我们的bubble-sort更具通用性,其实也是把bubble-sort封装得更好些,也就是把它弄成跟qsort一样~那么我们就可以声明这样一个函数:
void bubble_sort(void *arr[], int len,int (*cmp)(void *a, void *b));
根据要比较的数据类型的差异,我们可以传入不同的比较函数给cmp这个函数指针,来实现不同类型的排序。然后我们会发现,为什么要声明一个void *arr[],这是一个指针数组,什么是指针数组?首先它是一个数组,其次,它指向的是数组元素都是一个个指针,某个数据类型的地址(因为这里是void类型,所以可以转换成各种类型)。比如int *arr[5]:
---------------------------------------------
| int * | int * | int * | int * | int * |
---------------------------------------------
如果要获得它指向的类型的值,必须还需经过间接的*符号来获取。
因为在程序中我们声明了void *arr[9]这样一个指针数组,那么我们在对不同的数据输入的时候,就必须先给它开辟相应类型的空间来存储。涉及到 指针数组的时候,操作起来就没那么简单了,如果真正把这个给理解并实现的话,那么对指针的理解将会是更深刻。
下面是我重新参照老师的算法实现的代码,如果是针对字符或者浮点型的比较,那么我们可以只在输入的地方稍微再做些修改,或者我们可以把输入也封装成一个函数,那就更方便了:
#include <stdio.h> #include <stdlib.h> int int_cmp(void *a, void *b); int char_cmp(void *a, void *b); void swap(void *arr, int a, int b); void bubble_sort(void *arr[], int len,int (*cmp)(void *a, void *b)); int main() { int len = 9,i; void *arr[9]; //void 类型的数组指针 for (i = 0; i < len; i++) { arr[i] =(int *)malloc(sizeof(int)); scanf("%d",(int *)arr[i]); } bubble_sort(arr,len,int_cmp); for (i = 0; i < len; i++) { printf("%d ",*(int *)arr[i]); } printf("\n"); free(arr); return 0; } int int_cmp(void *a, void *b) { return *(int *)a > *(int *)b ? 1:0; } void swap(void *arr[], int a, int b) { void *tmp; tmp = arr[a]; arr[a] = arr[b]; arr[b] = tmp; } void bubble_sort(void *arr[], int len,int (*cmp)(void *a, void *b)) { int i,j; for (i = 0; i < len-1; i++) { for (j = 0; j < len-i-1; j++) { if (cmp(arr[j],arr[j+1])) swap(arr,j,j+1); } } } 2013/10/11 22:02