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

先需要了解函数指针数组的使用,依旧通过最简单最容易理解的例子来讲解。

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

   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数组,程序圈复杂度不会随功能增多而增加,从而也降低了维护成本。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值