版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、C語言編程要點(diǎn)-第18章 程序的編寫和編譯第18章 程序的編寫和編譯本章講述在編譯程序時可以使用的一些技術(shù)。在本章中,你將學(xué)到專業(yè)C程序員在日常編程中所使用的一些技巧。你將會發(fā)現(xiàn),無論是對小項目還是大項目,把源代碼分解成幾個文件都是很有益處的。在生成函數(shù)庫時,這一點(diǎn)更為重要。你還將學(xué)到可以使用的各種存儲模式以及怎樣為不同的項目選擇不同的存儲模式。如果你的程序是由幾個源文件組成的,那么你可以通過一個叫MAKE的工具來管理你的項目(project)。你還將學(xué)到“COM文件和EXE文件的區(qū)別以及使用“COM”文件的一個好處。 此外,你還將學(xué)到用來解決一個典型的DOS問題的一些技巧,這個問題就是“沒有
2、足夠的內(nèi)存來運(yùn)行DOS程序”。本章還討論了擴(kuò)展內(nèi)存、擴(kuò)充內(nèi)存、磁盤交換區(qū)、覆蓋管理程序和DOS擴(kuò)展程序的用法,提出了解決RAM阻塞”這一問題的多種方法,你可以從中選擇一種最合適的方法18.1. 程序是應(yīng)該寫成一個源文件還是多個源文件? 如果你的程序確實很小又很緊湊,那么當(dāng)然應(yīng)該把所有的源代碼寫在一個“C”文件中。然而,如果你發(fā)現(xiàn)自己編寫了許多函數(shù)(特別是通用函數(shù)),那么你就應(yīng)該把程序分解成幾個源文件(也叫做模塊)。 把一個程序分解成幾個源文件的過程叫做模塊化程序設(shè)計(modular programming)。模塊化程序設(shè)計技術(shù)提倡用幾個不同的結(jié)構(gòu)緊湊的模塊一起組成一個完整的程序。例如,如果一個
3、程序中有幾種實用函數(shù)、屏幕函數(shù)和數(shù)據(jù)庫函數(shù),你就可以把這些函數(shù)分別放在三個源文件中,分別組成實用模塊、屏幕模塊和數(shù)據(jù)庫模塊。 把函數(shù)放在不同的文件中后,你就可以很方便地在其它程序中重復(fù)使用那些通用函數(shù)。如果你有一些函數(shù)還要供其它程序員使用,那么你可以生成一個與別人共享的函數(shù)庫(見189)。 你永遠(yuǎn)不必?fù)?dān)心模塊數(shù)目“太多”只要你認(rèn)為合適,你可以生成很多個模塊。一條好的原則就是保持模塊的緊湊性即在同一個源文件中只包含那些在邏輯上與其相關(guān)的函數(shù)。如果你發(fā)現(xiàn)自己把幾個沒有關(guān)系的函數(shù)放在了同一個源文件中,那么最好停下來檢查一下程序的源代碼結(jié)構(gòu),并且對模塊做一下邏輯上的分解。例如,如果要建立一個通信管理數(shù)
4、據(jù)庫,你可能需要有這樣一個模塊結(jié)構(gòu):- 模塊名 內(nèi) 容- Mainc maln()函數(shù) Screenc 屏幕管理函數(shù) Menusc 菜單管理函數(shù) Databasec 數(shù)據(jù)庫管理函數(shù) Utilityc 通用功能函數(shù) Contactc 通信處理函數(shù) Importc 記錄輸入函數(shù) Exportc 記錄輸出函數(shù) Helpc 聯(lián)機(jī)幫助支持函數(shù)-請參見:1810 如果一個程序包含多個源文件,怎樣使它們都能正常工作?18.2. 各種存儲模式之間有什么區(qū)別? DOS用一種段地址結(jié)構(gòu)來編址計算機(jī)的內(nèi)存,每一個物理內(nèi)存位置都有一個可通過段地址一偏移量的方式來訪問的相關(guān)地址。為了支持這種段地址結(jié)構(gòu),大多數(shù)C編譯程序
5、都允許你用以下6種存儲模式來創(chuàng)建程序:-存儲模式 限制 所用指針-Tiny(微) 代碼、數(shù)據(jù)和棧一64KB NearSmall(小) 代碼一64KB Near 數(shù)據(jù)和棧一64KB NearMedium(中) 代碼一1MB Far 數(shù)據(jù)和棧一64KB NearCompact(緊縮) 代碼一64KB Near 數(shù)據(jù)和棧一1MB FarLarge(大) 代碼一1MB Far 數(shù)據(jù)和棧一1MB FarHuge*(巨) 代碼一1MB Far 數(shù)據(jù)和棧一1MB Far- *注意:在Huge存儲模式下,靜態(tài)數(shù)據(jù)(如數(shù)組)可以超過64KB,這在其它存儲模式下都不行。 Tiny存儲模式的限制很嚴(yán)(所有的代碼、數(shù)
6、據(jù)和棧都被限制在64KB中),它通常用來生成COM文件。由于內(nèi)存地址的“安排”方式的限制,Huge模式會帶來顯著的性能損失,因此它很少被使用。 請參見: 183 最常使用的存儲模式有哪些? 184 應(yīng)該使用哪種存儲模式?18.3. 最常使用的存儲模式有哪些? 最常使用的存儲模式有Small,Medium和Large這幾種。Tiny存儲模式一般只用來生成COM文件,在現(xiàn)在的高性能計算機(jī)上,它已很少被使用了。Compact存儲模式允許程序有很少的代碼和大量的數(shù)據(jù),在今天的商業(yè)應(yīng)用環(huán)境中,它同樣也不常用了。由于Huge存儲模式的存儲地址機(jī)制導(dǎo)致它的效率較低,所以它也很少被使用。 一般說來,你應(yīng)該根據(jù)
7、程序的大小選用Small,Medium或Large中的一種存儲模式。對一個小的實用程序來說,Small存儲模式可能是最合適的,這種存儲模式允許有64KB的代碼和64KB數(shù)據(jù)和棧。如果程序有更大一些的數(shù)據(jù)要求,你可以使用Medium存儲模式,它允許程序有多達(dá)1MB的可尋址數(shù)據(jù)空間。對于更大的程序,你應(yīng)該使用Large存儲模式,它允許程序有1MB的代碼和1MB的數(shù)據(jù)和棧空間。 如果你在編寫一個Windows程序或者在使用一個32位編譯程序,那么你最好使用Small存儲模式,因為這樣的環(huán)境并不受DOS程序的段地址結(jié)構(gòu)的限制。 請參見: 182 各種存儲模式之間有什么區(qū)別? 184 應(yīng)該使用哪種存儲模
8、式?18.4. 應(yīng)該使用哪種存儲模式? 如果要生成一個“COM”文件,必須使用Tiny存儲模式,即所有的代碼、數(shù)據(jù)和??臻g都被限制在64KB中。小的實用程序普遍使用這種存儲模式。相對較小的程序也可以使用Small存儲模式,只不過不必把整個程序都限制在64KB中。在Small存儲模式下,有64KB的代碼空間和64KB的數(shù)據(jù)和??臻g。除了用于小程序外,Small存儲模式還可用在Windows或32位編譯程序這樣的環(huán)境中,因為在這些環(huán)境中內(nèi)存尋址并不受DOS中16位的限制。 如果一個程序的代碼量相對較大而靜態(tài)數(shù)據(jù)量相對較小,你可以用Medium存儲模式來創(chuàng)建程序。如果程序很大(需要很多模塊,大量的代
9、碼和數(shù)據(jù)),那么你應(yīng)該選用Large存儲模式,這種存儲模式常用在DOS下編寫商用軟件。 與Small,Medium和Large存儲模式相比,Compact和Huge存儲模式要少用得多。Cornpact存儲模式允許程序有大量的靜態(tài)數(shù)據(jù)和相對較少(64KB或更少)的代碼。滿足這種模式的程序很少,常常是一些轉(zhuǎn)移程序,它們有大量必須存到內(nèi)存中的靜態(tài)轉(zhuǎn)移表。Huge存儲模式與Large存儲模式基本相同,只是Huge存儲模式允許程序有超過64KB的靜態(tài)數(shù)據(jù)。與Compact存儲模式相似,Huge存儲模式也很少被使用,這主要是因為它會帶來顯著的性能損失。由于Huge存儲模式的執(zhí)行效率較低,因此你應(yīng)該避免使用
10、這種模式,除非你確實需要超過64KB的一個數(shù)組或其它靜態(tài)數(shù)據(jù)。記住,數(shù)組和其它程序結(jié)構(gòu)可通過malloc()和calloc()在程序運(yùn)行時進(jìn)行動態(tài)分配,它們在本質(zhì)上并不必須是靜態(tài)的。 請參見: 182各種存儲模式之間有什么區(qū)別? 183最常使用的存儲模式有哪些?18.5. 怎樣生成一個“COM”文件? 生成一個“COM”文件是指用Tiny存儲模式編譯程序,并用特殊的連接命令產(chǎn)生擴(kuò)展名為COM而不是EXE的文件。記住,如果要使一個程序成為一個“COM”文件,那么所有的代碼、數(shù)據(jù)和棧都必須限制在64KB之內(nèi)。這種存儲模式通常只被一些很小的程序使用,例如TSR程序和小的實用程序。 每個編譯程序生成“
11、COM”文件的方法都是不同的,你應(yīng)該在編譯程序手冊中查找有關(guān)信息,以了解哪些編譯選項或連接選項是用來生成COM文件而不是EXE文件的。 請參見: 186“COM”文件有哪些地方優(yōu)于“EXE文件?18.6. “COM”文件有哪些地方優(yōu)于“EXE”文件? 一個“COM”文件的所有代碼、數(shù)據(jù)和棧都被限制在64KB之內(nèi),因此,它只能用在一些小的應(yīng)用中,例如實用程序和TSR程序(終止并駐留程序)。“COM”文件的一個明顯優(yōu)點(diǎn)就是它的裝入要比“EXE文件快得多。 “COM”文件也被稱作“內(nèi)存映象”文件,因為它可以直接裝入內(nèi)存,不需要任何“處理”?!癊XE文件中包含了由連接程序插入到其它文件頭中的一些特殊的
12、組裝指令,這些指令中包括一個用來管理可執(zhí)行程序的不同部分的重定位表。“COM”文件中不包含任何這樣的指令或重定位表,因為整個程序可以裝入64KB的內(nèi)存空間中。因此,DOS不必去分析任何組裝指令,“COM”文件的裝入速度也就比.EXE文件快。 “COM”文件通常很簡單,因此它們所能實現(xiàn)的功能也就受到限制。例如,你不能在“COM”文件中從遠(yuǎn)程堆中分配內(nèi)存。 請參見: 185怎樣生成一個“COM”文件?18.7. 當(dāng)一個庫被連接到目標(biāo)上時,庫中的所有函數(shù)是否都會被加到一個EXE文件中? 不會。當(dāng)啟動連接程序時,它會尋找“未定義的外部函數(shù)”,也就是說,它將在每一個庫文件中查找源代碼文件中未定義的函數(shù)。
13、當(dāng)它找到一個未定義的外部函數(shù)后,它會引入包含該函數(shù)定義的目標(biāo)代碼。(obj)。不幸的是,如果這個函數(shù)是在一個包含其它函數(shù)定義的源文件中被編譯的話,那么這些函數(shù)也會被包含進(jìn)來,你的可執(zhí)行代碼中將包含一些不需要的代碼。因此,將庫函數(shù)放到各自的源文件中是很重要的否則會浪費(fèi)寶貴的程序空間。有些編譯程序包含特殊的“精明的”連接程序,這些連接程序能查出不需要的函數(shù)并去掉它們,從而使這些函數(shù)不再進(jìn)入你的程序。 下面舉一個例子:假設(shè)有兩個源文件,分別為libfunc1c和libfunc2c,它們所包含的函數(shù)都要被放到一個庫中。 源文件libfunc1c包含以下兩個函數(shù): void func_one () .
14、void rune_two() . 源文件libfunc2c包含以下函數(shù): void func_three() . 現(xiàn)在假設(shè)已經(jīng)把這兩個源文件編譯到一個名為myfuncs1ib的庫中。如果一個與myfuncslib連接的程序要調(diào)用func_one()函數(shù),連接程序就會在myfuncslib庫中尋找包含func_one()函數(shù)定義的目標(biāo)代碼,并且把它連接進(jìn)來。不幸的是,函數(shù)func_one()是在包含func_two()函數(shù)定義的同一個源文件中被編譯的,因此,即使你的程序不會用到func_two(),連接程序也不得不把它連接進(jìn)來。當(dāng)然,這里假設(shè)func_one()中并沒有包含對func_two(
15、)的調(diào)用。如果一個程序包含一個對func_three()的調(diào)用,那么只有func_othree()的目標(biāo)代碼會被連接進(jìn)來,因為該函數(shù)是在它自己的源文件中被編譯的。 一般說來,你應(yīng)該盡量把庫函數(shù)放到各自的源文件中。這種組織方式有助于提高程序的效率,因為程序只會和那些真正需要的函數(shù)進(jìn)行連接,而不會和那些不需要的函數(shù)進(jìn)行連接。這種組織方式在小組開發(fā)的情況下也是很有幫助的;在小組開發(fā)中,源文件的上交和發(fā)放非常頻繁,如果一個程序員要對一個包含在其自身的源文件中的函數(shù)進(jìn)行維護(hù),那么他可以集中維護(hù)這個函數(shù);如果這個函數(shù)所在的源文件中還包含其它一些需要維護(hù)的函數(shù),那么這些函數(shù)就無法發(fā)放給其它小組成員,因為它們
16、包含在一個源文件中。 請參見: 188 可以把多個庫函數(shù)包含在同一個源文件中嗎? 189 為什么要建立一個庫?18.8. 可以把多個庫函數(shù)包含在同一個源文件中嗎? 在同一個源文件中,你想要定義多少個函數(shù),就可以定義多個函數(shù),并且可以把它們都包含到一個庫中然而,在小組開發(fā)環(huán)境中連接程序和共享源文件時,這種編程風(fēng)格存在著嚴(yán)重的缺陷。 當(dāng)你在一個源文件中包含多個庫函數(shù)時,這些函數(shù)會被編譯到同一個目標(biāo)(obj)文件中。當(dāng)連接程序要把其中的一個函數(shù)連接到程序中去時,目標(biāo)文件中的所有函數(shù)都將被連接進(jìn)來-不管程序是否用到它們。如果這些函數(shù)是無關(guān)的(在它們的定義中沒有相互調(diào)用),那么會因為把不需要的代碼連接進(jìn)
17、來而浪費(fèi)寶貴的程序空間,見187中的例子。這就是要把庫函數(shù)放到各自的源文件中的原因之一。 另一個原因是為了在小組開發(fā)環(huán)境下便于進(jìn)行代碼共享。使用獨(dú)立的源文件能使小組程序員上交和收回單獨(dú)一個函數(shù),而不必先鎖住源文件中的一些函數(shù),然后才能修改源文件中的其它函數(shù)。 請參見: 187 當(dāng)一個庫被連接到目標(biāo)上時,庫中的所有函數(shù)是否都會被加到一個“EXE文件中? 189 為什么要建立一個庫?18.9. 為什么要建立一個庫? 建立一個數(shù)據(jù)庫是為了把可重復(fù)使用的函數(shù)放在一起,供其它程序員和程序共享。例如,你的幾個程序可能都會用到一些通用的功能函數(shù),你不必在每個程序中都復(fù)制這些源代碼,而只需把這些函數(shù)集中到一個
18、函數(shù)庫中,然后用連接程序把它們連接到你的程序中去。這種方法有利于程序的維護(hù),因為你可以在一個集中的地方而不是幾個分散的地方維護(hù)你的函數(shù)。 如果你在小組環(huán)境中工作,那么你應(yīng)該把你的可重復(fù)使用的函數(shù)放到一個庫中,這樣其它小組成員就可以把你的函數(shù)連接到他們的程序中去,從而節(jié)省了他們復(fù)制或從頭開始寫這些函數(shù)的時間。此外,在一個包含幾個模塊的大項目中,可以把那些自始至終都要用到的“框架”支持函數(shù)包含到一個庫中。 編譯程序中包含一個庫管理器(通常叫做LIBEXE或其它類似的名字),可用來在函數(shù)庫中增減目標(biāo)代碼模塊(obj)。有些編譯程序允許你在它們的集成開發(fā)環(huán)境中維護(hù)你的庫,而不必人為地啟動庫管理器。無論
19、如何,你都應(yīng)該參考一下187和188。其中有一些有關(guān)建庫的重要信息和有用的技巧。 請參見: 187 當(dāng)一個庫被連接到目標(biāo)上時,庫中的所有函數(shù)是否都會被加到一個“EXE文件中? 188 可以把多個庫函數(shù)包含在同一個源文件中嗎? 建立一個數(shù)據(jù)庫是為了把可重復(fù)使用的函數(shù)放在一起,供其它程序員和程序共享。例如,你的幾個程序可能都會用到一些通用的功能函數(shù),你不必在每個程序中都復(fù)制這些源代碼,而只需把這些函數(shù)集中到一個函數(shù)庫中,然后用連接程序把它們連接到你的程序中去。這種方法有利于程序的維護(hù),因為你可以在一個集中的地方而不是幾個分散的地方維護(hù)你的函數(shù)。 如果你在小組環(huán)境中工作,那么你應(yīng)該把你的可重復(fù)使用的
20、函數(shù)放到一個庫中,這樣其它小組成員就可以把你的函數(shù)連接到他們的程序中去,從而節(jié)省了他們復(fù)制或從頭開始寫這些函數(shù)的時間。此外,在一個包含幾個模塊的大項目中,可以把那些自始至終都要用到的“框架”支持函數(shù)包含到一個庫中。 編譯程序中包含一個庫管理器(通常叫做LIBEXE或其它類似的名字),可用來在函數(shù)庫中增減目標(biāo)代碼模塊(obj)。有些編譯程序允許你在它們的集成開發(fā)環(huán)境中維護(hù)你的庫,而不必人為地啟動庫管理器。無論如何,你都應(yīng)該參考一下187和188。其中有一些有關(guān)建庫的重要信息和有用的技巧。 請參見: 187 當(dāng)一個庫被連接到目標(biāo)上時,庫中的所有函數(shù)是否都會被加到一個“EXE文件中? 188 可以把
21、多個庫函數(shù)包含在同一個源文件中嗎?18.10. 如果一個程序包含多個源文件,怎樣使它們都能正常工作? 編譯程序中包含一個MAKE工具(通常叫做MAKEEXE,NMAKEEXE或其它類似的名字),其作用是記錄項目以及組成項目的源文件之間的依賴關(guān)系。下面是一個典型的MAKE文件的例子。myapp. ohj : myapp. c myapp. h cl-c myapp. cutility. obj : utility. c myapp. h cl-c utility. cmyapp, exe : myapp. obj utility. obj cl myapp. obj utility. obj 這
22、個例子表明myappobj依賴于myappc和myapph,utilityobj依賴于utilityc和myapph,myappexe依賴于myappobj和utilityobj。在表示依賴關(guān)系的每一行下面,都附有一條對相應(yīng)的目標(biāo)進(jìn)行重新編譯或重新連接的編譯程序命令。例如,myappobj是通過執(zhí)行下面的命令行重新生成的: cl-c myappc 在上面的例子中,只有在myappc或myapph的時間標(biāo)志晚于myappobj的時間標(biāo)志時,myappobj才會被重新編譯。同樣,只有在utilityc或myapph的時間標(biāo)志晚于utilityobj的時間標(biāo)志時,utilityobj才會被重新編譯;
23、只有在myappobj或utilityobj的時間標(biāo)志晚于myappexe的時間標(biāo)志時,myappexe才會被重新連接。 如果一個大型項目包含著源文件依賴關(guān)系,那么用MAKE文件來處理是非常方便的。MAKE工具及其相關(guān)的命令和實現(xiàn)因編譯程序的不同而不同關(guān)于如何使用MAKE工具,你可以查閱你的編譯程序文檔。 今天,大多數(shù)編譯程序都帶有集成開發(fā)環(huán)境,你可以在其中用項目文件來管理程序中的多個源文件,如果你有一個集成環(huán)境,你就不必去了解MAKE工具的復(fù)雜用法,并且可以很方便地管理項目中的源文件,因為集成環(huán)境會為你記錄所有的源文件依賴關(guān)系。 請參見: 181程序是應(yīng)該寫成一個源文件還是多個源文件?18.
24、11. 連接過程中出現(xiàn)DGROUP:group exceeds 64K消息是怎么回事? 如果在連接時看到這條出錯消息,那是連接程序在指示數(shù)據(jù)(DGROUP)段中的近程數(shù)據(jù)(靜態(tài)數(shù)組元素,全局變量等)超過了64KB。解決這個問題的辦法有以下幾種: 減少一些全局變量; 減少程序的棧; 用動態(tài)存儲分配技術(shù)為數(shù)據(jù)元素分配動態(tài)內(nèi)態(tài),而不把它們定義為靜態(tài)型或全局型; 把數(shù)據(jù)元素說明為遠(yuǎn)程型而不是近程型。 減少一些全局變量可能要求對程序的內(nèi)部結(jié)構(gòu)進(jìn)行重新設(shè)計,但這是值得的。從本質(zhì)上講,全局變量的維護(hù)很可能是一場惡夢,因此只有在確實需要時才能使用全局變量。如果你分配了大量的空間作為??臻g,那么你應(yīng)該試試減少棧
25、空間,看看是否能增加可用的內(nèi)存。如果你在程序中使用了大量靜態(tài)數(shù)據(jù),那么你應(yīng)該想辦法重新安排這些靜態(tài)數(shù)據(jù),并且為它們分配動態(tài)的而不是靜態(tài)的內(nèi)存。這種技術(shù)可以釋放近程堆,并且使你能從遠(yuǎn)程堆中分配內(nèi)存(見1815中有關(guān)近程堆和遠(yuǎn)程堆的討論)。 請參見: 1812 怎樣防止程序用盡內(nèi)存? 1813 如果程序大太而不能在DOS下運(yùn)行,怎樣才能使它在DOS下運(yùn)行呢? 1814 怎樣才能使DOS程序獲得超過640KB的可用內(nèi)存呢? 1815 近程型(near)和遠(yuǎn)程型(far)的區(qū)別是什么?18.12. 怎術(shù)防止程序用盡內(nèi)存? 如果你使用了大量的靜態(tài)數(shù)據(jù),那么你應(yīng)該考慮使用動態(tài)內(nèi)存分配技術(shù)。通過使用動態(tài)內(nèi)存
26、分配技術(shù)(即使用malloc()和calloc()函數(shù)),你可以在需要時動態(tài)地分配內(nèi)存,在不需要時釋放內(nèi)存。這種方法有幾個好處:首先,動態(tài)內(nèi)存分配技術(shù)會使程序的效率更高,因為程序只在需要時才使用內(nèi)存,并且只使用所需大小的內(nèi)存空間。這樣,靜態(tài)和全局變量就不會占用大量的空間。其次,你可以通過檢查malloc()和calloc()函數(shù)的返回值來掌握內(nèi)存不足的情況。 如果你的程序特別大,你可能要使用覆蓋管理程序或DOS擴(kuò)展程序,或者使用其它內(nèi)存分配機(jī)制,例如EMS和XMS(有關(guān)內(nèi)容見1813和1814)。 請參見: 1811連接過程中出現(xiàn)DGROUP:group exceeds 64K消息是怎么回事?
27、 1813 如果程序太大而不能在DOS下運(yùn)行,怎樣才能使它在DOS下運(yùn)行呢? 1814 怎樣才能使DOS程序獲得超過640KB的可用內(nèi)存呢? 1815 近程型(near)和遠(yuǎn)程型(far)的區(qū)別是什么?18.13. 如果程序太大而不能在DOS下運(yùn)行,怎樣才能使它在DOS下運(yùn)行呢? 如果你的程序因太大(超過640KB)而無法在DOS下運(yùn)行,有兩種辦法可為該程序提供更多的內(nèi)存。一種辦法是使用覆蓋管理程序(overlay manager)。覆蓋管理程序用來管理程序的模塊,并根據(jù)需要把它們從磁盤中讀入內(nèi)存或從內(nèi)存中刪去。這樣,即使你的程序有幾兆字節(jié)那么大,仍然可以在只有640KB可用內(nèi)存的計算機(jī)上運(yùn)行
28、。一些高級的覆蓋管理程序允許你對需要同時讀入和刪除的模塊進(jìn)行“編組”,這有助于你通過精心調(diào)整程序來改善它的性能。其它一些稍差的覆蓋管理程序不具備這種功能,因此使用它們時你無法通過編組方式去精心調(diào)整覆蓋模塊。 另一種獲得更多的可用內(nèi)存的辦法是使用DOS擴(kuò)展程序(DOS extender),DOS擴(kuò)展程序是一種特殊的應(yīng)用程序,它通過使用386,486或更新機(jī)型的保護(hù)模式,按一個平面地址空間的方式來存取多達(dá)數(shù)兆字節(jié)的內(nèi)存。當(dāng)你的程序和DOS擴(kuò)展程序連接時,DOS擴(kuò)展程序的代碼將成為該程序的啟動代碼的一部分。當(dāng)你的程序被執(zhí)行時,DOS擴(kuò)展程序?qū)⒈谎b入,并且將掌握程序的控制權(quán)。所有的內(nèi)存分配調(diào)用都要通過
29、DOS擴(kuò)展程序來進(jìn)行,這樣就跳過了DOS,而由DOS擴(kuò)展程序來分配超過640KB的內(nèi)存。 遺憾的是,DOS擴(kuò)展程序也有一些明顯的缺點(diǎn),其中之一就是,在你發(fā)行你的程序時,大多數(shù)DOS擴(kuò)展程序要求你交納運(yùn)行版稅。這可能非常昂貴,特別是在你有很多用戶時。也有少數(shù)編譯程序帶有免收版稅的DOS擴(kuò)展程序,但這只不過是一種例外。使用DOS擴(kuò)展程序的另一個缺點(diǎn)是它通常要求你通過修改源代碼而不是通過DOS調(diào)用來使用其應(yīng)用編程接口(API)。 覆蓋管理程序一般不要求運(yùn)行費(fèi)用,因此它具有較高的性能價格比,并且比DOS擴(kuò)展程序更便宜。此外,在使用覆蓋管理程序時,一般不需要修改源代碼,在大多數(shù)情況下,使用覆蓋管理程序?qū)?/p>
30、程序來說是透明的。 請參見: 1811 連接過程中出現(xiàn)DGROUP:group exceeds 64K消息是怎么回事? 1812 怎樣防止程序用盡內(nèi)存? 1814 怎樣才能使DOS程序獲得超過640KB的可用內(nèi)存呢? 1815 近程型(near)和遠(yuǎn)程型(far)的區(qū)別是什么?18.14. 怎樣才能使DOS程序獲得超過640KB的可用內(nèi)存呢? 當(dāng)你發(fā)現(xiàn)自己遇到內(nèi)存危機(jī)的情況,需要在DOS程序中使用超過640KB的內(nèi)存時,你可以用幾種辦法來獲得更多的可用內(nèi)存。一種辦法是使用磁盤交換技術(shù)(disk swapping),即把內(nèi)存中不需要的數(shù)據(jù)元素(變量、數(shù)組、結(jié)構(gòu)等)寫到磁盤上,并把它們原來占用的內(nèi)
31、存空間釋放掉(使用free()函數(shù)),從而使程序獲得更多的可用內(nèi)存。當(dāng)需要使用被交換到磁盤上的數(shù)據(jù)時,你可以把其它不需要的數(shù)據(jù)交換到磁盤上,然后把要用的數(shù)據(jù)從磁盤上讀到內(nèi)存中。遺憾的是,這種辦法要求編寫大量的代碼,而且實現(xiàn)起來比較麻煩。 另一種獲得超過640KB可用內(nèi)存的辦法是使用其它內(nèi)存資源一EMS(擴(kuò)充內(nèi)存)或XMS(擴(kuò)展內(nèi)存)。EMS和XMS指的是分配640KB區(qū)域以上的內(nèi)存的兩種方法,下文將分別對其進(jìn)行介紹。 EMS指的是擴(kuò)充內(nèi)存規(guī)范(Expand Memory Specification),它是由Lotus,Intel和Microsoft共同制定的,用來在IBM兼容機(jī)上訪問1MB以上
32、的內(nèi)存區(qū)域。目前該規(guī)范有兩種版本在被使用:LIM32和LIM4O。LIM4O是新的版本,它克服了LIM32的一些局限性。在裝入擴(kuò)充內(nèi)存管理程序(例如DOS中的EMM386EXE)后,你就可以使用擴(kuò)充內(nèi)存了。你的程序可以向擴(kuò)充內(nèi)存管理程序發(fā)出要求使用擴(kuò)充內(nèi)存的請求,擴(kuò)充內(nèi)存管理程序?qū)⑹褂靡环N叫做成組交換(bank switching)的技術(shù),把位于IMB以上區(qū)域中的內(nèi)存暫時移到640KB和1MB之間的上位內(nèi)存中的一個空閑區(qū)中。成組交換技術(shù)包括這樣一些內(nèi)容:接受應(yīng)用程序的內(nèi)存分配請求,并通過每次分配16KB上位內(nèi)存的方式來映射并管理1MB以上區(qū)域中的內(nèi)存。 擴(kuò)展內(nèi)存在裝入擴(kuò)展內(nèi)存管理程序(例如DO
33、S中的HIMEMSYS)后才會起作用。你的程序可以向擴(kuò)展內(nèi)存管理程序發(fā)出要求使用擴(kuò)展內(nèi)存塊(EMB)的請求。在申請擴(kuò)展內(nèi)存時,不需要使用“成組交換技術(shù)”,你的程序只需向擴(kuò)展內(nèi)存管理程序發(fā)一個函數(shù)調(diào)用來申請一塊位于1MB以上區(qū)域中的內(nèi)存。不幸的是,在DOS下位于1MB以上存儲區(qū)內(nèi)的代碼無法被執(zhí)行,因此你無法執(zhí)行在擴(kuò)展內(nèi)存中的代碼。同樣,你也不能直接尋址存在擴(kuò)展內(nèi)存中的數(shù)據(jù),所以,許多程序員喜歡在常規(guī)內(nèi)存(640KB以下)中建立一個“緩沖區(qū)”,從而為常規(guī)內(nèi)存和擴(kuò)展內(nèi)存提供一個交換空間。 擴(kuò)充內(nèi)存所使用的技術(shù)比較舊,并且有些過時了。當(dāng)基于DOS的帶有擴(kuò)充內(nèi)存的計算機(jī)剛出現(xiàn)時,擴(kuò)充內(nèi)存的使用極為普遍。
34、使用擴(kuò)充內(nèi)存技術(shù)比使用擴(kuò)展內(nèi)存技術(shù)要慢一些。實際上,通過在configsys文件的EMM386EXE設(shè)置項中加入NOEMS標(biāo)志,今天的許多PC機(jī)配置都已完全取消了擴(kuò)充內(nèi)存。大多數(shù)現(xiàn)代程序已經(jīng)放棄了舊的擴(kuò)充內(nèi)存技術(shù),而使用了新的擴(kuò)展內(nèi)存技術(shù)。 如果你的程序要在高于1MB的區(qū)域內(nèi)尋址,你應(yīng)該使用擴(kuò)展內(nèi)存而不是擴(kuò)充內(nèi)存。與使用擴(kuò)充內(nèi)存時相比,在使用擴(kuò)展內(nèi)存時,你的程序?qū)@得更高的穩(wěn)定性和執(zhí)行速度。 實現(xiàn)擴(kuò)展內(nèi)存和擴(kuò)充內(nèi)存的具體步驟已超出了本書的范圍。如果要解釋如何用這些技術(shù)來訪問內(nèi)存,恐怕就要再寫一章了。EMS(擴(kuò)充內(nèi)存規(guī)范)和XMS(擴(kuò)展內(nèi)存規(guī)范)文檔可以直接從Mcrosoft公司獲得,也可以從C
35、ompuServe這樣的網(wǎng)絡(luò)服務(wù)器上卸載下來,這些文檔詳細(xì)地介紹了EMS和XMS的應(yīng)用編程接口(API)以及每一項技術(shù)的具體用法。 請參見: 1811 連接過程出現(xiàn)DGROUP:group exceeds 64K消息是怎么回事? 1812 怎樣防止程序用盡內(nèi)存? 1813 如果程序太大而不能在DOS下運(yùn)行,怎樣才能使它在DOS下運(yùn)行呢? 1815 近程型(near)和遠(yuǎn)程型(far)的區(qū)別是什么?18.15. 近程型(near)和遠(yuǎn)程型(far)的區(qū)別是什么? DOS用一種分段結(jié)構(gòu)來尋址計算機(jī)的內(nèi)存,每一個物理存儲位置都有一個可以用段一偏移量方式來訪問的相關(guān)地址。例如,下面就是一個典型的段式地
36、址: A000:1234 冒號左邊的部分代表段地址(A000),冒號右邊的部分代表相對于段地址的偏移量。DOS下的每個程序都是按這種方式訪問內(nèi)存的盡管段一偏移量尋址方法的機(jī)理對大多數(shù)C程序員來說是隱蔽的。 當(dāng)你的程序被執(zhí)行時,一個存放在數(shù)據(jù)段(DS)寄存器中的數(shù)據(jù)段地址將被賦給你的程序。這個缺省的數(shù)據(jù)段地址指向一個64KB的內(nèi)存空間,這個空間通常就被叫做近程型數(shù)據(jù)段。在這個近程型數(shù)據(jù)段空間中,你會找到程序的棧、靜態(tài)數(shù)據(jù)和近程堆。近程堆用來為程序啟動時所需的全局變量和其它數(shù)據(jù)元素分配內(nèi)存,在這個空間中分配的任何數(shù)據(jù)都被叫做近程型數(shù)據(jù)。例如,下面的程序在程序啟動時從近程堆中分配了32KB的近程型數(shù)
37、據(jù):/ * Note :Program uses the Medium memory model.* /# include # include # include # include # include void main(void) ;void main(void) char * near_data; near_data= (char * )malloc(32 * 1024) * sizeof(char) ; if (near data= = (char * )NULL) printf(Whoopsie ! Malloc failed! n) ; exit(l) ; strcpy (near_data, This string is going to be. stored in the near heap) ; printf(Address of near_data : %Pn, ,&near_data) ; free (near_data) ; 在上例中,near_data是一個字符指針,程序分配給它一個32KB的內(nèi)存塊。在缺省情況下,這個32KB的內(nèi)存塊是從近程堆中分配的,并且相應(yīng)的16位地址將被存放在字符指針near_data中。 現(xiàn)在,
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 醫(yī)療行業(yè)中的家居智能技術(shù)應(yīng)用案例分享
- 專屬2024版婚禮主持與現(xiàn)場布置一體化服務(wù)協(xié)議版
- 二零二五年度高層建筑消防通道改造施工協(xié)議3篇
- 2025年度個人二手房交易合同模板產(chǎn)權(quán)清晰保障版2篇
- 二零二五年度電子商務(wù)平臺軟件開發(fā)框架合作協(xié)議3篇
- 牡丹江2025年黑龍江牡丹江醫(yī)學(xué)院科大學(xué)招聘93人筆試歷年參考題庫附帶答案詳解
- 二零二五年度車輛保養(yǎng)與綠色出行獎勵合同4篇
- 2025版智慧社區(qū)門衛(wèi)服務(wù)與物業(yè)管理合同2篇
- 湖北2025年湖北省水利水電科學(xué)研究院招聘14人筆試歷年參考題庫附帶答案詳解
- 溫州2025年浙江溫州市公安局洞頭區(qū)分局第一期招聘編外用工筆試歷年參考題庫附帶答案詳解
- 2023年譯林版英語五年級下冊Units-1-2單元測試卷-含答案
- Unit-3-Reading-and-thinking課文詳解課件-高中英語人教版必修第二冊
- 施工管理中的文檔管理方法與要求
- DL∕T 547-2020 電力系統(tǒng)光纖通信運(yùn)行管理規(guī)程
- 種子輪投資協(xié)議
- 物業(yè)客服培訓(xùn)課件PPT模板
- 員工工資條模板
- 執(zhí)行依據(jù)主文范文(通用4篇)
- 浙教版七年級數(shù)學(xué)下冊全冊課件
- 華為攜手深圳國際會展中心創(chuàng)建世界一流展館
- 2023版思想道德與法治專題2 領(lǐng)悟人生真諦 把握人生方向 第3講 創(chuàng)造有意義的人生
評論
0/150
提交評論