近来阅读《代码大全》中“表驱动法”这一章节,发现其编程的思想在C语言实际编程很有指导作用,就想着将“表驱动法”应用于实际项目中。
任务需求:函数在进行业务处理之前,需要对外部输入的数据类型(dataType),数据索引(dataIndex),数据长度(dataLen)进行正确性检查
如果按照if-else结构进行判断的话,代码可能如下所示:
enum DATA_TYPE{APPLE=0,PEAR=1,BANANA=2}; enum DATA_LEN{APPLE_LEN=20,PEAR_LEN=30,BANANA_LEN=40}; #define STATE_SUCCESS 0 #define STATE_PARAERROR 1 //通过多重if-else语句进行参数检查 int CheckParaByMulIF(int dataType,int dataIndex,int dataLen) { if (dataType == APPLE && dataIndex == 0 && dataLen == APPLE_LEN) { return STATE_SUCCESS; }else if (dataType == APPLE && dataIndex == 1 && dataLen == APPLE_LEN) { return STATE_SUCCESS; }else if (dataType == PEAR && dataIndex == 0 && dataLen == PEAR_LEN) { return STATE_SUCCESS; }else if (dataType == PEAR && dataIndex == 1 && dataLen == PEAR_LEN) { return STATE_SUCCESS; }else if (dataType == BANANA && dataIndex == 0 && dataLen == BANANA_LEN) { return STATE_SUCCESS; } return STATE_PARAERROR; }
刚开始写完这段代码之后,觉得任务完成了,可以进行后续的开发,但是等到了一段时间之后,代码走查阶段/给项目组其他人员讲述这段代码时,发现自己阅读这段代码特别费劲,而且对这段代码是否“真正正确”没有信心。通过“表驱动法”的学习,上述函数可以修改为下述格式:
typedef struct{ enum DATA_TYPE type; int index; enum DATA_LEN len; }ParaTable; //通过查表方法进行参数检查 int CheckParaByTable(int dataType,int dataIndex,int dataLen) { ParaTable paraTableList[] ={ {APPLE,0,APPLE_LEN}, {APPLE,1,APPLE_LEN}, {PEAR,0,PEAR_LEN}, {PEAR,1,PEAR_LEN}, {BANANA,0,BANANA_LEN} }; int listLen = sizeof(paraTableList)/sizeof(paraTableList[0]); int i; for (i=0;i<listLen;i++) { if (dataType == paraTableList[i].type && dataIndex == paraTableList[i].index && dataLen == paraTableList[i].len) { return STATE_SUCCESS; } } return STATE_PARAERROR; }
对比两者的实现,可发现面对这种多参数检查的问题,用表驱动法比多重if-else方法更聪明些。
参考资料:
1、《代码大全2》
2、C语言表驱动法编程实践 http://www.cnblogs.com/clover-toeic/p/3730362.html