狀態(tài)機(jī)思路在單片機(jī)程序設(shè)計中的應(yīng)用_第1頁
狀態(tài)機(jī)思路在單片機(jī)程序設(shè)計中的應(yīng)用_第2頁
狀態(tài)機(jī)思路在單片機(jī)程序設(shè)計中的應(yīng)用_第3頁
狀態(tài)機(jī)思路在單片機(jī)程序設(shè)計中的應(yīng)用_第4頁
狀態(tài)機(jī)思路在單片機(jī)程序設(shè)計中的應(yīng)用_第5頁
已閱讀5頁,還剩12頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

狀態(tài)機(jī)思路在單片機(jī)程序設(shè)計中的應(yīng)用1,狀態(tài)機(jī)的概念:狀態(tài)機(jī)是軟件編程中的一個重要概念。比這個概念更重要的是對它的靈活應(yīng)用。在一個思路清晰而且高效的程序中,必然有狀態(tài)機(jī)的身影浮現(xiàn)。比如說一個按鍵命令解析程序,就可被看做狀態(tài)機(jī):本來在A狀態(tài)下,觸發(fā)一個按鍵后切換到了B狀態(tài);再觸發(fā)另一個鍵后切換到C狀態(tài),或者返回到A狀態(tài)。最簡按鍵狀態(tài)機(jī)例。實際按鍵解析程序比這更復(fù)雜,但不影響我們對狀態(tài)機(jī)的認(rèn)識。進(jìn)一步,擊鍵動作本身也可看做一個狀態(tài)機(jī)。一個細(xì)小的擊鍵動作包含了:釋放、抖動、閉合、抖動和重新釋放等狀態(tài)。同樣,一個串行通信的時序(不管它是遵循何種協(xié)議,標(biāo)準(zhǔn)串口也好、I2C也好;也不管它是有線的、還是紅外的、無線的)也都可看做由一系列有限的狀態(tài)構(gòu)成。顯示掃描程序也是狀態(tài)機(jī);通信命令解析程序也是狀態(tài)機(jī);甚至連繼電器的吸合/釋放控制、發(fā)光管(LED)的亮/滅控制又何嘗不是個狀態(tài)機(jī)。當(dāng)我們打開思路,把狀態(tài)機(jī)作為一種思想導(dǎo)入到程序中去時,就會找到解決問題的一條有效的捷徑。有時候用狀態(tài)機(jī)的思維去思考程序該干什么,比用控制流程的思維去思考,可能會更有效。這樣一來狀態(tài)機(jī)便有了更實際的功用。2,程序其實就是狀態(tài)機(jī):也許你還不理解上面這句話。請想想看,計算機(jī)的大廈不就是建立在“0”和“1”兩個基本狀態(tài)的地基之上么?3,狀態(tài)機(jī)的要素:狀態(tài)機(jī)可歸納為4個要素,即現(xiàn)態(tài)、條件、動作、次態(tài)。這樣的歸納,主要是出于對狀態(tài)機(jī)的內(nèi)在因果關(guān)系的考慮?!艾F(xiàn)態(tài)”和“條件”是因,“動作”和“次態(tài)”是果。詳解如下:①現(xiàn)態(tài):是指當(dāng)前所處的狀態(tài)。②條件:又稱為“事件”。當(dāng)一條件被滿足,將觸發(fā)一動作,或執(zhí)行一狀態(tài)的遷移。③動作:條件滿足后執(zhí)行的動作。動作執(zhí)行完畢后,可遷移到新狀態(tài),也可仍舊保持原狀。動作非必需的,當(dāng)條件滿足后,也可不執(zhí)行任何動作,直接遷移到新狀態(tài)。④次態(tài):條件滿足后要遷往的新狀態(tài)。“次態(tài)”是相對于“現(xiàn)態(tài)”而言的,“次態(tài)”一旦被激活,就轉(zhuǎn)變成新的“現(xiàn)態(tài)”了。若我們進(jìn)一步歸納,把“現(xiàn)態(tài)”和“次態(tài)”統(tǒng)一起來,而把“動作”忽略(降格處理),則只剩下兩個最關(guān)鍵的要素,即:狀態(tài)、遷移條件。狀態(tài)機(jī)的表示方法有多種,可用文字、圖形或表格的形式來表示一個狀態(tài)機(jī)。純粹用文字描述是很低效的,所以就不介紹了。接下來先介紹圖形的方式。4,狀態(tài)遷移圖(STD):狀態(tài)遷移圖(STD),是一種描述系統(tǒng)的狀態(tài)、以及相互轉(zhuǎn)化關(guān)系的圖形方式。狀態(tài)遷移圖的畫法有許多種,不過一般都大同小異。我們結(jié)合一個例子來說明一下它的畫法,如圖1所示。圖1狀態(tài)遷移圖①狀態(tài)框:用方框表示狀態(tài),包括所謂的“現(xiàn)態(tài)”和“次態(tài)”。②條件及遷移箭頭:用箭頭表示狀態(tài)遷移的方向,并在該箭頭上標(biāo)注觸發(fā)條件。③節(jié)點圓圈:當(dāng)多個箭頭指向一個狀態(tài)時,可用節(jié)點符號(小圓圈)連接匯總。④動作框:用橢圓框表示。⑤附加條件判斷框:用六角菱形框表示。狀態(tài)遷移圖和我們常見的流程圖相比有著本質(zhì)的區(qū)別,具體體現(xiàn)為:在流程圖中,箭頭代表了程序PC指針的跳轉(zhuǎn);而在狀態(tài)遷移圖中,箭頭代表的是狀態(tài)的改變。我們會發(fā)現(xiàn),這種狀態(tài)遷移圖比普通程序流程圖更簡練、直觀、易懂。這正是我們需要達(dá)到的目的。狀態(tài)遷移表除了狀態(tài)遷移圖,我們還可用表格的形式來表示狀態(tài)之間的關(guān)系。這種表一般稱為狀態(tài)遷移表。表1就是前面介紹的那張狀態(tài)遷移圖的另一種描述形式。表1狀態(tài)遷移表狀態(tài)(現(xiàn)態(tài))狀態(tài)描述條件動作次態(tài)狀態(tài)1條件1狀態(tài)2條件2動作1狀態(tài)3狀態(tài)2條件3附加條件滿足狀態(tài)4附加條件不滿足狀態(tài)3條件5狀態(tài)1條件6動作2狀態(tài)2狀態(tài)3條件4狀態(tài)4條件5狀態(tài)1狀態(tài)4條件5狀態(tài)1①采用表格方式來描述狀態(tài)機(jī),優(yōu)點是可容納更多的文字信息。例如,我們不但可在狀態(tài)遷移表中描述狀態(tài)的遷移關(guān)系,還可把每個狀態(tài)的特征描述也包含在內(nèi)。②若表格內(nèi)容較多,過于臃腫不利于閱讀,我們也可將狀態(tài)遷移表進(jìn)行拆分。經(jīng)過拆分后的表格根據(jù)其具體內(nèi)容,表格名稱也有所變化。③比如,我們可把狀態(tài)特征和遷移關(guān)系分開列表。被單獨拆分出來的描述狀態(tài)特征的表格,也可稱為“狀態(tài)真值表”。這其中比較常見的就是把每個狀態(tài)的顯示內(nèi)容單獨列表。這種描述每個狀態(tài)顯示內(nèi)容的表稱之為“顯示真值表”。同樣,我們把單獨表述基于按鍵的狀態(tài)遷移表稱為“按鍵功能真值表”。另外,若每一個狀態(tài)包含的信息量過多,我們也可把每個狀態(tài)單獨列表。④由此可見,狀態(tài)遷移表作為狀態(tài)遷移圖的有益補(bǔ)充,它的表現(xiàn)形式是靈活的。⑤狀態(tài)遷移表優(yōu)點是信息涵蓋面大,缺點是視覺上不夠直觀,因此它并不能取代狀態(tài)遷移圖。比較理想的是將圖形和表格結(jié)合應(yīng)用。用圖形展現(xiàn)宏觀,用表格說明細(xì)節(jié)。二者互為參照,相得益彰。用狀態(tài)機(jī)思路實現(xiàn)一個時鐘程序接下來,我將就狀態(tài)機(jī)的應(yīng)用,結(jié)合流程圖、狀態(tài)遷移圖和狀態(tài)遷移,舉一個實際例子。下面這張圖是一個時鐘程序的狀態(tài)遷移圖,如圖2所示。圖2時鐘程序狀態(tài)遷移圖把這張圖稍做歸納,就可得到它的另一種表現(xiàn)形式——狀態(tài)遷移表,如表2所示。表2時鐘程序狀態(tài)遷移表工作狀態(tài)(現(xiàn)態(tài))狀態(tài)描述A鍵B鍵顯示內(nèi)容編號說明次態(tài)功能次態(tài)功能0顯示時間1-3-時:分:秒(12:00:001狀態(tài)2顯示鬧鐘2-5-時:分(12:00)2顯示秒表0--啟動/停止時:分:秒(12:00:003設(shè)置小時-時+14-(12:▋▋:▋▋)4設(shè)置分鐘-分+1;秒=00-(▋▋:00:00)5設(shè)置鬧鐘“時”-時+16-(TM:00:▋▋)6設(shè)置鬧鐘“分”-分+17-(TM:▋▋:00)7設(shè)置鳴叫時間-鳴叫分鐘+11-(TM:SP:00狀態(tài)機(jī)應(yīng)用的注意事項基于狀態(tài)機(jī)的程序調(diào)度機(jī)制,其應(yīng)用的難點并不在于對狀態(tài)機(jī)概念的理解,而在于對系統(tǒng)工作狀態(tài)的合理劃分。初學(xué)者往往會把某個“程序動作”當(dāng)作是一種“狀態(tài)”來處理。我稱之為“偽態(tài)”。那么如何區(qū)分“動作”和“狀態(tài)”。本匠人的心得是看二者的本質(zhì):“動作”是不穩(wěn)定的,即使沒有條件的觸發(fā),“動作”一旦執(zhí)行完畢就結(jié)束了;而“狀態(tài)”是相對穩(wěn)定的,若沒有外部條件的觸發(fā),一個狀態(tài)會一直持續(xù)下去。初學(xué)者的另一種比較致命的錯誤,就是在狀態(tài)劃分時漏掉一些狀態(tài)。我稱之為“漏態(tài)”?!皞螒B(tài)”和“漏態(tài)”這兩種錯誤的存在,將會導(dǎo)致程序結(jié)構(gòu)的渙散。因此要特別小心避免。更復(fù)雜的狀態(tài)機(jī)前面介紹的是一種簡單的狀態(tài)結(jié)構(gòu)。它只有一級,并且只有一維,如圖3所示。圖3線性狀態(tài)機(jī)結(jié)構(gòu)若有必要,我們可建立更復(fù)雜的狀態(tài)機(jī)模型。1多級狀態(tài)結(jié)構(gòu)狀態(tài)機(jī)可是多級的。在分層的多級狀態(tài)機(jī)系統(tǒng)中,一“父狀態(tài)”下可劃分多個“子狀態(tài)”,這些子狀態(tài)共同擁有上級父狀態(tài)的某些共性,同時又各自擁有自己的一些個性。在某些狀態(tài)下,還可進(jìn)一步劃分子狀態(tài)。如我們可把前面的時鐘例子修改如下:

把所有和時鐘功能有關(guān)的狀態(tài),合并成1個一級狀態(tài)。在這個狀態(tài)下,又可劃分出3個二級子狀態(tài),分別為顯示時間、設(shè)置小時、設(shè)置分鐘;同樣,我們也可把所有和鬧鐘功能有關(guān)的狀態(tài),合并成1個一級狀態(tài)。在此狀態(tài)下,再劃分出4個二級子狀態(tài),分別為顯示鬧鐘、設(shè)置“時”、設(shè)置“分”、設(shè)置鳴叫時間。我們需要用另一個狀態(tài)變量(寄存器)來表示這些子狀態(tài)。子狀態(tài)下面當(dāng)然還可有更低一級的孫狀態(tài)(子子孫孫無窮盡也),從而將整個狀態(tài)體系變成了樹狀多級狀態(tài)結(jié)構(gòu),如圖4所示。圖4樹狀多級狀態(tài)結(jié)構(gòu)2多維狀態(tài)結(jié)構(gòu)狀態(tài)結(jié)構(gòu)也可是多維的。從不同的角度對系統(tǒng)進(jìn)行狀態(tài)的劃分,這些狀態(tài)的某些特性是交叉的。比如,在按照按鍵和顯示劃分狀態(tài)的同時,又按照系統(tǒng)的工作進(jìn)程做出另一種狀態(tài)劃分。這兩種狀態(tài)劃分同時存在,相互交叉,從而構(gòu)成了二維的狀態(tài)結(jié)構(gòu)空間。舉一個這方面的例子,如:空調(diào)遙控器,如圖5所示。圖5多維狀態(tài)機(jī)結(jié)構(gòu)同樣,我們也可構(gòu)建三維、四維甚至更多維的狀態(tài)結(jié)構(gòu)。每一維的狀態(tài)都需要用一個狀態(tài)變量(寄存器)來表示。無論多級狀態(tài)結(jié)構(gòu)和多維狀態(tài)結(jié)構(gòu)看上去多么迷人,匠人的忠告是:我們依然要盡可能地簡化狀態(tài)結(jié)構(gòu),能用單級、單維的結(jié)構(gòu),就不要給自己找事,去玩那噩夢般的復(fù)雜結(jié)構(gòu)。簡單的才是最有效的。結(jié)束語對狀態(tài)機(jī)的理解需要一個由淺入深的過程。這個過程應(yīng)該是與實踐應(yīng)用和具體案例思考相結(jié)合的。當(dāng)一種良好的思路成為設(shè)計的習(xí)慣,它就能給設(shè)計者帶來回報。愿這篇手記里介紹的基于狀態(tài)機(jī)的編程思路能給新手們帶來一些啟迪,幫助大家找到“程序設(shè)計”的感覺?!巨D(zhuǎn)載1】有限狀態(tài)機(jī)的實現(xiàn)<type="text/javascript">有限狀態(tài)機(jī)(FiniteStateMachine或者FiniteStateAutomata)是軟件領(lǐng)域中一種重要的工具,很多東西的模型實際上就是有限狀態(tài)機(jī)。最近看了一些游戲編程AI的材料,感覺游戲中的AI,第一要說的就是有限狀態(tài)機(jī)來實現(xiàn)精靈的AI,然后才是A*尋路,其他學(xué)術(shù)界討論比較多的神經(jīng)網(wǎng)絡(luò)、模糊控制等問題還不是很熱。FSM的實現(xiàn)方式:1)switch/case或者if/else這無意是最直觀的方式,使用一堆條件判斷,會編程的人都可做到,對簡單小巧的狀態(tài)機(jī)來說最合適,但是毫無疑問,這樣的方式比較原始,對龐大的狀態(tài)機(jī)難以維護(hù)。2)狀態(tài)表維護(hù)一個二維狀態(tài)表,橫坐標(biāo)表示當(dāng)前狀態(tài),縱坐標(biāo)表示輸入,表中一個元素存儲下一個狀態(tài)和對應(yīng)的操作。這一招易于維護(hù),但是運(yùn)行時間和存儲空間的代價較大。3)使用StatePattern使用StatePattern使得代碼的維護(hù)比switch/case方式稍好,性能上也不會有很多的影響,但是也不是100%完美。不過RobertC.Martin做了兩個自動產(chǎn)生FSM代碼的工具,forjava和forC++各一個,在/resources/index上有免費下載,這個工具的輸入是純文本的狀態(tài)機(jī)描述,自動產(chǎn)生符合StatePattern的代碼,這樣developer的工作只需要維護(hù)狀態(tài)機(jī)的文本描述,每必要冒引入bug的風(fēng)險去維護(hù)code。4)使用宏定義描述狀態(tài)機(jī)一般來說,C++編程中應(yīng)該避免使用#define,但是這主要是因為若用宏來定義函數(shù)的話,很容易產(chǎn)生這樣那樣的問題,但是巧妙的使用,還是能夠產(chǎn)生奇妙的效果。MFC就是使用宏定義來實現(xiàn)大的架構(gòu)的。在實現(xiàn)FSM的時候,可把一些繁瑣無比的if/else還有花括號的組合放在宏中,這樣,在代碼中可3)中狀態(tài)機(jī)描述文本一樣寫,通過編譯器的預(yù)編譯處理產(chǎn)生1)一樣的效果,我見過產(chǎn)生C代碼的宏,若要產(chǎn)生C++代碼,己軟MFC可,那么理論上也是可行的。這兒以四位密碼校驗作為狀態(tài)機(jī)的例子,連續(xù)輸入2479就可通過密碼測試。一個非常簡單的例子,在實際的狀態(tài)機(jī)實例中,狀態(tài)轉(zhuǎn)移表要更復(fù)雜一些,不過方式非常類似。在狀態(tài)查詢的地方可做優(yōu)化,同時對于輸入量也可做有效性優(yōu)化。具體代碼如下:viewplaincopytoclipboardprint?c.htypedefenum{STATE1=1,STATE2,STATE3,STATE4,STATE5,//passwordpass//...ADDhere}STATE;typedefenum{INPUT1='2',INPUT2='4',INPUT3='7',INPUT4='9',}INPUT;typedefstruct{STATEcur_state;INPUTinput;STATEnext_state;}STATE_TRANS;c.htypedefenum{STATE1=1,STATE2,STATE3,STATE4,STATE5,//passwordpass//...ADDhere}STATE;typedefenum{INPUT1='2',INPUT2='4',INPUT3='7',INPUT4='9',}INPUT;typedefstruct{STATEcur_state;INPUTinput;STATEnext_state;}STATE_TRANS;c.c#include<stdio.h>#include"c.h"STATE_TRANSstate_trans_arry[]={{STATE1,INPUT1,STATE2},{STATE2,INPUT2,STATE3},{STATE3,INPUT3,STATE4},{STATE4,INPUT4,STATE5},};#defineSTATE_TRANS_CNT(sizeof(state_trans_arry)/sizeof(state_trans_arry[0]))intmain(){inti;charch;STATEstate_machine=STATE1;while(ch!='e'){ch=getchar();if((ch>='0')&&(ch<='9'))//fordigitpasswordinputonly{for(i=0;i<STATE_TRANS_CNT;i++){if((ch==state_trans_arry[i].input)&&(state_machine==state_trans_arry[i].cur_state)){state_machine=state_trans_arry[i].next_state;continue;}elseif(i==(STATE_TRANS_CNT-1))//notransfermatch,resetstate{state_machine=STATE1;}}if(state_machine==STATE5)printf("Passwordcorrect,statetransfermachinepass!\n");}}return0;}c.c#include<stdio.h>#include"c.h"STATE_TRANSstate_trans_arry[]={{STATE1,INPUT1,STATE2},{STATE2,INPUT2,STATE3},{STATE3,INPUT3,STATE4},{STATE4,INPUT4,STATE5},};#defineSTATE_TRANS_CNT(sizeof(state_trans_arry)/sizeof(state_trans_arry[0]))intmain(){inti;charch;STATEstate_machine=STATE1;while(ch!='e'){ch=getchar();if((ch>='0')&&(ch<='9'))//fordigitpasswordinputonly{for(i=0;i<STATE_TRANS_CNT;i++){if((ch==state_trans_arry[i].input)&&(state_machine==state_trans_arry[i].cur_state)){state_machine=state_trans_arry[i].next_state;continue;}elseif(i==(STATE_TRANS_CNT-1))//notransfermatch,resetstate{state_machine=STATE1;}}if(state_machine==STATE5)printf("Passwordcorrect,statetransfermachinepass!\n");}}return0;}狀態(tài)圖--一個圖的數(shù)據(jù)結(jié)構(gòu)!1.while+switch;2.狀態(tài)機(jī):是指定系統(tǒng)的所有可能的狀態(tài)及狀態(tài)間跳轉(zhuǎn)的條件,然后設(shè)一個初始狀態(tài)輸入給這臺機(jī)器,機(jī)器就會自動運(yùn)轉(zhuǎn),或最后處于終止?fàn)顟B(tài),或在某一個狀態(tài)不斷循環(huán)。游戲中狀態(tài)切換是很頻繁的??赡芤郧耙袚Q狀態(tài)就是if~else,或者設(shè)標(biāo)志,但這些都不太結(jié)構(gòu)化,若把它嚴(yán)格的設(shè)為一種標(biāo)準(zhǔn)的狀態(tài)機(jī),會清楚的多。如控制一扇門的運(yùn)動,初始時門是關(guān)的,當(dāng)有力作用在門上時,門開始慢慢打開,力的作用完后,門漸漸停止不動,當(dāng)有反向的力時,門又漸漸關(guān)上,知道回到初始關(guān)的狀態(tài)。這個你會怎么來編程實現(xiàn)呢。似乎很麻煩,的確,沒有狀態(tài)機(jī)的思想時會很煩,設(shè)很多標(biāo)志,一堆if條件。用狀態(tài)機(jī)的話,不只是代碼更清晰,關(guān)鍵是更符合邏輯和自然規(guī)律,不同狀態(tài)不同處理,滿足條件則跳轉(zhuǎn)到相關(guān)狀態(tài)。偽碼如下:enum{CLOSED,//關(guān)上狀態(tài)CLOSING,//正在關(guān)狀態(tài)OPENED,//打開狀態(tài)OPENING,//正在開的狀態(tài)}doorState=CLOSED;//初始為關(guān)Update(){switch(doorState)caseCLOSED:if(有人推門)doorState=OPENING;//跳轉(zhuǎn)到正在開狀態(tài)break;caseOPENING:door.Rotation+=DeltaAngle;//門的旋轉(zhuǎn)量遞增if(門的速度為零)//力的作用已去doorState=OPENED;//跳轉(zhuǎn)到開狀態(tài)break;caseOPENED:if(有人關(guān)門)doorState=CLOSING;break;caseCLOSING:door.Rotation-=DeltaAngle;//門的旋轉(zhuǎn)量遞減if(門的旋轉(zhuǎn)角度減為零)doorState=CLOSED;//門已關(guān)上break;}//而繪制代碼幾乎不用怎么變,門就是會嚴(yán)格按照狀態(tài)機(jī)的指示去運(yùn)動,該停就會停Render(){RotateView(door.Rotation);DrawDoor(door.Position);}enum{CLOSED,//關(guān)上狀態(tài)CLOSING,//正在關(guān)狀態(tài)OPENED,//打開狀態(tài)OPENING,//正在開的狀態(tài)}doorState=CLOSED;//初始為關(guān)Update(){switch(doorState)caseCLOSED:if(有人推門)doorState=OPENING;//跳轉(zhuǎn)到正在開狀態(tài)break;caseOPENING:door.Rotation+=DeltaAngle;//門的旋轉(zhuǎn)量遞增if(門的速度為零)//力的作用已去doorState=OPENED;//跳轉(zhuǎn)到開狀態(tài)break;caseOPENED:if(有人關(guān)門)doorState=CLOSING;break;caseCLOSING:door.Rotation-=DeltaAngle;//門的旋轉(zhuǎn)量遞減if(門的旋轉(zhuǎn)角度減為零)doorState=CLOSED;//門已關(guān)上break;}//而繪制代碼幾乎不用怎么變,門就是會嚴(yán)格按照狀態(tài)機(jī)的指示去運(yùn)動,該停就會停Render(){RotateView(door.Rotation);DrawDoor(door.Position);}這是一個簡單但很典型的例子,狀態(tài)機(jī)的應(yīng)用太多了。就說一個基本游戲的運(yùn)轉(zhuǎn):(用到了一個狀態(tài)然后還有子狀態(tài))UpdateGame()BEGIN;switch(gameState)case等待選擇菜單://它有三個子狀態(tài)。if(選擇菜單項==開始){游戲初始;gameState=開始游戲}if(選擇菜單項==選項)gameState

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論