表驱动--用于在复杂消息分发中,取代if/else和switch/case结构
来源:互联网 发布:wildfly 端口配置 编辑:程序博客网 时间:2024/06/05 04:44
在开发过程中,经常遇到需要在不同的场景下调用不同的函数以实现不同的功能(例如消息分发),传统的设计方法中大量的使用 if/else,switch/case结构,如下所示:
int dispatch_func(unsigned msg_id, void* p_msg, int msg_len) { int result; switch (msg_id) { case MSG_A: result = f_a(p_msg,mgs_len); break; case MSG_B: result = f_b(p_msg,msg_len); break; case MSG_C: result = f_c(p_msg,msg_len); break; //... default: puts("The msg_id is not defined!"); break; } return result;}int f_a(void* p_msg, int msg_len){...}int f_b(void* p_msg, int msg_len){...}int f_c(void* p_msg, int msg_len){...}
很明显,上面这种实现方式,分支越多,可读性越差,维护起来也越麻烦。下面使用表驱动的方式对代码进行重新规划:
#define MSG_BEGIN 0x123#define MSG_A MSG_BEGIN+1#define MSG_B MSG_BEGIN+2#define MSG_C MSG_BEGIN+3#define MSG_MAX MSG_BEGIN+4typedef int (*msg_func)(unsigned msg_id, void* p_msg, int msg_len);msg_func dispatch_table[]={ f_a, f_b, f_c};int dispatch_func(unsigned msg_id, void* p_msg, int msg_len){ if(( msg_id >= MSG_A) && ( msg_id < MSG_MAX)) return dispatch_table[msg_id-MSG_A](p_msg,msg_len); else return -1;}
如果msg_id为不连续的,不能直接找到其处理函数,就要从数组中查找出其处理函数,如下:
#define MSG_BEGIN 0x123#define MSG_A MSG_BEGIN+1#define MSG_B MSG_BEGIN+2#define MSG_C MSG_BEGIN+3#define MSG_MAX MSG_BEGIN+4typedef int (*msg_func)(unsigned msg_id, void* p_msg, int msg_len);typedef struct { unsigned msg_id; msg_func func;}dispatch_item;dispatch_item dispatch_table[]={ /*这里假定这三个消息不是连续存放的*/ {MSG_A,f_a}, //... {MSG_B,f_b}, //... {MSG_C,f_c}};int max_items=sizeof(dispatch_table)/sizeof(dispatch_table[0]);int dispatch_func(unsigned msg_id, void* p_msg, int msg_len){ int i; for (i=0; i<max_items; i++) { if (function_no == dispatch_table[i].msg_id) return dispatch_table[i].func(p_msg, msg_len); } return -1;}
还可以使用哈希表设计表驱动,这样对于不连续的消息,也能快速查找到其处理函数:
#define MSG_BEGIN 0x123#define MSG_A MSG_BEGIN+1#define MSG_B MSG_BEGIN+2#define MSG_C MSG_BEGIN+3#define MSG_MAX MSG_BEGIN+4typedef int (*msg_func)(unsigned msg_id, void* p_msg, int msg_len);typedef std::hash_map<unsigned , msg_func> MsgHandlerMap;MsgHandlerMap HandlerMap;void InitHandlerMap(){ HandlerMap[MSG_A] = reinterpret_cast<ProcessFuncPtr>(&f_a); HandlerMap[MSG_B] = reinterpret_cast<ProcessFuncPtr>(&f_b); HandlerMap[MSG_C] = reinterpret_cast<ProcessFuncPtr>(&f_c); //...}int ProcessControl(unsigned msg_id, void* p_msg, int msg_len){ CmdHandlerMap::iterator it = HandlerMap.find(msg_id); if (it != HandlerMap.end()) { ProcessFuncPtr pHandler = it->second; return pHandler(p_msg, msg_len); } return -1;}
表驱动是C语言设计利器,搭配函数指针,威力无穷。
0 0
- 表驱动--用于在复杂消息分发中,取代if/else和switch/case结构
- 优化if else 和 switch case 结构
- 分支结构 if...else和switch...case
- if...else和switch..case
- if else和switch case
- C#中的分支结构:if..else if 、if... else 和 switch ...case语句的区别
- Java (if else)(switch case)结构
- switch...case和if...else效率比较
- switch...case和if...else效率比较
- 判断语句switch - case 和if - else
- switch...case和if...else效率比较
- switch...case...和if...else...区别
- C#分支结构if,if-else,if-else if,switch-case区别
- if.....else if .....else 与switch....case.....
- 黑马程序员--if..else...和switch....case和循环结构和三元表达式
- if...else if...和switch...case...执行效率
- 分支结构、大量选择、if—else、switch case
- switch case 与 if else
- 在VMware10下安装VxWorks6.6虚拟机教程(上篇——准备环节)
- Windows环境下搭建机器学习玩flappy bird(2)
- 封装HttpClient工具类;转载请标明出处
- Python-day3
- C++--模板遇上运算符重载
- 表驱动--用于在复杂消息分发中,取代if/else和switch/case结构
- [LeetCode]445. Add Two Numbers II
- 大数据各组件的开启命令及WEB UI端口号
- 蓝鸥Unity入门Transform学习笔记
- linux单用户模式需要密码登录的安全机制
- 生动形象的jQuery上下文选择器实例
- android提供了几种常用的方式,用于实现后台线程与UI线程的交互
- jenkins(五)---jenkins添加项目
- Focussend:无处不在的“消费场景”,看邮件营销步步为营