已经看到第18章了,今天还重温了下c写了个小程序。一直没项目,只有看书写博客了。
-
什么是table-driven
首先看一个例子:
这是一段java代码,作用很明显判断字符类型。当然可以用函数封装起来,也可以用table来查询。
只需要一句:
前提是这张表要提前做好。顺便说一句,inputChar虽然是一个字符,但是放在数组下标里是作为ASCII
码来解释。如charTypeTable['a'] 等同于charTypeTable[97].这是一个很简单的table-driven methods的例子。
总的来说有三种table lookup的方法
- direct access
- indexed access
- stair-step acces
我对indexed理解不深,就讲下剩下两种。
-
direct access
所谓直接读取就是将数据直接放进表中,上面的例子就是一个direct access的例子。还有一个比较好的例子,
就是计算月份天数,这个在K&R里有,我就不粘代码了。新手算一个月有多少天的话,肯定用if来算:
等等一直算到12月,但是如果用一个全局变量保存着12个月的天数,看一个VB的例子:
在计算的话又只有一句代码:
如果要计算闰年的话,就把一维数组改为二维就好了,再加个判断闰年的函数。是不是很方便了。
-
stair-step acces
上面这个应用还有点简单,看一个数据是区间的情况下如何运用这种方法。一个非常古老的例子,如果
学生成绩大于等于90就是a,大于等于75小于90是B.依次类推:
这是一个以前练习c语言时候的联系题,那个时候全部都用if和else来做。看了代码大全我用c重新写了一个函数。代码如下:
- double rangeLimit[] = {50.0, 65.0, 75.0, 90.0, 100.0};
- char grade[100] = {'F', 'D', 'C', 'B', 'A'};
- char GetLevel(double *rangeLimit, char *grade, double score)
- {
- int level;
- int maxGrade;
- level = 0;
- //maxGrade = ARRAY_LENGTH(grade);
- maxGrade = strlen(grade) - 1;
- while ((score>=rangeLimit[level]) && (score<=rangeLimit[maxGrade]))
- {
- level++;
- }
- return grade[level];
- }
首先用两个数组一个保存分数的上线,一个保存分数等级,Level作为索引变量。这样就避免了繁琐的判断,这里使用的一个思路是将分段的数据保存起上限,然后再进行比较。尤其是分段较多时,或者改动分数范围,对代码的修改仅仅是对数组的修改,同时提高了复用。
-
.数组退化成指针
可以看到上面的代码中我注释了一行,本来我是用一个宏来获得数组长度,如下:
#define ARRAY_LENGTH( x ) (sizeof(x)/sizeof(x[0]))
后来经调试发现,结果总是4,而且不管我数组长度是多少!这是我才想起来数组传参时会退化成指针!这点林锐的《高质量c编程指南》讲的很详细。这里也就发现了面向对象的好处,直接定义一个string类,然后再调用length方法即可。不用指针这么容易出错。