




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、偉大的Bill Gates 曾經(jīng)失言:640K ought to be enough for everybody Bill Gates 1981程序員們經(jīng)常編寫內(nèi)存管理程序,往往提心吊膽。如果不想觸雷,唯一的解決辦法就是發(fā)現(xiàn)所有潛伏的地雷并且排除它們,躲是躲不了的。本文的內(nèi)容比一般教科書的要深入得多,讀者需細(xì)心閱讀,做到真正地通曉內(nèi)存管理。1、內(nèi)存分配方式內(nèi)存分配方式有三種:(1從靜態(tài)存儲區(qū)域分配。內(nèi)存在程序編譯的時(shí)候就已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在。例如全局變量,static變量。(2在棧上創(chuàng)建。在執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變量的存儲單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些存儲單
2、元自動被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限。(3從堆上分配,亦稱動態(tài)內(nèi)存分配。程序在運(yùn)行的時(shí)候用malloc或new申請任意多少的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用free或delete釋放內(nèi)存。動態(tài)內(nèi)存的生存期由我們決定,使用非常靈活,但問題也最多。2、常見的內(nèi)存錯(cuò)誤及其對策發(fā)生內(nèi)存錯(cuò)誤是件非常麻煩的事情。編譯器不能自動發(fā)現(xiàn)這些錯(cuò)誤,通常是在程序運(yùn)行時(shí)才能捕捉到。而這些錯(cuò)誤大多沒有明顯的癥狀,時(shí)隱時(shí)現(xiàn),增加了改錯(cuò)的難度。有時(shí)用戶怒氣沖沖地把你找來,程序卻沒有發(fā)生任何問題,你一走,錯(cuò)誤又發(fā)作了。常見的內(nèi)存錯(cuò)誤及其對策如下:* 內(nèi)存分配未成功,卻使用了它。編程
3、新手常犯這種錯(cuò)誤,因?yàn)樗麄儧]有意識到內(nèi)存分配會不成功。常用解決辦法是,在使用內(nèi)存之前檢查指針是否為NULL。如果指針p是函數(shù)的參數(shù),那么在函數(shù)的入口處用assert(p!=NULL進(jìn)行檢查。如果是用malloc或new來申請內(nèi)存,應(yīng)該用if(p=NULL 或if(p!=NULL進(jìn)行防錯(cuò)處理。* 內(nèi)存分配雖然成功,但是尚未初始化就引用它。犯這種錯(cuò)誤主要有兩個(gè)起因:一是沒有初始化的觀念;二是誤以為內(nèi)存的缺省初值全為零,導(dǎo)致引用初值錯(cuò)誤(例如數(shù)組。內(nèi)存的缺省初值究竟是什么并沒有統(tǒng)一的標(biāo)準(zhǔn),盡管有些時(shí)候?yàn)榱阒?我們寧可信其無不可信其有。所以無論用何種方式創(chuàng)建數(shù)組,都別忘了賦初值,即便是賦零值也不可省略
4、,不要嫌麻煩。* 內(nèi)存分配成功并且已經(jīng)初始化,但操作越過了內(nèi)存的邊界。例如在使用數(shù)組時(shí)經(jīng)常發(fā)生下標(biāo)“多1”或者“少1”的操作。特別是在for循環(huán)語句中,循環(huán)次數(shù)很容易搞錯(cuò),導(dǎo)致數(shù)組操作越界。* 忘記了釋放內(nèi)存,造成內(nèi)存泄露。含有這種錯(cuò)誤的函數(shù)每被調(diào)用一次就丟失一塊內(nèi)存。剛開始時(shí)系統(tǒng)的內(nèi)存充足,你看不到錯(cuò)誤。終有一次程序突然死掉,系統(tǒng)出現(xiàn)提示:內(nèi)存耗盡。動態(tài)內(nèi)存的申請與釋放必須配對,程序中malloc與free的使用次數(shù)一定要相同,否則肯定有錯(cuò)誤(new/delete同理。* 釋放了內(nèi)存卻繼續(xù)使用它。有三種情況:(1程序中的對象調(diào)用關(guān)系過于復(fù)雜,實(shí)在難以搞清楚某個(gè)對象究竟是否已經(jīng)釋放了內(nèi)存,此時(shí)
5、應(yīng)該重新設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu),從根本上解決對象管理的混亂局面。(2函數(shù)的return語句寫錯(cuò)了,注意不要返回指向“棧內(nèi)存”的“指針”或者“引用”,因?yàn)樵搩?nèi)存在函數(shù)體結(jié)束時(shí)被自動銷毀。(3使用free或delete釋放了內(nèi)存后,沒有將指針設(shè)置為NULL。導(dǎo)致產(chǎn)生“野指針”。【規(guī)則1】用malloc或new申請內(nèi)存之后,應(yīng)該立即檢查指針值是否為NULL。防止使用指針值為NULL的內(nèi)存?!疽?guī)則2】不要忘記為數(shù)組和動態(tài)內(nèi)存賦初值。防止將未被初始化的內(nèi)存作為右值使用?!疽?guī)則3】避免數(shù)組或指針的下標(biāo)越界,特別要當(dāng)心發(fā)生“多1”或者“少1”操作?!疽?guī)則4】動態(tài)內(nèi)存的申請與釋放必須配對,防止內(nèi)存泄漏?!疽?guī)則5】用fr
6、ee或delete釋放了內(nèi)存之后,立即將指針設(shè)置為NULL,防止產(chǎn)生“野指針”。3、指針與數(shù)組的對比C /C程序中,指針和數(shù)組在不少地方可以相互替換著用,讓人產(chǎn)生一種錯(cuò)覺,以為兩者是等價(jià)的。數(shù)組要么在靜態(tài)存儲區(qū)被創(chuàng)建(如全局?jǐn)?shù)組,要么在棧上被創(chuàng)建。數(shù)組名對應(yīng)著(而不是指向一塊內(nèi)存,其地址與容量在生命期內(nèi)保持不變,只有數(shù)組的內(nèi)容可以改變。指針可以隨時(shí)指向任意類型的內(nèi)存塊,它的特征是“可變”,所以我們常用指針來操作動態(tài)內(nèi)存。指針遠(yuǎn)比數(shù)組靈活,但也更危險(xiǎn)。下面以字符串為例比較指針與數(shù)組的特性。3.1 修改內(nèi)容示例3-1中,字符數(shù)組a的容量是6個(gè)字符,其內(nèi)容為hello。a的內(nèi)容可以改變,如a0= X
7、。指針p指向常量字符串“world”(位于靜態(tài)存儲區(qū),內(nèi)容為world,常量字符串的內(nèi)容是不可以被修改的。從語法上看,編譯器并不覺得語句p0= X有什么不妥,但是該語句企圖修改常量字符串的內(nèi)容而導(dǎo)致運(yùn)行錯(cuò)誤。1.char a = “hello”;2.a0 = X;3.cout << a << endl;4.char *p = “world”; / 注意p指向常量字符串5.p0 = X; / 編譯器不能發(fā)現(xiàn)該錯(cuò)誤6.cout << p << endl;復(fù)制代碼示例3.1 修改數(shù)組和指針的內(nèi)容3.2 內(nèi)容復(fù)制與比較不能對數(shù)組名進(jìn)行直接復(fù)制與比較。示例
8、7-3-2中,若想把數(shù)組a的內(nèi)容復(fù)制給數(shù)組b,不能用語句b = a ,否則將產(chǎn)生編譯錯(cuò)誤。應(yīng)該用標(biāo)準(zhǔn)庫函數(shù)strcpy進(jìn)行復(fù)制。同理,比較b和a的內(nèi)容是否相同,不能用if(b=a 來判斷,應(yīng)該用標(biāo)準(zhǔn)庫函數(shù)strcmp進(jìn)行比較。語句p = a 并不能把a(bǔ)的內(nèi)容復(fù)制指針p,而是把a(bǔ)的地址賦給了p。要想復(fù)制a的內(nèi)容,可以先用庫函數(shù)malloc為p申請一塊容量為strlen(a 1個(gè)字符的內(nèi)存,再用strcpy進(jìn)行字符串復(fù)制。同理,語句if(p=a 比較的不是內(nèi)容而是地址,應(yīng)該用庫函數(shù)strcmp來比較。1./ 數(shù)組2.char a = "hello"3.char b10;4.st
9、rcpy(b, a; / 不能用b = a;5.if(strcmp(b, a = 0 / 不能用if (b = a6.7./ 指針8.int len = strlen(a;9.char *p = (char *malloc(sizeof(char*(len 1;10.strcpy(p,a; / 不要用p = a;11.if(strcmp(p, a = 0 / 不要用if (p = a12.復(fù)制代碼示例3.2 數(shù)組和指針的內(nèi)容復(fù)制與比較3.3 計(jì)算內(nèi)存容量用運(yùn)算符sizeof可以計(jì)算出數(shù)組的容量(字節(jié)數(shù)。示例7-3-3(a中,sizeof(a的值是12(注意別忘了。指針p指向a,但是sizeof
10、(p的值卻是4。這是因?yàn)閟izeof(p得到的是一個(gè)指針變量的字節(jié)數(shù),相當(dāng)于sizeof(char*,而不是p所指的內(nèi)存容量。C /C語言沒有辦法知道指針?biāo)傅膬?nèi)存容量,除非在申請內(nèi)存時(shí)記住它。注意當(dāng)數(shù)組作為函數(shù)的參數(shù)進(jìn)行傳遞時(shí),該數(shù)組自動退化為同類型的指針。示例7-3-3(b中,不論數(shù)組a的容量是多少,sizeof(a始終等于sizeof(char *。1.char a = "hello world"2.char *p = a;3.cout<< sizeof(a << endl; / 12字節(jié)4.cout<< sizeof(p <
11、< endl; / 4字節(jié)復(fù)制代碼示例3.3(a計(jì)算數(shù)組和指針的內(nèi)存容量1.void Func(char a1002.3.cout<< sizeof(a << endl; / 4字節(jié)而不是100字節(jié)4.復(fù)制代碼示例3.3(b數(shù)組退化為指針4、指針參數(shù)是如何傳遞內(nèi)存的?如果函數(shù)的參數(shù)是一個(gè)指針,不要指望用該指針去申請動態(tài)內(nèi)存。示例7-4-1中,Test函數(shù)的語句GetMemory(str, 200并沒有使str獲得期望的內(nèi)存,str依舊是NULL,為什么?1.void GetMemory(char *p, int num2.3.p = (char *malloc(s
12、izeof(char * num;4.5.void Test(void6.7.char *str = NULL;8.GetMemory(str, 100; / str 仍然為NULL9.strcpy(str, "hello" / 運(yùn)行錯(cuò)誤10.復(fù)制代碼示例4.1 試圖用指針參數(shù)申請動態(tài)內(nèi)存毛病出在函數(shù)GetMemory中。編譯器總是要為函數(shù)的每個(gè)參數(shù)制作臨時(shí)副本,指針參數(shù)p的副本是_p,編譯器使_p = p。如果函數(shù)體內(nèi)的程序修改了_p的內(nèi)容,就導(dǎo)致參數(shù)p的內(nèi)容作相應(yīng)的修改。這就是指針可以用作輸出參數(shù)的原因。在本例中,_p申請了新的內(nèi)存,只是把_p所指的內(nèi)存地址改變了,但是
13、p絲毫未變。所以函數(shù)GetMemory并不能輸出任何東西。事實(shí)上,每執(zhí)行一次GetMemory就會泄露一塊內(nèi)存,因?yàn)闆]有用free釋放內(nèi)存。如果非得要用指針參數(shù)去申請內(nèi)存,那么應(yīng)該改用“指向指針的指針”,見示例4.2。1.void GetMemory2(char *p, int num2.3.*p = (char *malloc(sizeof(char * num;4.5.void Test2(void6.7.char *str = NULL;8.GetMemory2(&str, 100; / 注意參數(shù)是&str,而不是str9.strcpy(str, "hello&
14、quot;10.cout<< str << endl;11.free(str;12.復(fù)制代碼由于“指向指針的指針”這個(gè)概念不容易理解,我們可以用函數(shù)返回值來傳遞動態(tài)內(nèi)存。這種方法更加簡單,見示例4.3。1.char *GetMemory3(int num2.3.char *p = (char *malloc(sizeof(char * num;4.return p;5.6.void Test3(void7.8.char *str = NULL;9.str = GetMemory3(100;10.strcpy(str, "hello"11.cout&l
15、t;< str << endl;12.free(str;13.復(fù)制代碼示例4.3 用函數(shù)返回值來傳遞動態(tài)內(nèi)存用函數(shù)返回值來傳遞動態(tài)內(nèi)存這種方法雖然好用,但是常常有人把return語句用錯(cuò)了。這里強(qiáng)調(diào)不要用return語句返回指向“棧內(nèi)存”的指針,因?yàn)樵搩?nèi)存在函數(shù)結(jié)束時(shí)自動消亡,見示例4.4。1.char *GetString(void2.3.char p = "hello world"4.return p; / 編譯器將提出警告5.6.void Test4(void7.8.char *str = NULL;9.str = GetString(; / str
16、 的內(nèi)容是垃圾10.cout<< str << endl;11.復(fù)制代碼示例4.4 return語句返回指向“棧內(nèi)存”的指針用調(diào)試器逐步跟蹤Test4,發(fā)現(xiàn)執(zhí)行str = GetString語句后str不再是NULL指針,但是str的內(nèi)容不是“hello world”而是垃圾。如果把示例4.4改寫成示例4.5,會怎么樣?1.char *GetString2(void2.3.char *p = "hello world"4.return p;5.6.void Test5(void7.8.char *str = NULL;9.str = GetStrin
17、g2(;10.cout<< str << endl;11.復(fù)制代碼示例4.5 return語句返回常量字符串函數(shù)Test5運(yùn)行雖然不會出錯(cuò),但是函數(shù)GetString2的設(shè)計(jì)概念卻是錯(cuò)誤的。因?yàn)镚etString2內(nèi)的“hello world”是常量字符串,位于靜態(tài)存儲區(qū),它在程序生命期內(nèi)恒定不變。無論什么時(shí)候調(diào)用GetString2,它返回的始終是同一個(gè)“只讀”的內(nèi)存塊。5、杜絕“野指針”“野指針”不是NULL指針,是指向“垃圾”內(nèi)存的指針。人們一般不會錯(cuò)用NULL指針,因?yàn)橛胕f 語句很容易判斷。但是“野指針”是很危險(xiǎn)的,if語句對它不起作用?!耙爸羔槨钡某梢蛑饕?/p>
18、兩種:(1指針變量沒有被初始化。任何指針變量剛被創(chuàng)建時(shí)不會自動成為NULL指針,它的缺省值是隨機(jī)的,它會亂指一氣。所以,指針變量在創(chuàng)建的同時(shí)應(yīng)當(dāng)被初始化,要么將指針設(shè)置為NULL,要么讓它指向合法的內(nèi)存。例如1.char *p = NULL;2.char *str = (char * malloc(100;復(fù)制代碼(2指針p被free或者delete之后,沒有置為NULL,讓人誤以為p是個(gè)合法的指針。(3指針操作超越了變量的作用范圍。這種情況讓人防不勝防,示例程序如下:1.class A2.3.public:4.void Func(void cout << “Func of cla
19、ss A” << endl; 5.;6.void Test(void7.8. A *p;9.10. A a;11.p = &a; / 注意a 的生命期12.13.p->Func(; / p是“野指針”14.復(fù)制代碼函數(shù)Test在執(zhí)行語句p->Func(時(shí),對象a已經(jīng)消失,而p是指向a的,所以p就成了“野指針”。但奇怪的是我運(yùn)行這個(gè)程序時(shí)居然沒有出錯(cuò),這可能與編譯器有關(guān)。6、有了malloc/free為什么還要new/delete?malloc與free是C /C語言的標(biāo)準(zhǔn)庫函數(shù),new/delete是C 的運(yùn)算符。它們都可用于申請動態(tài)內(nèi)存和釋放內(nèi)存。對于非內(nèi)部數(shù)
20、據(jù)類型的對象而言,光用maloc/free無法滿足動態(tài)對象的要求。對象在創(chuàng)建的同時(shí)要自動執(zhí)行構(gòu)造函數(shù),對象在消亡之前要自動執(zhí)行析構(gòu)函數(shù)。由于malloc/free是庫函數(shù)而不是運(yùn)算符,不在編譯器控制權(quán)限之內(nèi),不能夠把執(zhí)行構(gòu)造函數(shù)和析構(gòu)函數(shù)的任務(wù)強(qiáng)加于malloc/free。因此C 語言需要一個(gè)能完成動態(tài)內(nèi)存分配和初始化工作的運(yùn)算符new,以及一個(gè)能完成清理與釋放內(nèi)存工作的運(yùn)算符delete。注意new/delete不是庫函數(shù)。我們先看一看malloc/free和new/delete如何實(shí)現(xiàn)對象的動態(tài)內(nèi)存管理,見示例6。1.class Obj2.3.public :4.Obj(void cout
21、 << “Initialization” << endl; 5.Obj(void cout << “Destroy” << endl; 6.void Initialize(void cout << “Initialization” << endl; 7.voi d Destroy(void cout << “Destroy” << endl; 8.;9.void UseMallocFree(void10.11.Obj *a = (obj *malloc(sizeof(obj; / 申請動態(tài)內(nèi)存12.
22、a->Initialize(; / 初始化13./14.a->Destroy(; / 清除工作15.free(a; / 釋放內(nèi)存17.void UseNewDelete(void18.19.Obj *a = new Obj; / 申請動態(tài)內(nèi)存并且初始化20./21.delete a; / 清除并且釋放內(nèi)存22.復(fù)制代碼示例6 用malloc/free和new/delete如何實(shí)現(xiàn)對象的動態(tài)內(nèi)存管理類Obj的函數(shù)Initialize模擬了構(gòu)造函數(shù)的功能,函數(shù)Destroy模擬了析構(gòu)函數(shù)的功能。函數(shù)UseMallocFree中,由于malloc/free不能執(zhí)行構(gòu)造函數(shù)與析構(gòu)函數(shù),必須
23、調(diào)用成員函數(shù)Initialize和Destroy來完成初始化與清除工作。函數(shù)UseNewDelete則簡單得多。所以我們不要企圖用malloc/free來完成動態(tài)對象的內(nèi)存管理,應(yīng)該用new/delete。由于內(nèi)部數(shù)據(jù)類型的“對象”沒有構(gòu)造與析構(gòu)的過程,對它們而言malloc/free和new/delete是等價(jià)的。既然new/delete的功能完全覆蓋了malloc/free,為什么C 不把malloc/free淘汰出局呢?這是因?yàn)镃 程序經(jīng)常要調(diào)用C函數(shù),而C程序只能用malloc/free管理動態(tài)內(nèi)存。如果用free釋放“new創(chuàng)建的動態(tài)對象”,那么該對象因無法執(zhí)行析構(gòu)函數(shù)而可能導(dǎo)致程序
24、出錯(cuò)。如果用delete釋放“malloc申請的動態(tài)內(nèi)存”,理論上講程序不會出錯(cuò),但是該程序的可讀性很差。所以new/delete必須配對使用,malloc/free也一樣。7、內(nèi)存耗盡怎么辦?如果在申請動態(tài)內(nèi)存時(shí)找不到足夠大的內(nèi)存塊,malloc和new將返回NULL指針,宣告內(nèi)存申請失敗。通常有三種方式處理“內(nèi)存耗盡”問題。(1判斷指針是否為NULL,如果是則馬上用return語句終止本函數(shù)。例如:1.void Func(void3. A *a = new A;4.if(a = NULL5.6.return;7.8.9.復(fù)制代碼(2判斷指針是否為NULL,如果是則馬上用exit(1終止整個(gè)
25、程序的運(yùn)行。例如:1.void Func(void2.3. A *a = new A;4.if(a = NULL5.6.cout << “Memory Exhausted” << endl;7.exit(1;8.9.10.復(fù)制代碼(3為new和malloc設(shè)置異常處理函數(shù)。例如Visual C 可以用_set_new_hander函數(shù)為new設(shè)置用戶自己定義的異常處理函數(shù),也可以讓malloc享用與new相同的異常處理函數(shù)。詳細(xì)內(nèi)容請參考C 使用手冊。上述(1(2方式使用最普遍。如果一個(gè)函數(shù)內(nèi)有多處需要申請動態(tài)內(nèi)存,那么方式(1就顯得力不從心(釋放內(nèi)存很麻煩,應(yīng)該用方式
26、(2來處理。很多人不忍心用exit(1,問:“不編寫出錯(cuò)處理程序,讓操作系統(tǒng)自己解決行不行?”不行。如果發(fā)生“內(nèi)存耗盡”這樣的事情,一般說來應(yīng)用程序已經(jīng)無藥可救。如果不用exit(1 把壞程序殺死,它可能會害死操作系統(tǒng)。道理如同:如果不把歹徒擊斃,歹徒在老死之前會犯下更多的罪。有一個(gè)很重要的現(xiàn)象要告訴大家。對于32位以上的應(yīng)用程序而言,無論怎樣使用malloc與new,幾乎不可能導(dǎo)致“內(nèi)存耗盡”。我在Windows 98下用Visual C 編寫了測試程序,見示例7。這個(gè)程序會無休止地運(yùn)行下去,根本不會終止。因?yàn)?2位操作系統(tǒng)支持“虛存”,內(nèi)存用完了,自動用硬盤空間頂替。我只聽到硬盤嘎吱嘎吱地
27、響,Window 98已經(jīng)累得對鍵盤、鼠標(biāo)毫無反應(yīng)。我可以得出這么一個(gè)結(jié)論:對于32位以上的應(yīng)用程序,“內(nèi)存耗盡”錯(cuò)誤處理程序毫無用處。這下可把Unix和Windows程序員們樂壞了:反正錯(cuò)誤處理程序不起作用,我就不寫了,省了很多麻煩。我不想誤導(dǎo)讀者,必須強(qiáng)調(diào):不加錯(cuò)誤處理將導(dǎo)致程序的質(zhì)量很差,千萬不可因小失大。1.void main(void2.3.float *p = NULL;4.while(TRUE5.6.p = new float1000000;7.cout << “eat memory” << endl;8.if(p=NULL9.exit(1;10.11.復(fù)
28、制代碼示例7試圖耗盡操作系統(tǒng)的內(nèi)存8、malloc/free 的使用要點(diǎn)函數(shù)malloc的原型如下:1.void * malloc(size_t size;復(fù)制代碼用malloc申請一塊長度為length的整數(shù)類型的內(nèi)存,程序如下:1.int *p = (int * malloc(sizeof(int * length;復(fù)制代碼我們應(yīng)當(dāng)把注意力集中在兩個(gè)要素上:“類型轉(zhuǎn)換”和“sizeof”。* malloc返回值的類型是void *,所以在調(diào)用malloc時(shí)要顯式地進(jìn)行類型轉(zhuǎn)換,將void * 轉(zhuǎn)換成所需要的指針類型。* malloc函數(shù)本身并不識別要申請的內(nèi)存是什么類型,它只關(guān)心內(nèi)存的總字
29、節(jié)數(shù)。我們通常記不住int, float等數(shù)據(jù)類型的變量的確切字節(jié)數(shù)。例如int變量在16位系統(tǒng)下是2個(gè)字節(jié),在32位下是4個(gè)字節(jié);而float變量在16位系統(tǒng)下是4個(gè)字節(jié),在32位下也是4個(gè)字節(jié)。最好用以下程序作一次測試:1.cout << sizeof(char << endl;2.cout << sizeof(int << endl;3.cout << sizeof(unsigned int << endl;4.cout << sizeof(long << endl;5.cout <&l
30、t; sizeof(unsigned long << endl;6.cout << sizeof(float << endl;7.cout << sizeof(double << endl;8.cout << sizeof(void * << endl;復(fù)制代碼在malloc的“(”中使用sizeof運(yùn)算符是良好的風(fēng)格,但要當(dāng)心有時(shí)我們會昏了頭,寫出p =malloc(sizeof(p這樣的程序來。* 函數(shù)free的原型如下:1.void free( void * memblock ;復(fù)制代碼為什么free 函數(shù)不象malloc函數(shù)那樣復(fù)雜呢?這是因?yàn)橹羔榩的類型以及它所指的內(nèi)存的容量事先都是知道的,語句
溫馨提示
- 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 第2.6講 指數(shù)與指數(shù)函數(shù)(解析版)-2024年高考數(shù)學(xué)一輪復(fù)習(xí)精講精練寶典(新高考專用)
- 浙教版2023小學(xué)信息技術(shù)六年級上冊《算法的多樣性》教學(xué)設(shè)計(jì)及反思
- (一模)萍鄉(xiāng)市2025年高三第一次模擬考試歷史試卷(含答案解析)
- 2025年B2B營銷業(yè)務(wù) AI提示詞手冊
- 陶瓷攔水帶施工方案
- 高樓地鐵隧道施工方案
- 砂漿基礎(chǔ)知識培訓(xùn)課件
- 2025年山東聊城高三一模高考數(shù)學(xué)試卷試題(含答案詳解)
- 2025年藥具科技工作培訓(xùn)標(biāo)準(zhǔn)教案
- 寫贈予房產(chǎn)合同范例
- 2024-2025學(xué)年第二學(xué)期天域全國名校協(xié)作體高三3月聯(lián)考 地理試卷(含答案)
- 修理木橋施工合同范本
- 學(xué)校2025年每日兩小時(shí)體育活動方案-陽光體育活力四溢
- 錘擊式PHC預(yù)應(yīng)力混凝土管樁貫入度的控制
- 新教科版一年級科學(xué)下冊第一單元第6課《哪個(gè)流動得快》課件
- 屋面種植土垂直施工方案
- 2025年新人教PEP版英語三年級下冊全冊課時(shí)練習(xí)
- 《愛耳日課件》課件
- 2024年安徽中醫(yī)藥高等專科學(xué)校高職單招職業(yè)適應(yīng)性測試歷年參考題庫含答案解析
- GB/T 45107-2024表土剝離及其再利用技術(shù)要求
- 2025年保密工作計(jì)劃(3篇)
評論
0/150
提交評論