[转载]C语言函数指针的用法

C语言函数指针的用法

作者:wuyudong

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

 

函数指针是一种在C、C++、D语言、其他类 C 语言和Fortran 2003中的指针。函数指针可以像一般函数一样,用于调用函数、传递参数。在如 C 这样的语言中,通过提供一个简单的选取、执行函数的方法,函数指针可以简化代码。

函数指针只能指向具有特定特征的函数。因而所有被同一指针运用的函数必须具有相同的参数和返回类型。

本文地址:http://www.cnblogs.com/archimedes/p/3669872.html,转载请注明源地址。

下面的代码说明了一种初始化函数指针的方法:

1 int f(int);
2 int (*fp)(int) = &f;
3 
4 //使用三种方式调用函数
5 int ans;
6 ans = f(25);
7 ans = (*pf)(25);
8 ans = pf(25);

以下为函数指针在C中的简单运用:

 1 #include <stdio.h>
 2 
 3 int max(int x, int y)
 4 {
 5     return x > y ? x : y;
 6 }
 7  
 8 int main(void)
 9 {
10     /* p 是函数指针 */
11     int (* p)(int, int) = & max; // &可以省略
12     int a, b, c, d;
13  
14     printf("please input 3 numbers:");
15     scanf("%d %d %d", & a, & b, & c);
16  
17     /* 与直接调用函数等价,d = max(max(a, b), c) */
18     d = (* p)(( *p)(a, b), c); 
19  
20     printf("the maxumum number is: %d\n", d);
21     return 0;
22 }

下面介绍函数指针最常见的两个用途:作为参数传递给另一个函数(回调函数)、转换表

1、回调函数:                                                                           

下面有一个简单的函数,用来在单链表中查找一个给定的值

1 Node* search_list(Node* node, int const value)
2 {
3     while(node != NULL) {
4         if(node->value == value)
5             break;
6         node = node->next;
7     }
8     return node;
9 }

一种更加通用的方法就是使该函数能用任何类型值的链表,必须修改函数,使它与类型无关。解决的方案就是使用函数指针。

 1 #include <stdio.h>
 2 #include "node.h"
 3 
 4 Node *search_list( Node *node, void const *value,
 5     int (*compare)( void const *, void const * ) )
 6 {
 7     while( node != NULL ){
 8         if( compare( &node->value, value ) == 0 )
 9             break;
10         node = node->next;
11     }
12     return node;
13 }

在特定的链表中进行比较的时候,用户需要编写适当的比较函数,并把指向该函数的指针和指向需要查找的值的指针传递给查找函数,下面是一个整型链表中查找的比较函数:

 1 int compare_ints(void const *a, void const *b)
 2 {
 3     if( *(int *)a == *(int *)b)
 4         return 0;
 5     else
 6         return 1;
 7 }
 8 
 9 //这个函数将像下面这样调用
10 desired_node = search_list(root, &desired_value, compare_ints);

如果你希望在一个字符串链表中进行查找,下面的代码可以完成任务:

1 #include<string.h>
2 ...
3 desired_node = search_list(root, "desired_value", strcmp);

再看一个完整的例子:

 1 #include<stdio.h>
 2 struct object
 3 {
 4     int data;
 5 };
 6  
 7 int object_compare(struct object * a,struct object * z)
 8 {
 9     return a->data < z->data ? 1 : 0;
10 }
11  
12 struct object *maximum(struct object * begin,struct object * end,int (* compare)(struct object *, struct object *))
13 {
14     struct object * result = begin;
15     while(begin != end)
16     {
17         if(compare(result, begin))
18         {
19             result = begin;
20         }
21         ++ begin;
22     }
23     return result;
24 }
25  
26 int main(void)
27 {
28     struct object data[8] = {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}};
29     struct object * max;
30     max = maximum(data + 0, data + 8, & object_compare);
31     printf("max: %d\n", (*max).data);
32     return 0;
33 }

2、转移表                                                                                

下面的程序是一个简化的根据运算符转到相应运算的例子:

 1 #include<stdio.h>
 2 
 3 double _add(double, double);
 4 double _sub(double, double);
 5 double _mul(double, double);
 6 double _div(double, double);
 7 
 8 double _add(double a, double b)
 9 {
10     return a + b;
11 }
12 
13 double _sub(double a, double b)
14 {
15     return a - b;
16 }
17 
18 double _mul(double a, double b)
19 {
20     return a * b;
21 }
22 
23 double _div(double a, double b)
24 {
25     return a / b;
26 }
27 
28 int main(void)
29 {
30     int n;
31     enum Operation{ADD, SUB, MUL, DIV}op;
32     double a, b, ans;
33     a = 0.232332;
34     b = 0.234398;
35     printf("请输入一个整数(0-3): ");
36     scanf("%d", &n);
37     op = (enum Operation)n;
38     switch(op) {
39     case ADD:
40         ans = _add(a, b);
41         break;
42     case SUB:
43         ans = _sub(a, b);
44         break;
45     case MUL:
46         ans = _mul(a, b);
47         break;
48     case DIV:
49         ans = _div(a, b);
50         break;
51     default:
52         break;
53     }
54     printf("%lf\n", ans);
55     return 0;
56 }

使用可以使用转换表来实现相同的任务,转换表就是一个函数指针数组,代码如下:

 1 #include<stdio.h>
 2 
 3 double _add(double, double);
 4 double _sub(double, double);
 5 double _mul(double, double);
 6 double _div(double, double);
 7 
 8 double _add(double a, double b)
 9 {
10     return a + b;
11 }
12 
13 double _sub(double a, double b)
14 {
15     return a - b;
16 }
17 
18 double _mul(double a, double b)
19 {
20     return a * b;
21 }
22 
23 double _div(double a, double b)
24 {
25     return a / b;
26 }
27 
28 int main(void)
29 {
30     int n;
31     double a, b, ans;
32     a = 0.232332;
33     b = 0.234398;
34     printf("请输入一个整数(0-3): ");
35     scanf("%d", &n);
36 
37     double (*oper_func[])(double, double) = {
38         _add, _sub, _mul, _div
39     };
40 
41     ans = oper_func[n](a, b);
42     printf("%lf\n", ans);
43     return 0;
44 }

 

posted @ 2016-10-05 20:22  GhostRiderLi  阅读(1777)  评论(0)    收藏  举报