Chinaunix首页 | 论坛 | 博客
  • 博客访问: 899201
  • 博文数量: 119
  • 博客积分: 2493
  • 博客等级: 大尉
  • 技术积分: 2363
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-03 14:00
文章分类

全部博文(119)

文章存档

2013年(19)

2012年(100)

分类: LINUX

2012-09-08 11:23:44

      函数指针在C语言学习的时候提到过,但一直都很少用到。如果分析开源代码,比如说内核,里面就用到了函数指针,用的还很普遍。在内核中对函数指针
有个通俗的名字,叫“钩子函数”。

     学习C语言的人喜欢把函数指针和指针函数做区分,我觉得这没多大意思,
两个八竿子打不着的东西放在一起做区分。而且指针函数这个概念也不知道是谁提出来的。返回值为指针的函数就是指针函数?那且不返回int型的函数称为int函数,返回void的函数称为void函数?

函数指针的内核中的使用示例:

  1. struct module
  2. {
  3.    ...
  4.    int (*init)(void);
  5.    void (*exit)(void);
  6.    ...
  7. }

该结构体是对内核中可加载模块的描述,其中就用了两个“钩子函数”,一个init执行模块的入口函数,也就是在编写内核模块的时候 module_init(hello_init);指定的参数。另外一个exit就是模块卸载时的入口函数。例如:
module_exit(hello_exit);

  1.  struct vm_operations_struct {
  2.        void (*open)(struct vm_area_struct * area);
  3.        void (*close)(struct vm_area_struct * area);
  4.        int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf);
  5.        int (*page_mkwrite)(struct vm_area_struct *vma, struct vm_fault *vmf);
  6.        int (*access)(struct vm_area_struct *vma, unsigned long addr,
  7.            void *buf, int len, int write);
  8.     #ifdef CONFIG_NUMA
  9.        int (*set_policy)(struct vm_area_struct *vma, struct mempolicy *new);
  10.        struct mempolicy *(*get_policy)(struct vm_area_struct *vma,
  11.         unsigned long addr);
  12.        int (*migrate)(struct vm_area_struct *vma, const nodemask_t *from,
  13.        const nodemask_t *to, unsigned long flags);
  14.     #endif
  15.  };
上面是进程虚存区的“操作集”,也就是用结构体封装了一些“钩子函数”。

其实函数指针主要是为了实现面向对象的思想,C++中有类进行封装,C语言就只能靠结构体进行封装,类中有成员函数,但结构体中没有成员函数,没办法,C语言只能使用函数指针来代替成员函数。


----------------------------------------------------------------------------------------------
下面使用C语言结构体和函数指针实现一个面向对象的例子。现在可以把一个数组看作一个对象,可以对这个对象定义一些成员函数,比如说get_length(),get_max(),get_min()等。

  1. #include <stdio.h>

  2. #define array_size(x) (sizeof(x)/sizeof((x)[0]))

  3. struct array{
  4.     int array_len;
  5.     int max;
  6.     int min;
  7.     int (*get_max)(int *);
  8.     int (*get_min)(int *);
  9.     void (*print)(struct array *);
  10. };

  11. struct array arr;

  12. int get_max(int a[])
  13. {
  14.         int max = a[0];
  15.         int i;
  16.         for (i = 1;i < arr.array_len;i++) {
  17.                 if (a[i] > max)
  18.                     max = a[i];
  19.         }
  20.         return max;
  21. }

  22. int get_min(int a[])
  23. {
  24.         int min = a[0];
  25.         int i;
  26.         for (i = 1;i < arr.array_len;i++) {
  27.                 if (a[i] < min)
  28.                     min = a[i];
  29.         }
  30.         return min;
  31. }

  32. void print(struct array *arr)
  33. {
  34.         printf("array_len = %d\n",arr->array_len);
  35.         printf("array_max = %d\n",arr->max);
  36.         printf("array_min = %d\n",arr->min);
  37.         return ;
  38. }

  39. void init(void)
  40. {
  41.         arr.get_max = get_max;
  42.         arr.get_min = get_min;
  43.         arr.print = print;
  44. }

  45. int main(void)
  46. {
  47.         int a[] = {1,2,3,4,5,6,7,8,9};
  48.         init();
  49.         arr.array_len = array_size(a);
  50.         arr.max = arr.get_max(a);
  51.         arr.min = arr.get_min(a);
  52.         arr.print(&arr);
  53.         return 0;
  54. }
---------------------------------------------------------------------------------------------

函数指针只是定义了一个接口。也就是一个钩子,钩子上挂的东西不清楚。
具有很强的拓展性。



阅读(1388) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~