已經看到第18章了,今天還重溫了下c寫了個小程式。一直沒項目,只有看書寫部落格了。
首先看一個例子:
這是一段java代碼,作用很明顯判斷字元類型。當然可以用函數封裝起來,也可以用table來查詢。
只需要一句:
前提是這張表要提前做好。順便說一句,inputChar雖然是一個字元,但是放在數組下標裡是作為ASCII
碼來解釋。如charTypeTable['a'] 等同於charTypeTable[97].這是一個很簡單的table-driven methods的例子。
總的來說有三種table lookup的方法
- direct access
- indexed access
- stair-step acces
我對indexed理解不深,就講下剩下兩種。
所謂直接讀取就是將資料直接放進表中,上面的例子就是一個direct access的例子。還有一個比較好的例子,
就是計算月份天數,這個在K&R裡有,我就不粘代碼了。新手算一個月有多少天的話,肯定用if來算:
等等一直算到12月,但是如果用一個全域變數儲存著12個月的天數,看一個VB的例子:
在計算的話又只有一句代碼:
如果要計算閏年的話,就把一維數組改為二維就好了,再加個判斷閏年的函數。是不是很方便了。
上面這個應用還有點簡單,看一個資料是區間的情況下如何運用這種方法。一個非常古老的例子,如果
學產生績大於等於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方法即可。不用指標這麼容易出錯。