函数指针

来源:互联网 发布:淘宝店logo设计 编辑:程序博客网 时间:2024/05/18 00:15

      在程序运行中,函数代码是程序的算法指令部分,它们和数组一样也占用存储空间,都有相应的地址。可以使用指针变量指向数组的首地址,也可以使用指针变量指向函数代码的首地址,指向函数代码首地址的指针变量称为函数指针。

1.函数指针定义

函数类型 (*指针变量名)(形参列表);

“函数类型”说明函数的返回类型,由于“()”的优先级高于“*”,所以指针变量名外的括号必不可少,后面的“形参列表”表示指针变量指向的函数所带的参数列表。

2.函数指针的赋值

函数名和数组名一样代表了函数代码的首地址,因此在赋值时,直接将函数指针指向函数名就行了。

例如,

int func(int x); /* 声明一个函数 */

int (*f) (int x); /* 声明一个函数指针 */

f=func; /* 将func函数的首地址赋给指针f */

赋值时函数func不带括号,也不带参数,由于func代表函数的首地址,因此经过赋值以后,指针f就指向函数func(x)的代码的首地址。

3.通过函数指针调用函数

函数指针是通过函数名及有关参数进行调用的。

与其他指针变量相类似,如果指针变量pi是指向某整型变量i的指针,则*p等于它所指的变量i;如果pf是指向某浮点型变量f的指针,则*pf就等价于它所指的变量f。同样地,*f是指向函数func(x)的指针,则*f就代表它所指向的函数func。所以在执行了f=func;之后,(*f)和func代表同一函数。

由于函数指针指向存储区中的某个函数,因此可以通过函数指针调用相应的函数。现在我们就讨论如何用函数指针调用函数,它应执行下面三步:

首先,要说明函数指针变量。

例如:int (*f)(int x);

其次,要对函数指针变量赋值。

例如: f=func; (func(x)必须先要有定义)

最后,要用 (*指针变量)(参数表);调用函数。

例如: (*f)(x);(x必须先赋值)

 

 

----------------------------------------------------分割线----------------------------------------------------------------------------------------------------------------------

1.简单的函数指针的应用

形式1:返回类型(*函数名)(参数表)

  1. char (*pFun)(int);
  2. char glFun(int a){return;}
  3. void main()
  4. {
  5. pFun = glFun;
  6. (*pFun)(2);
  7. }


第一行定义了一个指针变量pFun。首先我们根据前面提到的“形式1”认识到它是一个指向某种函数的指针,这种函数参数是一个int型,返回值是char类型。只有第一句我们还无法使用这个指针,因为我们还未对它进行赋值。
第二行定义了一个函数glFun()。该函数正好是一个以int为参数返回char的函数。我们要从指针的层次上理解函数——函数的函数名实际上就是一个指针,函数名指向该函数的代码在内存中的首地址
然后就是main()函数了,它的第一句您应该看得懂了——它将函数glFun的地址赋值给变量pFun。main()函数的第二句中“*pFun”显然是取pFun所指向地址的内容,当然也就是取出了函数glFun()的内容,然后给定参数为2。

2.使用typedef更直观更方便

形式1:typedef 返回类型(*新类型)(参数表)

  1. typedefchar (*PTRFUN)(int);
  2. PTRFUN pFun;
  3. char glFun(int a){return;}
  4. void main()
  5. {
  6. pFun = glFun;
  7. (*pFun)(2);
  8. }

typedef的功能是定义新的类型。第一句就是定义了一种PTRFUN的类型,并定义这种类型为指向某种函数的指针,这种函数以一个int为参数并返回char类型。后面就可以像使用int,char一样使用PTRFUN了。
第二行的代码便使用这个新类型定义了变量pFun,此时就可以像使用形式1一样使用这个变量了。

3.例子说明

  1. #include <stdio.h>
  2. #include <assert.h>
  3. typedefint (*FP_CALC)(int,int);//定义一个函数指针类型
  4. int add(int a,int b)
  5. {
  6. return a + b;
  7. }
  8. int sub(int a,int b)
  9. {
  10. return a - b;
  11. }
  12. int mul(int a,int b)
  13. {
  14. return a * b;
  15. }
  16. int div(int a,int b)
  17. {
  18. return b ? a/b : -1;
  19. }
  20. //定义一个函数,参数为op,返回一个指针,该指针类型为拥有两个int参数、
  21. //返回类型为int的函数指针。它的作用是根据操作符返回相应函数的地址
  22. FP_CALC calc_func(char op)
  23. {
  24. switch( op )
  25. {
  26. case'+':
  27. return add;
  28. case'-':
  29. return sub;
  30. case'*':
  31. return mul;
  32. case'/':
  33. return div;
  34. default:
  35. return NULL;
  36. }
  37. return NULL;
  38. }
  39. //s_calc_func为函数,它的参数是 op,
  40. //返回值为一个拥有两个int参数、返回类型为int的函数指针
  41. int (*s_calc_func(char op)) (int ,int)
  42. {
  43. return calc_func(op);
  44. }
  45. //最终用户直接调用的函数,该函数接收两个int整数,
  46. //和一个算术运算符,返回两数的运算结果
  47. int calc(int a,int b, char op)
  48. {
  49. FP_CALC fp = calc_func(op);
  50. int (*s_fp)(int,int) = s_calc_func(op);//用于测试
  51. assert(fp == s_fp);// 可以断言这两个是相等的
  52. if(fp)
  53. return fp(a,b);
  54. else
  55. return -1;
  56. }
  57. void main()
  58. {
  59. int a = 100, b = 20;
  60. printf("calc(%d, %d, %c) = %d\n", a, b,'+', calc(a, b, '+'));
  61. printf("calc(%d, %d, %c) = %d\n", a, b,'-', calc(a, b, '-'));
  62. printf("calc(%d, %d, %c) = %d\n", a, b,'*', calc(a, b, '*'));
  63. printf("calc(%d, %d, %c) = %d\n", a, b,'/', calc(a, b, '/'));
  64. }

 


原创粉丝点击