-
下載積分: 6 賞幣
上傳時間:2024-03-06
頁數(shù): 18
大?。?0.1(MB)
子文件數(shù):
-
簡介:教育教材語言分中心工作匯報,廈門大學(xué)蘇新春2006826,要點,一、實驗室建設(shè)二、課題招標(biāo)、進(jìn)展三、語料庫建設(shè)四、網(wǎng)站五、目標(biāo)設(shè)想,一、實驗室建設(shè),1硬件建設(shè)科研用房110平米三間服務(wù)器1臺微機(jī)12臺投影儀高速掃描儀、打印機(jī)等,一、實驗室建設(shè),2實驗室管理規(guī)章制度,二、課題招標(biāo)與進(jìn)展,2005年11月20日,課題招標(biāo)發(fā)布。2005年12月20日,課題申報申報結(jié)束。2006年1月5日,中心學(xué)術(shù)委員會開會,審批通過七項課題。,,杜晶晶對外漢語教材語言的共時研究郭曙綸上海市中小學(xué)語文教材語料庫李焱臺灣九年一貫課程綱要下的國語教材語言面貌分析蘇新春人教版和蘇教版中小學(xué)語文教材對比研究王衍軍20世紀(jì)50年代以來對外漢語教材語言面貌研究趙小蕙香港地區(qū)基礎(chǔ)教育階段語文教材的語言基本概貌及特點研究鄭澤之教育教材資源平臺建設(shè),三、語料庫建設(shè),教材語料庫;教材庫;教材研究文獻(xiàn)庫;詞匯學(xué)研究文獻(xiàn)庫;通用詞語庫;通用語料庫;詞語系統(tǒng)庫;辭書語料庫,四、網(wǎng)站建設(shè),2005年12月始建;2006年3月正式開通目標(biāo)信息平臺;研究平臺;交流平臺;服務(wù)平臺;,五、目標(biāo)設(shè)想,1、語言信息的擴(kuò)充,,,2、教材種類的擴(kuò)充;對“對外漢語類”與”基礎(chǔ)教材類”的覆蓋面3、地區(qū)教材的擴(kuò)充;4、教材語言內(nèi)容的擴(kuò)充;5、教材語言與教材編寫、教學(xué)方法、教學(xué)效果的關(guān)系;,,對計算機(jī)處理數(shù)據(jù)的人工干預(yù)要不要干預(yù)方法與干預(yù)程度分詞、空格、斷詞、偶例,,第一個環(huán)節(jié)語料性質(zhì)、語料來源、語料規(guī)模、第二個環(huán)節(jié)語料加工分詞、標(biāo)注、歸類、第三個環(huán)節(jié)數(shù)據(jù)分析、意義、價值、,困難,教材單位的合作意愿與畏懼,
下載積分: 6 賞幣
上傳時間:2024-01-06
頁數(shù): 14
大?。?0.05(MB)
子文件數(shù):
-
下載積分: 5 賞幣
上傳時間:2024-03-05
頁數(shù): 4
大?。?0.05(MB)
子文件數(shù):
-
下載積分: 5 賞幣
上傳時間:2024-03-06
頁數(shù): 5
大?。?0.13(MB)
子文件數(shù):
-
下載積分: 5 賞幣
上傳時間:2024-03-05
頁數(shù): 5
大?。?0.02(MB)
子文件數(shù):
-
下載積分: 8 賞幣
上傳時間:2024-03-05
頁數(shù): 41
大?。?0.45(MB)
子文件數(shù):
-
簡介:1,VHDL硬件描述語言及其應(yīng)用-數(shù)字IC前端設(shè)計實例,,2,講授內(nèi)容,數(shù)字IC設(shè)計中的前端設(shè)計內(nèi)容數(shù)字IC前端設(shè)計實例UART文檔階段編碼階段驗證階段,3,數(shù)字IC設(shè)計流程,4,INITIAL,,FRONTEND,,BACKEND,,PHYSICAL,,XAANDBYCNORD,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,A,B,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,A,B,,,,X,V,VSS,VSS,VDD,,,A,B,C,D,X,Y,Z,,X,,,VDD,VSS,,,VERIFICATION,,,,,SPEC,,,IDEA,,TAPEOUT,5,數(shù)字IC前端設(shè)計的層次,前端設(shè)計可分3個階段文檔階段SPEC-設(shè)計文檔編碼階段設(shè)計文檔-HDL代碼驗證階段SPEC-驗證平臺-大量的驗證,6,講授內(nèi)容,數(shù)字IC設(shè)計中的前端設(shè)計內(nèi)容數(shù)字集成電路前端設(shè)計實例UART文檔階段編碼階段驗證階段,7,,8,數(shù)字集成電路前端設(shè)計實例UART,UART預(yù)期操作環(huán)境,9,數(shù)字集成電路前端設(shè)計實例UART,實例通用異步收發(fā)器UARTAPB外圍總線的從設(shè)備硬件流控制模式CTSN/RTSN握手協(xié)議采用的數(shù)據(jù)格式是8個數(shù)據(jù)位,1個可選的奇偶校驗位以及1個停止位,UART數(shù)據(jù)格式,10,文檔階段,SPEC-設(shè)計說明定義接口表格形式-接口一致性子模塊劃分子模塊設(shè)計文檔設(shè)計描述子模塊設(shè)計指導(dǎo)-設(shè)計文檔實現(xiàn)方法說明流程圖、狀態(tài)圖、時序圖寄存器描述,11,1SPEC,模塊功能數(shù)據(jù)接收功能數(shù)據(jù)發(fā)送功能波特率生成器APB總線接口數(shù)據(jù)流模式控制預(yù)期環(huán)境APB總線其他UART,12,1SPEC,UART數(shù)據(jù)發(fā)送功能描述當(dāng)UART發(fā)送器被使能可進(jìn)行發(fā)送操作。其操作為將待發(fā)送8位數(shù)據(jù)轉(zhuǎn)換成一個串行數(shù)據(jù),按位時鐘輸出到發(fā)送器的串行輸出端口上。在停止位發(fā)送完成后,如果沒有新的數(shù)據(jù)傳送到發(fā)送保持寄存器中,則發(fā)送器串行數(shù)據(jù)輸出端保持高電平。數(shù)據(jù)發(fā)送完成置發(fā)送移位寄存器空標(biāo)識位為1。當(dāng)有新數(shù)據(jù)傳送到空的發(fā)送保持寄存器中時,發(fā)送重新開始,發(fā)送移位寄存器空標(biāo)識位被清0。假如發(fā)送器被禁止,則它將繼續(xù)工作直到當(dāng)前數(shù)據(jù)被完全發(fā)送完成。此時發(fā)送保持寄存器不能夠重新裝載數(shù)據(jù)。如果采用流控制方式,CTSN輸入必須保持低電平,這樣數(shù)據(jù)才能被發(fā)送。如果在發(fā)送過程中,被設(shè)置成高,移位寄存器中的數(shù)據(jù)被發(fā)送,完成后發(fā)送端保持不變直到CTSN被重新設(shè)置成0。,13,2定義接口,APB接口PSEL輸入SLAVESELECTPENABLE輸入STROBE(選通脈沖)PADDR(7DOWNTO0)輸入ADDRESSBUSBYTEPWRITE輸入WRITEPWDATA(31DOWNTO0)輸入WRITEDATABUSPRDATA(31DOWNTO0)輸出READDATABUSUART接口RXD輸入TXD輸出CTSN輸入RTSN輸出其他接口IRQ輸出,14,3子模塊劃分,按功能劃分按層次劃分,,,,,15,4子模塊設(shè)計文檔設(shè)計描述,例數(shù)據(jù)發(fā)送子模塊功能設(shè)計描述輸入信號發(fā)送時鐘(TXTICK)由波特率發(fā)生部件產(chǎn)生的基準(zhǔn)時鐘8得到的位時鐘,高電平有效發(fā)送器使能(TE)高電平有效發(fā)送器中斷使能(TI)高電平有效奇偶校驗選擇(PS)“0”表示偶校驗,“1”表示奇校驗奇偶校驗使能(PE)高電平有效流控制使能(FL)高電平有效。復(fù)位信號(RST)高電平有效輸出信號發(fā)送移位寄存器空(TS)說明發(fā)送移位寄存器中的數(shù)據(jù)已經(jīng)發(fā)送完畢發(fā)送保持寄存器空(TH)說明先前的數(shù)據(jù)已經(jīng)發(fā)送完畢,目前沒有新的數(shù)據(jù)待發(fā)送。數(shù)據(jù)發(fā)送輸出端(TXD)中斷輸出信號(IRQ),16,4子模塊設(shè)計文檔設(shè)計描述,數(shù)據(jù)發(fā)送UART發(fā)送器的使能位(TE)控制,高電平有效。數(shù)據(jù)由發(fā)送保持寄存器(THOLD)傳送到發(fā)送移位寄存器(TSHIFT)中,并且將其轉(zhuǎn)換成一個串行隊列,輸出到發(fā)送器的串行輸出端口TXD上。它將自動在8位有效數(shù)據(jù)前添加開始位,并在數(shù)據(jù)后添加一位可選的奇偶校驗位和一位停止位。在停止位發(fā)送完成后,如果沒有新的數(shù)據(jù)傳送到發(fā)送保持寄存器中,則發(fā)送器串行數(shù)據(jù)輸出端保持高電平,并且設(shè)置發(fā)送移位寄存器空標(biāo)識位(TSRE)為1。當(dāng)有新數(shù)據(jù)傳送到發(fā)送保持寄存器中時,判斷發(fā)送保持寄存器空標(biāo)識位(THRE)是否為1,如果為1且TI=1,則發(fā)出IRQ中斷;如果TSRE=0,則發(fā)送開始,TSRE被清除。假如發(fā)送器被禁止,則它將繼續(xù)工作直到當(dāng)前數(shù)據(jù)被完全發(fā)送完成。此時發(fā)送保持寄存器不能夠重新裝載數(shù)據(jù)。流控制方式CTSN輸入必須保持低電平,這樣數(shù)據(jù)才能被發(fā)送。如果在發(fā)送過程中,CTSN被設(shè)置成高,移位寄存器TSHIFT中的數(shù)據(jù)被發(fā)送,完成后發(fā)送端保持高電平不變,直到CTSN被重新設(shè)置成0。,17,4子模塊設(shè)計文檔模塊實現(xiàn)方法,數(shù)字IC=數(shù)據(jù)通路+控制邏輯數(shù)據(jù)通路寄存器提?。淮鎯ζ骺刂七壿嬘邢逘顟B(tài)機(jī)狀態(tài)圖,狀態(tài)表硬連邏輯流程圖,時序圖,18,例發(fā)送控制狀態(tài)機(jī),,19,,20,4子模塊設(shè)計文檔寄存器描述,寄存器的功能保持歷史值數(shù)據(jù)通路寄存器,計數(shù)器,移位器控制輸出信號的行為命令、控制寄存器如實反映當(dāng)前電路工作狀態(tài)狀態(tài)寄存器方法保存采樣信號值-歷史值和當(dāng)前值比較必要中間值例如有限狀態(tài)機(jī)的狀態(tài)、跨周期信號等模塊輸出信號寄存器輸出,21,控制寄存器該寄存器用來控制UART的操作第0位接收器使能(RE),高電平有效。第1位發(fā)送器使能(TE),高電平有效。第2位接收器中斷使能(RI),高電平有效。第3位發(fā)送器中斷使能(TI),高電平有效。第4位奇偶校驗選擇(PS),“0”表示偶校驗,“1”表示奇校驗。第5位奇偶校驗使能(PE),高電平有效。第6位流控制使能(FL),高電平有效。第7位回送使能(LB),高電平有效。第8位外部時鐘使能(EC),高電平有效,此時PIO3用作時鐘。,,22,UART狀態(tài)寄存器用來反映UART的狀態(tài)第0位接收數(shù)據(jù)就緒(DR),說明在接收保持寄存器中,數(shù)據(jù)已經(jīng)準(zhǔn)備就緒。第1位發(fā)送移位寄存器空(TS),說明發(fā)送移位寄存器中的數(shù)據(jù)已經(jīng)發(fā)送完畢。第2位發(fā)送保持寄存器空(TH),說明先前的數(shù)據(jù)已經(jīng)發(fā)送完畢,目前沒有新的數(shù)據(jù)待發(fā)送。第3位接收到暫停(BR),說明在數(shù)據(jù)接收過程接收到暫停信息。第4位溢出(OV),說明由于超出限度一個或多個字符而丟失。第5位奇偶錯(PE),說明檢測到奇偶錯。第6位格式錯(FE),說明檢測到格式錯。,,23,編碼階段,編程前準(zhǔn)備設(shè)計思路設(shè)計文檔-RTL代碼編碼風(fēng)格編碼實例文件層次化管理,24,編程前準(zhǔn)備,遵守工程指定命名及格式規(guī)則版本、設(shè)計日期、編者信息以及注釋的使用標(biāo)識符對應(yīng)具體功能含義如THEMPTY(TRANSMITHOLDEMPTY)標(biāo)識符表明信號/變量屬性如CTS_N,CTS_,CTSN,25,設(shè)計思路,模塊設(shè)計考慮電路結(jié)構(gòu)串行對輸入的處理分步驟進(jìn)行(PROCESS)并行對到達(dá)的信號同時處理(多個等價PROCESS)流水線多步驟、每個步驟同時處理設(shè)計考慮在內(nèi)部模塊之間的輸入輸出可采用組合邏輯,不同芯片之間必須采用寄存器輸入輸出(否則增加后端實現(xiàn)難度)盡量將組合電路和時序電路分開,26,編碼風(fēng)格,自頂向下規(guī)劃并發(fā)并行等價進(jìn)程規(guī)劃順序串行進(jìn)程規(guī)劃自底向上編碼獨立功能順序編碼順序語句-PROCESS并發(fā)進(jìn)程協(xié)調(diào)信號通信關(guān)系,27,自頂向下并行等價進(jìn)程規(guī)劃,BAUDOPPROCESSRST,R_P,UARTI_PBAUDRATE/BITCLOCKPROCESSBAUDRATEGENERATERX/TXCLOCKRESETOPERATIONENDPROCESSAPBOPPROCESSRST,R_P,APBIAPBOPERATIONREAD/WRITEREGISTERS(APBSLAVEINTERFACE)RESETOPERATIONUPDATEREGISTERSDRIVEOUTPUTSENDPROCESSTXRXOPPROCESSRST,R_P,APBITRANSMIT/RECEIVEROPERATIONFILTERRXDATATRANSMITTEROPERATIONRECEIVEROPERATIONRESETOPERATIONUPDATEREGISTERSDRIVEOUTPUTSENDPROCESS,28,自頂向下串行進(jìn)程的規(guī)劃,在最小信號間隔(CLK)內(nèi)更新信號及輸出UARTOPPROCESSRST,R,APBI,UARTISERIALPROCESSVARIABLEVUARTREGSBAUDRATEGENERATEREAD/WRITEREGISTERS(APBSLAVEINTERFACE)RX/TXCLOCKFILTERRXDATATRANSMITTEROPERATIONRECEIVEROPERATIONRESETOPERATIONUPDATEREGISTERSRINIDLESTATEIFRTXTICK1THENVTSEMPTY1ENDIFIFRTXENANDNOTRTHEMPTYANDRTXTICKANDNOTCTSN1THENVTSHIFT“10“VTXSTATEDATAVTPARRPARSELVIRQRTIRQENVTHEMPTY1VTSEMPTY0VTXCLK“00“VTXTICK0ENDIF,數(shù)據(jù)發(fā)送代碼段,編碼實例有限狀態(tài)機(jī)實現(xiàn),31,WHENDATATRANSMITDATAFRAMEIFRTXTICK1THENVTPARRTPARXORRTSHIFT1VTSHIFT1IFRTSHIFT10DOWNTO1“1111111110“THENIFRPAREN1THENVTSHIFT0RTPARVTXSTATEPARITYELSEVTSHIFT01VTXSTATESTOPBITENDIFENDIFENDIF,數(shù)據(jù)發(fā)送代碼段(續(xù)),編碼實例有限狀態(tài)機(jī)實現(xiàn),32,WHENPARITYTRANSMITPARITYBITIFRTXTICK1THENVTSHIFT1VTXSTATESTOPBITENDIFWHENSTOPBITTRANSMITSTOPBITIFRTXTICK1THENVTSHIFT1VTXSTATEIDLEENDIFENDCASE,數(shù)據(jù)發(fā)送代碼段(續(xù)),編碼實例有限狀態(tài)機(jī)實現(xiàn),33,SCALERRSCALER1--BAUDRATEGENERATETICKIFRRXENORRTXEN1THENVSCALERSCALERVTICKSCALER11ANDNOTRSCALER11IFVTICK1THENVSCALERRBRATEENDIFENDIFTXCLKRTXCLK1--TXCLKGENERATE(8TICK)IFRTICK1THENVTXCLKTXCLKVTXTICKRTXCLK2ANDNOTTXCLK2ENDIF,發(fā)送定標(biāo)代碼段位時鐘,編碼實例控制信號,34,編碼實例記錄的使用-信號鎖存,TYPEUARTREGSISRECORDRXENSTD_LOGICRECEIVERENABLEDTXENSTD_LOGICTRANSMITTERENABLEDRIRQENSTD_LOGICRECEIVERIRQENABLETIRQENSTD_LOGICTRANSMITTERIRQENABLEPARSELSTD_LOGICPARITYSELECTPARENSTD_LOGICPARITYSELECTFLOWSTD_LOGICFLOWCONTROLENABLEDREADYSTD_LOGICDATAREADYRSEMPTYSTD_LOGICRECEIVERSHIFTREGISTEREMPTYINTERNALTSEMPTYSTD_LOGICTRANSMITTERSHIFTREGISTEREMPTYTHEMPTYSTD_LOGICTRANSMITTERHOLDREGISTEREMPTYBREAKSTD_LOGICBREAKDETECTEDRHOLDSTD_LOGIC_VECTOR7DOWNTO0RSHIFTSTD_LOGIC_VECTOR7DOWNTO0TSHIFTSTD_LOGIC_VECTOR10DOWNTO0,35,編碼實例記錄的使用-信號鎖存,THOLDSTD_LOGIC_VECTOR7DOWNTO0IRQSTD_LOGICTX/RXINTERRUPTINTERNALTPARSTD_LOGICTXDATAPARITYINTERNALTXSTATETXFSMTYPETXCLKSTD_LOGIC_VECTOR2DOWNTO0TXCLOCKDIVIDERTXTICKSTD_LOGICTXCLOCKINTERNALRXSTATERXFSMTYPERXCLKSTD_LOGIC_VECTOR2DOWNTO0RXCLOCKDIVIDERRXDBSTD_LOGIC_VECTOR1DOWNTO0RXDELAYDPARSTD_LOGICRXDATAPARITYINTERNALRXTICKSTD_LOGICRXCLOCKINTERNALTICKSTD_LOGICRXCLOCKINTERNALSCALERSTD_LOGIC_VECTOR11DOWNTO0BRATESTD_LOGIC_VECTOR11DOWNTO0RXFSTD_LOGIC_VECTOR7DOWNTO0RXDATAFILTERINGBUFFERENDRECORD,36,編碼實例時鐘同步,ARCHITECTURERTLOFUARTISTYPERXFSMTYPEISIDLE,STARTBIT,DATA,PARITY,STOPBITTYPETXFSMTYPEISIDLE,DATA,PARITY,STOPBITTYPEUARTREGSISRECORDSIGNALR,RINUARTREGSBEGINUARTOPPROCESSRST,R,APBI,UARTISERIALPROCESSVARIABLEVUARTREGSRIN底層結(jié)構(gòu)描述-行為描述不同用途文件命名規(guī)則區(qū)分,如_TOP,_PACKAGE等目錄的層次化工作目錄不同目的文件-不同目錄,如SRC,SIM,DOC,38,文件層次化管理,39,驗證階段,驗證環(huán)境和測試方案-TESTBENCH根據(jù)設(shè)計文檔確定驗證點(TESTCASE)-驗證文檔描述每個驗證點的目的、具體實現(xiàn)步驟驗證文檔-TESTCASE提取覆蓋率分析-不理想-回到第2階段記錄驗證結(jié)果-LOG文件,40,驗證環(huán)境架構(gòu)及建立方式,基于軟件模擬的層次式架構(gòu)TESTCASE層由過程(PROCEDURE)調(diào)用組成行為模型以及BFM不可綜合的代碼,描述系統(tǒng)環(huán)境中可能的其他電路模型或行為TESTBENCH驗證配置TESTBENCH組織CONFIGURATIONS裝配TESTCASE,行為模型,BFM以及待測模塊DUT,41,UART驗證環(huán)境架構(gòu),42,確定驗證點,TESTCASE提取PROCEDURES激勵從單一功能到復(fù)雜功能,輔以覆蓋率工具響應(yīng)針對具體TESTCASE描述檢查相關(guān)響應(yīng),43,例數(shù)據(jù)發(fā)送進(jìn)程TESTCASE生成TESTCASE1驗證UART是否能夠正確發(fā)送數(shù)據(jù)A保持發(fā)送時鐘基準(zhǔn)時鐘8得到的位時鐘TXTICK;B調(diào)用APB_WRITE過程向UART控制寄存器寫入“000101010”;C調(diào)用APB_WRITE過程向UART發(fā)送保持寄存器THOLD寫入“10101010”;D調(diào)用TXD_VERIFY過程,并檢測是否正確接收“10101010”TESTCASE2驗證UART能否檢驗出奇偶校驗錯,并據(jù)此發(fā)出中斷請求A保持發(fā)送時鐘基準(zhǔn)時鐘8得到的位時鐘TXTICK;B調(diào)用APB_WRITE過程向UART控制寄存器寫入“000101010”;C調(diào)用APB_WRITE過程向UART發(fā)送保持寄存器THOLD寫入“10101010”;D調(diào)用TXD_VERIFY過程,并檢測是否正確接收“10101010”,偶校驗無誤,并接收到IRQ信號;E調(diào)用APB_WRITE過程向UART控制寄存器寫入“000111010”;F調(diào)用APB_WRITE過程向UART發(fā)送保持寄存器THOLD寫入“10101010”;G調(diào)用TXD_VERIFY過程,并檢測是否正確接收“10101010”,奇校驗無誤,并接收到IRQ信號;TESTCASE3溢出錯誤檢查TESTCASE4發(fā)送過程清TETESTCASE5流控制檢查,TESTCASE提取,44,TESTCASE實例接收過程,READRXDPROCEDUREFORTESTBENCHPROCEDURERXCSIGNALRXDINSTD_LOGICDOUTSTD_LOGIC_VECTORISVARIABLERXDATASTD_LOGIC_VECTOR7DOWNTO0BEGINWAITUNTILRXD0WAITFORTXPERIOD/2FORIIN0TO7LOOPWAITFORTXPERIODRXDATAIRXDENDLOOPWAITFORTXPERIODDRXDATAENDENDRXC,TESTCASE-PROCEDURE,45,TESTCASE實例發(fā)送過程續(xù),TRANSMITTDDATATOTXDPROCEDUREFORTESTBENCHPROCEDURETXCSIGNALTXDOUTSTD_LOGICTDINTEGERISVARIABLETXDATASTD_LOGIC_VECTOR10DOWNTO0BEGINTXDATA“11“FORIIN0TO10LOOPWAITFORTXPERIODTXDTESTBENCH,則可進(jìn)行模擬驗證,49,TESTBENCH,復(fù)用將所有過程集中在PACKAGE中,供所有設(shè)計者使用在TESTBENCH中配置,50,覆蓋率分析,代碼覆蓋率EDA工具+TESTCASE驗證施加的激勵使得RTL代碼都被覆蓋了,驗證仍然可能是不完整的如果RTL代碼根本就沒有達(dá)到完整的覆蓋,則驗證肯定是不完整的。功能覆蓋率邊緣功能點(CORNERCASE)多功能交叉、組合隨機(jī)測試,51,覆蓋率分析,,,,,,,,,,,,,,PERIOD1PERIOD2,BUGRATE,TIME(EFFORT)READYTOSHIPSHIP,,,,BUGRATEWITHCODECOVERAGE,52,小結(jié),數(shù)字IC前端設(shè)計用心良苦的文檔加快編碼編碼遵守規(guī)則,忠實再現(xiàn)驗證階段關(guān)鍵為TESTCASE提取,
下載積分: 6 賞幣
上傳時間:2024-01-06
頁數(shù): 52
大?。?0.31(MB)
子文件數(shù):
-
簡介:C語言軟件編程規(guī)范工作組,公司常見軟件編程低級錯誤內(nèi)存泄漏,前言,這套材料作為編程規(guī)范的輔助材料,幫助大家理解編程規(guī)范背后的原理。C和C語言是我司的主流編程語言,然而C/C具有很多強(qiáng)大的語言特性,從而導(dǎo)致C/C非常復(fù)雜,使得代碼更容易出現(xiàn)BUG、難以閱讀和維護(hù)。業(yè)界知名的編程規(guī)范都對C/C容易出現(xiàn)問題的語言特性進(jìn)行管理。例如MISRA(汽車工業(yè)軟件可靠性聯(lián)合會)制定的1998版的MISRAC規(guī)范指出,一些在C看來可以接受,卻存在隱患的地方有127處之多。2004版的MISRAC規(guī)范將針對C語言的規(guī)則增加到了141條。對于程序員來說,能工作的代碼并不等于“好”代碼?!昂谩贝a的指標(biāo)很多,包括可讀性、可維護(hù)性、可移植性和可靠性等。出現(xiàn)網(wǎng)上問題的代碼,大多數(shù)是不良編程習(xí)慣引起的。不遵守編程規(guī)范的代碼,往往也是最不可靠的代碼。本膠片收集了常見的內(nèi)存泄漏案例,給出了相應(yīng)的糾正措施。對應(yīng)的編程規(guī)范防止內(nèi)存泄漏;函數(shù)中分配的內(nèi)存,在函數(shù)退出之前要釋放,內(nèi)存泄漏案例問題和糾正措施建議,異常出口處沒有釋放內(nèi)存,【問題描述】代碼飛檢發(fā)現(xiàn)如下代碼PMSGDB_DEVPDBDEVMSGGETBUFFSIZEOFDBDEVMSG,__LINE__IFPMSGDB_DEVNULL{RETURN}PMSGDBAPP_TO_LOGICLPDBSELFMSGGETBUFFSIZEOFDBSELFMSG,__LINE__IFPMSGDBAPP_TO_LOGICNULL{RETURN}【問題定位】在第2個RETURN處,PMSGDB_DEV指向的內(nèi)存丟失,異常出口處沒有釋放內(nèi)存續(xù)1,【問題描述】代碼飛檢發(fā)現(xiàn)如下代碼/在AVL樹中添加節(jié)點/IF_VC_AVL_ADDNODEIFULRETVOS_OK/創(chuàng)建VC控制塊失敗/{RETURN}【問題定位】創(chuàng)建VC控制塊失敗時,RETURN前沒有刪除AVL樹中的節(jié)點【舉一反三】看見RETURN要注意,要去前面找資源,特別要注意鏈表等數(shù)據(jù)結(jié)構(gòu)中的資源,異常出口處沒有釋放信號量資源,【問題描述IFRCNP_RC_SUCCESS/申請信號量失敗/{NP_SS_ASSERT0,“CREATEQINQSEMFAILED“RETURNRC}IFSOFT_VERSIONRCNP_SS_SEMB_CREATENP_SEM_EMPTY,NP_SEM_Q_FIFO,IFRCNP_RC_SUCCESS/申請信號量失敗/{NP_SS_ASSERT0,“CREATEQINQSEMFAILED“RETURNRC//沒有釋放前面分配的信號量G_IMS_VPORT_BASE_INFOQINQ_BASE_INFOSEM}ENDIFNP_FREE_SEMG_IMS_VPORT_BASE_INFOQINQ_BASE_INFOSEMIFSOFT_VERSIONNP_FREE_SEMG_IMS_VPORT_BASE_INFOEQINQ_BASE_INFOSEMENDIFRETURNRC,異常出口處沒有釋放信號量資源(續(xù)),【糾正措施】第二個信號量申請失敗RETURN之前釋放第一個申請的信號量。。。。。。。。。。。。IFSOFT_VERSIONRCNP_SS_SEMB_CREATENP_SEM_EMPTY,NP_SEM_Q_FIFO,IFRCNP_RC_SUCCESS/申請信號量失敗/{NP_SS_ASSERT0,“CREATEQINQSEMFAILED“NP_FREE_SEMG_IMS_VPORT_BASE_INFOQINQ_BASE_INFOSEMRETURNRC}ENDIF。。。。。。。。。。。?!九e一反三】看見RETURN要注意,要去前面找資源,特別要注意信號量、定時器等資源,異常出口處沒有釋放GUI資源,【問題描述】網(wǎng)上問題案例CBITMAPBMPCBITMAPPOLDBMPBMPLOADBITMAPIDB_MYBMPPOLDBMPPDCSELECTOBJECTIFSOMETHING{RETURN}PDCSELECTOBJECTPOLDBMP【問題定位】RETURN前沒有調(diào)用SELECTOBJECT把POLDBMP選回PDC中,這會導(dǎo)致POLDBMP指向的HBITMAP對象發(fā)生泄漏。這個程序如果長時間的運行,會導(dǎo)致系統(tǒng)花屏【舉一反三】除了申請的內(nèi)存外,系統(tǒng)提供的其它資源,如文件句柄/SOCKET/隊列等也是資源,使用完畢必須釋放,沒有釋放結(jié)構(gòu)的成員指針,【問題描述】網(wǎng)上問題案例STRUCTSTORE_BUF_S{ULONGULLENUCHARPCDATA}STORE_BUF_TVOIDFUNC{STORE_BUF_TPSTSTORAGEBUFFNULL//申請結(jié)構(gòu)內(nèi)存//程序處理。。。FREEPSTSTORAGEBUFFRETURN}刪除了PSTSTORAGEBUFF,但PSTSTORAGEBUFFPCDATA沒有刪除?!締栴}定位】先刪除了PSTSTORAGEBUFF,PSTSTORAGEBUFFPCDATA永遠(yuǎn)不可能被刪除了【舉一反三】刪除結(jié)構(gòu)指針時,必須從底層向上層順序刪除,沒有釋放數(shù)組的成員指針,【問題描述】測試部對M產(chǎn)品進(jìn)行壓力和穩(wěn)定性測試,模擬文件上傳的場景,把本地目錄下的3萬個文件上傳到另一臺主機(jī)。發(fā)現(xiàn)上傳程序在傳送文件過程中,內(nèi)存在快速增長,通過PSAUWX監(jiān)控,發(fā)現(xiàn)該進(jìn)程占用的內(nèi)存每隔4分鐘(一個周期)就突然增加20~30M的內(nèi)存?!締栴}定位】STRUCTDIRENTNAMELISTINTNSCANDIRPATHC_STR,【1】INTI0FORIID_NAMEFREENAMELISTI【2】IFNAME““IFMAX_SCAN_FILE_NUMFILENUM//MAX_SCAN_FILE_NUM1000{BREAK}}}FREENAMELIST【3】RETURN,沒有釋放數(shù)組的成員指針(續(xù)),從上面的代碼可以看是指針數(shù)組NAMELIST由系統(tǒng)函數(shù)進(jìn)行分配內(nèi)存(如【1】所示),內(nèi)存釋放時時分別由【2】【3】完成的。但是中間有個條件,每次只取1000個文件,如果目錄下的文件大于1000就跳出,后面的就不會再管了(【2】沒有執(zhí)行到)。所以導(dǎo)致原來本地目錄下文件數(shù)比較小,小于等1000時沒有內(nèi)存泄漏;而當(dāng)本地目錄下的文件比較多,大于1000時,就會導(dǎo)致內(nèi)存泄漏?!九e一反三】開發(fā)人員在使用指針數(shù)組時,要特別注意,確保在釋放數(shù)組時,數(shù)組中的每個元素指針是否已經(jīng)提前被釋放了,這樣才不會導(dǎo)致內(nèi)存泄漏。,重復(fù)分配內(nèi)存,【問題描述】代碼飛檢發(fā)現(xiàn)如下代碼ULONGCQC_CMDNODROPLEVELCLASSVOIDPMSGRCV,VOIDPPMSGSND{/以下是從別處拷貝的代碼/ULERRCODECFG_CREATERESMSGSPMSGRCV,PPMSGSND/拷貝代碼結(jié)束/ULERRCODECFG_CREATERESMSGSPMSGRCV,PPMSGSND}【舉一反三】代碼COPY要小心,沒有釋放傳入定時器的內(nèi)存,【問題描述】使用PURIFY測試,發(fā)現(xiàn)上報MLK在我們的應(yīng)用程序的對象中,由于在設(shè)置定時器時需要傳遞一個參數(shù),這個參數(shù)的需要從堆中去獲取,因為在后續(xù)的定時器超時回調(diào)時需要使用這個參數(shù)。在對象中設(shè)置定時器的代碼如下THISSETTIMERTIMERID,PENDING_USER_ENROLL_TIMER_ID,30,1,//設(shè)置一個30秒的定時器,定時1次NEWTSTRINGIPPORT在定時器的超時處理程序簡化后如下VOIDSESSIONONTIMEOUTTINT4TIMERID,TINT4USERTIMERID,VOIDPDATA{SWITCHUSERTIMERID{CASEPENDING_USER_ENROLL_TIMER_ID{TSTRINGIPPORTREINTERPRET_CASTPDATADELETEIPPORT}}}在我們設(shè)置的定時器超時后,會自動調(diào)用ONTIMEOUT這個函數(shù),根據(jù)USERTIMERID來把所需要的參數(shù)轉(zhuǎn)化為我們原來的數(shù)據(jù)類型,使用完成后在銷毀它。這看起來一切都很正常,NEW出來資源通過DELETE來進(jìn)行釋放,為什么出現(xiàn)了內(nèi)存泄漏呢,沒有釋放傳入定時器的內(nèi)存(續(xù)),【問題定位】定時器設(shè)置之后在未超時的時候,這個定時器的所在的對象就結(jié)束了,定時器自然就消失了,也就是我們NEW出來的東西也就消失了,內(nèi)存泄漏就此產(chǎn)生了?!炯m正措施】使用智能指針進(jìn)行解決,資源的釋放操作由C語言特性進(jìn)行保證(在對象的生命周期結(jié)束調(diào)用其析構(gòu)函數(shù)),具體方案如下在該對象類添加一個智能指針類型的私有成員變量PRIVATESTDAUTO_PTRTIMER_ARG_IPPORT_這樣,在該對象被銷毀時,根據(jù)智能指針的特性,由TIMER_ARG_IPPORT_這個變量持有的資源會自動被釋放。這樣,我們就不用擔(dān)心資源的泄漏問題了。相應(yīng)的,設(shè)置定時器的代碼就變?yōu)轭愃迫缦铝薚IMER_ARG_IPPORT_STDAUTO_PTRNEWTSTRINGIPPORTTHISSETTIMERTIMERID,PENDING_USER_ENROLL_TIMER_ID,30,1,//設(shè)置一個30秒的定時器,定時1次TIMER_ARG_IPPORT_GET同時,在ONTIMEROUT函數(shù)里也不用進(jìn)行DELETE的調(diào)用了?!九e一反三】資源的分配與釋放不在同一個地方,可以考慮使用智能指針,類型轉(zhuǎn)換不當(dāng)刪除的對象類型不正確,【問題描述】網(wǎng)上問題案例VOIDCPTRLISTREMOVEHEAD{}//返回為VOID無類型方式的通用指針TYPEDEFSTRUCTTAGPROPINFO{//M_PROPLIST中的節(jié)點,其中的成員變量有自己的構(gòu)造和析構(gòu)函數(shù)CSTRINGPROPNAMECSTRINGPROPVALUE}PROPINFO;WHILEM_PROPLISTISEMPTY{DELETEM_PROPLISTREMOVEHEAD}【問題定位】調(diào)用DELETEM_PROPLISTREMOVEHEAD時,C編譯器認(rèn)為DELETE一個VOID的對象,并沒有調(diào)用類PROPINFO的析構(gòu)函數(shù),導(dǎo)致內(nèi)存泄漏【糾正措施】將M_PROPLISTREMOVEHEAD的返回值強(qiáng)制進(jìn)行一次類型轉(zhuǎn)換【舉一反三】盡量避免將多個功能寫作一條語句中,如果上面的代碼使用了臨時變量VOIDTEMPPROPINFOM_PROPLISTREMOVEHEADDELETEPROPINFOTEMPPROPINFO則很容易發(fā)現(xiàn)TEMPPROPINFO的類型不正確,就不會忘記進(jìn)行類型轉(zhuǎn)換了,對需要釋放的指針重新賦值,【問題描述】代碼飛檢發(fā)現(xiàn)如下代碼STRUCTFILEINFOPDBFFILENEWSTRUCTFILEINFOPFILEPDBFFILE【問題定位】PFILE不為空,PFILE以前指向的內(nèi)存丟失了【舉一反三】盡量不要對指針重新賦值。對指針重新賦值,首先考慮設(shè)計是否合理;除建立鏈表等特殊情況外,不要將非空指針作為左值。,宏里面有RETURN語句,【問題描述】代碼飛檢發(fā)現(xiàn)如下代碼頭文件中的宏定義如下DEFINEACE_NEW_RETURNPOINTER,CONSTRUCTOR,RET_VAL\DO{POINTERNEWCONSTRUCTOR\IFPOINTER0{ERRORENOMEMRETURNRET_VAL}\}WHILE0C文件中的語句如下ACE_NEW_RETURNG_PPROCTIMER,CNMTIMERPROC,ONE_SECOND,IM_NM_NEW_FAILACE_NEW_RETURNG_PBPTIMER,CNMTIMERPROC,FIVE_SECOND,IM_NM_NEW_FAIL【問題定位】當(dāng)?shù)诙€ACE_NEW_RETURN語句在宏里面出錯直接RETURN時,第一個ACE_NEW_RETURN語句申請的內(nèi)存泄漏了,宏里面有RETURN語句續(xù)1,【問題描述】代碼飛檢發(fā)現(xiàn)如下代碼頭文件中的宏定義如下DEFINEERROR_HANDLE_RETURNCONDITION,RETURNVALUE{IFTRUECONDITION{RETURNRETURNVALUE}}C文件中的語句如下NEWPSHELL,MESSAGEHANDLERSHELLIREGISTINGPREGISTINGPSERVICEGETFEATUREREGISTERROR_HANDLE_RETURNNULLPREGISTING,FALSE【問題定位】一旦宏ERROR_HANDLE_RETURN執(zhí)行RETRURN,前面分配的內(nèi)存PSHELL就會泄漏?!九e一反三】小心使用有RETURN語句的宏,確保前面資源已經(jīng)釋放。,宏里面有RETURN語句續(xù)2,【問題描述】代碼飛檢發(fā)現(xiàn)如下代碼//將SESSION從BUSYSESSION池移出,放入FREESESSION池ERROR_HANDLE_RETURNFALSETHISPOPENUM_SESSION_POOL_BUSY,PSESSION,FALSEERROR_HANDLE_RETURNFALSETHISONIDLESESSIONPSESSION,FALSEERROR_HANDLE_RETURNFALSETHISPUSHENUM_SESSION_POOL_FREE,PSESSION,FALSE【問題定位】一旦從第2個ERROR_HANDLE_RETURN處退出,PSESSION已經(jīng)從BUSYSESSION池移出,但并沒有放入FREESESSION池,也沒有被刪除【舉一反三】宏里面有RETURN語句,很容易造成各種隱患,產(chǎn)品最好禁止這種做法。,C的析構(gòu)函數(shù)沒有釋放內(nèi)存,【問題描述】代碼飛檢發(fā)現(xiàn)如下代碼CDBOPERATIONCDBOPERATION{}【問題定位】上面代碼忘記對類成員指針刪除,導(dǎo)致內(nèi)存泄漏【糾正措施】修改代碼為CDBOPERATIONCDBOPERATION{IFNULLM_PMMLPROCSSTIMECOST{DELETEM_PMMLPROCSSTIMECOST}}【舉一反三】類或函數(shù)申請的資源應(yīng)該在退出時釋放,使用復(fù)雜語句或函數(shù)多個判斷條件寫在一起,【問題描述】代碼飛檢發(fā)現(xiàn)如下代碼CHARPSZINFOBUFVOS_NULLPTRCHARPSZINFOBUF2VOS_NULLPTRPSZINFOBUFCHARVOS_MALLOCMID_BVLAN,ULBUFFLENPSZINFOBUF2CHARVOS_MALLOCMID_BVLAN,ULBUFFLENIFPSZINFOBUFNULL||PSZINFOBUF2NULL{RETURNVOS_ERR}【問題定位】當(dāng)PSZINFOBUF申請成功,但PSZINFOBUF2申請失敗時,進(jìn)入此分支,PSZINFOBUF指向的內(nèi)存泄漏了【舉一反三】不要將多個判斷條件寫在一起。,使用復(fù)雜語句或函數(shù)沒有及時釋放不使用的內(nèi)存,【問題描述】代碼飛檢發(fā)現(xiàn)如下代碼ULONGCQC_CMDNOAPPLYSYSTEMVOIDPMSGRCV,VOIDPPMSGSND代碼太長,這里不引用。【問題定位】該函數(shù)共531行,函數(shù)開頭就申請了PMSGRCV指針,從128行開始,即不再使用這個指針,但沒有及時釋放,一直到531行函數(shù)完全結(jié)束時才釋放PMSGRCV指針。但在128行以后,共有9處異常退出,有5處釋放了PMSGRCV指針,有4處卻沒有釋放PMSGRCV指針。【舉一反三】1。盡量避免過于復(fù)雜的函數(shù)2。養(yǎng)成及時釋放內(nèi)存和資源的習(xí)慣。,使用復(fù)雜語句或函數(shù)一個語句,多個分配,【問題描述】網(wǎng)上問題案例FUNSHARED_PTRNEWWIDGET,SHARED_PTRNEWWIDGET【問題定位】函數(shù)FUN的兩個入?yún)⒍际侵悄苤羔?,會被自動回收,通常不可能出現(xiàn)內(nèi)存泄漏。但C++標(biāo)準(zhǔn)沒有強(qiáng)制規(guī)定函數(shù)參數(shù)的計算順序,不同的編譯器處理不同。編譯器可能將上面代碼細(xì)化操作為對第一個參數(shù)執(zhí)行NEWWIDGET,分配內(nèi)存對第二個參數(shù)執(zhí)行NEWWIDGET,分配內(nèi)存對第一個參數(shù)執(zhí)行構(gòu)造函數(shù),實例化對第二個參數(shù)執(zhí)行構(gòu)造函數(shù),實例化如果第3步失敗,拋出異常,第1步申請的內(nèi)存被自動回收,但第2步分配的內(nèi)存就丟失了【糾正措施】修改代碼為SHARED_PTRSP1NEWWIDGETSHARED_PTRSP2NEWWIDGETFUNSP1,SP2【舉一反三】不要在一條語句中分配一個以上的資源,應(yīng)該在自己的代碼語句中這些顯式的資源分配(比如NEW),而且每次都應(yīng)該馬上將分配的資源賦予管理對象(比如SHARED_PTR)。,非空指針作為左值需要釋放的指針參與運算,【問題描述】網(wǎng)上問題案例WHILENULLLPSRCSTRSTRCHRLPSRCSTR,{LPBACKSTRLPSRCSTR1IFLPCHECK255{FREELPSRCSTRRETURN0}ELSE{ULRESULTULRESULT100{BREAK}IFTRUECACHEALARMPMSGPARAM_ALARMREPORT{DELETEPMSG}ELSE{SENDMESSAGEPMSG//把消息掛入消息隊列中}【問題定位】條件IFIFILECOUNT100為真,導(dǎo)致BREAK時,內(nèi)存泄漏?!炯m正措施】將申請內(nèi)存的語句NEWPMSG,TMSG移動到判斷語句IFIFILECOUNT100后面【舉一反三】如果在程序塊中存在異常檢查或退出機(jī)制,應(yīng)放在最前面,這條控制語句前面的代碼必須與異常檢查或退出條件相關(guān)。,基類中沒有定義虛析構(gòu)函數(shù),【問題描述】代碼飛檢人員發(fā)現(xiàn)某產(chǎn)品缺陷跟蹤庫中這樣解決某網(wǎng)上問題CLASSA{//VIRTUALA{}//問題定位析構(gòu)函數(shù)中打印LOG信息內(nèi)存越界,刪除析構(gòu)函數(shù)}【問題定位】檢查CLASSA的子類CLASSBPUBLICA{B{}//子類B定義了自己的析構(gòu)函數(shù)}如果出現(xiàn)下面的代碼APNEWBDELETEP聲明的對象P的類型為基類A,但實際類型為子類B,所以DELETEP時,編譯器認(rèn)為刪除的是CLASSA的對象,則調(diào)用CLASSA的析構(gòu)函數(shù)(編譯器對A添加的默認(rèn)析構(gòu)函數(shù)),而不調(diào)用B的析構(gòu)函數(shù),這樣B里面申請的內(nèi)存就泄漏了【糾正措施】在基類A中增加一個空的虛析構(gòu)函數(shù),則編譯器會自動調(diào)用B的析構(gòu)函數(shù)【舉一反三】只要在類中有虛函數(shù),就必須有虛析構(gòu)函數(shù),基類中沒有定義虛析構(gòu)函數(shù)(續(xù)),【問題描述】使用PURIFY發(fā)現(xiàn)如下代碼內(nèi)存泄漏VOIDCALARMERDESTROYALARMINFOIALARMINFOPALARMINFODELETEPCAI}【問題定位】為了減少耦合,對外暴露的是IALARMINFO的純虛接口。但內(nèi)部的實現(xiàn)是CALARMINFO。在創(chuàng)建時創(chuàng)建一個CALARMINFO而后強(qiáng)制轉(zhuǎn)換成IALARMINFO返回。典型的使用基類指針進(jìn)行刪除,由于基類沒有設(shè)置虛析構(gòu)函數(shù),導(dǎo)致派生類的析構(gòu)函數(shù)沒有調(diào)用,這樣派生類CALARMINFO里面申請的內(nèi)存就泄漏了?!炯m正措施】在基類IALARMINFO中析構(gòu)函數(shù)設(shè)置為虛【舉一反三】允許通過基類的指針進(jìn)行刪除操作,則基類的析構(gòu)函數(shù)必須是公用且虛擬。,未及時加入列表,異常拋出時內(nèi)存泄漏,【問題描述】CPARRAY類為管理對象指針的列表,具有自動釋放功能。程序正常情況下,加入CPARRAY中的對象可以得到釋放,在有異常發(fā)生的時候,對象的不到釋放,造成內(nèi)存泄漏?!締栴}定位】分析下面的代碼段,發(fā)現(xiàn)NEW的POBJ已經(jīng)放到了自動釋放列表中,粗看代碼沒什么問題;CPARRAYMYARRAYAUTO_FREECMYOBJECTPOBJNULLFORINTI0IM_IDIFUNCTION1POBJMYARRAYADDPOBJ}跟蹤FUNCTION1函數(shù),在該函數(shù)內(nèi)有異常拋出,導(dǎo)致MYARRAYADDPOBJ語句沒有被執(zhí)行,造成POBJ對象沒有被釋放。,未及時加入列表,異常拋出時內(nèi)存泄漏(續(xù)),【糾正措施】對象創(chuàng)建以后,首先加入到自動釋放列表中,再執(zhí)行其他操作;以上代碼修改為CPARRAYMYARRAYAUTO_FREECMYOBJECTPOBJNULLFORINTI0IM_IDIFUNCTION1POBJ}無論函數(shù)FUNCTION1是否有異常,都能保證對象得到釋放?!九e一反三】使用自動釋放列表的程序,要第一時間將新創(chuàng)建對象加入到列表中;調(diào)用函數(shù)時,要考慮到函數(shù)是否會拋出異常。,沒有釋放隊列中的內(nèi)存,【問題描述】發(fā)現(xiàn)加載軟件命令出現(xiàn)內(nèi)存泄漏現(xiàn)象?!締栴}定位】分析下面的代碼段,發(fā)現(xiàn)刪除隊列節(jié)點時,沒有刪除節(jié)點對應(yīng)的內(nèi)存。。。。。。。。。。。。。。//獲得加載命令附加信息指針CDLDALLSWADDINFOPDLDALLSWINFOCDLDALLSWADDINFOG_TASKIDGETDATAPTRITASKID//清除已經(jīng)完成加載的單板信息PDLDALLSWINFOM_PBOARDREPORTLISTREMOVEAT0PDLDALLSWINFOM_PBOARDREPORTLISTSETSIZEISIZE1PDLDALLSWINFOM_PBOARDREPORTLISTFREEEXTRA,沒有釋放隊列中的內(nèi)存(續(xù)),【糾正措施】添加如下代碼,問題解決IFPDLDALLSWINFOM_PBOARDREPORTLIST0NULL{DELETEPDLDALLSWINFOM_PBOARDREPORTLIST0PDLDALLSWINFOM_PBOARDREPORTLIST0NULL}PDLDALLSWINFOM_PBOARDREPORTLISTREMOVEAT0PDLDALLSWINFOM_PBOARDREPORTLISTSETSIZEISIZE1PDLDALLSWINFOM_PBOARDREPORTLISTFREEEXTRA【舉一反三】處理鏈表或隊列時,如果刪除了其中的一個節(jié)點,還必須同時釋放節(jié)點申請的內(nèi)存,重復(fù)連接數(shù)據(jù)庫,【問題描述】B020版本中,對模塊進(jìn)行系統(tǒng)測試。某個VOD處于上載中,點擊,刷新其狀態(tài),則頁面運行非常慢,最終出現(xiàn)錯誤提示頁面?!締栴}定位】在方法的SYNCHRONIZECASTATUSARRAYLIST方法中,在循環(huán)體內(nèi)NEWOPERATER,即在循環(huán)體中創(chuàng)建數(shù)據(jù)庫連接TRY{FORINTINDEX0INDEXVODCALISTSIZEINDEX{DBOPERNEWDBOPERATOR。。。。。。。。。。。。。。}}CATCHEXCEPTIONE{。。。。。。。。。。。。。。}FINALLY{DBOPERCLOSE},重復(fù)連接數(shù)據(jù)庫(續(xù)),【糾正措施】數(shù)據(jù)庫連接不能放在循環(huán)體中創(chuàng)建,否則會導(dǎo)致內(nèi)存泄漏,數(shù)據(jù)庫連接異常。將DBOPERNEWDBOPERATOR語句提前到循環(huán)體外,TRY語句內(nèi)TRY{DBOPERNEWDBOPERATORFORINTINDEX0INDEXVODCALISTSIZEINDEX{。。。。。。。。。。。。。。}}CATCHEXCEPTIONE{。。。。。。。。。。。。。。}FINALLY{DBOPERCLOSE},對非POD對象進(jìn)行MEMSET操作,【說明】POD(PLAINOLDDATA)是普通舊式數(shù)據(jù),如結(jié)構(gòu)/枚舉/成員指針等,內(nèi)存字節(jié)是連續(xù)的。非POD類的內(nèi)存字節(jié)不連續(xù),中間可能包含VPTR虛函數(shù)指針表等隱藏的數(shù)據(jù)【問題描述】網(wǎng)上問題案例SHARED_PTRP1NEWINT,P2NEWINTMEMCPY【問題定位】內(nèi)存泄漏P2不會刪除;內(nèi)存訪問失敗P1刪除兩次【舉一反三】C編譯器經(jīng)常會在多態(tài)對象中嵌入一些隱藏數(shù)據(jù)(如VPTR),多重繼承/虛擬繼承會添加更多的內(nèi)部指針。不要直接對C的類進(jìn)行MEMSET/MEMCPY等操作,應(yīng)盡量使用類自身提供的賦值/復(fù)制功能。,強(qiáng)制關(guān)閉線程沒有釋放線程占據(jù)的資源,【問題描述】網(wǎng)上問題案例CSHAKEHANDCSHAKEHAND{M_HDSHAKETHREADRECVCREATETHREADNULL,0,LPTHREAD_START_ROUTINETHREADPROC_SHAKEHANDS,THIS,NULL,}CSHAKEHANDCSHAKEHAND{TERMINATETHREADM_HDSHAKETHREADRECV,0/
下載積分: 6 賞幣
上傳時間:2024-01-06
頁數(shù): 43
大?。?0.44(MB)
子文件數(shù):
-
簡介:C語言程序設(shè)計提高篇,,第3章文件,內(nèi)容概述,文件分類緩沖文件系統(tǒng)文件的指針文件打開與關(guān)閉文件應(yīng)用,教學(xué)目標(biāo),1概述文件的概念,非緩沖文件系統(tǒng)和緩沖文件系統(tǒng);2描述文件類型指針的概念及定義方法;3正確進(jìn)行文件的打開和關(guān)閉操作,及對打開和關(guān)閉操作的錯誤處理;4正確使用文件的讀寫操作,包括基于字節(jié),數(shù)據(jù)項等的讀寫操作;5牢記文件的隨機(jī)讀寫方法;6正確使用文件訪問的錯誤檢測及處理方法;,文件是指存儲在外部介質(zhì)上,且按文件名訪問的一組信息序列,①文本文件字符代碼文件或ASCII代碼文件由一個一個字符組成,每一個字符用一個ASCII代碼表示,如12345以ASCII代碼形式存儲到磁盤需要6個字節(jié)。特點可通過顯示器或打印機(jī)顯示,即可讀,比較直觀。,,31文件分類,②非文本文件二進(jìn)制文件是指以數(shù)據(jù)在內(nèi)存中的存儲形式原樣輸出存儲到磁盤上的文件。如12345在內(nèi)存中以浮點數(shù)形式存儲占4個字節(jié),不管一個實數(shù)多大都占4個字節(jié)。特點節(jié)省存儲空間,輸入輸出無需轉(zhuǎn)換,速度快,不便閱讀。,說明①一個C文件是一個字節(jié)流或二進(jìn)制流,它把數(shù)據(jù)看作是一連串的字符序列字節(jié),而不考慮記錄的界限,即C文件并不是由記錄組成的。②由于對文件的操作要與各種外部設(shè)備發(fā)生聯(lián)系,因此對文件的輸入輸出讀寫過程是通過操作系統(tǒng)來實現(xiàn)的。對文件的讀寫都是通過標(biāo)準(zhǔn)的I/O函數(shù)進(jìn)行的。,,,32緩沖文件系統(tǒng)標(biāo)準(zhǔn)IO和非緩沖文件系統(tǒng),①緩沖文件系統(tǒng)又稱標(biāo)準(zhǔn)或高層文件系統(tǒng)特點對程序中的每一個文件都在內(nèi)存中開辟一個“緩沖區(qū)”。作用從磁盤文件讀入的數(shù)據(jù)先到“輸入緩沖區(qū)”中,然后再從緩沖區(qū)依次將數(shù)據(jù)送給接收變量。,在向磁盤文件輸出數(shù)據(jù)時,先將程序數(shù)據(jù)區(qū)中變量或表達(dá)式的值送到“輸出文件緩沖區(qū)”中,待裝滿后才一起輸出給磁盤文件。目的減少對磁盤的讀寫次數(shù),即一次可以讀入一批數(shù)據(jù)或輸出一批數(shù)據(jù)。,②非緩沖文件系統(tǒng)不由系統(tǒng)自動設(shè)置所需緩沖區(qū),而由用戶根據(jù)需要設(shè)置。③新的ANSI標(biāo)準(zhǔn)只建議使用緩沖系統(tǒng),并對緩沖文件系統(tǒng)的功能進(jìn)行了擴(kuò)充,使既能用于處理字符代碼文件,也能處理二進(jìn)制文件。,,33文件類型指針,對文件的操作是通過文件指針實現(xiàn)的,關(guān)鍵的概念是“文件指針”。調(diào)用一個文件需要的信息文件當(dāng)前讀寫的位置;與該文件對應(yīng)的內(nèi)存緩沖區(qū)的地址;緩沖區(qū)未被處理的字符數(shù)字符指針;文件的操作方式。,系統(tǒng)內(nèi)部定義了一個FILE的結(jié)構(gòu)類型。TYPEDEFSTRUCT{INT_FD//文件號INT_CLEFT//緩沖區(qū)中剩余的字符INT_MODE//文件操作方式CHAR_NEXTC//下一個字符位置CHAR_BUFF//文件緩沖區(qū)位置}FILE,FILE類型保存被使用的文件的有關(guān)信息所有的文件操作都需要FILE類型的指針FILE是庫文件中定義的結(jié)構(gòu)體的別名,FILE定義在STDIOH中注意不要寫成STRUCTFILE舉例FILEFP,,34文件的打開與關(guān)閉,文件必須先打開后,并及時關(guān)閉,1打開文件是在用戶程序和操作系統(tǒng)之間建立聯(lián)系,程序要把操作的文件的信息通知操作系統(tǒng),如文件名、文件操作方式讀寫。,讀文件需要先確定此文件是否存在,并將讀當(dāng)前位置設(shè)定為文件的開頭。寫文件需要檢查原來是否有同名文件,如有則將該文件的原有內(nèi)容刪除,如無同名文件就建立一個新文件,然后將寫當(dāng)前位置設(shè)定于文件的開頭,以便從文件開頭寫入數(shù)據(jù)。,文件的打開方式調(diào)用方式FOPEN“文件名“,“文件操作方式“;功能返回一個指向該文件的指針或錯誤標(biāo)志NULL。,為避免出錯,常用以下方法來打開文件FILEFPIFFPFOPEN“文件名”,“使用文件方式”NULL{PRINTF”CANNOTOPENTHISFILE\N”EXIT0//正常中止程序},文件的打開模式,文件的打開舉例,FILEFP1,FP2,FP3CHARFILENAME“FILE3DAT“/以文本只讀方式打開FILE1/IFFP1FOPEN“FILE1“,“R“{PRINTF“CANNOTOPENTHISFILE\N“EXIT0/退出程序/}/以二進(jìn)制讀寫方式打開FILE2TXT/FP2FOPEN“C\\HOME\\FILE2TXT“,“RB“/以二進(jìn)制讀寫方式打開FILE3DAT/FP3FOPENFILENAME,“AB“,2文件的關(guān)閉調(diào)用方式FCLOSE文件指針變量;功能關(guān)閉一個已打開的文件釋放文件信息區(qū)返回值若成功,返回0,若出錯,返回EOF13文件結(jié)尾標(biāo)志EOF,說明釋放文件的有關(guān)信息區(qū);將輸出文件緩沖區(qū)的內(nèi)容無論緩沖區(qū)是否為滿都輸出寫入文件,然后關(guān)閉文件,這樣可防止丟失本來應(yīng)寫入文件的數(shù)據(jù)。不用的文件應(yīng)關(guān)閉,防止數(shù)據(jù)破壞丟失,文件應(yīng)用示例例1格式化的輸入輸出。FPRINTFFP,格式字符串,輸出項表列功能將輸出按格式串規(guī)定輸出到指定文件。FSCANFFP,格式字符串,輸入項表列功能從FP所指文件按格式串讀入數(shù)據(jù)。函數(shù)執(zhí)行成功返回讀得的數(shù)據(jù)項個數(shù);若在讀第1項前已到達(dá)文件結(jié)束處,則返回EOF。,INCLUDEINCLUDEINCLUDEVOIDMAIN{FILEFPCHARNAME10INTNUMFLOATSCOREIFFPFOPEN“FILE3TXT“,“W“NULL{PRINTF“CANNOTOPENTHISFILE\N“EXIT0}PRINTF“ENTERNAME,NUM,SCORE“SCANF“SDF“,NAME,,WHILESTRLENNAME1{FPRINTFFP,“SDF\N“,NAME,NUM,SCOREPRINTF“ENTERNAME,NUM,SCORE“SCANF“SDF“,NAME,}REWINDFPWHILEFSCANFFP,“SDF“,NAME,FCLOSEFP},輸入ENTERNAME,NUM,SCOREZHANGSAN050190ENTERNAME,NUM,SCORELIMING050285ENTERNAME,NUM,SCOREGAOFEI050395ENTERNAME,NUM,SCORE000,輸出ZHANGSAN5019000LIMING5028500GAOFEI5039500,例2具有文件拷貝功能的程序FILECOPYC。說明兩個問題命令行參數(shù)的應(yīng)用和文件的字符輸入與輸出應(yīng)用。FGETCFP功能從指定文件讀入一個字符。FPUTCCH,FP功能把一個字符寫到指定文件中去。,INCLUDEINCLUDEINCLUDEVOIDFILECOPYFILEFP1,FILEFP2{CHARCWHILECFGETCFP1EOFFPUTCC,FP2},VOIDMAININTARGC,CHARARGV{FILEFP1,FP2//VOIDFILECOPYFILEFP1,FILEFP2IFARGC1{IFFP1FOPENARGV,“R“NULL{PRINTF“CANTFOPENS\N“,ARGVEXIT0}IFFP2FOPENARGV,“W“NULL{PRINTF“CANTFOPENS\N“,ARGVEXIT0}FILECOPYFP1,FP2}},例3文件的字符串的輸入輸出處理。FGETSSTR,N,FP字符串輸入函數(shù)其功能是從FP指定的文件中讀取一個串,若滿足以下條件讀取結(jié)束①已讀取N1個字符,②當(dāng)前讀取到的字符是回車符,③已讀取到文件尾。讀取的字符個數(shù)至多N1個,余下的一個字節(jié)空間作為加“\0”串結(jié)束符。讀取回車符時,也作為一個字符送入由STR所指的內(nèi)存緩沖區(qū)。然后再加一個字符結(jié)束符“\0”STR為數(shù)組名或字符指針N為讀取字符個數(shù),例3文件的字符串的輸入輸出處理。FPUTSSTR,FP字符串輸出寫函數(shù)其功能是將STR所指定的字符串寫到FP指向的文件中。與FGETS函數(shù)在輸入字符串自動加“\0”特性對應(yīng),F(xiàn)PUTS函數(shù)在將C字符串寫入文件時其末尾的“\0”字符自動舍去。,INCLUDEINCLUDEINCLUDEVOIDMAIN{FILEFPCHARSTR16IFFPOPEN“FILE2TXT”,”W”NULL{PRINTF“CANNOTOPENTHISFILE\N”EXIT0}WHILESTRLENGETSSTR0FPUTSSTR,FPFCLOSEFPIFFPOPEN“FILE2TXT”,”R”NULL{PRINTF“CANNOTOPENTHISFILE\N”EXIT0}WHILEFGETSSTR,16,FPNULLPRINTF“S\N”,STRFCLOSEFP},文件的讀寫,例4數(shù)據(jù)塊二進(jìn)制形式的讀寫FREADBUFFER,SIZE,COUNT,FP功能從指定文件讀入COUNT個大小為SIZE的字節(jié)數(shù)據(jù)塊,存入BUFFER所指存儲單元。返回所讀的數(shù)據(jù)項個數(shù),如遇文件結(jié)束或出錯返回0。FWRITEBUFFER,SIZE,COUNT,FP功能從BUFFER所指存儲單元的數(shù)據(jù)取SIZECOUNT個字節(jié)送FP所指文件。返回寫到FP所指文件中的數(shù)據(jù)項的個數(shù)。,例4數(shù)據(jù)塊二進(jìn)制形式的讀寫FREADBUFFER,SIZE,COUNT,FPFWRITEBUFFER,SIZE,COUNT,FP說明BUFFER為輸入輸出在內(nèi)存中存放的首地址;SIZE為讀、寫的字節(jié)數(shù),即數(shù)據(jù)塊的大??;COUNT為輸入輸出的數(shù)據(jù)項的個數(shù);FREAD和FWRITE用于二進(jìn)制文件的輸入輸出。,INCLUDEINCLUDEDEFINESIZE4STRUCTSTUDENT{CHARNAME10INTNUM,AGECHARADDR15}STUDSIZEVOIDSAVE_LOAD{FILEFPINTIIFFPFOPEN“STU_LIST“,“WB“NULL{PRINTF“CANNOTOPENFILE\N“EXIT0},FORI0ISIZEI{IFFWRITEEXIT0}}REWINDFPFORI0ISIZEI{IFFREAD}},輸入ZHANG100119ROOM_101LI100219ROOM_102WANG100321ROOM_103ZHAO100421ROOM_104,輸出ZHANG100119ROOM_101LI100219ROOM_102WANG100321ROOM_103ZHAO100421ROOM_104,VOIDMAIN{INTIFORI0ISIZEISCANF“SDDS“,STUDINAME,SAVE_LOAD},回顧FGETC,FPUTC,FGETS,FPUTS,FSCANF,FPRINTF,,這些函數(shù)都是按順序讀/寫文件,35文件的隨機(jī)讀寫,解決的辦法把文件指針移到指定的位置即可。,關(guān)鍵步驟文件的定位。,35文件的隨機(jī)讀寫,問題要求打開文件后,對指定位置上的數(shù)據(jù)進(jìn)行讀寫操作,減少一些不必要的中間環(huán)節(jié)。,一、對文件隨機(jī)存取的思想,?對一個文件流,有主觀的愿望要取指定位置的記錄和更新指定位置的記錄。,如對一個文件流,可以有兩種目的,?從第I個字節(jié)開始,讀取K個字節(jié)的內(nèi)容,?把K個字節(jié)的內(nèi)容寫到從第I個字節(jié)開始后,存在的問題讀取的內(nèi)容是否滿足我們的要求,,二、隨機(jī)存取的應(yīng)用,?隨機(jī)存取文件適合于具有固定長度記錄的文件,程序可以很方便的訪問到指定位置處的記錄。,訪問,,三、隨機(jī)存取的目的,1方便、快捷,2只改變指定位置后的固定長度字節(jié)的內(nèi)容不會破壞其它的數(shù)據(jù),讀取、修改等,,問題的實質(zhì)把指定的數(shù)據(jù)寫到文件流中指定的位置。,問題的關(guān)鍵把文件指針定位到文件流中指定的位置。,步驟定位??寫數(shù)據(jù),四、向隨機(jī)文件中隨機(jī)地寫入數(shù)據(jù),五、文件定位函數(shù),FSEEK文件指針變量、位移量、起始點,注起始點的取值只有3種,位移量以起始點為基點移動的字節(jié)數(shù),0??文件開始處,1??文件位置指針的當(dāng)前位置,2??文件尾。,,位移量應(yīng)為LONG型,FSEEK的返回值,0??成功,非零??失敗,例FSEEKFP,20L,0,將位置指針從文件頭移動20個字節(jié),FSEEKFP,?10L,1,將位置指針移到離文件尾30個字節(jié)處,FSEEKFP,?30L,2,將位置從當(dāng)前位置向后移10個字節(jié),六、位置函數(shù),FTELL文件指針變量;,作用返回位置指針的當(dāng)前指向,返回值,,≥0,文件指針的當(dāng)前指向,?1,出錯,例5文件DATA1TXT的內(nèi)容如下,THISISATEST,C語言程序設(shè)計,隨機(jī)讀寫函數(shù)測試。,要求編寫一程序隨機(jī)讀出指定的記錄。,七、重新定位函數(shù),REWIND文件指針變量,作用使文件指針返回到文件的開頭,無返回值,INCLUDEINCLUDEINCLUDEVOIDMAIN{FILEFPINTLOC1,LOC2LONGD8LCHARWFPFOPEN“DATA1TXT“,“R“IFFPNULLPRINTF“ERROR\N“ELSE{LOC1FSEEKFP,D,0IFLOC10{WFGETCFPPRINTF“WC\N“,W}},運行結(jié)果,WALOC29LOC20,LOC2FTELLFPREWINDFPPRINTF“LOC2D\N“,LOC2LOC2FTELLFPFCLOSEFPPRINTF“LOC2D\N“,LOC2},,,思考,若要采用隨機(jī)讀寫的方式讀取一個漢字,程序如何修改,提示一個漢字占2個字節(jié),可使用FGETS函數(shù)將要讀出的漢字裝A數(shù)組,讀取的字符個數(shù)必須為≥3的單數(shù),八、文件操作的錯誤檢測,C語言對于大多數(shù)標(biāo)準(zhǔn)I/O函數(shù)不具有明確的出錯信息。,調(diào)用形式FERRORFP,,文件指針,返回值,,0未出錯,非0出錯,FERROR函數(shù)的值是最后一次調(diào)用時的出錯狀態(tài)。,練習(xí),程序設(shè)計題統(tǒng)計滿足條件XXYYZZ2000的所有解的個數(shù),并將統(tǒng)計結(jié)果以格式“D“寫入到新建的文件DESIGNDAT。說明若A、B、C是1個解,則A、C、B也是1個解,等等。INCLUDEVOIDMAIN{FILEPINTX,Y,Z,K0//////////////},PFOPEN“DESIGNDAT“,“W“FORX1XSQRT2000XFORY1YSQRT2000YFORZ1ZSQRT2000ZIFXXYYZZ2000KFPRINTFP,“D“,KFCLOSEP,練習(xí),程序設(shè)計題在正整數(shù)中找出1個最小的、被3、5、7、9除余數(shù)分別為1、3、5、7的數(shù),將該數(shù)以格式“D“寫到新建文件DESIGNDAT。INCLUDEINCLUDEVOIDMAIN{//////////////},FILEPINTX0PFOPEN“DESIGNDAT“,“W“DO{X}WHILEX31FPRINTFP,“D“,XFCLOSEP,
下載積分: 6 賞幣
上傳時間:2024-01-05
頁數(shù): 53
大小: 0.3(MB)
子文件數(shù):
-
簡介:第5章單片機(jī)的C語言程序設(shè)計,1C語言與MCS512C51數(shù)據(jù)類型及在MCS51中的存儲方式3C51數(shù)據(jù)的存儲類型與MCS51存儲結(jié)構(gòu)4MCS51特殊功能寄存器SFR的C51定義5MCS51并行接口的C51定義6位變量的C51定義7C51構(gòu)造數(shù)據(jù)類型8模塊化程序開發(fā)過程,,采用C51的優(yōu)點,編譯器能自動完成變量的存儲單元的分配,編程者可以專注于應(yīng)用軟件的設(shè)計,可以對常用的接口芯片編制通用的驅(qū)動函數(shù),對常用的功能模塊和算法編制相應(yīng)的函數(shù),可以方便地進(jìn)行信號處理算法和程序的移植,從而加快單片機(jī)應(yīng)用系統(tǒng)的開發(fā)速度。當(dāng)代碼長度超過4KB以上時,C51比匯編語言更具有明顯的優(yōu)勢。,C51與ASM51相比,有如下優(yōu)點1對單片機(jī)的指令系統(tǒng)不要求了解,僅要求對8051的存貯器結(jié)構(gòu)有初步了解;2寄存器分配、不同存貯器的尋址及數(shù)據(jù)類型等細(xì)節(jié)可由編譯器管理;3程序有規(guī)范的結(jié)構(gòu),可分成不同的函數(shù),這種方式可使程序結(jié)構(gòu)化;,4具有將可變的選擇與特殊操作組合在一起的能力,改善了程序的可讀性;5提供的庫包含許多標(biāo)準(zhǔn)子程序,具有較強(qiáng)的數(shù)據(jù)處理能力;6由于具有方便的模塊化編程技術(shù),使已編好程序可容易地移植;,例清零程序?qū)?000H20FFH的內(nèi)容清零★匯編語言程序ORG0000HSE01MOVR0,00HMOVDPTR,2000H0000H送DPTRLOO1CLRAMOVXDPTR,A0送DPTRINCDPTRDPTR1INCR0字節(jié)數(shù)加1CJNER0,00H,LOO1不到FF個字節(jié)再清LOOPSJMPLOOPEND,清零程序?qū)?000H20FFH的內(nèi)容清零★C-51程序INCLUDEVOIDMAIN{INTIUNSIGNEDCHARXDATAP0X2000/指針指向2000H單元/FORI0I256I{P0P}/清零2000H20FFH單元/},ORG0000HL00MOVR0,10H查找16個字節(jié)MOVR1,00HMOVDPTR,2000HL11MOVXA,DPTRCJNEA,00H,L16取出內(nèi)容與00H相等嗎INCR1取出個數(shù)加1L16INCDPTRDJNZR0,L11未完繼續(xù)MOVDPTR,2100HMOVA,R1MOVXDPTR,A相同數(shù)個數(shù)送2100HL1ESJMPL1EEND,例查找零的個數(shù)(在2000H200FH中查出有幾個字節(jié)是零,把個數(shù)放在2100H單元中),★查找零的個數(shù)C-51程序INCLUDEVOIDMAIN{UNSIGNEDCHARXDATAP0X2000/指針P指向2000H單元/INTN0,IFORI0I16I{IFP0N/若該單元內(nèi)容為零,則N1/P/指針指向下一單元/}P0X2100/指針P指向2100H單元/PN/把個數(shù)放在2100H單元中/},1C語言與MCS–51,用匯編語言編程時,必須要考慮其存儲器結(jié)構(gòu),尤其必須考慮其片內(nèi)數(shù)據(jù)存儲器與特殊功能寄存器正確、合理的使用以及按實際地址處理端口數(shù)據(jù)。用C語言編程中,對數(shù)據(jù)類型與變量的定義,必須要與單片機(jī)的存儲結(jié)構(gòu)相關(guān)聯(lián),否則編譯器不能正確地映射定位。用C語言編寫單片機(jī)程序與標(biāo)準(zhǔn)C語言程序的不同之處就在于根據(jù)單片機(jī)存儲結(jié)構(gòu)及內(nèi)部資源定義相應(yīng)的C語言中的數(shù)據(jù)類型和變量。,用C語言編寫的應(yīng)用程序必須經(jīng)單片機(jī)的C語言編譯器簡稱C51,轉(zhuǎn)換生成單片機(jī)可執(zhí)行的代碼程序。現(xiàn)在支持MCS–51系列單片機(jī)的C語言編譯器有很多種。如AMERICANAUTOMATION、AUOCET、BSO/TASKING、DUNFIELDSHAREWARE、KEIL/FRANKLIN等。其中KEIL/FRANKLIN以它的代碼緊湊和使用方便等特點優(yōu)于其它編譯器。本章是針對這種編譯器介紹MCS–51單片機(jī)C語言程序設(shè)計。,2C51數(shù)據(jù)類型及在MCS51中的存儲方式,21C51的數(shù)據(jù)類型KEIL/FRANKLINC51編譯器支持的數(shù)據(jù)類型有位型BIT、無符號字符UNSIGNEDCHAR、有符號字符SINGEDCHAR、無符號整型UNSIGNEDINT、有符號整型SIGNEDINT、無符號長整型UNSIGNEDLONG、有符號長整型SIGNEDLONG、浮點型FLOAT和指針類型等。,表1C51的數(shù)據(jù)類型,22C51數(shù)據(jù)在MCS51中的存儲方式,位變量BIT與MCS51硬件特性操作有關(guān)的可定義成位變量。位變量必須定位在MCS51單片機(jī)片內(nèi)RAM的位尋址空間中。字符變量CHAR字符變量的長度為1字節(jié)即8位。對于無符號變量UNSIGNEDCHAR的值域范圍是0255。對于有符號字符變量SIGNEDCHAR,最具有重要意義的位是最高位上的符號標(biāo)志位MSB。此位為1代表“負(fù)“,為0代表“正“。有符號字符變量和無符號字符變量在表示0127的數(shù)值時,其含義是一樣的,都是00X7F。負(fù)數(shù)一般用補(bǔ)碼表示,即用11111111表示1,用11111110表示2。,整型變量INT整型變量的長度為16位。MCS51系列單片機(jī)將INT型變量的高位字節(jié)數(shù)存放在低地址字節(jié)中,低位字節(jié)數(shù)存放在高地址字節(jié)中。有符號整型變量SIGNEDINT也使用MSB位作符號標(biāo)志位,并使用二進(jìn)制補(bǔ)碼表示數(shù)值??芍苯邮褂脦追N專用的機(jī)器指令來完成多字節(jié)的加、減、乘、除運算。整型變量值0X1234以圖1所示的方式存放在內(nèi)存中。,圖1整型數(shù)的存儲結(jié)構(gòu),01,地址,0123,地址,圖2長整型變量的存儲結(jié)構(gòu),浮點型變量FLOAT浮點型變量為32位,占4個字節(jié),許多復(fù)雜的數(shù)學(xué)表達(dá)式都采用浮點變量數(shù)據(jù)類型。用符號位表示數(shù)的符號,用階碼和尾數(shù)表示數(shù)的大小。用它們進(jìn)行任何數(shù)學(xué)運算都需要使用由編譯器決定的各種不同效率等級的庫函數(shù)。C51的浮點變量數(shù)據(jù)類型的使用格式與IEEE754標(biāo)準(zhǔn)有關(guān),具有24位精度,尾數(shù)的高位始終為“1“,因而不保存,位的分布如下●1位符號位?!?位指數(shù)位?!?3位尾數(shù)。,符號位是最高位,尾數(shù)為低23位,內(nèi)存中按字節(jié)存儲順序如下,其中,S為符號位,1表示負(fù),0表示正;E為階碼;M為23位尾數(shù),最高位為“1“。浮點變量值125的十進(jìn)制為0XC1480000,它按圖3所示方式存于內(nèi)存中。,0123,地址,圖3浮點數(shù)的存儲結(jié)構(gòu),在編程時,如果只強(qiáng)調(diào)運算速度而不進(jìn)行負(fù)數(shù)運算時,最好采用無符號UNSIGNED格式。無符號字符類型的使用無論何時,應(yīng)盡可能使用無符號字符變量,因為它能直接被MCS51所接受?;谕瑯拥脑?,也應(yīng)盡量使用位變量。有符號字符變量雖然也只占用一個字節(jié),但需要進(jìn)行額外的操作來進(jìn)行測試代碼的符號位。,使用簡化形式定義數(shù)據(jù)類型。其方法是在源程序開頭使用DEFINE語句自定義簡化的類型標(biāo)識符。例如DEFINEUCHARUNSIGNEDCHARDEFINEUINTUNSIGNEDINT這樣,在編程中,就可以用UCHAR代替UNSIGNEDCHAR,用UINT代替UNSIGNEDINT來定義變量。,3C51數(shù)據(jù)的存儲類型與MCS51存儲結(jié)構(gòu),表2C51存儲類型與MCS51存儲空間的對應(yīng)關(guān)系,1、DATA區(qū)8051內(nèi)128字節(jié)的內(nèi)部RAM,或8052的前128字節(jié)內(nèi)部RAM,這部分主要是作為數(shù)據(jù)段稱為DATA區(qū)。指令用一個或兩個周期來訪問數(shù)據(jù)段。數(shù)據(jù)段中有兩個小段,第一個子段包含四組寄存器組。另外一個子段叫做位尋址段BDATA,包括16個字節(jié)共128位每一位都可單獨尋址。對DATA區(qū)的尋址是最快的所以應(yīng)該把使用頻率高的變量放在DATA區(qū),DATA區(qū)除了包含程序變量外還包含了堆棧和寄存器組UNSIGNEDCHARDATASYSTEM_STATUS0UNSIGNEDINTDATAUNIT_ID2CHARDATAINP_STRING16FLOATDATAOUTP_VALUEMYTYPEDATANEW_VAR,2、BDATA區(qū)單片機(jī)內(nèi)部RAM的位尋址區(qū)叫做位尋址段BDATA區(qū),包括16個字節(jié)共128位??梢栽贒ATA區(qū)的位尋址區(qū)定義變量非浮點型,這個變量就可進(jìn)行位尋址,并且可以聲明位變量。UNSIGNEDCHARBDATASTATUS_BYTEUNSIGNEDINTBDATASTATUS_WORDSBITSTAT_FLAGSTATUS_BYTE4IFSTATUS_WORD15{}STAT_FLAG1編譯器不允許在BDATA段中定義FLOAT和DOUBLE類型的變量。,IDATA段8051系列的一些單片機(jī)如8052有附加的128字節(jié)的內(nèi)部RAM,位于從80H開始的地址空間中,這部分加上低128字節(jié)的內(nèi)部RAM共256字節(jié),被稱為IDATA。因為IDATA區(qū)的地址和SFR的地址是重疊的,通過區(qū)分所訪問的存儲區(qū)來解決地址重疊問題,因此IDATA區(qū)只能通過間接尋址來訪問IDATA段也可存放使用比較頻繁的變量,使用寄存器作為指針進(jìn)行尋址,在寄存器中設(shè)置8位地址進(jìn)行間接尋址。和外部存儲器尋址比較,它的指令執(zhí)行周期和代碼長度都比較短。UNSIGNEDCHARIDATASYSTEM_STATUS0UNSIGNEDINTIDATAUNIT_ID2CHARIDATAINP_STRING16FLOATIDATAOUTP_VALUE,,PDATA區(qū)外部存儲區(qū)的最低地址的256個字節(jié),稱為PDATA區(qū)。通過P0口的地址對其尋址,使用指令MOVXRN,需要兩個指令周期。UNSIGNEDINTPDATAUNIT_ID2FLOATPDATAOUTP_VALUE,XDATA區(qū)8051單片機(jī)的外部RAM,存儲空間為64K,采用16位地址尋址稱作外部數(shù)據(jù)區(qū)簡稱XDATA區(qū)。這個區(qū)通常包括一些RAM如SRAM或一些需要通過總線接口的外圍器件。UNSIGNEDCHARXDATASYSTEM_STATUS0CHARXDATAINP_STRING16,CODE區(qū)程序存儲區(qū)稱為CODE區(qū),使用MOVCA,DPTR訪問。代碼段的數(shù)據(jù)是不可改變的8051的代碼段不可重寫一般代碼段中可存放數(shù)據(jù)表、跳轉(zhuǎn)向量和狀態(tài)表。對CODE段的訪問和對XDATA段的訪問的時間是一樣的,代碼段中的對象在編譯的時候初始化。UNSIGNEDINTCODEUNIT_ID1234UNSIGNEDCHARCH_ARRAY16{0X00,0X01,0X02,0X03,0X04,0X05,0X06,0X07,0X08,0X09,0X10,0X11,0X12,0X13,0X14,0X15},表3C51存儲類型及其數(shù)據(jù)長度和值域,帶存儲類型的變量的定義的一般格式為數(shù)據(jù)類型存儲類型變量名,帶存儲類型的變量定義舉例CHARDATAVAR1;BITBDATAFLAGS;FLOATIDATAX,Y,Z;UNSIGNEDINTPDATAVAR2;UNSIGNEDCHARVECTOR34;,表4存儲模式說明,4MCS51特殊功能寄存器SFR的C51定義,MCS51單片機(jī)中,除了程序計數(shù)器PC和4組工作寄存器組外,其它所有的寄存器均為特殊功能寄存器SFR,分散在片內(nèi)RAM區(qū)的高128字節(jié)中,地址范圍為80H0FFH。SFR中有11個寄存器具有位尋址能力,它們的字節(jié)地址都能被8整除,即字節(jié)地址是以8或0為尾數(shù)的。為了能直接訪問這些SFR,C51提供了一種自主形式的定義方法,這種定義方法與標(biāo)準(zhǔn)C語言不兼容,只適用于對MCS51系列單片機(jī)進(jìn)行C語言編程。,特殊功能寄存器C51定義的一般語法格式如下SFRSFRNAMEINTCONSTANT;“SFR“是定義語句的關(guān)鍵字,其后必須跟一個MSC51單片機(jī)真實存在的特殊功能寄存器名,““后面必須是一個整型常數(shù),不允許帶有運算符的表達(dá)式,是特殊功能寄存器“SFRNAME“的字節(jié)地址,這個常數(shù)值的范圍須在SFR地址范圍內(nèi),位于0X800XFF。例如SFRSCON0X98;/串口控制寄存器地址98H/SFRTMOD0X89;/定時/計數(shù)器方式控制寄存器地址89H/,MCS51系列單片機(jī)的特殊功能寄存器的數(shù)量與類型不盡相同,因此一般將所有特殊的“SFR“定義放入一個頭文件中,該文件應(yīng)包括MCS51單片機(jī)系列機(jī)型中的SFR定義。C51編譯器的“REG51H“頭文件就是這樣一個文件。在新的MCS51系列產(chǎn)品中,SFR在功能上經(jīng)常組合為16位值,當(dāng)SFR的高字節(jié)地址直接位于低字節(jié)之后時,對16位SFR的值可以直接進(jìn)行訪問。如52子系列的定時器/計數(shù)器2就是這種情況。為了有效地訪問這類SFR,可使用關(guān)鍵字“SFR16“來定義,其定義語句的語法格式與8位SFR相同,只是““后面的地址必須用16位SFR的低字節(jié)地址,即低字節(jié)地址作為“SFR16“的定義地址。,例如SFR16T20XCC/定時器/計數(shù)器2T2低8位地址為0CCH,T2高8位地址為0CDH/這種定義適用于所有新的16位SFR,但不能用于定時器/計數(shù)器0和1。對于位尋址的SFR中的位,C51的擴(kuò)充功能支持特殊位的定義,像SFR一樣不與標(biāo)準(zhǔn)C兼容,使用“SBIT“來定義位尋址單元。,第一種格式SBITBITNAMESFRNAMEINTCONSTANT;“SBIT“是定義語句的關(guān)鍵字,后跟一個尋址位符號名該位符號名必須是MCS51單片機(jī)中規(guī)定的位名稱,““后的“SFRNAME“必須是已定義過的SFR的名字,““后的整常數(shù)是尋址位在特殊功能寄存器“SFRNAME“中的位號,必須是07范圍中的數(shù)。例如SFRPSW0XD0;/定義PSW寄存器地址為D0H/SBITOVPSW2;/定義OV位為PSW2,地址為D2H/SBITCYPSW7;/定義CY位為PSW7,地址為D7H/,第二種格式SBITBITNAMEINTCONSTANTINTCONSTANT;““后的INTCONSTANT為尋址地址位所在的特殊功能寄存器的字節(jié)地址,““符號后的INTCONSTANT為尋址位在特殊功能寄存器中的位號。例如SBITOV0XD02;/定義OV位地址是D0H字節(jié)中的第2位/SBITCY0XD07;/定義CY位地址是D0H字節(jié)中的第7位/,第三種格式SBITBITNAMEINTCONSTANT;““后的INTCONSTANT為尋址位的絕對位地址。例如SBITOV0XD2;/定義OV位地址為D2H/SBITCY0XD7;/定義CY位地址為D7H/特殊功能位代表了一個獨立的定義類,不能與其它位定義和位域互換。,5MCS51并行接口的C51定義,MCS51系列單片機(jī)并行I/O接口除了芯片上的4個I/O口P0P3外,還可以在片外擴(kuò)展I/O口。MCS51單片機(jī)I/O口與數(shù)據(jù)存儲器統(tǒng)一編址,即把一個I/O口當(dāng)作數(shù)據(jù)存儲器中的一個單元來看待。使用C51進(jìn)行編程時,MCS51片內(nèi)的I/O口與片外擴(kuò)展的I/O可以統(tǒng)一在一個頭文件中定義,也可以在程序中一般在開始的位置進(jìn)行定義,其定義方法如下,對于MCS51片內(nèi)I/O口按特殊功能寄存器方法定義。如SFRP00X80;/定義P0口,地址為80H/SFRP10X90;/定義P1口,地址為90H/,對于片外擴(kuò)展I/O口,則根據(jù)硬件譯碼地址,將其視作為片外數(shù)據(jù)存儲器的一個單元,使用DEFINE語句進(jìn)行定義。例如INCLUDEDEFINEPORTAXBYTE0XFFC0ABSACCH是C51中絕對地址訪問函數(shù)的頭文件,將PORTA定義為外部I/O口,地址為FFC0H,長度為8位。一旦在頭文件或程序中對這些片外I/O口進(jìn)行定義后,在程序中就可以自由使用變量名與其實際地址的聯(lián)系,以便使程序員能用軟件模擬MCS51的硬件操作。,1位變量C51定義。使用C51編程時,定義了位變量后,就可以用定義了的變量來表示MCS51的位尋址單元。位變量的C51定義的一般語法格式如下位類型標(biāo)識符BIT位變量名;例如BITDIRECTION_BIT;/把DIRECTION_BIT定義為位變量/BITLOOK_POINTER;/把LOOK_POINTER定義為位變量/,6位變量的C51定義,2函數(shù)可包含類型為“BIT“的參數(shù),也可以將其作為返回值。例如BITFUNCBITB0,BITB1/變量B0,B1作為函數(shù)的參數(shù)/{RETURNB1;/變量B1作為函數(shù)的返回值/}注意,使用PRAGMADISABLE或包含明確的寄存器組切換USINGN的函數(shù)不能返回位值,否則編輯器將會給出一個錯誤信息。,,3對位變量定義的限制。位變量不能定義成一個指針,如不能定義BITBIT_POINTER。不存在位數(shù)組,如不能定義BITB_ARRAY。在位定義中,允許定義存儲類型,位變量都被放入一個位段,此段總位于MCS51片內(nèi)的RAM區(qū)中。因此,存儲類型限制為BDATA和IDATA,如果將位變量的存儲類型定義成其它存儲類型都將編譯出錯。,例1先定義變量的數(shù)據(jù)類型和存儲類型BDATAINTIBASE;/定義IBASE為BDATA整型變量/BDATACHARBARY4;/BARY4定義為BDATA字符型數(shù)組/然后可使用“SBIT“定義可獨立尋址訪問的對象位SBITMYBIT0IBASE0;/MYBIT0定義為IBASE的第0位/SBITMYBIT15IBASE15;/MYBIT0定義為IBASE的第15位/SBITARY07BARY07;/ARY07定義為ABRY0的第7位/SBITARY37BARY37;/ARY37定義為ABRY3的第7位/,對象IBASE和BARY也可以字節(jié)尋址ARY370;/BARY3的第7位賦值為0/BARY3A/字節(jié)尋址,BARY3賦值為A/SBIT定義要位尋址對象所在字節(jié)基址對象的存儲類型為“BDATA“,否則只有絕對的特殊位定義SBIT是合法的?!啊安僮鞣蟮淖畲笾狄蕾囉谥付ǖ幕愋?,對于CHAR/UCHAR而言是07,對于INT/UINT而言是015,對于LONG/ULONG而言是031。,7C51構(gòu)造數(shù)據(jù)類型,71基于存儲器的指針基于存儲器的指針以存儲器類型為參量,它在編譯時才被確定。因此,為指針選擇存儲器的方法可以省掉,以便這些指針的長度為一個字節(jié)IDATA,DATA,PDATA或2個字節(jié)CODE,XDATA。編譯時,這類操作一般被“行內(nèi)“INLINE編碼,而無需進(jìn)行庫調(diào)用?;诖鎯ζ鞯闹羔樁x舉例CHARXDATAPX;,在XDATA存儲器中定義了一個指向字符型CHAR的指針變量PX。指針自身在默認(rèn)存儲區(qū)決定于編譯模式,長度為2個字節(jié)值為00XFFFF。CHARDATAPDX;除了明確定義指針位于MCS51內(nèi)部存儲區(qū)DATA外,其它與上例相同,它與編譯模式無關(guān)。CHARXDATADATAPDX,STRUCTTIME{CHARHOUR;CHARMIN;CHARSEC;STRUCTTIMEXDATAPXTIME;}在結(jié)構(gòu)STRUCTTIME中,除了其它結(jié)構(gòu)成員外,還包含有一個具有和STRUCTTIME相同的指針PXTIME,TIME位于外部數(shù)據(jù)存儲器XDATA,指針PXTIME具有兩個字節(jié)長度。,STRUCTTIMEIDATAPTIME;這個聲明定義了一個位于默認(rèn)存儲器中的指針,它指向結(jié)構(gòu)TIME,TIME位于IDATA存儲器中,結(jié)構(gòu)成員可以通過MCS51的R0或R1進(jìn)行間接訪問,指針PTIME為1個字節(jié)長。PTIME→PXTIME→HOUR12;使用上面的關(guān)于STRUCTTIME和STRUCTIDATAPTIME的定義,指針“PXTIME“被從結(jié)構(gòu)中間接調(diào)用,它指向位于XDATA存儲器中的TIME結(jié)構(gòu)。結(jié)構(gòu)成員HOUR被賦值為12。,72一般指針一般指針包括3個字節(jié)1個字節(jié)存儲類型和2個字節(jié)偏移地址,即,其中,第一字節(jié)代表了指針的存儲器類型,存儲器類型編碼如下,例如,以XDATA類型的0X1234地址為指針可以表示如下,當(dāng)用常數(shù)作指針時,必須注意正確定義存儲器類型和偏移量。例如,將常數(shù)值0X41寫入地址為0X8000的外部數(shù)據(jù)存儲器。DEFINEXBYTECHAR0X20000LXBYTE0X80000X41;其中,XBYTE被定義為CHAR0X20000L,0X20000L為一般指針,其存儲類型為2,偏移量為0000H,這樣XBYTE成為指向XDATA零地址的指針。而XBYTE8000則是外部數(shù)據(jù)存儲器的0X8000絕對地址。,8模塊化程序開發(fā)過程,圖4程序開發(fā)過程,C51程序開發(fā)過程,81混合編程,1.命名規(guī)則,表5函數(shù)名的轉(zhuǎn)換,例2用匯編語言編寫函數(shù)“TOUPPER“,參數(shù)傳遞發(fā)生在寄存器R7中。UPPERSEGMENTCODE;程序段PUBLIC_TOUPPER;入口地址PSEGUPPER;程序段_TOUPPERMOVA,R7;從R7中取參數(shù)CJNEA,A,3JCUPPERETCJNEA,Z1,3JNCUPPERETCLRACC,5UPPERETMOVR7,A;返回值放在R7中RET;返回到C,2.參數(shù)傳遞規(guī)則,表6參數(shù)傳遞的寄存器選擇,FUNC1INTA“A“是第一個參數(shù),在R6,R7中傳遞。FUNC2INTB,INTC,INTD“B“是第一個參數(shù),在R6,R7中傳遞;“C“是第二個參數(shù),在R4,R5中傳遞;“D“是第三個參數(shù),在R1,R2,R3中傳遞。FUNC3LONGE,LONGF“E“是第一個參數(shù),在R4R7中傳遞;“F“是第二個參數(shù),不能在寄存器中傳遞,只能在參數(shù)傳遞段中傳遞。FUNC4FLOATG,CHARH“G“是第一個參數(shù),在R4R7中傳遞;“H“是第二個參數(shù),必須在參數(shù)傳遞段中傳遞。,表7函數(shù)返回值的寄存器,在匯編子程序中,當(dāng)前選擇的寄存器組及寄存器ACC、B、DPTR和PSW都可能改變。當(dāng)被C調(diào)用時,必須無條件地假設(shè)這些寄存器的內(nèi)容已被破壞。如果已在連接/定位程序時選擇了覆蓋,那么每個匯編子程序包含一個單獨的程序段是必要的,因為在覆蓋過程中,函數(shù)間參量通過子程序各自的段參量計算。匯編子程序的數(shù)據(jù)區(qū)甚至可包含在覆蓋部分中,但應(yīng)注意下面兩點1所有段名必須以C51類似的方法建立。2每個有局部變量的匯編程序必須指定自己的數(shù)據(jù)段,這個數(shù)據(jù)段只能為其它函數(shù)訪問作參數(shù)傳遞用。所有參數(shù)一個接一個被傳遞,由其它函數(shù)計算的結(jié)果保存入棧。,82覆蓋和共享,1.覆蓋單片機(jī)片內(nèi)存儲空間有限,連接器/定位器通常重新啟用程序不再用的位置。這就是說,若一個程序不再調(diào)用,也不由其它程序調(diào)用甚至間接調(diào)用,那么在其它程序執(zhí)行完之前,這個程序不再運行。這個程序的變量可以放在與其它程序完全相同的RAM空間,很像可重用的寄存器。這種技術(shù)就是覆蓋。在匯編中直接通過手工完成的這些空間分配,C語言中可以由連接器自動管理。若有幾個不相關(guān)聯(lián)的程序時,它可以使RAM單元比手工考慮要用的少。,2.共享1共享變量,2共享函數(shù)/子程序C中函數(shù)若是全局的公用的,可以放在調(diào)用的函數(shù)之后。若函數(shù)是模塊專用的,它可以定義為靜態(tài)函數(shù),這樣它不能被其它模塊調(diào)用。C語言的ANSI標(biāo)準(zhǔn)建議所有函數(shù)在主函數(shù)前要有原型進(jìn)行說明,然后實際函數(shù)可在主函數(shù)之后或其它模塊中。匯編語言中,子程序使用標(biāo)號可在給定模塊的任何位置。匯編器首先掃描得到所有的符號名,然后值就可填入LCALL或LJMP。一個模塊或另一模塊共享子程序,一個使用PUBLIC而另一個使用EXTERN。當(dāng)指定為EXTERN,符號類型CODE,DATA,XDATA,IDATA,BIT或NUMBER必須特別加以指定,以便連接器可以確定放在一起的正確類型。,83庫和連接器/定位器1庫,表9C51的編譯庫,2.連接器/定位器1組合程序模塊將幾個不同程序模塊組合為一個模塊,并自動從庫中挑選模塊嵌入目標(biāo)文件。輸入文件按命令行中出現(xiàn)的順序處理。通常的程序模塊是由C51編譯器或A51宏匯編生成的可重入的目標(biāo)文件。,2組合段將具有相同段名的可重定位段組合成單一的段。在一個程序模塊中定義的一個段成為部分段。一個部分段在源文件中以下列形式指定1名字每個重定位段有一個名字,它可與來自其它模塊的同名的可重定位段組合。絕對段沒有名字。2類型類型表明段所屬的地址空間CODE,XDATA,DATA或BIT。,3定位方式可重定位段的定位方式有PAGE,INPAGE,INBLOCK,BITADDRESSABLE或UNIT。INPAGE表明段必須放入一頁高8位地址相同中以使用短轉(zhuǎn)移和調(diào)用指令。INBLOCK段應(yīng)使用ACALL,必須放在2048字節(jié)塊中。因為沒有連接器可以靈活地判知調(diào)用和轉(zhuǎn)移是否在塊內(nèi)??芍囟ㄎ坏钠渌拗剖荘AGE不能超過256字節(jié)
下載積分: 6 賞幣
上傳時間:2024-01-05
頁數(shù): 79
大小: 0.7(MB)
子文件數(shù):
-
下載積分: 9 賞幣
上傳時間:2024-03-05
頁數(shù): 66
大?。?0.15(MB)
子文件數(shù):
-
下載積分: 3 賞幣
上傳時間:2024-03-05
頁數(shù): 1
大小: 0.05(MB)
子文件數(shù):
-
下載積分: 5 賞幣
上傳時間:2024-03-05
頁數(shù): 5
大?。?0.6(MB)
子文件數(shù):
-
下載積分: 3 賞幣
上傳時間:2024-03-05
頁數(shù): 1
大?。?0.03(MB)
子文件數(shù):
-
簡介:第三講程序語言的語法描述,作業(yè)P36(6,7,8)其中6(2)做01278(1)做III,上下文無關(guān)文法語法范疇完全獨立于這種范疇可能出現(xiàn)的環(huán)境,1)文法與語言文法上下文無關(guān)文法G是一個四元式(VT,VN,S,P)。其中VT非空集,每個元素叫終結(jié)符VN非空有限集,每個元素稱為非終結(jié)符S非終結(jié)符,叫做開始符號P產(chǎn)生式集(有限),形式為P?,其中P?VN,??VT?VN注意開始符S至少必須在某個產(chǎn)生式的左部出現(xiàn)一次P?1P?2P?N可以縮寫為P?1|?2||?N每個?I也叫P的一個侯選式討論中多以大寫字母表示非終結(jié)符,,語言上下文無關(guān)文法定義語言的辦法從文法的開始符出發(fā),反復(fù)連續(xù)使用產(chǎn)生式,對非終結(jié)符實施替換和展開EG文法EEE|EE|E|IP28據(jù)規(guī)則EE,我們說從“E”可以直接推出“E”,記為EE對“E”中“E”再用EEE便有EEE,即由“E”可以推出EE表示為EEEE,,基本術(shù)語P29學(xué)員閱讀直接推出推導(dǎo)可推導(dǎo)出?1?N?1?N文法的句型文法G的句子全體形成它的語言LG{?|S?且??VT}最左推導(dǎo)最右推導(dǎo)EEEEEEEIEEIIEIII,,2語法樹及二義性語法樹(P31圖22,侯選式中自左至右的每個符號對應(yīng)一個新結(jié)點包含了最左、最右推導(dǎo),但不含所有可能推導(dǎo)E(E)EE文法的二義性EEIII,,,,,,,,,,,,,文法的二義性文法二義性若一文法中存在某個句子,它有兩個不同的最左最右推導(dǎo),或者說一文法存在某個句子對應(yīng)兩棵不同的語法樹例P31圖22,P32圖23III語言的二義性某語言由不同文法刻畫兩種二義性有何不同,,P28的表達(dá)式文法可以通過規(guī)定,優(yōu)先順序,結(jié)合規(guī)則而構(gòu)造一無二義的文法ET|ET概念分層思想TF|TFFE|I,,對上下文無關(guān)文法的兩點限制文法中不含任何PP形式的產(chǎn)生式會產(chǎn)生二義每個非終結(jié)符都有用處即存在S??P?,則必有??VT,使得P?,,3形式語言鳥瞰CHOMSKY將文法分為四類0,1,2,30每個產(chǎn)生式???滿足??VN?VT且至少含一個非終結(jié)符,而??VN?VT1每個產(chǎn)生式???滿足|?|0}2型文法無法產(chǎn)生{ANBNCN|N0},
下載積分: 6 賞幣
上傳時間:2024-01-05
頁數(shù): 10
大?。?0.05(MB)
子文件數(shù):