我理解的函数指针:
函数指针是一种指向一块代码区域的指针。就像struct,int char等对应的指针类型,只不过函数指针是指向一个函数。函数指针可以用来做为回调使用,也可以用来在C语言中模拟面向对象编程。函数指针的格式一般如下:
int (*POINTER_NAME)(...)
函数指针的demo:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <errno.h> 4 #include <string.h> 5 6 void die(const char *message) 7 { 8 if(errno) { 9 perror(message); 10 } else { 11 printf("ERROR: %s\n", message); 12 } 13 14 exit(1); 15 } 16 17 // a typedef creates a fake type, in this 18 // case for a function pointer 19 typedef int (*compare_cb)(int a, int b); 20 21 /** 22 * A classic bubble sort function that uses the 23 * compare_cb to do the sorting. 24 */ 25 int *bubble_sort(int *numbers, int count, compare_cb cmp) 26 { 27 int temp = 0; 28 int i = 0; 29 int j = 0; 30 int *target = malloc(count * sizeof(int)); 31 32 if(!target) die("Memory error."); 33 34 memcpy(target, numbers, count * sizeof(int)); 35 36 for(i = 0; i < count; i++) { 37 for(j = 0; j < count - 1; j++) { 38 if(cmp(target[j], target[j+1]) > 0) { 39 temp = target[j+1]; 40 target[j+1] = target[j]; 41 target[j] = temp; 42 } 43 } 44 } 45 46 return target; 47 } 48 49 int sorted_order(int a, int b) 50 { 51 return a - b; 52 } 53 54 int reverse_order(int a, int b) 55 { 56 return b - a; 57 } 58 59 int strange_order(int a, int b) 60 { 61 if(a == 0 || b == 0) { 62 return 0; 63 } else { 64 return a % b; 65 } 66 } 67 68 /** 69 * Used to test that we are sorting things correctly 70 * by doing the sort and printing it out. 71 */ 72 void test_sorting(int *numbers, int count, compare_cb cmp) 73 { 74 int i = 0; 75 int *sorted = bubble_sort(numbers, count, cmp); 76 77 if(!sorted) die("Failed to sort as requested."); 78 79 for(i = 0; i < count; i++) { 80 printf("%d ", sorted[i]); 81 } 82 printf("\n"); 83 84 free(sorted); 85 } 86 87 88 int main(int argc, char *argv[]) 89 { 90 if(argc < 2) die("USAGE: ex18 4 3 1 5 6"); 91 92 int count = argc - 1; 93 int i = 0; 94 char **inputs = argv + 1; 95 96 int *numbers = malloc(count * sizeof(int)); 97 if(!numbers) die("Memory error."); 98 99 for(i = 0; i < count; i++) { 100 numbers[i] = atoi(inputs[i]); 101 } 102 103 test_sorting(numbers, count, sorted_order); 104 test_sorting(numbers, count, reverse_order); 105 test_sorting(numbers, count, strange_order); 106 107 free(numbers); 108 109 return 0; 110 }
运行结果:
1 zhaoscmatoMacBook-Pro:c zhaosc$ ./ex18 2 ERROR: USAGE: ex18 4 3 1 5 6 3 zhaoscmatoMacBook-Pro:c zhaosc$ ./ex18 4 2 1 9 7 4 1 2 4 7 9 5 9 7 4 2 1 6 4 2 9 7 1
分析:
在程序中定义die(...)方法,这个主要就是用于启动程序错误提示。
使用typedef定义函数指针,其实这个就是把函数指针定义成一个类型,就像我们熟悉的struct。
在int *bubble_sort(int *numbers, int count, compare_cb cmp)函数中使用了我们定义的类型compare_cb,变量可以为我们真正操作的函数,在main函数中我们把之前定义的函数sorted_order,reverse_order,strange_order函数作为参数传递给test_sorting。这里其实很好理解,我们定义的每个函数其实在内存都有具体的位置,而函数名就指向一块内存的起始位置。仔细一想函数指针其实就是指针之间的赋值。(这个我的理解,不清楚是否存在问题)。
附带:
随便说下指针函数,这两个概念名字很相似,容易被弄混。指针函数,相对简单,只不过是一个很普通的函数,唯一不同的是这个函数的返回值是一个指针。
想一想,函数指针,和指针函数,配合可以写出很奇妙的代码,不过个人感觉使用它们的时候注释真的要写清楚,要不想我这样对C/C++了解不多的人读起代码来还真的有点吃力。前段时间一直在移植spice-space到Android平台下,源码中写的很复杂,其中就是使用了很多函数指针,当时看的我真的有点头晕目眩,最近补充了些C/C++的基础,感觉好多啦。
Note:如博文中存在问题,请大家及时指出,我会及时纠正,谢谢。