在此之前,曾经分享过两种状态机的实现方法,有些朋友说有点难度,我想再补充一些基础实现方法以及思路,一步一步走,链接放在这里了:
(资料图片)
用C语言实现状态机(实用篇)
函数指针方法实现简单状态机(附代码)
本文将从最基础入门的方法,帮助大家了解状态机,从我常用的两种状态机编写方式为大家慢慢展开。
用switch/case的结构配合一个状态变量,通过修改状态变量的值来切换状态。
1//代码参考网络 2 3//!定义状态名称与状态值之间的关系 4#defineFSM_START0x00 5#defineFSM_STATE_A0x01 6#defineFSM_STATE_B0x02 7… 8#defineFSM_RESET0xFF 910boolfsm_example_A(<形参列表>){11staticuint8_ts_chFSMState=FSM_START;//!<定义状态变量12…13switch(s_chFSMState){14caseFSM_START:15//!这里添加状态机初始化代码16…17s_chFSMState=FSM_STATE_A;//!<进入下一状态18break;19caseFSM_STATE_A:20//!这里添加状态机A进入下一状态的检测代码21if(<某某条件>){22//!这里做一些进入下一状态时要做的准备工作23s_chFSMState=FSM_STATE_B;//!<进入下一状态24}25break;26caseFSM_STATE_B:27//!这里添加状态机A进入下一状态的检测代码28if(<某某条件>){29//!这里做一些进入下一状态时要做的准备工作30s_chFSMState=FSM_STATE_A;//!<进入下一状态31}elseif(<某某条件>){32}elseif(<某某条件>){33…34}else{35}36break;37…38caseFSM_STOP:39caseFSM_RESET:40default:41//!这里添加状态机复位相关的代码42…43chFSMState=FSM_START;//!<状态机复位44//!返回false表示状态机已经不需要继续运行了45returnfalse;46}4748//!返回true表示状态机正在运行49returntrue;50}
从代码可知,这种状态机就是一路走到黑,没有让多个状态同时处于激活状态,也就是说在同一时刻,只能处于一种状态之下。
无疑,实际中有很多这样的应用,比如简单的灯的开关,当然也有很多情况是多种状态并存的,比如天气的状态就可以分为晴天、阴天、风雨雷电等等,可以同时处于多个状态。
用if else…else if结构的组合来描述状态流程图。
1//代码参考网络 2//!首先将布尔量的状态标志压缩在一个字节里面以节省内存开支 3typedefunion{ 4uint8_tValue; 5uint8_tByte; 6struct{ 7unsignedBIT0:1; 8unsignedBIT1:1; 9unsignedBIT2:1;10unsignedBIT3:1;11unsignedBIT4:1;12unsignedBIT5:1;13unsignedBIT6:1;14unsignedBIT7:1;15}Bits;16}byte_t;1718#defineFSM_ACTION_FLAGs_tbState.Bits19#defineFSM_STOP_ALL_ACTIONS()do{s_tbState.Value=0;}while(0)20#defineFSM_START(0==s_tbState.Value)21#defineFSM_STATE_AFSM_ACTION_FLAG.BIT022#defineFSM_STATE_BFSM_ACTION_FLAG.BIT123…24#defineFSM_STATE_HFSM_ACTION_FLAG.BIT72526boolfsm_example_B(<形参列表>){27staticbyte_ts_tbState={0};//!<定义状态变量2829if(FSM_START){//!<起始状态30//!这里放置状态机初始化的代码31…32FSM_STATE_A=true;//!<进入状态B,start装台自动结束33}3435if(FSM_STATE_A){//!<一个典型的简单状态36//!这里放置状态A的代码或者37…38//!这里放置某些条件以开启别的状态39if(<某些条件>){40//!这里做一些“进入”下一个状态之前的准备工作41FSM_STATE_B=true;//!<开启下一个状态42FSM_STATE_A=false;//!<结束当前状态43}44}4546if(FSM_STATE_B){//!<一个典型的监视状态47…48//!这里检测某些条件49if(<某些条件>){50//!这里做一些“开启”某个状态的准备工作51FSM_STATE_C=true;//!<开启某一个状态而不结束当前状态52FSM_STATE_D=true;//!<你当然可以一次触发多个状态53…54}elseif(<某些条件>){55//!满足某些条件以后关闭当前状态56FSM_STATE_B=false;57}58}59…60if(FSM_STATE_F){//!<一个典型的子状态机调用61if(!fsm_example_a(<实参列表>)){//!<等待子状态机返回false62//!子状态机运行完成,进入下一状态63…64FSM_STATE_F=false;//!<结束当前状态65FSM_STATE_x=true;//!<进入下一状态x代表某个字母66}67}6869if(FSM_STATE_H){//!<一个典型的中止状态70//!<某些状态机的操作,比如释放某些资源71…72FSM_STOP_ALL_ACTIONS();//!<复位状态机73returnfalse;//!<返回false表示状态机结束74}7576returntrue;//!<返回true表示状态机保持运行77}
从范例可知,这种状态机虽然看起来比较费脑子,但是在应用当中非常灵活,通过布尔变量的开启和关闭,你可以自由的控制某些状态的开启。
并且同一时刻可能有多个状态是激活的,这种结构几乎可以翻译任何流程图。
所有的函数都可以看作是状态机,如果函数有返回值,且这个返回值能表征至少两种以上不同的状态,那么这些返回值就可以被用作指示当前状态机的运行情况。
在我们实际编程中,我们也需要有这样的思维,比如函数之间的引用,参数传递,这些都可以当作一个状态,那么我们编码的过程中,就能够根据状态运行进行相应的模块化。
我们经常会用到的枚举类型,来写测试用例,以判断程序具体执行到函数体的哪一块了
1enum 2{ 3test1=0, 4test2, 5test3, 6test4, 7... 8} 910//举个简单的例子,根据返回值判断函数运行到哪里,来判断逻辑走向11inttestDemo()12{13if(FSM_STATE_A){14if(<某些条件>){15returntest1;16}else{17returntest2;18}19}else{20returntest3;21}22returntest4;23}
状态机可以说是一个万能的计算机语言表述方式,应用很广泛,是裸机条件下多任务的廉价实现方案。
在带有操作系统的情况下也是如此,我们了解了状态机的本质,能够运用得当的话,对我们的模块化编程,代码的整理是很有帮助的。
标签:
精彩推荐
美苹果店开售智能门锁、购小米智能门锁赠台灯+NFC门卡、京东智能门锁采用PB指纹、华为再推智能门锁SE…...
近日,山东省高级人民法院向社会通报全省法院消费者权益司法保护工作情况及10起典型案例。据了解,五年...
南京市19日通报,公安部门在疫情防控期间依法打击各类涉疫违法犯罪行为,截至3月18日,全市共查处各类涉...
日前,北京市人民政府新闻办公室举行新闻发布会,解读《北京市全民科学素质行动规划纲要(2021—2035年)...
去年下半年以来,受多重因素影响,房地产市场出现下行态势。今年以来,各方共同努力持续稳地价、稳房价...
联合国人权理事会第49届会议新疆经济社会发展与人权保障边会18日在广州举办。会议由中国人权研究会、中...
人力资源和社会保障部近日印发《关于开展技术技能类山寨证书专项治理工作的通知》(以下简称《通知》),...
针对网络消费乱象,最高人民法院近期发布《最高人民法院关于审理网络消费纠纷案件适用法律若干问题的规...
当好农民工的“护薪人” 近日,罗某等7名农民工在收到被拖欠的工资后,纷纷打电话向江西省南昌市...
“通讯录里所有人都知道我欠钱了” □ 本报记者 韩丹东 □ 本报见习记者 张守坤 ...
大连宝马车撞人案肇事司机被判死刑 本报讯 记者韩宇 10月29日,辽宁省大连市中级人民法院一审...
医院财务迷上网络赌博输光5000万元公款 □ 本报记者 马维博 □ 本报通讯员 汪宇堂 曹...
辊环车削 雕琢毫厘(工匠绝活) 【绝活看点】 23年来,雷虎始终扎根一线,改进钢材轧制工艺...
交警严查超标电动自行车挪用“白牌” 截至昨晚6时,处罚电动自行车违法行为共计6585笔;下一步将...
明起寒潮来袭 北方气温普降10℃以上 中央气象台预计,本周日北京平原地区最低气温降至-4℃左右...
多种蔬菜价格降幅达五成 包括菠菜、蒿子秆等 预计本月中旬蔬菜恢复供需平衡 本报讯(记者...
北京周日最低气温或达-4℃ 本报讯(记者 赵婷婷)北京青年报记者昨天从中央气象台获悉,新一股...
昌平一家四口确诊新冠肺炎 天通北苑第二社区升级为中风险地区 朝阳两涉疫校区及16所学校停课 ...
人社部发布通知 事业单位招聘可适当降低学历要求 昨日,人社部发布《关于职业院校毕业生参加...
民警马拓 在地铁里看见人生百态 写下200多个故事 他们积极努力生活的样子 全都是最好的素材 ...
资讯News
05-06
05-06
05-06
05-06
05-06
05-06
05-06
05-06
05-06
05-06
05-06
05-06
05-06
05-06
05-06
05-06
05-06
05-06
05-06
05-06
聚焦Policy
当好农民工的“护薪人” 近日,罗某等7名农民工在收到被拖欠的工资后,纷纷打电话向江西省南昌市...
“通讯录里所有人都知道我欠钱了” □ 本报记者 韩丹东 □ 本报见习记者 张守坤 ...
大连宝马车撞人案肇事司机被判死刑 本报讯 记者韩宇 10月29日,辽宁省大连市中级人民法院一审...
医院财务迷上网络赌博输光5000万元公款 □ 本报记者 马维博 □ 本报通讯员 汪宇堂 曹...
辊环车削 雕琢毫厘(工匠绝活) 【绝活看点】 23年来,雷虎始终扎根一线,改进钢材轧制工艺...
交警严查超标电动自行车挪用“白牌” 截至昨晚6时,处罚电动自行车违法行为共计6585笔;下一步将...
明起寒潮来袭 北方气温普降10℃以上 中央气象台预计,本周日北京平原地区最低气温降至-4℃左右...
多种蔬菜价格降幅达五成 包括菠菜、蒿子秆等 预计本月中旬蔬菜恢复供需平衡 本报讯(记者...
北京周日最低气温或达-4℃ 本报讯(记者 赵婷婷)北京青年报记者昨天从中央气象台获悉,新一股...
昌平一家四口确诊新冠肺炎 天通北苑第二社区升级为中风险地区 朝阳两涉疫校区及16所学校停课 ...