用表驅動代替switch case

2021-08-22 14:23:27 字數 2107 閱讀 8629

不知道從什麼時候開始,switch-case語句成了**壞味道的代名詞,寫**的時候小心翼翼地避開它,看到別人**中的switch-case就皺眉頭,想想其實大可不必這樣,switch-case語句並不是**壞味道的根源,壞味道來自糟糕的**(結構)設計,比如過多的switch-case分支,或者多重switch-case巢狀等等,這些都將導致**可讀性下降,如果再加上**風格較差,**不對齊,那麼壞味道就相當地大了。

簡短的switch-case還是繼續用吧,但是對於分支太多的長switch-case最好能想辦法化解開,那麼什麼算長什麼算短呢?我也不知道,就以在最低解析度的顯示器上能夠在乙個視窗中完整顯示整個switch-case塊為判斷依據吧。化解長switch-case的方法有很多種,用函式封裝或者巨集取代case塊是治標不治本的方法,使用表驅動通常是**這種頑症的有效方法,本文將介紹如何用表驅動方法化解長switch-case。

還是用例子說明問題吧,假設我們要為乙個系統編寫驅動,系統已經定義好了如下所示的復用介面(mux):

status driveriocontrol(uint function_no, pvoid para_in, pvoid para_out)

使用者層程式通過復用介面呼叫驅動,功能號就是function_no,驅動程式負責實現具體的driveriocontrol()函式完成相應的功能。這是使用switch-case的典型場景,先看乙個使用switch-case的方案:

status driveriocontrol(uint function_no, pvoid para_in, pvoid para_out)

return rc;

}status processa(pvoid para_in, pvoid para_out)

status processb(pvoid para_in, pvoid para_out)

status processc(pvoid para_in, pvoid para_out)

................

這個方案中規中矩,但是如果驅動很複雜,功能很多,那麼driveriocontrol函式**的長度是相當可觀的,好像已經聞到壞味道了,呵呵。現在換成使用巨集的解決方案:

#define dispatch_begin(func) switch(func) /

status driveriocontrol(uint function_no, pvoid para_in, pvoid para_out)

如果function_no不是線性的,那就需要查表:

typedef struct tagdispatchitem

dispatch_item;

dispatch_item dispatch_table[max_dispatch_item];

status driveriocontrol(uint function_no, pvoid para_in, pvoid para_out)

}return un_support;

}使用表驅動的好處就是driveriocontrol的**就這幾行,新增新功能,只需要維護驅動表dispatch_table就行了,就這樣擺脫了冗長乏味的switch-case。

前面例子中的switch-case語句中各個case分支引數比較簡單整齊,也就是各個case分支都是用相同的引數para_in和para_out,如果各個分支使用的引數不整齊怎麼辦?那就需要封裝,通常是用struct和union結合定義乙個統一的資料結構做為介面引數,不同的分支dispatch函式內部根據需要從這個統一的資料結構中提取相應的資料。具體方法就是首先定義統一的dispatch函式介面,例如:

typedef status (*processfuncptr)(dispatch_data *para);

然後用struct和union相結合定義dispatch_data,dispatch_data通常有這樣的結構:

typedef struct tagdispatch_data

processa;

union

processb;

union

processc;

......

}dispatch_data;

做過windows驅動程式的朋友肯定對irp不陌生,irp就是乙個典型的例子。

就這樣吧,打完,收工。

用表驅動代替switch case

不知道從什麼時候開始,switch case語句成了 壞味道的代名詞,寫 的時候小心翼翼地避開它,看到別人 中的switch case就皺眉頭,想想其實大可不必這樣,switch case語句並不是 壞味道的根源,壞味道來自糟糕的 結構 設計,比如過多的switch case分支,或者多重switc...

用表驅動代替switch case

不知道從什麼時候開始,switch case語句成了 壞味道的代名詞,寫 的時候小心翼翼地避開它,看到別人 中的switch case就皺眉頭,想想其實大可不必這樣,switch case語句並不是 壞味道的根源,壞味道來自糟糕的 結構 設計,比如過多的switch case分支,或者多重switc...

用bypass ujvc改驅動表

有一群友需要改update語句中的驅動表 update p set gflag 1 where exists select 1 from t where t.region b2 and t.cycle b1 and t.acctid p.acctid 因為t表返回資料較少,所以他想讓t做驅動表。一般...