优化程序-- -函数指针数组及驱动表程序解读

来源:互联网 发布:淘宝国际物流怎么发货 编辑:程序博客网 时间:2024/04/28 14:52
先需要了解函数指针数组的使用,依旧通过最简单最容易理解的例子来讲解。

  首先看下面这个函数指针数组的使用实例。

   1. #include <stdio.h>     2. #include <stdlib.h>     3.      4.      5. int Sum(int a, int b)     6. {     7.     return a + b;     8. }     9.     10. int Sub(int a, int b)    11. {    12.     return a - b;    13. }    14.     15. typedef int (*pfFun)(int, int);    16.     17. int TestFun(int a, int b, pfFun pf)    18. {    19.     int i = 0;    20.     i = pf(a, b);    21.     return i;    22. }    23.     24. int main(int argc, char *argv[])    25. {    26.   int iTmp = 0;    27.       28.   pfFun pf[] = {Sum, Sub}; /*定义并一个函数指针数组,包含2个元素,并将其初始化为Sum和Sub函数地址*/    29.       30.   iTmp = TestFun(20, 10, pf[0]);    31.   printf("Tmp is: %d\n", iTmp);    32.       33.   iTmp = TestFun(20, 10, pf[1]);    34.   printf("Tmp is: %d\n", iTmp);    35.       36.   system("PAUSE");      37.       38.   return 0;    39. }  

有了上面的概念,让我们通过另一个实例看看驱动表的使用,下面这个小程序几乎每个程序员都应该写过,一个没有考虑精度的加减乘除运算程序,如下:

   1. #include <stdio.h>     2. #include <stdlib.h>     3.      4. /*加法*/     5. int Sum(int a, int b)     6. {     7.     return a + b;     8. }     9.     10. /*减法*/    11. int Sub(int a, int b)    12. {    13.     return a - b;    14. }    15.     16. /*乘法*/    17. int Multi(int a, int b)    18. {    19.     return a * b;    20. }    21.     22. /*除法*/    23. int Division(int a, int b)    24. {    25.     return (b == 0)? 0:(a / b);    26. }    27.     28. /*操作码*/    29. typedef enum _ENOPCODE    30. {    31.     OPCODE_ADD = 0,   /*加*/    32.     OPCODE_SUB,       /*减*/    33.     OPCODE_MULTI,     /*乘*/    34.     OPCODE_DIVISION,  /*除*/    35.     OPCODE_BUTT    36. }enOpCode;    37.     38. /*通过Switch-case语句计算*/    39. int GetOpResultBySwitch(int a, int b, enOpCode enOp)    40. {    41.     int iTmp = 0;    42.         43.     switch(enOp)    44.     {    45.         case OPCODE_ADD:    46.              iTmp = Sum(a, b);    47.              break;    48.                  49.         case OPCODE_SUB:    50.              iTmp = Sub(a, b);    51.              break;          52.             53.         case OPCODE_MULTI:    54.              iTmp = Multi(a, b);    55.              break;    56.                  57.         case OPCODE_DIVISION:    58.              iTmp = Division(a, b);    59.              break;    60.         default:    61.              iTmp = -1;    62.     }    63.         64.     return iTmp;               65. }    66.     67. int main(int argc, char *argv[])    68. {    69.   int iTmp = 0;    70.   int a = 10;    71.   int b = 30;    72.     73.   iTmp = GetOpResultBySwitch(a, b, OPCODE_ADD);    74.     75.   printf("Tmp is: %d\n", iTmp);    76.       77.   system("PAUSE");      78.   return 0;    79. }  

 程序看上去很清晰,但如果要扩展一下功能,就发现要增加更多的case语句,记得ansi c标准中case的最大个数是256个,暂且不论这个值到底是多少,从代码本身来看,增加过多的case使得圈复杂度不断上升,程序维护困难加大。

   这时就可以考虑使用驱动表的方法,同样看一下实现,请关注GetOpResultByTable函数。

   1. #include <stdio.h>     2. #include <stdlib.h>     3.      4. /*加法*/     5. int Sum(int a, int b)     6. {     7.     return a + b;     8. }     9.     10. /*减法*/    11. int Sub(int a, int b)    12. {    13.     return a - b;    14. }    15.     16. /*乘法*/    17. int Multi(int a, int b)    18. {    19.     return a * b;    20. }    21.     22. /*除法*/    23. int Division(int a, int b)    24. {    25.     return (b == 0)? 0:(a / b);    26. }    27.     28. /*定义函数指针*/    29. typedef int (*pfFun)(int, int);    30.     31. /*操作码*/    32. typedef enum _ENOPCODE    33. {    34.     OPCODE_ADD = 0,   /*加*/    35.     OPCODE_SUB,       /*减*/    36.     OPCODE_MULTI,     /*乘*/    37.     OPCODE_DIVISION,  /*除*/    38.     OPCODE_BUTT    39. }enOpCode;    40.     41. /*使用驱动表计算*/    42. int GetOpResultByTable(int a, int b, enOpCode enOp)    43. {    44.     if (OPCODE_BUTT == enOp)    45.     {    46.        return -1;    47.     }    48.     pfFun pf[OPCODE_BUTT] = {Sum, Sub, Multi, Division};    49.     return pf[enOp](a, b);    50.         51. }    52.     53. int main(int argc, char *argv[])    54. {    55.   int iTmp = 0;    56.   int a = 10;    57.   int b = 30;    58.     59.   iTmp = GetOpResultByTable(a, b, OPCODE_ADD);    60.   printf("Tmp is: %d\n", iTmp);    61.       62.   system("PAUSE");      63.   return 0;    64. }  

实现相当简单,如果增加其他操作等功能,仅需要扩展pf数组,程序圈复杂度不会随功能增多而增加,从而也降低了维护成本。

原创粉丝点击