rel="file-list" href="file:///g:%5ctmp%5cmsohtml1%5c01%5cclip_filelist.xml">函式指標,領域語言,亂彈
實現乙個模組
ct,該模組的需求如下:
ct的收到資料後,進行處理,並將結果輸出可能有三個不同的地方,我們稱之為
am,bm,cm
(稱為模組
a, 模組
b, 模組c)。
並且在模組的執行過程中,有可能改變輸出的位置
(叢輸出到模組
a變更為輸出到模組b)。
模組a,
模組b, 模組c
會給ct
傳送反饋資訊,收到這些資訊之後,
ct將進行
lcd顯示,
led點燈,
buzzer
鳴動。根據反饋的資訊不同,以上三個資訊也會不同。
ct在未收到反饋之前,再次收到資料的話,將這些資料丟棄。
(也有可能快取起來,收到反饋之後,再處理快取的資料)
設計時的考慮: 1,
由於輸出有
3個不同的地方,我們很自然的想到抽象。將輸出的動作抽象為統一的介面。這樣
ct模組的絕大多數處理邏輯將不會意識到具體的輸出地。當然,一部分的處理邏輯需要了解並控制輸出到哪個模組。但是,我們想得到的是集中控制。這種控制權要集中在乙個或者盡肯能少函式中。這種控制邏輯越混亂,**出錯的可能性就越高。 2,
ct在收到資料時,要進行
lcd顯示,
led點燈,
buzzer
鳴動處理。並且根據反饋的資訊不同,以上三個資訊也會不。由於這種處理是相當容易變化的,(
lcd顯示什麼內容?哪個
led需要點亮,需要
buzzer
多長時間?等),所以我們不能將這種易變的,細節的內容放進**中。而應該將其放到外部配置檔案或資料中。 3,
ct模組很明顯有根據狀態的不同,作不同的處理的邏輯。狀態模式能夠排上用場。
實現時的考慮: 1,
抽象出輸出功能的介面。很自然,函式指標。在更改輸出位置時,只需要重新設定該指標就可以了。 2,
lcd顯示,
led點燈,
buzzer
鳴動的控制資訊,我們很容易想到
xml配置檔案,
xml檔案稍嫌複雜,有點兒大材小用了。不過這種簡單的功能我們可以使用表達力更強的領域語言來描述。也就是說,我們站在更高階的抽象層上進行思考,設計,實現。形如
dsv(delimiter-separated values)
字串的格式就可以勝任該工作。有變化時,直接修改
dsv字串。體現了將細節放進元資料,將抽象放進**的思想。 3,
ct模組的狀態。有基於表的狀態遷移的實現和基於
robert c. martin
的三層狀態機實現。考慮到僅有兩個狀態,就不用勞駕複雜的三層狀態機了。體現了實現複雜度和問題域間的一種權衡。
下面是基於這種考慮的乙個架子性實現。
#include
typedef
unsigned
char
uc ;
typedef
unsigned
short us ;
typedef
unsigned
long
ul ;
typedef
intsmessage ;
typedef
enum
ct_sts ;
typedef
ul ( * pfcmevicehandler ) ( smessage * pmessage ) ;
static
pfcmevicehandler gpfcmevicehandlers ;
static
ul am_handler ( smessage * pmessage ) ;
static
ul bm_handler ( smessage * pmessage ) ;
static
ul cm_handler ( smessage * pmessage ) ;
static
pfcmevicehandler gpfnamhandlers =am_handler ;
static
pfcmevicehandler gpfnbmhandlers =bm_handler ;
static
pfcmevicehandler gpfncmhandlers =cm_handler ;
typedef
pfcmevicehandlerpfnmatrixhandler ;
/* [idle .. processing] */
static
ul idle_handler ( smessage * pmessage ) ;
static
ul proc_handler ( smessage * pmessage ) ;
static
pfnmatrixhandlergmatrixhandler = ;
static
ct_sts gsts ;
/* lcd
、led、ブザーの処理*/
/* 次のフォーマットで表す*/
/* [lcd msg]: [led ok/ng]: [time]: [buzza on]: [off]: [cnt] */
#define
llb_separator
": "
#define
llb_scenario_1 "null: ok: 100: 200: 0: 1"
#define
llb_scenario_2 "msg1: ng: 100: 200: 200: 3"
#define
llb_scenario_3 "msg2: ng: 100: 200: 200: 3"
typedef
struct lcdledbuzzactrlinfo
lcdledbuzzactrlinfo ;
static
lcdledbuzzactrlinfo parsedl( const
char * pdl ) ;
static
void
processdl( lcdledbuzzactrlinfo * info ) ;
int_tmain(int argc, _tchar* argv)
ul am_handler ( smessage * pmessage )
ul bm_handler ( smessage * pmessage )
ul cm_handler ( smessage * pmessage )
ul idle_handler ( smessage * pmessage )
ul proc_handler ( smessage * pmessage )
lcdledbuzzactrlinfo parsedl( const
char * pdl )
printf("lcd->%s, led->%s:%s, buzza->%s:%s:%s/n" ,
plcdmsg ,
pledtype , pledtime ,
pbuzontime , pbuzofftime , pbuzcnt ) ;
return info ;
} void
processdl( lcdledbuzzactrlinfo * info )
C語言 指標函式和函式指標
指標函式和函式指標 指標函式其實是乙個簡稱,是指帶指標的函式,它本質上是乙個函式,只是返回的是某種型別的指標。其定義的格式為 型別識別符號 函式名 參數列 函式指標,從本質上說是乙個指標,只是它指向的不是一般的變數,而是乙個函式。因為每個函式都有乙個入口位址,函式指標指向的就是函式的入口位址。其定義...
C語言 指標函式和函式指標
1 指標函式是指帶指標的函式,本質上是乙個函式,函式返回值是某一型別的指標 定義 型別識別符號 函式名 參數列 int f int x,int y 它首先是乙個函式,只不過這個函式的返回值是乙個位址值,函式返回值必須用同型別的指標變數來接受,也就是說,指標函式一定有函式返回值,而且,在主調函式中,函...
c語言函式指標與指標函式
include include include using namespace std 1 c語言函式指標 解釋 這是一種很特殊的指標,它的指向是乙個函式的入口 作用 該指標可以接受乙個函式的位址,代表這個函式執行函式的操作 函式指標舉例 下面是乙個函式指標pfunc,它只能指向返回值為float,...