2023年全國碩士研究生考試考研英語一試題真題(含答案詳解+作文范文)_第1頁
已閱讀1頁,還剩22頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、<p><b>  小型數(shù)據(jù)庫</b></p><p>  ——命令解析器、數(shù)據(jù)存儲(chǔ)的設(shè)計(jì)與實(shí)現(xiàn)</p><p><b>  摘 要</b></p><p>  當(dāng)今時(shí)代,“數(shù)據(jù)”已經(jīng)成為一種資源。隨著各種數(shù)據(jù)獲取技術(shù)和數(shù)據(jù)庫技術(shù)的迅速發(fā)展,人們積累的數(shù)據(jù)越來越多,如何更加合理的管理數(shù)據(jù)顯得更加重要。小型數(shù)據(jù)

2、庫就是模擬目前比較流行的一些大型數(shù)據(jù)庫,實(shí)現(xiàn)通過在命令行輸入相應(yīng)命令來對(duì)數(shù)據(jù)進(jìn)行存儲(chǔ),管理和查詢。</p><p>  該小型數(shù)據(jù)庫MyDB包括兩大模塊:SQL命令解析器及數(shù)據(jù)存儲(chǔ)模塊。SQL命令解析器負(fù)責(zé)解析用戶命令并完成用戶對(duì)表的創(chuàng)建、刪除、插入、更新等操作;數(shù)據(jù)存儲(chǔ)模塊的主要功能是保存和管理用戶的數(shù)據(jù)。整個(gè)系統(tǒng)是用C語言、采用模塊化的程序設(shè)計(jì)思想實(shí)現(xiàn)的。</p><p>  關(guān)鍵詞:

3、MyDB;命令解析;數(shù)據(jù)存儲(chǔ);C語言</p><p>  Minidatabase</p><p>  ---- Design and Implementation of Command Interpreter and Data Storage</p><p><b>  Abstract</b></p><p>  I

4、n this information era, data has been a kind of resource. With the fast development of data getting technology and database technology, people accumulate more and more data. How to manage these data more rational become

5、more and more important. Minidatabase is to simulate popular database at present and implement data storage, management and querying by inputting commands from command line. </p><p>  This Minidatabase ——My

6、DB includes two modules: SQL command parser and data storage. SQL command parser takes in change of parsing user commands and operating tables, such as creating a table, deleting a table, inserting elements into table an

7、d updating table. The primary function of data storage module is to save and manage user data. The whole system is designed with the idea of modularized programmer and developed with C program language.</p><p&

8、gt;  Key words: MyDB ; command parse ; data storage ; C program language</p><p><b>  目 錄</b></p><p><b>  論文總頁數(shù):24頁</b></p><p><b>  1引言1</b><

9、;/p><p>  1.1數(shù)據(jù)庫課程教學(xué)的現(xiàn)狀1</p><p>  1.2研制DBMS的重要性1</p><p>  1.3MyDB的設(shè)計(jì)目標(biāo)2</p><p><b>  2數(shù)據(jù)庫理論2</b></p><p>  2.1數(shù)據(jù)元素的表示2</p><p>

10、;<b>  2.1.1字段2</b></p><p><b>  2.1.2記錄3</b></p><p><b>  2.1.3塊3</b></p><p>  2.2查詢編譯器3</p><p>  3MyDB的實(shí)現(xiàn)5</p><p>

11、;  3.1記錄的定義5</p><p>  3.2命令解析模塊6</p><p>  3.2.1 詞法分析器7</p><p>  3.2.2 語法分析器11</p><p>  3.2.3 SQL語句的實(shí)現(xiàn)13</p><p>  3.3基本表模塊18</p><p>  

12、3.3.1數(shù)據(jù)組織18</p><p>  3.3.2基本表的實(shí)現(xiàn)19</p><p>  3.4數(shù)據(jù)存儲(chǔ)模塊20</p><p><b>  結(jié) 論21</b></p><p><b>  參考文獻(xiàn)21</b></p><p><b>  致 謝

13、23</b></p><p><b>  聲 明24</b></p><p><b>  引言</b></p><p>  數(shù)據(jù)庫課程教學(xué)的現(xiàn)狀</p><p>  現(xiàn)在數(shù)據(jù)庫教學(xué)的不足突出地表現(xiàn)在以下幾點(diǎn):</p><p>  1.普遍只強(qiáng)調(diào)理論,不重視實(shí)踐

14、,在學(xué)習(xí)過程中難以對(duì)概念深刻領(lǐng)悟,課程結(jié)束后就很快把其中許多內(nèi)容給淡忘掉了。</p><p>  2.現(xiàn)有對(duì)數(shù)據(jù)庫的實(shí)踐也是流于形式,內(nèi)容膚淺與真實(shí)的數(shù)據(jù)庫管理系統(tǒng)相去甚遠(yuǎn)。比如用SQL語言對(duì)數(shù)據(jù)庫進(jìn)行一定的創(chuàng)建查詢操作。這些實(shí)踐都不過是對(duì)數(shù)據(jù)庫管理系統(tǒng)的使用,根本談不上了解數(shù)據(jù)庫本身的運(yùn)行機(jī)理。而且這些實(shí)踐都太過理想化,完全把底層原理透明化了,這些實(shí)踐充其量只不過是對(duì)SQL語言熟悉而已。</p>

15、<p>  3.用真實(shí)的數(shù)據(jù)庫管理系統(tǒng)來實(shí)踐顯然要好得多。但現(xiàn)實(shí)中的數(shù)據(jù)庫管理系統(tǒng)都太過龐大,比如開源的數(shù)據(jù)庫管理系統(tǒng)MYSQL,僅源代碼就達(dá)數(shù)十萬行之多。專業(yè)人員閱讀起來都不會(huì)很容易,更不要說剛讀本科的學(xué)生對(duì)其進(jìn)行修改了,所以收效甚微。</p><p>  以上三點(diǎn)明顯地說明了:“實(shí)踐”在數(shù)據(jù)庫原理教學(xué)中的重要性。需要一個(gè)能夠真正對(duì)數(shù)據(jù)庫所學(xué)理論進(jìn)行有效的實(shí)踐的數(shù)據(jù)庫管理系統(tǒng)。但缺少一個(gè)好的教學(xué)用數(shù)據(jù)

16、庫管理系統(tǒng),現(xiàn)有的教學(xué)用數(shù)據(jù)庫管理系統(tǒng)并不那么適合中國的實(shí)際情況。</p><p>  因此,無論是從應(yīng)用的角度還是學(xué)習(xí)數(shù)據(jù)庫的理論教學(xué)的角度來看,設(shè)計(jì)與實(shí)現(xiàn)一個(gè)小型的數(shù)據(jù)庫管理系統(tǒng)都是很有必要的。</p><p>  研制DBMS的重要性</p><p>  數(shù)據(jù)庫技術(shù)產(chǎn)生于1970年前后。它的出現(xiàn)使得計(jì)算機(jī)的應(yīng)用進(jìn)入了新的時(shí)期,社會(huì)的每個(gè)領(lǐng)域都與計(jì)算機(jī)發(fā)生了聯(lián)系

17、。數(shù)據(jù)庫技術(shù)聚集了數(shù)據(jù)處理最精華的思想,是管理信息最先進(jìn)的工具。信息社會(huì)的緊迫需求使數(shù)據(jù)庫技術(shù)成為計(jì)算機(jī)園地中一支最有生命力的新秀。而與人工智能的結(jié)合又使它獲得了新的血液。20世紀(jì)80年代中期數(shù)據(jù)庫技術(shù)進(jìn)入一個(gè)新的層次,智能數(shù)據(jù)庫、演繹數(shù)據(jù)庫、專家數(shù)據(jù)庫、面向?qū)ο髷?shù)據(jù)庫、工程數(shù)據(jù)庫、多介質(zhì)數(shù)據(jù)庫、并行數(shù)據(jù)庫、實(shí)時(shí)數(shù)據(jù)庫等就是當(dāng)代數(shù)據(jù)庫研究的前沿。</p><p>  數(shù)據(jù)庫管理系統(tǒng)(DBMS)的研制是一件非常復(fù)雜

18、的軟件工程。它涉及的面非常廣泛,需要軟件、硬件及設(shè)備方面的知識(shí);需要一定的物質(zhì)條件;需要研制人員的豐富的編程經(jīng)驗(yàn)和精深的軟件技術(shù);需要科學(xué)的管理方法和科學(xué)先進(jìn)的測試技術(shù)。當(dāng)然由于系統(tǒng)的功能和規(guī)模不一樣,其復(fù)雜程度也相差很大。大一點(diǎn)的數(shù)據(jù)庫如IMS花費(fèi)幾千人年,系統(tǒng)R的研制花費(fèi)了120個(gè)專家人年以及幾千程序員人年,SYSTEM2000花費(fèi)400人年。數(shù)據(jù)庫的設(shè)計(jì)與數(shù)據(jù)庫的設(shè)計(jì)不同,前者屬于系統(tǒng)軟件設(shè)計(jì),與機(jī)器世界比較接近,它的基礎(chǔ)是OS;

19、后者屬于應(yīng)用軟件設(shè)計(jì),與現(xiàn)實(shí)世界更為接近,它的基礎(chǔ)是數(shù)據(jù)庫。所以數(shù)據(jù)庫是介于用戶程序和OS之間的一個(gè)中間媒介,是使得物理數(shù)據(jù)庫與用戶程序相互獨(dú)立的軟件系統(tǒng)。</p><p>  研制數(shù)據(jù)庫對(duì)于從事數(shù)據(jù)庫開發(fā)的科研人員和教學(xué)人員是一件十分有價(jià)值的工作。通過參加研制數(shù)據(jù)庫的工作,可以加深對(duì)數(shù)據(jù)庫技術(shù)的理解,弄清其來龍去脈,提高技術(shù)水平,從而改進(jìn)數(shù)據(jù)庫教學(xué)質(zhì)量。更重要的是滿足社會(huì)需求。同時(shí)數(shù)據(jù)庫的研制是一件很基礎(chǔ)的工作

20、,是研究面向?qū)ο髷?shù)據(jù)庫、分布式數(shù)據(jù)庫、知識(shí)庫以及智能數(shù)據(jù)庫的基礎(chǔ)。因此,數(shù)據(jù)庫原理一般都作為計(jì)算機(jī)專業(yè)的基礎(chǔ)課程學(xué)習(xí)。</p><p><b>  MyDB的設(shè)計(jì)目標(biāo)</b></p><p>  先看看國際上有關(guān)數(shù)據(jù)庫發(fā)展的情況。隨著計(jì)算機(jī)廣泛而深入地應(yīng)用與社會(huì)各行各業(yè),作為其中重要支柱的系統(tǒng)軟件——數(shù)據(jù)庫變的越來越龐大,功能越來越強(qiáng),而且這種發(fā)展勢頭絲毫不見有放慢的

21、跡象。特別是隨著網(wǎng)絡(luò)通信技術(shù)的發(fā)展,現(xiàn)代主流的數(shù)據(jù)庫廠商紛紛把網(wǎng)絡(luò)特性集成系統(tǒng)之中,甚至還出現(xiàn)了專門應(yīng)用于網(wǎng)絡(luò)環(huán)境的分布式數(shù)據(jù)庫管理系統(tǒng)。所有這些數(shù)據(jù)庫的復(fù)雜性給數(shù)據(jù)庫的設(shè)計(jì)帶來很大的挑戰(zhàn)。</p><p>  如果個(gè)人想設(shè)計(jì)并實(shí)現(xiàn)一個(gè)商用的數(shù)據(jù)庫基本上是不可能的,復(fù)雜的技術(shù)細(xì)節(jié)會(huì)把數(shù)據(jù)庫的最基本的理論完全掩蓋。因此,學(xué)生很難通過商用的數(shù)據(jù)庫學(xué)習(xí)數(shù)據(jù)庫的原理。MyDB是一個(gè)面向教學(xué)用的DBMS,這是必須首先堅(jiān)持的

22、,同時(shí)亦對(duì)DBMS的存儲(chǔ)管理、SQL語言感興趣。</p><p>  總之,MyDB是一個(gè)基于關(guān)系代數(shù)的、用C實(shí)現(xiàn)的、面向教學(xué)的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)。</p><p><b>  數(shù)據(jù)庫理論</b></p><p><b>  數(shù)據(jù)元素的表示</b></p><p>  首先,研究一下最基本的數(shù)據(jù)元

23、素的表示,即關(guān)系數(shù)據(jù)庫系統(tǒng)中的屬性值的表示。這是用“字段”來表示的。然后,考察字段如何組裝成存儲(chǔ)系統(tǒng)中更大的元素:記錄、塊和文件</p><p><b>  字段</b></p><p>  屬性需要用定長或變長的字節(jié)序列表示,稱作“字段”;</p><p>  可以用下式所示的CREATE TABLE 語句在SQL系統(tǒng)中聲明一個(gè)關(guān)系。數(shù)據(jù)庫負(fù)

24、責(zé)表示和存儲(chǔ)由這個(gè)定義描述的關(guān)系。既然關(guān)系是元組的集合,元組與記錄或“結(jié)構(gòu)”(C或C++術(shù)語)相似,可以設(shè)想每一個(gè)元組在磁盤中作為一條記錄來存儲(chǔ)。記錄會(huì)占據(jù)某個(gè)磁盤塊(或一部分),在記錄內(nèi)部,對(duì)應(yīng)于關(guān)系的每一個(gè)屬性有一個(gè)字段。</p><p>  CREATE TABLE StudentInfor</p><p><b> ?。?lt;/b></p><

25、p>  number int ,</p><p>  name CHAR(6) ,</p><p><b>  age int ,</b></p><p>  address CHAR(20) ,</p><p><b>  ……</b></p><p><b&g

26、t; ?。?lt;/b></p><p><b>  記錄</b></p><p>  字段被組裝成定長或變長的集合,成為“記錄”;</p><p><b>  定長記錄的構(gòu)造</b></p><p>  元組由記錄表示,而記錄由上述所討論的各種字段組成。最簡單的情況是記錄的所有字段均為定長,

27、則可以將字段連接成記錄。</p><p><b>  記錄首部</b></p><p>  當(dāng)設(shè)計(jì)記錄的格式的時(shí)候,必然會(huì)引出另一個(gè)問題:通常在記錄中需要保存一些信息,而這些信息不是任何字段的值。因此有必要在記錄的首部添加相關(guān)信息,如:記錄長度、字段數(shù)等。</p><p><b>  塊</b></p>&l

28、t;p>  構(gòu)成一個(gè)關(guān)系或類的外延的記錄集存儲(chǔ)為塊的集合,成為文件。</p><p><b>  查詢編譯器</b></p><p>  查詢處理器需采取三個(gè)主要步驟:</p><p>  1)對(duì)使用諸如SQL的某種語言書寫的查詢進(jìn)行語法分析,亦即將查詢語句轉(zhuǎn)換成按某種有用方式表示查詢語句結(jié)構(gòu)的語法樹;</p><p&

29、gt;  2)把語法分析樹轉(zhuǎn)換成代數(shù)關(guān)系表達(dá)式樹(或某種類似標(biāo)記),稱之為邏輯查詢計(jì)劃;</p><p>  3)邏輯查詢計(jì)劃需轉(zhuǎn)換成物理查詢計(jì)劃,物理查詢計(jì)劃不僅指名了要執(zhí)行的操作,而且也找出了這些操作執(zhí)行的順序、執(zhí)行每步所用的算法、獲得所存儲(chǔ)數(shù)據(jù)的方式以及數(shù)據(jù)從一個(gè)操作傳遞給另一個(gè)操作的方式。</p><p>  查詢編譯的開始幾個(gè)階段如圖所示:</p><p>

30、;  圖1 查詢編譯的階段圖</p><p>  語法分析與語法分析樹</p><p>  語法分析器的工作是接收用類似SQL這樣的語言編寫的文本并將之轉(zhuǎn)換成語法分析樹,結(jié)點(diǎn)對(duì)應(yīng)于以下兩者之一:</p><p>  1)原子:它們是詞法成分,如關(guān)鍵字(如SELECT等)、關(guān)系或?qū)傩缘拿帧⒊?shù)、括號(hào)、操作符(如+等),以及其它成分;</p><p

31、>  2)語法類:即在一個(gè)查詢中起相似作用的查詢子成分所形成族的名字??梢杂眉饫ㄌ?hào)將描述性的名稱括起來表示語法類。例如,<SFW>用于表示以常用的select-from-where形式的查詢,而<Condition>將用于表示屬性條件的任何表達(dá)式,如跟在SQL語句where之后的表達(dá)式。</p><p>  如果結(jié)點(diǎn)是一個(gè)原子,則該結(jié)點(diǎn)沒有子女。然而,若該結(jié)點(diǎn)是一個(gè)語法類,則其子女通

32、過該語言的語法規(guī)則之一進(jìn)行描述。</p><p>  SQL的一個(gè)簡單子集的語法</p><p>  通過給出可用于SQL子集的語言的某些規(guī)則,我們借此說明語法分析樹的過程。</p><p><b>  1)查詢</b></p><p>  語法<Query>用于表示所有正則SQL查詢語句。它的一些語法規(guī)則是

33、:</p><p>  <Query> ::= <SFW></p><p>  <Query> ::= (<Query>)</p><p>  ::=符號(hào)表示“可以表述為”。</p><p>  2)Select列表</p><p>  <SelList> :

34、:= <Attribute> , <SelList></p><p>  <SelList> ::= <Attribute></p><p>  這兩條規(guī)則說明一個(gè)選擇列表可以為任何由逗號(hào)分隔的屬性列表:要么是單個(gè)屬性,要么是一個(gè)屬性、一個(gè)逗號(hào)以及一個(gè)或多個(gè)屬性的任意列表。</p><p><b>  3)F

35、rom列表</b></p><p>  <FromList> ::= <Relation> , <FromList></p><p>  <FromList> ::= <Relation></p><p>  這里的from列表可由任意用逗號(hào)分隔的關(guān)系列表組成。</p><p

36、>  這里只列出了部分規(guī)則,其他的規(guī)則請參考其他的書籍。</p><p>  我們來看這樣一個(gè)查詢語句:</p><p>  SELECT title </p><p>  FROM StarsIn</p><p>  WHERE starName IN</p><p><b>  (</b>

37、;</p><p>  SELECT name</p><p>  FROM MovieStar</p><p>  WHERE birthdate LIKE ‘%1960’</p><p><b>  );</b></p><p>  按照我們所描繪的語法,此查詢語句的語法分析樹如下所示<

38、/p><p><b>  圖2 語法分析樹</b></p><p>  根是語法類<Query>,任何一個(gè)查詢語句的語法樹都必然是這種情況。順著數(shù)往下走,我們可知該查詢語句是select-from-where的形式;選擇列表僅由屬性title構(gòu)成,from列表只有一個(gè)關(guān)系StarsIn。</p><p><b>  MyDB的

39、實(shí)現(xiàn)</b></p><p><b>  記錄的定義</b></p><p>  在這里,段是解析用戶命令的最小單位,若干段的集合就構(gòu)成了一條記錄。因此段和記錄的定義是進(jìn)行命令解析器及數(shù)據(jù)存儲(chǔ)的基礎(chǔ)。</p><p>  在MyDB中,段與記錄的關(guān)系可表示如下:</p><p>  圖3 段與記錄的關(guān)系<

40、;/p><p>  段和記錄的定義在hrecord.h中實(shí)現(xiàn):</p><p><b>  段的定義:</b></p><p>  typedef struct FldInforStruct</p><p><b>  {</b></p><p><b>  /* 字段

41、名 */</b></p><p>  char fldname[10] ;</p><p>  /* 字段類型 */</p><p>  char fldclass[6] ;</p><p>  /* 字段長度 */</p><p>  int fldlen ;</p><p&

42、gt;  /* 小數(shù)長度 */</p><p>  int dicimllen ;</p><p>  } FieldInfor_T ;</p><p><b>  記錄的定義:</b></p><p>  typedef struct WorkAreaStruct </p><p><

43、;b>  {</b></p><p>  /* 記錄長度 */</p><p>  int reclen ;</p><p>  /* 字段數(shù) */</p><p>  int fldnum ;</p><p>  /* 記錄總數(shù) */</p><p>  

44、int rectotal ;</p><p>  /* 字段結(jié)構(gòu)信息指針數(shù)組,0號(hào)單元未用 */</p><p>  FieldInfor_T fldinforptr[MAX_FIELD_NUM + 1];</p><p>  /* 文件指針 */</p><p>  FILE *DBFile_ptr ;</p>

45、<p>  } RecordWorkArea ;</p><p><b>  命令解析模塊</b></p><p>  SQL語言是一種面向集合的結(jié)構(gòu)化查詢語言。用SQL語言編寫的命令一般都是解釋執(zhí)行的。所謂解釋執(zhí)行,就是解釋和執(zhí)行同步,不是像編譯那樣先把程序全部掃描一遍翻譯成機(jī)器指令再直接運(yùn)行機(jī)器指令。一般SQL語言可以嵌套在C等其他的高級(jí)語言中。因此

46、,現(xiàn)在的商業(yè)用數(shù)據(jù)庫都有自己的一套編譯器系統(tǒng),實(shí)現(xiàn)SQL解釋(或編譯)和高級(jí)語言編譯器的無縫集成。由于MyDB的各個(gè)模塊接口是采用C語言函數(shù)調(diào)用,因此SQL語言也不可避免地要和底層模塊的接口函數(shù)打交道。MyDB命令解析器具體的原理圖如下:</p><p>  圖4 命令解析器具體工作流程原理圖</p><p><b>  詞法分析器</b></p>&l

47、t;p>  詞法分析器將SQL源程序解釋成一個(gè)個(gè)獨(dú)立的記號(hào),然后將記號(hào)的類型以及記號(hào)所對(duì)應(yīng)的值返回給語法分析器。</p><p>  MyDB的詞法分析過程如圖所示:</p><p><b>  圖5 詞法分析</b></p><p>  首先刪除用戶命令中的空格、制表符、逗號(hào)等,提取相關(guān)的字符,這個(gè)功能由函數(shù)CutBlankTab_He

48、ad_Tail完成;</p><p>  然后掃描提取的字符串,分步將關(guān)鍵字提取出。第一步,連分隔符(如括號(hào)等)一起提取,這個(gè)由函數(shù)GetSubstr_Delimitor完成;第二步,提取分隔符內(nèi)的字符串,這步由函數(shù)GetSubstr_BetweenDelim完成;第三步,提取合法字符集,這一步由函數(shù)GetSubstr_ValidChar完成;</p><p>  將字段信息存入數(shù)組,包括

49、所提取出的字段名,字段類型,字段長度等,這個(gè)主要由函數(shù)*Change完成;</p><p>  將記錄值存入結(jié)構(gòu)中,將所提取出來的記錄值插入相應(yīng)的結(jié)構(gòu)之中。</p><p>  實(shí)現(xiàn)各流程的函數(shù)會(huì)在下面分別敘述。</p><p>  MyDB的詞法分析器的關(guān)鍵字表為:</p><p>  enum SysKeyWordSet</p>

50、;<p><b>  {</b></p><p>  CREATE,DROP,INSERT,DELETE,</p><p>  SELECT,UPDATE,EXIT,HELP</p><p><b>  } ;</b></p><p>  由于MyDB只是一個(gè)面向教學(xué)的微型數(shù)據(jù)庫,所以

51、它所包含的關(guān)鍵字僅僅是標(biāo)準(zhǔn)SQL的一個(gè)很小的子集。</p><p>  詞法分析器的接口參數(shù):</p><p>  用戶給出的命令結(jié)構(gòu)是SQL編譯器進(jìn)行詞法分析的基礎(chǔ)。詞法分析的任務(wù)在于提取關(guān)鍵字、省略多余空格等等。所以用戶命令結(jié)構(gòu)信息的定義也是必要的。</p><p>  /* 用戶命令結(jié)構(gòu)信息 */</p><p>  typedef s

52、truct </p><p><b>  {</b></p><p>  /* 命令內(nèi)部代碼,如"INSERT" , "CREATE"等 */</p><p>  SysKeyWord_Type Cmd ;</p><p>  /* 表名 */</p><

53、;p>  char userstr[10] ;</p><p>  /* 字段信息指針 */</p><p>  FieldInfor_T *fld ;</p><p>  /* 記錄值指針數(shù)組 */</p><p>  char *recvalptr[MAX_FIELD_NUM + 1] ;</p><p

54、>  /* 查找范圍 */</p><p>  char range[10] ;</p><p>  /* 介詞 */</p><p>  char parse[20] ;</p><p><b>  /* 表達(dá)式 */</b></p><p>  char expressio

55、n[30] ;</p><p>  char token[100] ;</p><p>  int count ;</p><p>  }CmdRec_Type ;</p><p>  此接口參數(shù)定義了用戶命令的結(jié)構(gòu)信息,以便后來詞法分析中關(guān)鍵字及有效值的提取。</p><p>

56、  詞法分析器的接口函數(shù)</p><p>  詞法分析器的接口函數(shù)定義在頭文件lexical_tool.h中。主要是與詞法分析相關(guān)的函數(shù)體,包括:</p><p>  void CutBlankTab_Head_Tail (char *S);</p><p>  此函數(shù)用于刪除詞頭和詞尾的空格以及控制符;</p><p>  void Cut

57、Comma (char *S) ;</p><p>  此函數(shù)用于刪除詞頭逗號(hào);</p><p>  int CountSymbol (char *S , char c) ;</p><p>  此函數(shù)用于計(jì)算字符個(gè)數(shù);</p><p>  int GetSubstr_Delimitor (char *S , int *ScanPos , c

58、har * Delimitor , char *Substr) ;</p><p>  此函數(shù)根據(jù)分隔符集合Delimitor,在串S中掃描起點(diǎn)ScanPos,取出子串Substr,并且移動(dòng)掃描起點(diǎn)到新的位置,用于詞法分析。偽碼如下:</p><p>  int GetSubstr_Delimitor(char *S , int *ScanPos , char * Delimitor ,

59、char *Substr)</p><p><b>  {</b></p><p>  InStr = FALSE;</p><p>  /*跳過分隔符(雙引號(hào)的分隔符除外)*/</p><p>  while((*ScanPos < len) && (strchr(Delimitor , *(S

60、+ (*ScanPos))) != NULL))</p><p><b>  {</b></p><p>  if(*(S + (*ScanPos)) == '\"')</p><p>  InStr = !InStr ;</p><p>  (*ScanPos) ++ ;</p>

61、<p><b>  }</b></p><p>  SubstrBegin = *ScanPos ;</p><p>  /*掃描子串,包括雙引號(hào)內(nèi)的分隔符*/</p><p>  while((*ScanPos <= len) && (InStr || (strchr (Delimitor , *(S + *

62、ScanPos)) == NULL)))</p><p><b>  {</b></p><p>  if(*(S + (*ScanPos)) == '\"')</p><p>  InStr = !InStr ;</p><p>  (*ScanPos) ++ ;</p><

63、;p><b>  }</b></p><p><b>  /*復(fù)制子串*/</b></p><p>  strncpy(Substr , S + SubstrBegin , *ScanPos - SubstrBegin) ;</p><p><b>  /*串尾加0*/</b></p>

64、;<p>  (Substr + *ScanPos - SubstrBegin) = '\0' ;</p><p>  ok = ((strcmp(Substr , "") != 0) && (*ScanPos) <= len) ;</p><p><b>  }</b></p>&

65、lt;p>  int GetSubstr_BetweenDelim(char *S , int *ScanPos , char Delim1 , char Delim2 , char *Substr);</p><p>  此函數(shù)在串S中掃描起點(diǎn),取出在分隔符Delim1和Delim2之間的子串Substr,并且移動(dòng)掃描起點(diǎn)到新的位置,用于詞法分析。偽碼如下:</p><p>  i

66、nt GetSubstr_BetweenDelim(char *S , int *ScanPos , char Delim1 , char Delim2 , char *Substr)</p><p><b>  {</b></p><p>  left = *ScanPos ;</p><p>  len = strlen(S) ;</

67、p><p>  if(len == 0)</p><p><b>  {</b></p><p>  *Substr = '\0' ;</p><p>  return (TURE) ;</p><p><b>  }</b></p><p&g

68、t;  /*驗(yàn)明左邊的分隔符*/</p><p>  while((left < len) && (Delim1 != S[left]))</p><p><b>  ++left ;</b></p><p>  if(S[left] != Delim1)</p><p>  return 0 ;&

69、lt;/p><p>  right = left + 1 ;</p><p>  /*驗(yàn)明右邊的分隔符*/</p><p>  while((right < len) && S[right] != Delim2)</p><p><b>  ++right ;</b></p><p&

70、gt;  if(S[right] != Delim2)</p><p>  return 0 ;</p><p><b>  /*復(fù)制子串*/</b></p><p>  strncpy(Sunstr , &S[left + 1] , right - left + 1) ;</p><p>  Substr[ri

71、ght - left + 1] = '\0' ;</p><p><b>  /*移動(dòng)掃描點(diǎn)*/</b></p><p>  *ScanPos = right + 1 ;</p><p><b>  }</b></p><p>  int GetSunstr_ValidChar(ch

72、ar *S , int *ScanPos , char *ValidCh , char *Substr);</p><p>  此函數(shù)在串S中掃描起點(diǎn)后,取出由合法字符集合ValidCh組成的子串Substr,并且移動(dòng)掃描點(diǎn)到新的位置,用于詞法分析。偽碼如下:</p><p>  int GetSunstr_ValidChar(char *S , int *ScanPos , char *

73、ValidCh , char *Substr)</p><p><b>  {</b></p><p>  len = strlen(S) ;</p><p>  *Substr = '\0' ;</p><p>  while((*ScanPos < len) && (strchr

74、(ValidCh , S[ScanPos])) == NULL) </p><p>  ++ (*ScanPos) ;</p><p>  left = *ScanPos ;</p><p>  while((*ScanPos < len) && (strchr(ValidCh , S[ScanPos])) != NULL)</p>

75、<p>  ++ (*ScanPos) ;</p><p><b>  /*復(fù)制子串*/</b></p><p>  strncpy(Substr , &S[left] , *ScanPos - left) ;</p><p>  Substr[*ScanPos - left] = '\0' ;</p

76、><p>  return (*ScanPos - left) ;</p><p><b>  }</b></p><p>  void CloseWA();</p><p>  此函數(shù)用于關(guān)閉工作區(qū)間;</p><p>  void ClearCmdRec (CmdRec_Type CmdRec);

77、</p><p>  此函數(shù)用于把命令行記錄,即分析結(jié)果清0;</p><p>  void CallbackCmdRec (CmdRec_Type CmdRec);</p><p>  此函數(shù)用于回收分配的指針空間并清0;</p><p>  FieldInfor_T ToFldStr(char *Token , int i);</p

78、><p>  此函數(shù)通過字符串string,分別對(duì)各個(gè)參數(shù)進(jìn)行賦值;</p><p>  FieldInfor_T StoreToStr(char *Token , int i);</p><p>  此函數(shù)將第i個(gè)字段信息數(shù)組Token的字段名、字段類型,整數(shù)和小數(shù)長度存入結(jié)構(gòu)中,供建表時(shí)使用;</p><p>  FieldInfor_T *

79、Change(char *Token1);</p><p>  此函數(shù)用于將字段信息放入CmdRec的字段結(jié)構(gòu)數(shù)組中;</p><p>  char (*Value(char *Token))[15][30];</p><p>  將用戶插入的記錄值分別存入CmdRec結(jié)構(gòu)的recvalptr中,供插入時(shí)使用;</p><p>  以上函數(shù)均

80、在lexical_too.c中進(jìn)行了實(shí)現(xiàn)。SQL命令編譯器對(duì)用戶命令進(jìn)行掃描,調(diào)用以上函數(shù)實(shí)現(xiàn)基本的詞法分析。先根據(jù)第一個(gè)字符判斷該記號(hào)可能是什么類型,然后根據(jù)好的規(guī)則繼續(xù)分析,直到遇到一個(gè)新的記號(hào)類型。</p><p><b>  語法分析器</b></p><p>  語法分析器依據(jù)SQL語言的相關(guān)規(guī)則,對(duì)由詞法分析器返回的記號(hào)序列進(jìn)行分析。語法分析器和詞法分析類

81、似,不過語法分析器是在詞法分析的基礎(chǔ)上,對(duì)一系列記號(hào)進(jìn)行分析。</p><p>  MyDB的語法分析過程圖如下:</p><p><b>  圖6 語法分析</b></p><p><b>  語法分析過程如下:</b></p><p>  刪除用戶命令中的詞頭尾的空格、制表符等無關(guān)元素;<

82、/p><p>  掃描用戶命令,判斷其詞性并做相應(yīng)的處理,直到掃描到用戶命令的結(jié)尾;</p><p>  實(shí)現(xiàn)語法分析器相應(yīng)的函數(shù)體CmdRec_Type CmdLine_To_CmdRec (char *CmdLine)的偽碼表示為:</p><p>  CmdRec_Type CmdLine_To_CmdRec (char *CmdLine)</p>

83、<p><b>  {</b></p><p>  /*刪除命令行頭尾空格及制表符,并取得括號(hào)之間的字符串;*/</p><p>  CutBlankTab_Head_Tail(CmdLine) ;</p><p>  GetSubstr_BetweenDelim (CmdLine , &TokenPos , '(&#

84、39; , ')' , CmdRec.token) ;</p><p>  while(strlen(CmdLine) >= 1)</p><p><b>  {</b></p><p>  for(i = 0 ; i < strlen(Cmdline) ; i ++)</p><p><

85、;b>  {</b></p><p>  if(判斷是否為行為動(dòng)詞)</p><p>  /*存儲(chǔ)此關(guān)鍵字*/</p><p>  CmdRec.Cmd = SysKeyWordArray[i].SysW_N ;</p><p>  else if(判斷是否為介詞)</p><p><b>

86、  /*存儲(chǔ)此介詞*/</b></p><p>  strcpy(CmdRec.parse , Token) ;</p><p>  else if(判斷是否為表達(dá)式)</p><p>  ptr = strchr(Token , '=') ;</p><p><b>  if (ptr)</b&g

87、t;</p><p><b>  {</b></p><p>  strcpy(CmdRec.expression , Token) ;</p><p><b>  }</b></p><p><b>  else</b></p><p><b&g

88、t;  {</b></p><p>  /*判斷是否為全部范圍*/</p><p>  ptr = strchr(Token , '*') ;</p><p><b>  if(ptr)</b></p><p><b>  {</b></p><p&g

89、t;  strcpy(CmdRec.range , '*') ;</p><p><b>  }</b></p><p><b>  else</b></p><p><b>  {</b></p><p>  ptr = strchr(Token , '

90、;,') ;</p><p><b>  if(ptr)</b></p><p><b>  {</b></p><p>  strcpy(CmdRec.range , Token) ;</p><p><b>  }</b></p><p>&

91、lt;b>  else</b></p><p><b>  {</b></p><p>  strcpy(CmdRec.userstr , Token) ;</p><p><b>  }</b></p><p><b>  }</b></p>

92、<p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>  return ;</b></p><p><b>  }</b></p>

93、<p>  對(duì)具體SQL語句的語法的判斷在Mydb.c中進(jìn)行處理。相應(yīng)的偽碼表示如下:</p><p>  int main(void)</p><p><b>  {</b></p><p>  swich(CmdRec.Cmd)</p><p><b>  {</b></p&

94、gt;<p>  case CREATE:Do_Create(CmdRec) ;break</p><p>  case DROP:Do_Remove(CmdRec.userstr) ;break;</p><p>  case INSERT:Do_Insert(CmdRec) ;break;</p><p>  case SELECT:Do

95、_Select(CmdRec,CmdRec.token) ;break;</p><p>  case UPDATE:Do_Update(CmdRec,CmdRec.token);break;</p><p>  case DELETE:Do_Delete(CmdRec,CmdRec.token);break;</p><p>  case EXIT:exi

96、t(0);break;</p><p>  case HELP:Do_Help;break;</p><p>  default:break;</p><p><b>  }</b></p><p><b>  return 0;</b></p><p><b&

97、gt;  }</b></p><p><b>  SQL語句的實(shí)現(xiàn)</b></p><p>  MyDB所支持的SQL語句大體遵從標(biāo)準(zhǔn)的SQL語句的規(guī)范。在其規(guī)范上有稍許變動(dòng)。MyDB支持標(biāo)準(zhǔn)SQL語句的一個(gè)子集,具體所支持的SQL語句的行為動(dòng)詞是:create、select、drop、delete、update、insert等。</p>&

98、lt;p>  SQL語句的接口函數(shù)均包含在mysql.h頭文件中,在mysql.c中進(jìn)行具體的實(shí)現(xiàn)。接口函數(shù)如下:</p><p>  int Do_Remove(char *file) ;</p><p>  刪除文件,相當(dāng)于Drop語句;</p><p>  void Do_Insert(CmdRec_Type CmdRec) ;</p>&

99、lt;p>  插入語句,將要插入的值放入表內(nèi),插入語句的實(shí)現(xiàn)過程如下圖:</p><p>  圖7 Insert語句實(shí)現(xiàn)過程</p><p><b>  偽碼實(shí)現(xiàn)如下:</b></p><p>  void Do_Insert(CmdRec_Type CmdRec)</p><p><b>  {<

100、/b></p><p><b>  定位頭文件;</b></p><p><b>  讀取一級(jí)數(shù)據(jù)元;</b></p><p>  讀取二級(jí)數(shù)據(jù)元,即各字段信息;</p><p>  for(i = 0 ; i < 插入字段數(shù) ; i ++)</p><p>&l

101、t;b>  {</b></p><p>  /*根據(jù)不同情況將要出入的記錄值寫入文件;*/</p><p>  if(插入的屬性值為float)</p><p>  將此float類型字段值插入表中;</p><p>  else if(插入的屬性值為int)</p><p>  將此int類型字段值

102、插入表中;</p><p>  else (插入的屬性值為char)</p><p>  將此char類型字段值插入表中;</p><p><b>  }</b></p><p>  每插入一條記錄,記錄總數(shù)加1;</p><p><b>  關(guān)閉數(shù)據(jù)文件;</b></

103、p><p><b>  }</b></p><p>  void Do_Select (CmdRec_Type CmdRec , char *Token);</p><p>  查詢語句,根據(jù)不同的情況實(shí)現(xiàn)對(duì)數(shù)據(jù)的簡單查詢,SELECT函數(shù)的分析過程如下圖:</p><p>  圖8 Select語句實(shí)現(xiàn)過程</p&g

104、t;<p><b>  偽碼如下:</b></p><p>  void Do_Select(CmdRec_Type CmdRec , char *Token)</p><p><b>  {</b></p><p>  取得運(yùn)算符在查詢條件數(shù)組中的位置;</p><p>  把數(shù)據(jù)文

105、件一二級(jí)原數(shù)據(jù)載入工作區(qū);</p><p>  取得查詢條件中字段相對(duì)應(yīng)的本記錄首位置的長度以便定位;</p><p>  for(m = 0 ; m < reordtotal ; m ++)</p><p><b>  {</b></p><p>  逐一從文件讀取每一條記錄;</p><p&

106、gt;  根據(jù)字段類型讀取記錄值;</p><p><b>  swich(ch)</b></p><p><b>  {</b></p><p>  /**根據(jù)記錄類型對(duì)取出的記錄值進(jìn)行處理即滿足條件的記錄輸出到屏幕**/</p><p><b>  case 整形:</b>

107、</p><p>  該整型數(shù)據(jù)滿足條件,定位文件至該記錄頭位置;</p><p>  逐一輸出該記錄字段值;</p><p><b>  break;</b></p><p><b>  case 浮點(diǎn)形:</b></p><p>  該浮點(diǎn)型數(shù)據(jù)滿足條件,定位文件至該記錄

108、頭位置;</p><p>  逐一輸出該記錄字段值;</p><p><b>  break;</b></p><p><b>  case 字符型:</b></p><p>  該字符型數(shù)據(jù)滿足條件,定位文件至該記錄頭位置;</p><p>  逐一輸出該記錄字段值;<

109、;/p><p><b>  break;</b></p><p>  default:break;</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  關(guān)閉數(shù)據(jù)文件;</b><

110、;/p><p><b>  }</b></p><p>  void Do_Delete(CmdRec_Type CmdRec , char *Token);</p><p>  對(duì)基本表的數(shù)據(jù)的刪除。MyDB的刪除函數(shù)的分析過程如下圖:</p><p>  圖9 Delete語句實(shí)現(xiàn)過程</p><p&

111、gt;<b>  偽碼如下:</b></p><p>  void Do_Delete(CmdRec_Type CmdRec , char *Token)</p><p><b>  {</b></p><p><b>  打開數(shù)據(jù)文件;</b></p><p>  for(m

112、 = 0 ; m < recordtotal ; m ++)</p><p><b>  {</b></p><p><b>  swich(ch)</b></p><p><b>  {</b></p><p>  /**根據(jù)刪除條件字段的類型的不同,分流處理**/&l

113、t;/p><p><b>  case 整形:</b></p><p>  滿足刪除條件顯示的屏幕;</p><p>  不滿足刪除條件的寫入臨時(shí)新文件;</p><p><b>  break;</b></p><p><b>  case 浮點(diǎn)形:</b>

114、;</p><p>  滿足刪除條件顯示的屏幕;</p><p>  不滿足刪除條件的寫入臨時(shí)新文件;</p><p><b>  break;</b></p><p><b>  case 字符型:</b></p><p>  滿足刪除條件顯示的屏幕;</p>

115、<p>  不滿足刪除條件的寫入臨時(shí)新文件;</p><p><b>  break;</b></p><p>  default:break;</p><p><b>  }</b></p><p><b>  }</b></p><p>

116、<b>  關(guān)閉數(shù)據(jù)文件;</b></p><p><b>  }</b></p><p>  void Do_Update(CmdRec_Type CmdRec,char *Token);</p><p>  更新數(shù)據(jù)庫中的數(shù)據(jù)。MyDB中的Update函數(shù)分析過程如下圖:</p><p>  圖

117、10 Update語句實(shí)現(xiàn)過程</p><p><b>  偽碼如下:</b></p><p>  void Do_Update(CmdRec_Type CmdRec , char *Token)</p><p><b>  {</b></p><p><b>  打開數(shù)據(jù)文件 ;<

118、/b></p><p>  for(m = 0 ; m < recordtotal ; m ++)</p><p><b>  {</b></p><p>  /**根據(jù)字段的不同進(jìn)行分流處理**/</p><p><b>  swich(ch)</b></p><p

119、><b>  {</b></p><p><b>  case 整形:</b></p><p>  將滿足更新條件的進(jìn)行更新并現(xiàn)實(shí)在屏幕;</p><p>  不滿足條件的寫入臨時(shí)文件;</p><p><b>  break;</b></p><p&

120、gt;<b>  case 浮點(diǎn)形:</b></p><p>  將滿足更新條件的進(jìn)行更新并現(xiàn)實(shí)在屏幕;</p><p>  不滿足條件的寫入臨時(shí)文件;</p><p><b>  break;</b></p><p><b>  case 字符型:</b></p>

121、<p>  將滿足更新條件的進(jìn)行更新并現(xiàn)實(shí)在屏幕;</p><p>  不滿足條件的寫入臨時(shí)文件;</p><p><b>  break;</b></p><p>  default:break;</p><p><b>  }</b></p><p><

122、;b>  }</b></p><p><b>  關(guān)閉數(shù)據(jù)文件;</b></p><p><b>  }</b></p><p>  void Do_Help();</p><p>  幫助文檔,在這里就不再贅述。</p><p>  void Do_Cre

123、ate(CmdRec_Type CmdRec) ;</p><p>  創(chuàng)建基本表。參見基本表模塊設(shè)計(jì)。</p><p><b>  基本表模塊</b></p><p>  基本表是關(guān)系數(shù)據(jù)庫的基礎(chǔ),沒有基本表提供的路徑無關(guān)的存儲(chǔ)支持,所有基于基本表的操作都將難以實(shí)現(xiàn)?;颈砟K本身就可以看做是一個(gè)表式的系統(tǒng)。</p><p

124、>  基本表模塊負(fù)責(zé)把整個(gè)數(shù)據(jù)以表的方式來管理,用戶可以通過關(guān)系名、主鍵的值以及屬性名的關(guān)聯(lián)地址唯一地操控表中的任何數(shù)據(jù)?;颈砟K在提供關(guān)聯(lián)地址支持的同時(shí),也提供基本表的其他操作?;颈淼某S貌僮饔校簞?chuàng)建、刪除一個(gè)表,添加、刪除一個(gè)記錄,添加 、刪除一個(gè)列等。關(guān)于數(shù)據(jù)庫的操作本來不應(yīng)該是屬于基本表模塊的。但是數(shù)據(jù)庫由基本表組成,基本表和數(shù)據(jù)庫的關(guān)系太緊密了,如果要將數(shù)據(jù)庫的操作單獨(dú)分離成一個(gè)模塊,那它不可避免地要訪問基本表的內(nèi)部

125、數(shù)據(jù),那樣反而造成不安全。因此,在MyDB中將數(shù)據(jù)庫的操作和基本表的操作放在一個(gè)模塊實(shí)現(xiàn)。</p><p>  在MyDB中,每一個(gè)表即對(duì)應(yīng)一個(gè)文件,表中的數(shù)據(jù)按照順序表的數(shù)據(jù)結(jié)構(gòu)進(jìn)行存儲(chǔ)、刪除、更新等等。</p><p><b>  數(shù)據(jù)組織</b></p><p>  在MyDB中,將多個(gè)表實(shí)現(xiàn)在一起,對(duì)應(yīng)一個(gè)數(shù)據(jù)庫。每個(gè)表的基本屬性信息,

126、包括表的名稱、列的名稱、列的數(shù)據(jù)類型等都統(tǒng)一存放在一個(gè)二進(jìn)制文件中。將表屬性放在一個(gè)文件中的目的是為了方便查找表的信息。</p><p>  MyDB的表的數(shù)據(jù)組織方式如下:</p><p>  圖11 MyDB表的組織方式圖</p><p><b>  基本表的實(shí)現(xiàn)</b></p><p>  基本表的接口函數(shù)定義在t

127、able.h頭文件中,具體實(shí)現(xiàn)是在table.c文件中。至于刪除一個(gè)表、在表中對(duì)數(shù)據(jù)進(jìn)行刪除、插入、更新等操作,在命令行解析模塊中進(jìn)行了具體的講解,這里就不再贅述。</p><p>  MyDB的基本表的實(shí)現(xiàn)過程如下圖所示:</p><p>  圖12 基本表的實(shí)現(xiàn)過程</p><p><b>  打開文件;</b></p>&l

128、t;p>  若打開文件失敗則輸出文件不存在;若成功則計(jì)算記錄長度,直到掃描所有字段結(jié)束;</p><p><b>  將數(shù)據(jù)寫入文件;</b></p><p><b>  關(guān)閉文件指針。</b></p><p>  創(chuàng)建基本表的接口函數(shù)為:</p><p>  void Do_Create (

129、CmdRec_Type CmdRec);</p><p><b>  偽碼如下:</b></p><p>  void Do_Create(CmdRec_Type CmdRec)</p><p><b>  {</b></p><p><b>  FILE fp ;</b>&l

130、t;/p><p>  int string[3] = {0,0,0} ;</p><p><b>  /*打開文件*/</b></p><p>  fp = fopen(TemName , "w + b") ;</p><p>  if(fp == NULL)</p><p&g

131、t;<b>  {</b></p><p>  printf("文件不存在\n") ;</p><p><b>  }</b></p><p>  for(i = 0 ; i <= CmdRec.count ; i ++)</p><p><b>  {</

132、b></p><p><b>  計(jì)算記錄的長度;</b></p><p><b>  }</b></p><p><b>  /*記錄長度*/</b></p><p>  string[0] = reclen ;</p><p>  /*字段數(shù)

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論