progress

I'd rather be anything but ordinary

0%

code complete

本文是读完代码大全(code complete)18节的总结,不得不说这本书很好,与其他专业书籍不同,它教你的是真正在写程序时用到的技巧.

只读了一章就感到收益匪浅,在编写程序时你是否经常有大量的if,else 充斥在你的代码里,一眼望不到头,那么我建议你读一读这片文章.

首先给出一个简单的例子

输入一个月份,输出它的天数

通常的做法如下

if(month==1) day=31;
else if(month==2) day=28;
else if(month==3) day=31;
....

我没有将它写完整,不过我想你也知道之后的代码是什么样,不仅繁杂而且可读性差.
下面我用本文将要介绍的方法重写这个代码

int months [31,28,31,...];//建立一个存储天数的月份表
day=months[month-1];

二者孰优孰劣一目了然,上面就是本文将介绍的表驱动法(Table-Driven Methods).
其主要有三种方式

  • 直接访问(Direct access)
  • 索引访问(Indexed access)
  • 阶梯访问(Stair-step access)

    1.直接访问

    顾名思义,直接访问就是直接访问表进而得到所需要的值.典型的例子就是开篇介绍的根据月份求天数,如果需求再加入平,闰年的话,开始的普通做法if语句会更加的长,利用查找表就很简单了,变成二维列表就好了.
    int months[12][2];
    day=months[month][0];
    我们再看一个例子来让你对这个方法理解的更加深刻.

    计算医疗保险费率,这些费率随年龄,性别,婚姻状况和吸烟与否变化。

如果采用传统的逻辑控制结构,写的代码应该是这样的.

if(gender==female){
if(maritalStatus==single){
if(smokingStatus==smoking){
if(age<18) rate=200.0;

else if(age ==18){
rate=250.0;
}
else if(age==19){
rate=300.0;
}
...
else if(65<age){
rate=450.0
}
}
}
else {
if(age<18) rate=200.0;

else if(age ==18){
rate=250.0;
}
else if(age==19){
rate=300.0;
}
...
else if(65<age){
rate=450.0
}
}
else if(maritalStatus==Married){
...
}
}

我相信你想的和我是一样的,这代码太长了,我要优化它,实际上如果依旧采用这种逻辑控制结构,代码优化不了太多,这样我们的查找表法就要登场了,你可能会想将年龄作为下标,将它放入一个不同年龄对应的查找表里.
就像这样

int Rates[]={...};

不过这样并没有显著简化,其实我们不用局限在一维数组,二位数组这种,我们还可以采用多维数组,不用担心会占用很多的内存,实际上在现代计算机中多维数组和一维数组一样都是线性存储.我们可以将所有因素作为索引建造查找表.

enum smokingStatus {
smoking=0,
NonSmoking=1
};
enum Gender{
Female=0,
male=0
};
enum MaritalStatus{
Married=0,
single=1
};
int Rates[2][2][2][]={ ...};

如果我们想要求单身不吸烟的18岁男性的费率,只需这样

rate=Rates[NonSomking][male][single][18];

一目了然,不仅代码简介而且可读性高.

2. 索引访问

-待续

3. 阶梯访问

-待续