分享

函数指针数组的例子

 迎风翱翔 2014-02-26

来看这么一段代码:

  1. #include "stdio.h"  
  2. #include "stdlib.h"  
  3. #include "string.h"  
  4.    
  5.    
  6. enum response_type  
  7. {  
  8.     DUMP,  
  9.     SECOND_CHANCE,  
  10.     MARRIAGE  
  11. };  
  12.    
  13.    
  14. typedef struct  
  15. {  
  16.     char *name;  
  17.     enum response_type type;  
  18. }response;  
  19.    
  20.    
  21. void dump(response r)  
  22. {  
  23.     printf("Dear %s, \n", r.name);  
  24.     puts("dump function\n");  
  25. }  
  26.    
  27.    
  28. void second_chance(response r)  
  29. {  
  30.     printf("Dear %s, \n", r.name);  
  31.     puts("second_chance function\n");  
  32. }  
  33.    
  34.    
  35. void marriage(response r)  
  36. {  
  37.     printf("Dear %s, \n", r.name);  
  38.     puts("marriage function\n");  
  39. }  
  40.    
  41.    
  42. int main()  
  43. {  
  44.     response r[] = {  
  45.         {"Mike", DUMP}, {"Luis", SECOND_CHANCE},  
  46.         {"Matt", SECOND_CHANCE}, {"William", MARRIAGE}  
  47.     };  
  48.    
  49.     int index;  
  50.     for (index = 0; index < 4; index++)  
  51.     {  
  52.         switch (r[index].type)  
  53.         {  
  54.         case DUMP:  
  55.             dump(r[index]);  
  56.             break;  
  57.         case SECOND_CHANCE:  
  58.             second_chance(r[index]);  
  59.             break;  
  60.         case MARRIAGE:  
  61.             marriage(r[index]);  
  62.             break;  
  63.         default:  
  64.             break;  
  65.         }  
  66.     }  
  67.    
  68.    
  69.     return 0;  
  70. }  


这个程序是可以执行的,并且是正确的。但是代码中充斥着大量的函数调用,每次都需要根据r的type来调用函数,看起来像这样:

  1. switch (r.type)  
  2. {  
  3. case DUMP:  
  4.     dump(r[index]);  
  5.     break;  
  6. case SECOND_CHANCE:  
  7.     second_chance(r[index]);  
  8.     break;  
  9. case MARRIAGE:  
  10.     marriage(r[index]);  
  11.     break;  
  12. default:  
  13.     break;  
  14. }  

这么一来,如果增加r的第四种类型,那就不得不修改程序中每一个像这样的地方。很快,就有一大堆代码需要维护,而且这样很容易出错。



下面来看,如何通过创建函数指针数组来替代上面的这些代码:

  1. #include "stdio.h"  
  2. #include "stdlib.h"  
  3. #include "string.h"  
  4.    
  5.    
  6. enum response_type  
  7. {  
  8.     DUMP,  
  9.     SECOND_CHANCE,  
  10.     MARRIAGE  
  11. };  
  12.    
  13.    
  14. typedef struct  
  15. {  
  16.     char *name;  
  17.     enum response_type type;  
  18. }response;  
  19.    
  20.    
  21. void dump(response r)  
  22. {  
  23.     printf("Dear %s, \n", r.name);  
  24.     puts("dump function\n");  
  25. }  
  26.    
  27.    
  28. void second_chance(response r)  
  29. {  
  30.     printf("Dear %s, \n", r.name);  
  31.     puts("second_chance function\n");  
  32. }  
  33.    
  34.    
  35. void marriage(response r)  
  36. {  
  37.     printf("Dear %s, \n", r.name);  
  38.     puts("marriage function\n");  
  39. }  
  40.    
  41.    
  42. void (*replise[])(response) = { dump, second_chance, marriage };  
  43.    
  44.    
  45. int main()  
  46. {  
  47.     response r[] = {  
  48.         {"Mike", DUMP}, {"Luis", SECOND_CHANCE},  
  49.         {"Matt", SECOND_CHANCE}, {"William", MARRIAGE}  
  50.     };  
  51.    
  52.     int index;  
  53.     for (index = 0; index < 4; index++)  
  54.     {  
  55.         replise[r[index].type](r[index]);  
  56.     }  
  57.    
  58.    
  59.     return 0;  
  60. }  

可以看到,我们这里已经没有了那么一大段的switch代码。但是程序依然是和上边的初始程序一样的运行结果。

 

就这么一行代码,代替了上面的一大段switch代码!

 

那么我们现在来看增加r的第四种类型时候的代价:

  1. #include "stdio.h"  
  2. #include "stdlib.h"  
  3. #include "string.h"  
  4.    
  5.    
  6. enum response_type  
  7. {  
  8.     DUMP,  
  9.     SECOND_CHANCE,  
  10.     MARRIAGE,  
  11.     DEAD  
  12. };  
  13.    
  14.    
  15. typedef struct  
  16. {  
  17.     char *name;  
  18.     enum response_type type;  
  19. }response;  
  20.    
  21.    
  22. void dump(response r)  
  23. {  
  24.     printf("Dear %s, \n", r.name);  
  25.     puts("dump function\n");  
  26. }  
  27.    
  28.    
  29. void second_chance(response r)  
  30. {  
  31.     printf("Dear %s, \n", r.name);  
  32.     puts("second_chance function\n");  
  33. }  
  34.    
  35.    
  36. void marriage(response r)  
  37. {  
  38.     printf("Dear %s, \n", r.name);  
  39.     puts("marriage function\n");  
  40. }  
  41.    
  42.    
  43. void dead(response r)  
  44. {  
  45.     printf("Dear %s, \n", r.name);  
  46.     puts("dead function\n");  
  47. }  
  48.    
  49.    
  50. void (*replise[])(response) = { dump, second_chance, marriage, dead };  
  51.    
  52. int main()  
  53. {  
  54.     response r[] = {  
  55.         {"Mike", DUMP}, {"Luis", SECOND_CHANCE},  
  56.         {"Matt", SECOND_CHANCE}, {"William", MARRIAGE},  
  57.         {"Zeng", DEAD},  
  58.     };  
  59.    
  60.     int index;  
  61.     for (index = 0; index < 5; index++)  
  62.     {  
  63.         replise[r[index].type](r[index]);  
  64.     }  
  65.    
  66.    
  67.     return 0;  
  68. }  


对比一下,可以看到,仅仅需要修改3个地方,便能够加入一个对应的函数!维护代价大大的减少了!


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多