久久久国产精品视频袁燕,99re久久精品国产,亚洲欧美日韩国产综合v,天天躁夜夜躁狠狠久久,激情五月婷婷激情五月婷婷

程序小白
認(rèn)證:優(yōu)質(zhì)創(chuàng)作者
所在專題目錄 查看專題
【第一章】有限狀態(tài)機(jī)理論速成筆記
【第二章】HSM層次式狀態(tài)機(jī)理論(進(jìn)階版)
【第三章】有限狀態(tài)機(jī)(FSM)之炸彈項目(實戰(zhàn)1)
【第四章】有限狀態(tài)機(jī)(FSM)之炸彈項目(實戰(zhàn)2)
【第五章】有限狀態(tài)機(jī)(FSM)之炸彈項目(實戰(zhàn)3)
【第六章】層次式狀態(tài)機(jī)HSM = 有限狀態(tài)機(jī)FSM + 面向?qū)ο?
作者動態(tài) 更多
基于stm32采用PWM驅(qū)動伺服控制器學(xué)習(xí)筆記
05-13 15:25
基于STM32驅(qū)動TM1638學(xué)習(xí)筆記——軟件篇
04-19 12:42
基于TM1638驅(qū)動8位數(shù)碼管設(shè)計分享
02-24 11:26
RT-Thread驅(qū)動之路: Studio創(chuàng)建FAL分區(qū)⑤
01-02 08:30
RT-Thread驅(qū)動之路: Studio 掛載通用SPI flash④
2024-12-23 13:41

【第四章】有限狀態(tài)機(jī)(FSM)之炸彈項目(實戰(zhàn)2)

      前面講的定時炸彈的一種最基本的實現(xiàn)方式,但是條條大路通羅馬,總有大神出歪招,C語言的核心技能之一即將到達(dá)戰(zhàn)場,函數(shù)指針(這個詞有的童鞋可能比較陌生,也可能再別人程序上見到過,但是這種跳來跳去的操作總感覺和goto有的一拼,復(fù)雜難懂),對于指針大家用的更多的是變量指針,尤其是和數(shù)組一起用的時候,那種完美的數(shù)據(jù)流向真的很讓人沉醉,其實假如你真正的理解了函數(shù)指針的意義,那么你就知道他是C語言實現(xiàn)程序流向控制最核心的技術(shù)之一。

      夸得太多,其實現(xiàn)在開始講理論總是一個腦袋兩個大,還是先上例子,定時炸彈狀態(tài)表模式,如何用一個表來表示所有可能執(zhí)行的操作呢?

      我們把狀態(tài)和事件映射成一個二維的表,動作在表中定義,這樣就是可以做到最精細(xì)粒度的分解。  基于以上理論,我們實際把狀態(tài)機(jī)和事件聯(lián)合,映射成了一張狀態(tài)表,然后你需要構(gòu)造一個基于狀態(tài)表的通用事件處理器,其構(gòu)造如下:

基于上面的構(gòu)造圖,我們?nèi)绾握嬲么a來實現(xiàn)它,我們來看一下他具體實現(xiàn)的代碼,如下:

1.第一步,定義事件結(jié)構(gòu)體,根據(jù)上面的圖,代碼如下:

2.第二步,狀態(tài)表應(yīng)該是一個二維數(shù)組,在表中我們希望存有的是具體執(zhí)行的上下文,也就是函數(shù),但是函數(shù)本身并不能作為數(shù)據(jù)被存入表中,但是函數(shù)指針可以當(dāng)做數(shù)據(jù)被存入表中,而我們可以通過函數(shù)指針類型的變量來引用具體函數(shù),從而實現(xiàn)上下文的執(zhí)行,我們需要定義一個函數(shù)指針類型,如下:

3.第三部,有了前面的鋪墊,這里開始定義一個狀態(tài)表,如下:

4.第四部,實現(xiàn)ctor,init,dispatch三個構(gòu)造函數(shù),如下:

5.這里我們還需要定義一個狀態(tài)轉(zhuǎn)換宏,如下:

         小插曲:很久很久以前,我在思考一個問題,為什么要定義一個如此復(fù)雜的宏,當(dāng)所有的代碼都是需要我們自己寫的時候,我們不光要明白一處代碼的含義,還要精確地設(shè)計這里的代碼,這時候用不用宏其實都可以,但是假如我們設(shè)計的代碼是給別人來用的,他并不需要精確到設(shè)計的細(xì)節(jié),而是只需要理解這句代碼的含義,也就足夠了,這就是我們的對于軟件的設(shè)計理念不同所導(dǎo)致的,我們總想著徹底研究明白別人的代碼,別人設(shè)計的初衷其實是讓你快速的應(yīng)用,并不是徹底的理解。

         徹底的理解和應(yīng)用是兩個概念,年輕時候我鉆入的牛角尖就在這里,浪費了大把的精力從入門到放棄,關(guān)于對軟件的理念,從零重寫一整套代碼,遠(yuǎn)沒有熟練應(yīng)用一個成熟的系統(tǒng)更有價值,我們不是科學(xué)家,只是engineer,我們不生產(chǎn)構(gòu)架,只是構(gòu)架的搬運(yùn)工,舉個簡單的例子,例如你對安卓系統(tǒng)的理解和你對安卓系統(tǒng)的應(yīng)用,仔細(xì)想想,其實是兩個不同的命題,只是我們把命題弄反了,又扯遠(yuǎn)了。。。見諒。

      這里的dispatch是不是對比進(jìn)階1中基本被精簡很多了呢?這就是狀態(tài)表帶給我們的好處,接下來我們看一下bomb應(yīng)用state如何構(gòu)造真實的狀態(tài)表,及實例代碼,如下:

     1.main函數(shù)開始處,先會執(zhí)行bomb的ctor函數(shù),如下:

      每一處代碼都需要靜下心來,細(xì)細(xì)研究,慢慢的品味。

   2.執(zhí)行完構(gòu)造函數(shù)以后,那么就真正意義上構(gòu)造好一個statetable實例對象了,接下來需要初始化操作,讓我們的狀態(tài)表開始從初始狀態(tài)進(jìn)入到運(yùn)行階段,做好接收事件的準(zhǔn)備,調(diào)用順序如下:

   3.基于產(chǎn)生的事件,調(diào)用dispatch函數(shù)處理相應(yīng)的事件,如下:

      關(guān)于基于狀態(tài)表的方式設(shè)計的優(yōu)點,這里不想總結(jié)了,留給大家自行總結(jié),我們來說說他的缺點:

      1.第一,他看上去不怎么像狀態(tài)機(jī),而是變成狀態(tài)事件的一個聯(lián)合體,說白了把整個程序的精細(xì)粒度打的更散,你需要更多地狀態(tài)表結(jié)構(gòu)函數(shù),遠(yuǎn)多于狀態(tài)機(jī)。

      2.其二,擴(kuò)展?fàn)顟B(tài)機(jī)里面是有進(jìn)入和退出動作的, 這里該怎么加,它看上去更像Mearly機(jī),但有不符合Mearly機(jī)的定義,真正基于這個模型要擴(kuò)展有點難。

      3.第三,當(dāng)發(fā)生一個注冊狀態(tài)表之外的事件時,你需要明確的定義他,并忽略他,否則將會產(chǎn)生斷言,導(dǎo)致系統(tǒng)運(yùn)行出錯,這要求你在設(shè)計的時候要提一萬個心,防止以外的發(fā)生,異常處理不夠健壯。

      其實還有很多細(xì)節(jié),大家可以洗洗的品,比如狀態(tài)表結(jié)構(gòu)的聲明是一個函數(shù)指針,賦值的卻是一個二維數(shù)組,他們之間是如何發(fā)生轉(zhuǎn)換的,細(xì)細(xì)品很有意思,到這里我還特別想講講函數(shù)指針,但是這里還是把話咽到肚子里,留給大家自己思考和體會,在我們的后面設(shè)計通用的QEP事件處理器,他會再次粉末登場~!

      早這里,進(jìn)階2就結(jié)束了,下一章講講面向?qū)ο蟮臓顟B(tài)機(jī),這個版本是一個C++版本,也是我們的GUI事件驅(qū)動型系統(tǒng)應(yīng)用的根基,C語言實現(xiàn)多態(tài)還是有些復(fù)雜。到這里講先告一段落了,進(jìn)階3再見~!

聲明:本內(nèi)容為作者獨立觀點,不代表電子星球立場。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請聯(lián)系:editor@netbroad.com
覺得內(nèi)容不錯的朋友,別忘了一鍵三連哦!
贊 6
收藏 8
關(guān)注 151
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧