一,什麼是表驅動(出處《**大全》,對軟體感興趣者,此書值得一看)
表驅動,又稱之為表驅動法、表驅動方法。
「表」是幾乎所有資料結構課本都要討論的非常有用的資料結構。表驅動方法出於特定的目的來使用表,程式設計師們經常談到「表驅動」方法,但是課本中卻從未提到過什麼是"表驅動"方法。表驅動方法是一種使你可以在表中查詢資訊,而不必用很多的邏輯語句(if或case)來把它們找出來的方法。事實上,任何資訊都可以通過表來挑選。在簡單的情況下,邏輯語句往往更簡單而且更直接。但隨著邏輯鏈的複雜,表就變得越來越富有吸引力了,通過下面的這個例子大家就能知道什麼是所謂的表驅動方法了。
假設你需要乙個可以返回每個月中天數的函式(為簡單起見不考慮閏年),
乙個比較笨的方法是乙個大的if語句:
int igetmonthdays(int imonth)
else if(2 == imonth)
else if(3 == imonth)
else if(4 == imonth)
else if(5 == imonth)
else if(6 == imonth)
else if(7 == imonth)
else if(8 == imonth)
else if(9 == imonth)
else if(10 == imonth)
else if(11 == imonth)
else if(12 == imonth)
return idays;
} 可以看出本來應該很簡單的一件事情,**卻是這麼冗餘,解決這個的辦法就可以用表驅動方法。
static int aimonthdays[12] = ;
// 我們可以先定義乙個靜態陣列,這個陣列用來儲存一年十二個月的天數
int igetmonthdays(int imonth)
接下來不用多說了,大家都能看出用這種表驅動的方法代替這種情邏輯性不強,但分支很多的**是多麼令人"賞心悅目"的了。
函式:
函式指標在表驅動方法中的應用
在使用表驅動方法時需要說明的乙個問題是,你將在表中儲存些什麼。
在某些情況下,表查尋的結果是資料。如果是這種情況,你可以把資料儲存在表中。
在其它情況下,表查尋的結果是動作。在這種情況下,你可以把描述這一動作的**儲存在表中。
在某些語言中,也可以把實現這一動作的子程式的呼叫儲存在表中,也就是將函式的指標儲存在表中,當查詢到這項時,讓程式用這個函式指標來呼叫相應的程式**,這個就是函式指標在表驅動方法中的應用。
其實說到這已經說了很多表驅動方法的相關問題了,現在要把函式指標也應用進去,很多人應該已經想到會是個什麼樣子了,其實也很簡單,通過下面這兩段偽**的例子就可以充分體現函式指標在表驅動方法中應用會使**更加精緻。
我們在寫一段程式的過程中會經常遇到這樣的問題,我們在寫乙個task的主函式中有時會要等待不同的event通知,並且處理不同的分支,首先有如下的event bit的巨集定義和相應的處理函式的宣告。
#define task_event_bit00 (1 << 0)
#define task_event_bit01 (1 << 1)
#define task_event_bit02 (1 << 2)
#define task_event_bit03 (1 << 3)
#define task_event_bit04 (1 << 4)
#define task_event_bit05 (1 << 5)
#define task_event_bit06 (1 << 6)
#define task_event_bit07 (1 << 7)
#define task_event_bit08 (1 << 8)
#define task_event_bit09 (1 << 9)
void vdowithevent00();
void vdowithevent01();
void vdowithevent02();
void vdowithevent03();
void vdowithevent04();
void vdowithevent05();
void vdowithevent06();
void vdowithevent07();
void vdowithevent08();
void vdowithevent09();
我們一般首先想到的寫法是
unsigned long uleventbit;
for(;;)
if(uleventbit & task_event_bit01)
if(uleventbit & task_event_bit02)
if(uleventbit & task_event_bit03)
if(uleventbit & task_event_bit04)
if(uleventbit & task_event_bit05)
if(uleventbit & task_event_bit06)
if(uleventbit & task_event_bit07)
if(uleventbit & task_event_bit08)
if(uleventbit & task_event_bit09)
} 可以看出這樣寫是不是顯得程式太長了呢。
下面我們再看看同樣的一段**用函式指標和表驅動方法結合的方法寫出會是什麼樣子。
typedef struct eventdowithtable_t;
/* 定義eventbit 與相應處理函式關係的結構體 */
static const eventdowithtable_t astdowithtable = ,
, ,
, ,
, ,
, ,
}; /* 建立eventbit與相應處理函式的關係表 */
ulong uleventbit;
int i;
for(;;)
} }
可以看出這種**的風格使**變得精緻得多了,並且使程式的靈活性大大加強了,如果我們還要再加入eventbit,只修改表中的內容就可以了。
總結 通過上面介紹的,相信大家已經對函式指標的使用方法有所了解了,但是需要提醒大家,凡事都要具體情況具體分析,使用函式指標的時候一定要多加小心,因為函式指標有它的乙個致命的缺點。
函式指標的致命缺點是:無法對引數 (parameter) 和返回值 (return value) 的型別進行檢查,因為函式已經退化成指標,指標是不帶有這些型別資訊的。少了型別檢查,當引數或者反回值不一致時,會造成嚴重的錯誤。有些編譯器並不會幫我們找出函式指標這樣的致命錯誤。所以,許多新的程式語言都不支援函式指標了,而改用其他方式。
從上面的例3中我們可以看到
int max(int x,int y)
int min(int x,int y)
這三個函式都有兩個引數,而在後面卻把處理函式定義成
int process(int x,int y, int (*f)())
其中第三個引數是乙個函式的指標,從表面上看它是個沒有引數,並且返回int型的函式的指標,但是在後面卻用process(a,b,max)的方式進行呼叫,max帶有兩個引數,這段程式在c語言中就可以順利的編譯通過(但是在c++中卻編譯不通過),可以看出如果編譯器沒有檢查出錯誤,而我們又不小心寫錯的話,後果是很嚴重的,比如return (*f)(x,y);不小心寫成return (*f)(x);在c語言中可以正常的被編譯通過,但是執行結果一定不是我們想要的。
因此在c語言中使用函式指標的時候,一定要小心「型別陷阱」,小心地使用函式指標,只有這樣我們才可以從函式指標中獲益。
AnimateWindow 百度百科
animatewindow 開放分類 程式設計 計算機 api 函式功能 該函式能在顯示與隱藏視窗時能產生特殊的效果。有兩種型別的動畫效果 滾動動畫和滑動動畫。函式原型 bool animatewindow hwnd hwnd,dword dwtime,dword dwflags 引數 hwnd 指...
WCF百度百科
根據微軟官方的解釋,wcf 之前的版本名為 indigo 是使用託管 建立和執行面向服務 service oriented 應用程式的統一框架。它使得開發者能夠建立乙個跨平台的安全 可信賴 事務性的解決方案,且能與已有系統相容協作。wcf是微軟分布式應用程式開發的集大成者,它整合了.net平台下所有...
Mashup 百度百科
mashup是糅合,是當今網路上新出現的一種網路現象,將兩種以上使用公共或者私有資料庫的web應用,加在一起,形成乙個整合應用。一般使用源應用的api介面,或者是一些rss輸出 含atom 作為內容源,合併的web應用用什麼技術,則沒有什麼限制。mashup在geek群體和網際網路玩家之中獲得了極大...