C語言內(nèi)存講解_第1頁
C語言內(nèi)存講解_第2頁
C語言內(nèi)存講解_第3頁
C語言內(nèi)存講解_第4頁
已閱讀5頁,還剩45頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

(:語言中的堆和棧的區(qū)別堆和棧的區(qū)別.申請(qǐng)方式(1)棧(satck):由系統(tǒng)自動(dòng)分配。例如,聲明在函數(shù)中一個(gè)局部變量intb;系統(tǒng)自動(dòng)在棧中為b開辟空間。(2)堆(heap):需程序員自己申請(qǐng)(調(diào)用malloc,realloc,calloc),并指明大小,并由程序員進(jìn)行釋放。容易產(chǎn)生memoryleak.eg:charp;p=(char*)malloc(sizeof(char));但是,P本身是在棧中。.申請(qǐng)大小的限制(1)棧:在windows下棧是向底地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是ー塊連續(xù)的內(nèi)存區(qū)域(它的生長方向與內(nèi)存的生長方向相反)。棧的大小是固定的。如果申請(qǐng)的空間超過棧的剩余空間時(shí),將提示overflowo(2)堆:堆是高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)(它的生長方向與內(nèi)存的生長方向相同),是不連續(xù)的內(nèi)存區(qū)域。這是由于系統(tǒng)使用鏈表來存儲(chǔ)空閑內(nèi)存地址的,自然是不連續(xù)的,而鏈表的遍歷方向是由底地址向高地址。堆的大小受限于計(jì)算機(jī)系統(tǒng)中有效的虛擬內(nèi)存。.系統(tǒng)響應(yīng):(1)棧:只要棧的空間大于所申請(qǐng)空間,系統(tǒng)將為程序提供內(nèi)存,否則將報(bào)異常提示棧溢出。(2)堆:首先應(yīng)該知道操作系統(tǒng)有一個(gè)記錄空閑內(nèi)存地址的鏈表,但系統(tǒng)收到程序的申請(qǐng)時(shí),會(huì)遍歷該鏈表,尋找第一個(gè)空間大于所申請(qǐng)空間的堆結(jié)點(diǎn),然后將該結(jié)點(diǎn)從空閑鏈表中刪除,并將該結(jié)點(diǎn)的空間分配給程序,另外,對(duì)于大多數(shù)系統(tǒng),會(huì)在這塊內(nèi)存空間中的首地址處記錄本次分配的大小,這樣,代碼中的free語句オ能正確的釋放本內(nèi)存空間。另外,找到的堆結(jié)點(diǎn)的大小不一定正好等于申請(qǐng)的大小,系統(tǒng)會(huì)自動(dòng)的將多余的那部分重新放入空閑鏈表中。說明:對(duì)于堆來講,對(duì)于堆來講,頻繁的new/delete勢(shì)必會(huì)造成內(nèi)存空間的不連續(xù),從而造成大量的碎片,使程序效率降低。對(duì)于棧來講,則不會(huì)存在這個(gè)問題,.申請(qǐng)效率(1)棧由系統(tǒng)自動(dòng)分配,速度快。但程序員是無法控制的(2)堆是由malloc分配的內(nèi)存,一般速度比較慢,而且容易產(chǎn)生碎片,不過用起來最方便。.堆和棧中的存儲(chǔ)內(nèi)容(1)棧:在函數(shù)調(diào)用時(shí),第一個(gè)進(jìn)棧的主函數(shù)中后的下一條語句的地址,然后是函數(shù)的各個(gè)參數(shù),參數(shù)是從右往左入棧的,然后是函數(shù)中的局部變量。注:靜態(tài)變量是不入棧的。當(dāng)本次函數(shù)調(diào)用結(jié)束后,局部變量先出棧,然后是參數(shù),最后棧頂指針指向最開始存的地址,也就是主函數(shù)中的下一條指令,程序由該點(diǎn)繼續(xù)執(zhí)行。(2)堆:一般是在堆的頭部用ー個(gè)字節(jié)存放堆的大小。6,存取效率(1)堆:char*sl="hellowtigerjibo”;是在編譯是就確定的(2)棧:charsiロ="hellowtigerjibo";是在運(yùn)行時(shí)賦值的;用數(shù)組比用指針?biāo)俣雀飑`些,指針在底層匯編中需要用edx寄存器中轉(zhuǎn)ー下,而數(shù)組在棧上讀取。補(bǔ)充:棧是機(jī)器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu),計(jì)算機(jī)會(huì)在底層對(duì)棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執(zhí)行,這就決定了棧的效率比較高。堆則是C/C++函數(shù)庫提供的,它的機(jī)制是很復(fù)雜的,例如為了分配ー塊內(nèi)存,庫函數(shù)會(huì)按照一定的算法(具體的算法可以參考數(shù)據(jù)結(jié)構(gòu)/操作系統(tǒng))在堆內(nèi)存中搜索可用的足夠大小的空間,如果沒有足夠大小的空間(可能是由于內(nèi)存碎片太多),就有可能調(diào)用系統(tǒng)功能去增加程序數(shù)據(jù)段的內(nèi)存空間,這樣就有機(jī)會(huì)分到足夠大小的內(nèi)存,然后進(jìn)行返回。顯然,堆的效率比棧要低得多。.分配方式:(1)堆都是動(dòng)態(tài)分配的,沒有靜態(tài)分配的堆。(2)棧有兩種分配方式:靜態(tài)分配和動(dòng)態(tài)分配。靜態(tài)分配是編譯器完成的,比如局部變量的分配。動(dòng)態(tài)分配由alloca函數(shù)進(jìn)行分配,但是棧的動(dòng)態(tài)分配和堆是不同的。它的動(dòng)態(tài)分配是由編譯器進(jìn)行釋放,無需手工實(shí)現(xiàn)。C語言malloc工作機(jī)制void*malloc(size_tstSize);該函數(shù)在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中分配stSize連續(xù)空間,返回值是ー個(gè)指向所分配的連續(xù)存儲(chǔ)域的起始地址的指針。voidfree(void*firstbyte);如果給定一個(gè)由先前的malloc返回的指針,那么該函數(shù)會(huì)將分配的空間歸還給進(jìn)程的“空閑空間’’。malloc工作機(jī)制:malloc函數(shù)的實(shí)質(zhì)體現(xiàn)在,它有一個(gè)將可用的內(nèi)存塊連接為ー個(gè)長長的列表的所謂空閑鏈表。調(diào)用malloc函數(shù)時(shí),它沿連接表尋找ー個(gè)大到足以滿足用戶請(qǐng)求所需要的內(nèi)存塊。然后,將該內(nèi)存塊一分為二(ー塊的大小與用戶請(qǐng)求的大小相等,另ー塊的大小就是剩下的字節(jié))。接下來,將分配給用戶的那塊內(nèi)存?zhèn)鹘o用戶,并將剩下的那塊(如果有的話)返回到連接表上。調(diào)用free函數(shù)時(shí),它將用戶釋放的內(nèi)存塊連接到空閑鏈上。到最后,空閑鏈會(huì)被切成很多的小內(nèi)存片段,如果這時(shí)用戶申請(qǐng)一個(gè)大的內(nèi)存片段,那么空閑鏈上可能沒有可以滿足用戶要求的片段了。于是,malloc函數(shù)請(qǐng)求延時(shí),并開始在空閑鏈上翻箱倒柜地檢查各內(nèi)存片段,對(duì)它們進(jìn)行整理,將相鄰的小空閑塊合并成較大的內(nèi)存塊。C語言中的時(shí)間函數(shù)及使用實(shí)例#include<stdio.h> /*NULL#include<time.h> /*ctime,asctime*/main()(time_tnow;/*define'now',lime」isprobablyatypedef*//*Calendertimeisthenumberof*secondssince1/1/1970 */now=time((time_t*)NULL);/*Getthesystemtimeandputitinto'now'as'calendertime'*/printf("%sM,ctime(&now));/*Formatdatain'now'NOTEthat'ctime'insertsa'\n'*//*Hereisanotherwaytoextractthetime/dateinformation*/time(&now);printf("%sn,ctime(&now));/*Formatdatain'now'*/structtm*l_time;l_time=localtime(&now);/*Convert'calendertime'to'localtime'-returnapointertothe'tm'structure,localtimereservesthestoragefbrus.*/printf("%sM,asctime(l_time));}time(&now);printf("%sH,asctime(localtime(&now)));(structtm*l_time;charstring[20];time(&now);l_time=localtime(&now);strftime(string,sizeofstring,"%d-%b-%y\n",l_time);printf("%sn,string);內(nèi)存管理歡迎進(jìn)入內(nèi)存這片雷區(qū)。偉大的BillGates曾經(jīng)失言:640Koughttobeenoughforeverybody一BillGates1981程序員們經(jīng)常編寫內(nèi)存管理程序,往往提心吊膽。如果不想觸雷,唯一的解決辦法就是發(fā)現(xiàn)所有潛伏的地雷并且排除它們,躲是躲不了的。本章的內(nèi)容比一般教科書的要深入得多,讀者需細(xì)心閱讀,做到真正地通曉內(nèi)存管理。1內(nèi)存分配方式內(nèi)存分配方式有三種:(1)從靜態(tài)存儲(chǔ)區(qū)域分配。內(nèi)存在程序編譯的時(shí)候就已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在。例如全局變量,static變量。(2)在棧上創(chuàng)建。在執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變量的存儲(chǔ)單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些存儲(chǔ)單元自動(dòng)被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限。(3)從堆上分配,亦稱動(dòng)態(tài)內(nèi)存分配。程序在運(yùn)行的時(shí)候用malloc或new申請(qǐng)任意多少的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用free或delete釋放內(nèi)存。動(dòng)態(tài)內(nèi)存的生存期由我們決定,使用非常靈活,但問題也最多。2常見的內(nèi)存錯(cuò)誤及其對(duì)策發(fā)生內(nèi)存錯(cuò)誤是件非常麻煩的事情。編譯器不能自動(dòng)發(fā)現(xiàn)這些錯(cuò)誤,通常是在程序運(yùn)行時(shí)オ能捕捉到。而這些錯(cuò)誤大多沒有明顯的癥狀,時(shí)隱時(shí)現(xiàn),增加了改錯(cuò)的難度。有時(shí)用戶怒氣沖沖地把你找來,程序卻沒有發(fā)生任何問題,你一走,錯(cuò)誤又發(fā)作了。常見的內(nèi)存錯(cuò)誤及其對(duì)策如下:u內(nèi)存分配未成功,卻使用了它。編程新手常犯這種錯(cuò)誤,因?yàn)樗麄儧]有意識(shí)到內(nèi)存分配會(huì)不成功。常用解決辦法是,在使用內(nèi)存之前檢查指針是否為NULL。如果指針p是函數(shù)的參數(shù),那么在函數(shù)的入口處用assert(p!=NULL)進(jìn)行檢查。如果是用malloc或new:來申請(qǐng)內(nèi)存,應(yīng)該用if(p==NULL)或if(p!=NULL)進(jìn)行防錯(cuò)處理。u內(nèi)存分配雖然成功,但是尚未初始化就引用它。犯這種錯(cuò)誤主要有兩個(gè)起因:ー是沒有初始化的觀念;二是誤以為內(nèi)存的缺省初值全為零,導(dǎo)致引用初值錯(cuò)誤(例如數(shù)組)。內(nèi)存的缺省初值究竟是什么并沒有統(tǒng)ー的標(biāo)準(zhǔn),盡管有些時(shí)候?yàn)榱阒?我們寧可信其無不可信其有。所以無論用何種方式創(chuàng)建數(shù)組,都別忘了賦初值,即便是賦零值也不可省略,不要嫌麻煩。U內(nèi)存分配成功并且已經(jīng)初始化,但操作越過了內(nèi)存的邊界。例如在使用數(shù)組時(shí)經(jīng)常發(fā)生下標(biāo)“多1M或者“少ビ的操作。特別是在for循環(huán)語句中,循環(huán)次數(shù)很容易搞錯(cuò),導(dǎo)致數(shù)組操作越界。u忘記了釋放內(nèi)存,造成內(nèi)存泄露。含有這種錯(cuò)誤的函數(shù)每被調(diào)用一次就丟失一塊內(nèi)存。剛開始時(shí)系統(tǒng)的內(nèi)存充足,你看不到錯(cuò)誤。終有一次程序突然死掉,系統(tǒng)出現(xiàn)提示:內(nèi)存耗盡。動(dòng)態(tài)內(nèi)存的申請(qǐng)與釋放必須配對(duì),程序中malloc與free的使用次數(shù)一定要相同,否則肯定有錯(cuò)誤(new/delete同理)。u釋放了內(nèi)存卻繼續(xù)使用它。有三種情況:(1)程序中的對(duì)象調(diào)用關(guān)系過于復(fù)雜,實(shí)在難以搞清楚某個(gè)對(duì)象究竟是否已經(jīng)釋放了內(nèi)存,此時(shí)應(yīng)該重新設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu),從根本上解決對(duì)象管理的混亂局面。(2)函數(shù)的return語句寫錯(cuò)了,注意不要返回指向“棧內(nèi)存”的“指針”或者“引用”,因?yàn)樵搩?nèi)存在函數(shù)體結(jié)束時(shí)被自動(dòng)銷毀。(3)使用free或delete釋放了內(nèi)存后,沒有將指針設(shè)置為NULL。導(dǎo)致產(chǎn)生“野指針”。11規(guī)則7-2-1】用malloc或new申請(qǐng)內(nèi)存之后,應(yīng)該立即檢查指針值是否為NULL。防止使用指針值為NULL的內(nèi)存。1【規(guī)則7-2-2】不要忘記為數(shù)組和動(dòng)態(tài)內(nèi)存賦初值。防止將未被初始化的內(nèi)存作為右值使用。1【規(guī)則7-2-3]避免數(shù)組或指針的下標(biāo)越界,特別要當(dāng)心發(fā)生“多1”或者“少1”操作。1【規(guī)則7-2-4】動(dòng)態(tài)內(nèi)存的申請(qǐng)與釋放必須配對(duì),防止內(nèi)存泄漏。1【規(guī)則7-2-5】用free或delete釋放了內(nèi)存之后,立即將指針設(shè)置為NULL,防止產(chǎn)生“野指針”。7.3指針與數(shù)組的對(duì)比C++/C程序中,指針和數(shù)組在不少地方可以相互替換著用,讓人產(chǎn)生一種錯(cuò)覺,以為兩者是等價(jià)的。數(shù)組要么在靜態(tài)存儲(chǔ)區(qū)被創(chuàng)建(如全局?jǐn)?shù)組),要么在棧上被創(chuàng)建。數(shù)組名對(duì)應(yīng)著(而不是指向)ー塊內(nèi)存,其地址與容量在生命期內(nèi)保持不變,只有數(shù)組的內(nèi)容可以改變。指針可以隨時(shí)指向任意類型的內(nèi)存塊,它的特征是“可變”,所以我們常用指針來操作動(dòng)態(tài)內(nèi)存。指針遠(yuǎn)比數(shù)組靈活,但也更危險(xiǎn)。下面以字符串為例比較指針與數(shù)組的特性。示例7-3-1中,字符數(shù)組a的容量是6個(gè)字符,其內(nèi)容為hello、0。a的內(nèi)容可以改變,如a[0]='X'。指針p指向常量字符串“world”(位于靜態(tài)存儲(chǔ)區(qū),內(nèi)容為world、0),常量字符串的內(nèi)容是不可以被修改的。從語法上看,編譯器并不覺得語句p[0]='X’有什么不妥,但是該語句企圖修改常量字符串的內(nèi)容而導(dǎo)致運(yùn)行錯(cuò)誤。chara[]="hello";a[0]='X';cout?a?endl;char*p="world";//注意p指向常量字符串p[0]='X';〃編譯器不能發(fā)現(xiàn)該錯(cuò)誤cout<<p?endl;示例7-3-1修改數(shù)組和指針的內(nèi)容7.3.2內(nèi)容復(fù)制與比較不能對(duì)數(shù)組名進(jìn)行直接復(fù)制與比較。示例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申請(qǐng)ー塊容量為strlen(a)+!個(gè)字符的內(nèi)存,再用strcpy進(jìn)行字符串復(fù)制。同理,語句if(p==a)比較的不是內(nèi)容而是地址,應(yīng)該用庫函數(shù)strcmp來比較。/Z數(shù)組…chara[]="hello”;charb[10];strcpy(b,a);//不能用b=a;

if(strcmp(b,a)0)if(strcmp(b,a)0)//不能用if(b==a)/Z指針…intlen=strlen(a);char*p=(char*)malloc(sizeof(char)*(len+l));strcpy(p,a);//不要用p=a;if(strcmp(p,a)=0)//不要用if(p=a)示例7-3-2數(shù)組和指針的內(nèi)容復(fù)制與比較用運(yùn)算符sizeof可以計(jì)算出數(shù)組的容量(字節(jié)數(shù))。示例7-3-3(a)中,sizeof(a)的值是12(注意別忘了‘、〇’)〇指針p指向a,但是sizeof(p)的值卻是4〇這是因?yàn)閟izeof(p)得到的是ー個(gè)指針變量的字節(jié)數(shù),相當(dāng)于sizeof(char*),而不是p所指的內(nèi)存容量。C++/C語言沒有辦法知道指針?biāo)傅膬?nèi)存容量,除非在申請(qǐng)內(nèi)存時(shí)記住它。注意當(dāng)數(shù)組作為函數(shù)的參數(shù)進(jìn)行傳遞時(shí),該數(shù)組自動(dòng)退化為同類型的指針。示例7-3-3(b)中,不論數(shù)組a的容量是多少,sizeof(a)始終等于sizeof(char*)〇chara[]=helloworld”;char*p=a;cout<<sizeof(a)?endl;//12字節(jié)cout<<sizeof(p)?endl;//4字節(jié)示例7-3-3(a)計(jì)算數(shù)組和指針的內(nèi)存容量voidFunc(chara[100])Icout<<sizeof(a)?endl;//4字節(jié)而不是100字節(jié)示例7-3-3(b)數(shù)組退化為指針4指針參數(shù)是如何傳遞內(nèi)存的?如果函數(shù)的參數(shù)是ー個(gè)指針,不要指望用該指針去申請(qǐng)動(dòng)態(tài)內(nèi)存。示例7-4T中,Test函數(shù)的語句GetMemory(str,200)并沒有使str獲得期望的內(nèi)存,str依舊是NULL,為什么?voidGetMemory(char*p,intnum){p=(char*)malloc(sizeof(char)*num);}voidTest(void){char*str=NULL;GetMemory(str,100);//str仍然為NULLstrcpy(str,"hello");〃運(yùn)行錯(cuò)誤)示例7-4-1試圖用指針參數(shù)申請(qǐng)動(dòng)態(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申請(qǐng)了新的內(nèi)存,只是把ーp所指的內(nèi)存地址改變了,但是p絲毫未變。所以函數(shù)GetMemory并不能輸出任何東西。事實(shí)上,每執(zhí)行ー次GetMemory就會(huì)泄露ー塊內(nèi)存,因?yàn)闆]有用free釋放內(nèi)存。如果非得要用指針參數(shù)去申請(qǐng)內(nèi)存,那么應(yīng)該改用“指向指針的指針”,見示例7-4-2。voidGetMemory2(char**p,intnum)■!*p=(char*)malloc(sizeof(char)*num);voidTest2(void)char*str=NULL;GetMemory2(&str,100);//注意參數(shù)是&str?而不是strstrcpy(str,"hello");cout?str?endl;free(str);)示例7-4-2用指向指針的指針申請(qǐng)動(dòng)態(tài)內(nèi)存由于“指向指針的指針”這個(gè)概念不容易理解,我們可以用函數(shù)返回值來傳遞動(dòng)態(tài)內(nèi)存。這種方法更加簡(jiǎn)單,見示例7-4-3。char*GetMemory3(intnum)Ichar*p=(char*)malloc(sizeof(char)*num);returnp;)voidTest3(void)!char*str=NULL;str=GetMemory3(100);strcpy(str,"hello");cout<<str<<endl;free(str);示例7-4-3用函數(shù)返回值來傳遞動(dòng)態(tài)內(nèi)存用函數(shù)返回值來傳遞動(dòng)態(tài)內(nèi)存這種方法雖然好用,但是常常有人把return語句用錯(cuò)了。這里強(qiáng)調(diào)不要用retum語句返回指向“棧內(nèi)存”的指針,因?yàn)樵搩?nèi)存在函數(shù)結(jié)束時(shí)自動(dòng)消亡,見示例?-4-4〇char*GetString(void)(charp[]="helloworld";returnp;/Z編譯器將提出警告}voidTest4(void)Ichar*str=NULL;str=GetStringO;//str的內(nèi)容是垃圾cout?str<<endl;)示例7-4-4return語句返回指向“棧內(nèi)存”的指針用調(diào)試器逐步跟蹤Test4,發(fā)現(xiàn)執(zhí)行str=GetString語句后str不再是NULL指針,但是str的內(nèi)容不是“helloworld”而是垃圾。如果把示例7-4-4改寫成示例7-4-5,會(huì)怎么樣?char*GetString2(void)(char*p="helloworld";returnp;char*str=NULL;str=GetString2();cout?str?endl;)示例7-4-5return語句返回常量字符串函數(shù)Test5運(yùn)行雖然不會(huì)出錯(cuò),但是函數(shù)GetString2的設(shè)計(jì)概念卻是錯(cuò)誤的。因?yàn)镚etString2內(nèi)的“helloworld”是常量字符串,位于靜態(tài)存儲(chǔ)區(qū),它在程序生命期內(nèi)恒定不變。無論什么時(shí)候調(diào)用GetString2,它返回的始終是同一個(gè)“只讀”的內(nèi)存塊。7.5free和delete把指針怎么啦?7.7杜絕“野指針”“野指針”不是NULL指針,是指向“垃圾”內(nèi)存的指針。人們一般不會(huì)錯(cuò)用NULL指針,因?yàn)橛胕f語句很容易判斷。但是“野指針”是很危險(xiǎn)的,if語句對(duì)它不起作用?!耙爸羔槨钡某梢蛑饕袃煞N:(1)指針變量沒有被初始化。任何指針變量剛被創(chuàng)建時(shí)不會(huì)自動(dòng)成為NULL指針,它的缺省值是隨機(jī)的,它會(huì)亂指ー氣。所以,指針變量在創(chuàng)建的同時(shí)應(yīng)當(dāng)被初始化,要么將指針設(shè)置為NULL,要么讓它指向合法的內(nèi)存。例如char*p=NULL;char*str=(char*)malloc(100);(2)指針p被free或者delete之后,沒有置為NULL,讓人誤以為p是個(gè)合法的指針。參見7.5節(jié)。(3)指針操作超越了變量的作用范圍。這種情況讓人防不勝防,示例程序如下:classA■!public:voidFunc(void){cout?uFuncofclassA"?endl;});voidTest(void)A*p;Aa;p=&a;/Z注意a的生命期p->Func():〃p是“野指針”函數(shù)Test在執(zhí)行語句pー》Func()時(shí),對(duì)象a已經(jīng)消失,而p是指向a的,所以p就成了“野指針”。但奇怪的是我運(yùn)行這個(gè)程序時(shí)居然沒有出錯(cuò),這可能與編譯器有關(guān)。7.8有了malloc/free為什么還要new/delete?malloc與free是C++/C語言的標(biāo)準(zhǔn)庫函數(shù),new/delete是C++的運(yùn)算符。它們都可用于申請(qǐng)動(dòng)態(tài)內(nèi)存和釋放內(nèi)存。對(duì)于非內(nèi)部數(shù)據(jù)類型的對(duì)象而言,光用maloc/free無法滿足動(dòng)態(tài)對(duì)象的要求。對(duì)象在創(chuàng)建的同時(shí)要自動(dòng)執(zhí)行構(gòu)造函數(shù),對(duì)象在消亡之前要自動(dòng)執(zhí)行析構(gòu)函數(shù)。由于malloc/free是庫函數(shù)而不是運(yùn)算符,不在編譯器控制權(quán)限之內(nèi),不能夠把執(zhí)行構(gòu)造函數(shù)和析構(gòu)函數(shù)的任務(wù)強(qiáng)加于malloc/freeo因此C++語言需要一個(gè)能完成動(dòng)態(tài)內(nèi)存分配和初始化工作的運(yùn)算符new,以及ー個(gè)能完成清理與釋放內(nèi)存工作的運(yùn)算符deleteo注意new/delete不是庫函數(shù)。我們先看ー看malloc/free和new/delete如何實(shí)現(xiàn)對(duì)象的動(dòng)態(tài)內(nèi)存管理,見示例7-8。classObjpublic:Obj(void){cout?MInitialization<<endl;}^Obj(void){cout?"Destroy"?endl;}voidInitialize(void){cout<<"Initialization"?endl;}voidUseMallocFree(void)(Obj*a=(obj*)malloc(sizeof(obj));/Z申請(qǐng)動(dòng)態(tài)內(nèi)存a->Initialize();/Z初始化//-a->Destroy();//清除工作free(a);/Z釋放內(nèi)存}voidUseNewDelete(void)(Obj*a=newObj;/Z申請(qǐng)動(dòng)態(tài)內(nèi)存并且初始化//-deletea;/Z清除并且釋放內(nèi)存)示例7-8用malloc/free和new/delete如何實(shí)現(xiàn)對(duì)象的動(dòng)態(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ù),必須調(diào)用成員函數(shù)Initialize和Destroy來完成初始化與清除工作。函數(shù)UseNewDelete則簡(jiǎn)單得多。所以我們不要企圖用malloc/free來完成動(dòng)態(tài)對(duì)象的內(nèi)存管理,應(yīng)該用new/delete。由于內(nèi)部數(shù)據(jù)類型的“對(duì)象”沒有構(gòu)造與析構(gòu)的過程,對(duì)它們而言malloc/free和new/delete是等價(jià)的。既然new/delete的功能完全覆蓋了malloc/free,為什么C++不把malloc/free淘汰出局呢?這是因?yàn)镃++程序經(jīng)常要調(diào)用C函數(shù),而C程序只能用malloc/free管理動(dòng)態(tài)內(nèi)存。如果用free釋放"new創(chuàng)建的動(dòng)態(tài)對(duì)象”,那么該對(duì)象因無法執(zhí)行析構(gòu)函數(shù)而可能導(dǎo)致程序出錯(cuò)。如果用delete釋放"malloc申請(qǐng)的動(dòng)態(tài)內(nèi)存”,理論上講程序不會(huì)出錯(cuò),但是該程序的可讀性很差。所以new/delete必須配對(duì)使用,malloc/free也ー樣。7.9內(nèi)存耗盡怎么辦?如果在申請(qǐng)動(dòng)態(tài)內(nèi)存時(shí)找不到足夠大的內(nèi)存塊,malloc和new將返回NULL指針,宣告內(nèi)存申請(qǐng)失敗。通常有三種方式處理“內(nèi)存耗盡”問題。(1)判斷指針是否為NULL,如果是則馬上用return語句終止本函數(shù)。例如:voidFunc(void)(A*a=newA;if(a=NULL){return;(2)判斷指針是否為NULL,如果是則馬上用exit(1)終止整個(gè)程序的運(yùn)行。例如:voidFunc(void){A*a=newA;if(a=NULL)(cout?"MemoryExhausted"?endl;exit(1);(3)為new和malloc設(shè)置異常處理函數(shù)。例如VisualC++可以用_set_new_hander函數(shù)為new設(shè)置用戶自己定義的異常處理函數(shù),也可以讓malloc享用與new相同的異常處理函數(shù)。詳細(xì)內(nèi)容請(qǐng)參考C++使用手冊(cè)。上述(1)(2)方式使用最普遍。如果ー個(gè)函數(shù)內(nèi)有多處需要申請(qǐng)動(dòng)態(tài)內(nèi)存,那么方式(1)就顯得カ不從心(釋放內(nèi)存很麻煩),應(yīng)該用方式(2)來處理。很多人不忍心用exit(l),問:“不編寫出錯(cuò)處理程序,讓操作系統(tǒng)自己解決行不行?”不行。如果發(fā)生“內(nèi)存耗盡”這樣的事情,一般說來應(yīng)用程序已經(jīng)無藥可救。如果不用exit(l)把壞程序殺死,它可能會(huì)害死操作系統(tǒng)。道理如同:如果不把歹徒擊斃,歹徒在老死之前會(huì)犯下更多的罪。有一個(gè)很重要的現(xiàn)象要告訴大家。對(duì)于32位以上的應(yīng)用程序而言,無論怎樣使用malloc與new,幾乎不可能導(dǎo)致“內(nèi)存耗盡”。我在Windows98下用VisualC++編寫了測(cè)試程序,見示例7-9。這個(gè)程序會(huì)無休止地運(yùn)行下去,根本不會(huì)終止。因?yàn)?2位操作系統(tǒng)支持“虛存”,內(nèi)存用完了,自動(dòng)用硬盤空間頂替。我只聽到硬盤嘎吱嘎吱地響,Window98已經(jīng)累得對(duì)鍵盤、鼠標(biāo)毫無反應(yīng)。我可以得出這么一個(gè)結(jié)論:對(duì)于32位以上的應(yīng)用程序,“內(nèi)存耗盡”錯(cuò)誤處理程序毫無用處。這下可把Unix和Windows程序員們樂壞了:反正錯(cuò)誤處理程序不起作用,我就不寫了,省了很多麻煩。我不想誤導(dǎo)讀者,必須強(qiáng)調(diào):不加錯(cuò)誤處理將導(dǎo)致程序的質(zhì)量很差,千萬不可因小失大。voidmain(void)float*p=NULL;while(TRUE)p=newfloat[1000000];cout?“eatmemoryn?endl;if(p==NULL)exit(1);示例7-9試圖耗盡操作系統(tǒng)的內(nèi)存7.10malloc/free的使用要點(diǎn)函數(shù)malloc的原型如下:void*malloc(size_tsize);用malloc申請(qǐng)ー塊長度為length的整數(shù)類型的內(nèi)存,程序如下:int*p=(int*)malloc(sizeof(int)*length);我們應(yīng)當(dāng)把注意力集中在兩個(gè)要素上:“類型轉(zhuǎn)換”和“sizeof”。umalloc返回值的類型是void*,所以在調(diào)用malloc時(shí)要顯式地進(jìn)行類型轉(zhuǎn)換,將void*轉(zhuǎn)換成所需要的指針類型。umalloc函數(shù)本身并不識(shí)別要申請(qǐng)的內(nèi)存是什么類型,它只關(guān)心內(nèi)存的總字節(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é)。最好用以下程序作一次測(cè)試:cout?sizeof(char)?endl;cout?sizeof(int)?endl;cout?sizeof(unsignedint)?endl;cout?sizeof(long)?endl;cout?sizeof(unsignedlong)<<endl;cout?sizeof(float)<<endl;cout?sizeof(double)<<endl;cout?sizeof(void*)<<endl;在malloc的“()”中使用sizeof運(yùn)算符是良好的風(fēng)格,但要當(dāng)心有時(shí)我們會(huì)昏了頭,寫出p=malloc(sizeof(p))這樣的程序來。u函數(shù)free的原型如下:voidfree(void*memblock);為什么free函數(shù)不象malloc函數(shù)那樣復(fù)雜呢?這是因?yàn)橹羔榩的類型以及它所指的內(nèi)存的容量事先都是知道的,語句free(p)能正確地釋放內(nèi)存。如果p是NULL指針,那么free對(duì)P無論操作多少次都不會(huì)出問題。如果p不是NULL指針,那么free對(duì)p連續(xù)操作兩次就會(huì)導(dǎo)致程序運(yùn)行錯(cuò)誤。7.11new/delete的使用要點(diǎn)運(yùn)算符new使用起來要比函數(shù)malloc簡(jiǎn)單得多,例如:int*pl=(int*)malloc(sizeof(int)*length);int*p2=newint[length];這是因?yàn)閚ew內(nèi)置了sizeof、類型轉(zhuǎn)換和類型安全檢查功能。對(duì)于非內(nèi)部數(shù)據(jù)類型的對(duì)象而言,new在創(chuàng)建動(dòng)態(tài)對(duì)象的同時(shí)完成了初始化工作。如果對(duì)象有多個(gè)構(gòu)造函數(shù),那么new的語句也可以有多種形式。例如classObjIpublic:Obj(void);/Z無參數(shù)的構(gòu)造函數(shù)Obj(intx);/Z帶ー個(gè)參數(shù)的構(gòu)造函數(shù)}voidTest(void)IObj*a=newObj;Obj*b=newObj(l);//初值為1deletea;deleteb;如果用new創(chuàng)建對(duì)象數(shù)組,那么只能使用對(duì)象的無參數(shù)構(gòu)造函數(shù)。例如Obj*objects=newObj[100];/Z創(chuàng)建100個(gè)動(dòng)態(tài)對(duì)象不能寫成Obj*objects=new0bj[100](1);/Z創(chuàng)建100個(gè)動(dòng)態(tài)對(duì)象的同時(shí)賦初值1在用delete釋放對(duì)象數(shù)組時(shí),留意不要丟了符號(hào)‘口’。例如delete[]objects;//正確的用法deleteobjects;/Z錯(cuò)誤的用法后者相當(dāng)于deleteobjects[0]?漏掉了另外99個(gè)對(duì)象。7.12一些心得體會(huì)我認(rèn)識(shí)不少技術(shù)不錯(cuò)的C++/C程序員,很少有人能拍拍胸脯說通曉指針與內(nèi)存管理(包括我自己)。我最初學(xué)習(xí)C語言時(shí)特別怕指針,導(dǎo)致我開發(fā)第一個(gè)應(yīng)用軟件(約1萬行C代碼)時(shí)沒有使用ー個(gè)指針,全用數(shù)組來頂替指針,實(shí)在蠢笨得過分。躲避指針不是辦法,后來我改寫了這個(gè)軟件,代碼量縮小到原先的一半。我的經(jīng)驗(yàn)教訓(xùn)是:(1)越是怕指針,就越要使用指針。不會(huì)正確使用指針,肯定算不上是合格的程序員。(2)必須養(yǎng)成“使用調(diào)試器逐步跟蹤程序”的習(xí)慣,只有這樣才能發(fā)現(xiàn)問題的本質(zhì)。API之網(wǎng)絡(luò)函數(shù)WNetAddConnection創(chuàng)建同一個(gè)網(wǎng)絡(luò)資源的永久性連接WNetAddConnection2創(chuàng)建同一個(gè)網(wǎng)絡(luò)資源的連接WNetAddConnection3創(chuàng)建同一個(gè)網(wǎng)絡(luò)資源的連接WNetCancelConnection結(jié)束ー個(gè)網(wǎng)絡(luò)連接WNetCancelConnection2結(jié)束ー個(gè)網(wǎng)絡(luò)連接WNetCloseEnum結(jié)束一次枚舉操作WNetConnectionDialog啟動(dòng)ー個(gè)標(biāo)準(zhǔn)對(duì)話框,以便建立同網(wǎng)絡(luò)資源的連接WNetDisconnectDialog啟動(dòng)ー個(gè)標(biāo)準(zhǔn)對(duì)話框,以便斷開同網(wǎng)絡(luò)資源的連接WNetEnumResource枚舉網(wǎng)絡(luò)資源WNetGetConnection獲取本地或已連接的一個(gè)資源的網(wǎng)絡(luò)名稱WNetGetLastError獲取網(wǎng)絡(luò)錯(cuò)誤的擴(kuò)展錯(cuò)誤信息WNetGetUniversalName獲取網(wǎng)絡(luò)中一個(gè)文件的遠(yuǎn)程名稱以及/或者UNC(統(tǒng)一命名規(guī)范)名稱WNetGetUser獲取ー個(gè)網(wǎng)絡(luò)資源用以連接的名字WNetOpenEnum啟動(dòng)對(duì)網(wǎng)絡(luò)資源進(jìn)行枚舉的過程API之消息函數(shù)BroadcastSystemMessage將一條系統(tǒng)消息廣播給系統(tǒng)中所有的頂級(jí)窗口GetMessagePos取得消息隊(duì)列中上一條消息處理完畢時(shí)的鼠標(biāo)指針屏幕位置GetMessageTime取得消息隊(duì)列中上一條消息處理完畢時(shí)的時(shí)間PostMessage將一條消息投遞到指定窗口的消息隊(duì)列PostThreadMessage將一條消息投遞給應(yīng)用程序RegisterWindowMessage獲取分配給ー個(gè)字串標(biāo)識(shí)符的消息編號(hào)ReplyMessage答復(fù)ー個(gè)消息SendMessage調(diào)用一個(gè)窗口的窗口函數(shù),將一條消息發(fā)給那個(gè)窗口SendMessageCallback將一條消息發(fā)給窗口SendMessageTimeout向窗口發(fā)送一條消息SendNotifyMessage向窗口發(fā)送一條消息API之文件處理函數(shù)CloseHandle關(guān)閉ー個(gè)內(nèi)核對(duì)象。其中包括文件、文件映射、進(jìn)程、線程、安全和同步對(duì)象等CompareFileTime對(duì)比兩個(gè)文件的時(shí)間CopyFile復(fù)制文件CreateDirectory創(chuàng)建一個(gè)新目錄CreateFile打開和創(chuàng)建文件、管道、郵槽、通信服務(wù)、設(shè)備以及控制臺(tái)CreateFileMapping創(chuàng)建一個(gè)新的文件映射對(duì)象DeleteFile刪除指定文件DeviceloControl對(duì)設(shè)備執(zhí)行指定的操作DosDateTimeToFileTime將DOS日期和時(shí)間值轉(zhuǎn)換成一個(gè)Win32FILETIME值FileTimeToDosDateTime將一個(gè)Win32FILETIME值轉(zhuǎn)換成DOS日期和時(shí)間值FileTimeToLocalFileTime將一個(gè)FILETIME結(jié)構(gòu)轉(zhuǎn)換成本地時(shí)間FileTimeToSystemTime根據(jù)ー個(gè)FILETIME結(jié)構(gòu)的內(nèi)容,裝載ー個(gè)SYSTEMTIME結(jié)構(gòu)FindClose關(guān)閉由FindFirstFile函數(shù)創(chuàng)建的ー個(gè)搜索句柄FindFirstFile根據(jù)文件名查找文件FindNextFile根據(jù)調(diào)用FindFirstFile函數(shù)時(shí)指定的ー個(gè)文件名查找下ー個(gè)文件FlushFileBuffers針對(duì)指定的文件句柄,刷新內(nèi)部文件緩沖區(qū)FlushViewOfFile將寫入文件映射緩沖區(qū)的所有數(shù)據(jù)都刷新到磁盤GetBinaryType判斷文件是否可以執(zhí)行GetCompressedFileSize判斷ー個(gè)壓縮文件在磁盤上實(shí)際占據(jù)的字節(jié)數(shù)GetCurrentDirectory在ー個(gè)緩沖區(qū)中裝載當(dāng)前目錄GetDiskFreeSpace獲取與一個(gè)磁盤的組織有關(guān)的信息,以及了解剩余空間的容量GetDiskFreeSpaceEx獲取與一個(gè)磁盤的組織以及剩余空間容量有關(guān)的信息GetDriveType判斷一個(gè)磁盤驅(qū)動(dòng)器的類型GetExpandedName取得一個(gè)壓縮文件的全名GetFileAttributes判斷指定文件的屬性GetFilelnformationByHandle這個(gè)函數(shù)提供了獲取文件信息的ー種機(jī)制GetFileSize判斷文件長度GetFileTime取得指定文件的時(shí)間信息GetFileType在給出文件句柄的前提下,判斷文件類型GetFileVersionlnfo從支持版本標(biāo)記的ー個(gè)模塊里獲取文件版本信息GetFileVersionlnfoSize針對(duì)包含了版本資源的ー個(gè)文件,判斷容納文件版本信息需要一個(gè)多大的緩沖區(qū)GetFullPathName獲取指定文件的完整路徑名GetLogicalDrives判斷系統(tǒng)中存在哪些邏輯驅(qū)動(dòng)器字母GetLogicalDriveStrings獲取ー個(gè)字串,其中包含了當(dāng)前所有邏輯驅(qū)動(dòng)器的根驅(qū)動(dòng)器路徑GetOverlappedResult判斷ー個(gè)重疊操作當(dāng)前的狀態(tài)GetPrivateProfilelnt為初始化文件(.ini文件)中指定的條目獲取ー個(gè)整數(shù)值GetPrivateProfileSection獲取指定小節(jié)(在.ini文件中)所有項(xiàng)名和值的ー個(gè)列表GetPrivateProfileString為初始化文件中指定的條目取得字串GetProfilelnt取得win.ini初始化文件中指定條目的一個(gè)整數(shù)值GetProfileSection獲取指定小節(jié)(在win.ini文件中)所有項(xiàng)名和值的ー個(gè)列表GetProfileString為win.ini初始化文件中指定的條目取得字串GetShortPathName獲取指定文件的短路徑名GetSystemDirectory取得Windows系統(tǒng)目錄(即System目錄)的完整路徑名GetTempFileName這個(gè)函數(shù)包含了一個(gè)臨時(shí)文件的名字,它可由應(yīng)用程序使用GetTempPath獲取為臨時(shí)文件指定的路徑GetVolumelnformation獲取與一個(gè)磁盤卷有關(guān)的信息GetWindowsDirectory獲取Windows目錄的完整路徑名hread參考Ireadhwrite參考Iwrite函數(shù)Iclose關(guān)閉指定的文件Icreat創(chuàng)建一個(gè)文件Ilseek設(shè)置文件中進(jìn)行讀寫的當(dāng)前位置LockFile鎖定文件的某一部分,使其不與其他應(yīng)用程序共享LockFileEx與LockFile相似,只是它提供了更多的功能lopen以二進(jìn)制模式打開指定的文件Iread將文件中的數(shù)據(jù)讀入內(nèi)存緩沖區(qū)Iwrite將數(shù)據(jù)從內(nèi)存緩沖區(qū)寫入一個(gè)文件LZCIose關(guān)閉由LZOpenFile或LZInit函數(shù)打開的ー個(gè)文件LZCopy復(fù)制ー個(gè)文件LZInit這個(gè)函數(shù)用于初始化內(nèi)部緩沖區(qū)LZOpenFile該函數(shù)能執(zhí)行大量不同的文件處理,而且兼容于壓縮文件LZRead將數(shù)據(jù)從文件讀入內(nèi)存緩沖區(qū)LZSeek設(shè)置ー個(gè)文件中進(jìn)行讀寫的當(dāng)前位置MapViewOfFile將一個(gè)文件映射對(duì)象映射到當(dāng)前應(yīng)用程序的地址空間MoveFile移動(dòng)文件OpenFile這個(gè)函數(shù)能執(zhí)行大量不同的文件操作OpenFileMapping打開ー個(gè)現(xiàn)成的文件映射對(duì)象QueryDosDevice在WindowsNT中,DOS設(shè)備名會(huì)映射成NT系統(tǒng)設(shè)備名。該函數(shù)可判斷當(dāng)前的設(shè)備映射情況ReadFile從文件中讀出數(shù)據(jù)ReadFileEx與ReadFile相似,只是它只能用于異步讀操作,并包含了一個(gè)完整的回調(diào)RegCloseKey關(guān)閉系統(tǒng)注冊(cè)表中的ー個(gè)項(xiàng)(或鍵)RegConnectRegistry訪問遠(yuǎn)程系統(tǒng)的部分注冊(cè)表RegCreateKey在指定的項(xiàng)下創(chuàng)建或打開ー個(gè)項(xiàng)RegCreateKeyEx在指定項(xiàng)下創(chuàng)建新項(xiàng)的更復(fù)雜的方式。在Win32環(huán)境中建議使用這個(gè)函數(shù)RegDeleteKey刪除現(xiàn)有項(xiàng)下方ー個(gè)指定的子項(xiàng)RegDeleteValue刪除指定項(xiàng)下方的ー個(gè)值RegEnumKey枚舉指定項(xiàng)的子項(xiàng)。在Win32環(huán)境中應(yīng)使用RegEnumKeyExRegEnumKeyEx枚舉指定項(xiàng)下方的子項(xiàng)RegEnumValue枚舉指定項(xiàng)的值RegFlushKey將對(duì)項(xiàng)和它的子項(xiàng)作出的改動(dòng)實(shí)際寫入磁盤RegGetKeySecurity獲取與一個(gè)注冊(cè)表項(xiàng)有關(guān)的安全信息RegLoadKey從以前用RegSaveKey函數(shù)創(chuàng)建的ー個(gè)文件里裝載注冊(cè)表信息RegNotifyChangeKeyValue注冊(cè)表項(xiàng)或它的任何ー個(gè)子項(xiàng)發(fā)生變化時(shí),用這個(gè)函數(shù)提供ー種通知機(jī)制RegOpenKey打開ー個(gè)現(xiàn)有的注冊(cè)表項(xiàng)RegOpenKeyEx打開一個(gè)現(xiàn)有的項(xiàng)。在Win32下推薦使用這個(gè)函數(shù)RegQuerylnfoKey獲取與一個(gè)項(xiàng)有關(guān)的信息RegQueryValue取得指定項(xiàng)或子項(xiàng)的默認(rèn)(未命名)值RegQueryValueEx獲取ー個(gè)項(xiàng)的設(shè)置值RegReplaceKey用ー個(gè)磁盤文件保存的信息替換注冊(cè)表信息;并創(chuàng)建一個(gè)備份,在其中包含當(dāng)前注冊(cè)表信息RegRestoreKey從ー個(gè)磁盤文件恢復(fù)注冊(cè)表信息RegSaveKey將一個(gè)項(xiàng)以及它的所有子項(xiàng)都保存到ー個(gè)磁盤文件RegSetKeySecurity設(shè)置指定項(xiàng)的安全特性RegSetValue設(shè)置指定項(xiàng)或子項(xiàng)的默認(rèn)值RegSetValueEx設(shè)置指定項(xiàng)的值RegllnLoadKey卸載指定的項(xiàng)以及它的所有子項(xiàng)RemoveDirectory刪除指定目錄SearchPath查找指定文件SetCurrentDirectory設(shè)置當(dāng)前目錄SetEndOfFile針對(duì)一個(gè)打開的文件,將當(dāng)前文件位置設(shè)為文件末尾SetFileAttributes設(shè)置文件屬性SetFilePointer在一個(gè)文件中設(shè)置當(dāng)前的讀寫位置SetFileTime設(shè)置文件的創(chuàng)建、訪問及上次修改時(shí)間SetHandleCount這個(gè)函數(shù)不必在Win32下使用:即使使用,也不會(huì)有任何效果SetVolumeLabe!設(shè)置ー個(gè)磁盤的卷標(biāo)(Label)SystemTimeToFileTime根據(jù)ー個(gè)FILETIME結(jié)構(gòu)的內(nèi)容,載入ー個(gè)SYSTEMTIME結(jié)構(gòu)UnlockFile解除對(duì)ー個(gè)文件的鎖定UnlockFileEx解除對(duì)ー個(gè)文件的鎖定UnmapViewOfFile在當(dāng)前應(yīng)用程序的內(nèi)存地址空間解除對(duì)ー個(gè)文件映射對(duì)象的映射VerFindFile用這個(gè)函數(shù)決定一個(gè)文件應(yīng)安裝到哪里VerlnstallFile用這個(gè)函數(shù)安裝ー個(gè)文件VerLanguageName這個(gè)函數(shù)能根據(jù)16位語言代碼獲取ー種語言的名稱VerQueryValue這個(gè)函數(shù)用于從版本資源中獲取信息WriteFile將數(shù)據(jù)寫入ー個(gè)文件WHteFileEx與WHteFile類似,只是它只能用于異步寫操作,并包括了一個(gè)完整的回調(diào)WritePrivateProfileSection為ー個(gè)初始化文件(.ini)中指定的小節(jié)設(shè)置所有項(xiàng)名和值WritePrivateProfileString在初始化文件指定小節(jié)內(nèi)設(shè)置ー個(gè)字串WriteProfileSection為Win.ini初始化文件中?ー個(gè)指定的小節(jié)設(shè)置所有項(xiàng)名和值WriteProfileString在Win.ini初始化文件指定小節(jié)內(nèi)設(shè)置ー個(gè)字串API之打印函數(shù)AbortDoc取消一份文檔的打印AbortPrinter刪除與一臺(tái)打印機(jī)關(guān)聯(lián)在一起的緩沖文件AddForm為打印機(jī)的表單列表添加一個(gè)新表單AddJob用于獲取ー個(gè)有效的路徑名,以便用它為作業(yè)創(chuàng)建一個(gè)后臺(tái)打印文件。它也會(huì)為作業(yè)分配ー個(gè)作業(yè)編號(hào)AddMonitor為系統(tǒng)添加一個(gè)打印機(jī)監(jiān)視器AddPort啟動(dòng)“添加端口”對(duì)話框,允許用戶在系統(tǒng)可用端口列表中加入一個(gè)新端口AddPrinter在系統(tǒng)中添加一臺(tái)新打印機(jī)AddPrinterConnection連接指定的打印機(jī)AddPrinterDriver為指定的系統(tǒng)添加一個(gè)打印驅(qū)動(dòng)程序AddPrintProcessor為指定的系統(tǒng)添加一個(gè)打印處理器AddPrintProvidor為系統(tǒng)添加一個(gè)打印供應(yīng)商AdvancedDocumentproperties啟動(dòng)打印機(jī)文檔設(shè)置對(duì)話框ClosePrinter關(guān)閉ー個(gè)打開的打印機(jī)對(duì)象ConfigurePort針對(duì)指定的端口,啟動(dòng)ー個(gè)端口配置對(duì)話框ConnectToPrinterDIg啟動(dòng)連接打印機(jī)對(duì)話框,用它同訪問網(wǎng)絡(luò)的打印機(jī)連接DeleteForm從打印機(jī)可用表單列表中刪除ー個(gè)表單DeleteMonitor刪除指定的打印監(jiān)視器DeletePort啟動(dòng)“刪除端口”對(duì)話框,允許用戶從當(dāng)前系統(tǒng)刪除ー個(gè)端口DeletePrinter將指定的打印機(jī)標(biāo)志為從系統(tǒng)中刪除DeletePrinterConnection刪除與指定打印機(jī)的連接DeletePrinterDriver從系統(tǒng)刪除ー個(gè)打印機(jī)驅(qū)動(dòng)程序DeletePrintProcessor從指定系統(tǒng)刪除ー個(gè)打印處理器DeletePrintProvidor從系統(tǒng)中刪除ー個(gè)打印供應(yīng)商Devicecapabilities利用這個(gè)函數(shù)可獲得與一個(gè)設(shè)備的能力有關(guān)的信息Documentproperties打印機(jī)配置控制函數(shù)EndDocAP!結(jié)束ー個(gè)成功的打印作業(yè)EndDocPrinter在后臺(tái)打印程序的級(jí)別指定一個(gè)文檔的結(jié)束EndPage用這個(gè)函數(shù)完成一個(gè)頁面的打印,并準(zhǔn)備設(shè)備場(chǎng)景,以便打印下ー個(gè)頁EndPagePrinter指定一個(gè)頁在打印作業(yè)中的結(jié)尾EnumForms枚舉一臺(tái)打印機(jī)可用的表單EnumJobs枚舉打印隊(duì)列中的作業(yè)EnumMonitors枚舉可用的打印監(jiān)視器EnumPorts枚舉ー個(gè)系統(tǒng)可用的端口EnumPrinterDrivers枚舉指定系統(tǒng)中已安裝的打印機(jī)驅(qū)動(dòng)程序EnumPrinters枚舉系統(tǒng)中安裝的打印機(jī)EnumPrintProcessorDatatypes枚舉由一個(gè)打印處理器支持的數(shù)據(jù)類型EnumPrintProcessors枚舉系統(tǒng)中可用的打印處理器Escape設(shè)備控制函數(shù)FindClosePrinterChangeNotification關(guān)閉用FindFirstPrinterChangeNotification函數(shù)獲取的ー個(gè)打印機(jī)通告對(duì)象FindFirstPrinterChangeNotification創(chuàng)建一個(gè)新的改變通告對(duì)象,以便我們注意打印機(jī)狀態(tài)的各種變化FindNextPrinterChangeNotification用這個(gè)函數(shù)判斷觸發(fā)一次打印機(jī)改變通告信號(hào)的原因FreePrinterNotifylnfo釋放由FindNextPrinterChangeNotification函數(shù)分配的一個(gè)緩沖區(qū)GetForm取得與指定表單有關(guān)的信息GetJob獲取與指定作業(yè)有關(guān)的信息GetPrinter取得與指定打印機(jī)有關(guān)的信息GetPrinterData為打印機(jī)設(shè)置注冊(cè)表配置信息GetPrinterDriver針對(duì)指定的打印機(jī),獲取與打印機(jī)驅(qū)動(dòng)程序有關(guān)的信息GetPrinterDriverDirectory判斷指定系統(tǒng)中包含了打印機(jī)驅(qū)動(dòng)程序的目錄是什么GetPrintProcessorDirectory判斷指定系統(tǒng)中包含了打印機(jī)處理器驅(qū)動(dòng)程序及文件的目錄OpenPrinter打開指定的打印機(jī),并獲取打印機(jī)的句柄PrinterMessageBox在擁有指定打印作業(yè)的系統(tǒng)上顯示ー個(gè)打印機(jī)出錯(cuò)消息框Printerproperties啟動(dòng)打印機(jī)屬性對(duì)話框,以便對(duì)打印機(jī)進(jìn)行配置ReadPrinter從打印機(jī)讀入數(shù)據(jù)ResetDC重設(shè)ー個(gè)設(shè)備場(chǎng)景ResetPrinter改變指定打印機(jī)的默認(rèn)數(shù)據(jù)類型及文檔設(shè)置Schedulejob提交一個(gè)要打印的作業(yè)SetAbortProc為Windows指定取消函數(shù)的地址SetForm為指定的表單設(shè)置信息SetJob對(duì)ー個(gè)打印作業(yè)的狀態(tài)進(jìn)行控制SetPrinter對(duì)一臺(tái)打印機(jī)的狀態(tài)進(jìn)行控制SetPrinterData設(shè)置打印機(jī)的注冊(cè)表配置信息StartDoc開始ー個(gè)打印作業(yè)StartDocPrinter在后臺(tái)打印的級(jí)別啟動(dòng)ー個(gè)新文檔StartPage打印ー個(gè)新頁前要先調(diào)用這個(gè)函數(shù)StartPagePrinter在打印作業(yè)中指定一個(gè)新頁的開始WritePrinter將發(fā)送目錄中的數(shù)據(jù)寫入打印機(jī)API之文本和字體函數(shù)AddFontResource在Windows系統(tǒng)中添加一ー種字體資源CreateFont用指定的屬性創(chuàng)建一種邏輯字體CreateFontlndirect用指定的屬性創(chuàng)建一種邏輯字體CreateScalableFontResource為ー種TureType字體創(chuàng)建一個(gè)資源文件,以便能用API函數(shù)AddFontResource將其加入Windows系統(tǒng)DrawText將文本描繪到指定的矩形中DrawTextEx與DrawText相似,只是加入了更多的功能EnumFontFamilies列舉指定設(shè)備可用的字體EnumFontFamiliesEx列舉指定設(shè)備可用的字體EnumFonts列舉指定設(shè)備可用的字體ExtTextOut經(jīng)過擴(kuò)展的文本描繪函數(shù)。也請(qǐng)參考SetTextAlign函數(shù)GetAspectRatioFilterEx用SetMapperFlags要求Windows只選擇與設(shè)備當(dāng)前縱橫比相符的光柵字體時(shí),本函數(shù)可判斷縱橫比大小GetCharABCWidths判斷TureType字體中一個(gè)或多個(gè)字符的A-B-C大小GetCharABCWidthsFloat查詢ー種字體中一個(gè)或多個(gè)字符的A-B-C尺寸GetCharacterPlacement該函數(shù)用于了解如何用ー個(gè)給定的字符顯示ー個(gè)字串GetCharWidth調(diào)查字體中一個(gè)或多個(gè)字符的寬度GetFontData接收一種可縮放字體文件的數(shù)據(jù)GetFontLanguagelnfo返回目前選入指定設(shè)備場(chǎng)景中的字體的信息GetGlyphOutline取得TureType字體中構(gòu)成一個(gè)字符的曲線信息GetKerningPairs取得指定字體的字距信息GetOutlineTextMetrics接收與TureType字體內(nèi)部特征有關(guān)的詳細(xì)信息GetRasterizerCaps了解系統(tǒng)是否有能力支持可縮放的字體GetTabbedTextExtent判斷ー個(gè)字串占據(jù)的范圍,同時(shí)考慮制表站擴(kuò)充的因素GetTextAlign接收ー個(gè)設(shè)備場(chǎng)景當(dāng)前的文本對(duì)齊標(biāo)志GetTextCharacterExtra判斷額外字符間距的當(dāng)前值GetTextCharset接收當(dāng)前選入指定設(shè)備場(chǎng)景的字體的字符集標(biāo)識(shí)符GetTextCharsetlnfo獲取與當(dāng)前選定字體的字符集有關(guān)的詳細(xì)信息GetTextColor判斷當(dāng)前字體顏色。通常也稱為“前景色”GetTextExtentExPoint判斷要填入指定區(qū)域的字符數(shù)量。也用一個(gè)數(shù)組裝載每個(gè)字符的范圍信息GetTextExtentPoint判斷ー個(gè)字串的大?。ǚ秶〨etTextFace獲取ーー種字體的字樣名GetTextMetrics獲取與選入一種設(shè)備場(chǎng)景的物理字體有關(guān)的信息GrayString描繪ー個(gè)以灰色顯示的字串。通常由Windows用于標(biāo)識(shí)禁止?fàn)顟B(tài)PolyTextOut描繪ー系列字串RemoveFontResource從Windows系統(tǒng)中刪除?種字體資源SetMapperFlagsWindows對(duì)字體進(jìn)行映射時(shí),可用該函數(shù)選擇與目標(biāo)設(shè)備的縱橫比相符的光柵字體SetTextAlign設(shè)置文本對(duì)齊方式,并指定在文本輸出過程中使用設(shè)備場(chǎng)景的當(dāng)前位置SetTextCharacterExtra描繪文本的時(shí)候,指定要在字符間插入的額外間距SetTextColor設(shè)置當(dāng)前文本顏色。這種顏色也稱為“前景色”SetTextJustification通過指定一個(gè)文本行應(yīng)占據(jù)的額外空間,可用這個(gè)函數(shù)對(duì)文本進(jìn)行兩端對(duì)齊處理TabbedTextOut支持制表站的一個(gè)文本描繪函數(shù)TextOut文本繪圖函數(shù)API之菜單函數(shù)AppendMenu在指定的菜單里添加一個(gè)菜單項(xiàng)CheckMenultem復(fù)選或撤消復(fù)選指定的菜單條目CheckMenuRadioltem指定一個(gè)菜單條目被復(fù)選成“單選”項(xiàng)目CreateMenu創(chuàng)建新菜單CreatePopupMenu創(chuàng)建一個(gè)空的彈出式菜單DeleteMenu刪除指定的菜單條目DestroyMenu刪除指定的菜單DrawMenuBar為指定的窗口重畫菜單EnableMenultem允許或禁止指定的菜單條目GetMenu取得窗口中一個(gè)菜單的句柄GetMenuCheckMarkDimensions返回一個(gè)菜單復(fù)選符的大小GetMenuContextHelpId取得一個(gè)菜單的幫助場(chǎng)景IDGetMenuDefaultltem判斷菜單中的哪個(gè)條目是默認(rèn)條目GetMenultemCount返回菜單中條目(菜單項(xiàng))的數(shù)量GetMenultemID返回位于菜單中指定位置處的條目的菜單IDGetMenultemlnfo取得(接收)與一個(gè)菜單條目有關(guān)的特定信息GetMenuItemRect在ー個(gè)矩形中裝載指定菜單條目的屏幕坐標(biāo)信息GetMenuState取得與指定菜單條目狀態(tài)有關(guān)的信息GetMenuString取得指定菜單條目的字串GetSubMenu取得一個(gè)彈出式菜單的句柄,它位于菜單中指定的位置GetSystemMenu取得指定窗口的系統(tǒng)菜單的句柄HiliteMenultem控制頂級(jí)菜單條目的加亮顯示狀態(tài)InsertMenu在菜單的指定位置處插入一個(gè)菜單條目,并根據(jù)需要將其他條目向下移動(dòng)InsertMenultem插入一個(gè)新菜單條目IsMenu判斷指定的句柄是否為一個(gè)菜單的句柄LoadMenu從指定的模塊或應(yīng)用程序?qū)嵗休d入一個(gè)菜單LoadMenulndirect載入一個(gè)菜單MenultemFromPoint判斷哪個(gè)菜單條目包含了屏幕上一個(gè)指定的點(diǎn)ModifyMenu改變菜單條目RemoveMenu刪除指定的菜單條目SetMenu設(shè)置窗口菜單SetMenuContextHelpId設(shè)置ー個(gè)菜單的幫助場(chǎng)景IDSetMenuDefaultitem將一個(gè)菜單條目設(shè)為默認(rèn)條目SetMenultemBitmaps設(shè)置一幅特定位圖,令其在指定的菜單條目中使用,代替標(biāo)準(zhǔn)的復(fù)選符號(hào)(4)SetMenultemlnfo為ー個(gè)菜單條目設(shè)置指定的信息TrackPopupMenu在屏幕的任意地方顯示ー個(gè)彈出式菜單TrackPopupMenuEx與TrackPopupMenu相似,只是它提供了額外的功能API之位圖、圖標(biāo)和光柵運(yùn)算函數(shù)BitBIt將一幅位圖從ー個(gè)設(shè)備場(chǎng)景復(fù)制到另ー個(gè)Copyicon制作指定圖標(biāo)或鼠標(biāo)指針的一個(gè)副本。這個(gè)副本從屬于發(fā)出調(diào)用的應(yīng)用程序Copyimage復(fù)制位圖、圖標(biāo)或指針,同時(shí)在復(fù)制過程中進(jìn)行一些轉(zhuǎn)換工作CreateBitmap按照規(guī)定的格式創(chuàng)建一幅與設(shè)備有關(guān)位圖CreateBitmapIndirect創(chuàng)建一幅與設(shè)備有關(guān)位圖CreateCompatibleBitmap創(chuàng)建一幅與設(shè)備有關(guān)位圖,它與指定的設(shè)備場(chǎng)景兼容CreateCursor創(chuàng)建一個(gè)鼠標(biāo)指針CreateDIBitmap根據(jù)一幅與設(shè)備無關(guān)的位圖創(chuàng)建一幅與設(shè)備有關(guān)的位圖CreateDIBSection創(chuàng)建一個(gè)DIBSectionCreatelcon創(chuàng)建一個(gè)圖標(biāo)Createlconlndirect創(chuàng)建一個(gè)圖標(biāo)DestroyCursor清除指定的鼠標(biāo)指針,并釋放它占用的所有系統(tǒng)資源Destroylcon清除圖標(biāo)Drawicon在指定的位置畫一個(gè)圖標(biāo)DrawIconEx描繪ー個(gè)圖標(biāo)或鼠標(biāo)指針。與Drawicon相比,這個(gè)函數(shù)提供了更多的功能ExtractAssociatedIcon判斷ー個(gè)可執(zhí)行程序或DLL中是否存在圖標(biāo),或是否有"圖標(biāo)與系統(tǒng)注冊(cè)表中指定的文件存在關(guān)聯(lián)并提取之Extracticon判斷ー個(gè)可執(zhí)行文件或DLL中是否有圖標(biāo)存在,并將其提取出來GetBitmapBits將來自位圖的二進(jìn)制位復(fù)制到ー個(gè)緩沖區(qū)GetBitmapDimensionEx取得一幅位圖的寬度和高度GetDIBColorTable從選入設(shè)備場(chǎng)景的D舊Section中取得顏色表信息GetDIBits將來自一幅位圖的二進(jìn)制位復(fù)制到一幅與設(shè)備無關(guān)的位圖里Getlconlnfo取得與圖標(biāo)有關(guān)的信息GetStretchBItMode判斷StretchBIt和StretchDIBお函數(shù)采用的伸縮模式LoadBitmap從指定的模塊或應(yīng)用程序?qū)嵗休d入一幅位圖LoadCursor從指定的模塊或應(yīng)用程序?qū)嵗休d入一個(gè)鼠標(biāo)指針LoadCursorFromFile在ー個(gè)指針文件或一個(gè)動(dòng)畫指針文件的基礎(chǔ)上創(chuàng)建一個(gè)指針Loadicon從指定的模塊或應(yīng)用程序?qū)嵗休d入ー個(gè)圖標(biāo)LoadImage載入一個(gè)位圖、圖標(biāo)或指針MaskBIt執(zhí)行復(fù)雜的圖象傳輸,同時(shí)進(jìn)行掩模(MASK)處理PatBIt在當(dāng)前選定的刷子的基礎(chǔ)上,用ー個(gè)圖案填充指定的設(shè)備場(chǎng)景PlgBIt復(fù)制一幅位圖,同時(shí)將其轉(zhuǎn)換成一個(gè)平行四邊形。利用它可對(duì)位圖進(jìn)行旋轉(zhuǎn)處理SetBitmapBits將來自緩沖區(qū)的二進(jìn)制位復(fù)制到一幅位圖SetBitmapDimensionEx設(shè)置一幅位圖的寬度。以一毫米的十分之一為單位SetDIBColorTable設(shè)置選入設(shè)備場(chǎng)景的ー個(gè)D舊Section的顏色表信息SetDIBits將來自與設(shè)備無關(guān)位圖的二進(jìn)制位復(fù)制到一幅與設(shè)備有關(guān)的位圖里SetDIBitsToDevice將一幅與設(shè)備無關(guān)位圖的全部或部分?jǐn)?shù)據(jù)直接復(fù)制到ー個(gè)設(shè)備SetStretchBItMode指定StretchBIt和StretchDIB讓s函數(shù)的伸縮模式StretchBIt將一幅位圖從ー個(gè)設(shè)備場(chǎng)景復(fù)制到另ー個(gè)StretchDIBits將一幅與設(shè)備無關(guān)位圖的全部或部分?jǐn)?shù)據(jù)直接復(fù)制到指定的設(shè)備場(chǎng)景API之繪圖函數(shù)AbortPath拋棄選入指定設(shè)備場(chǎng)景中的所有路徑。也取消目前正在進(jìn)行的任何路徑的創(chuàng)建エ作AngleArc用ー個(gè)連接弧畫一條線Arc畫一個(gè)圓弧BeginPath啟動(dòng)一個(gè)路徑分支CancelDC取消另一個(gè)線程里的長時(shí)間繪圖操作Chord畫一個(gè)弦CloseEnhMetaFile關(guān)閉指定的增強(qiáng)型圖元文件設(shè)備場(chǎng)景,并將新建的圖元文件返回一個(gè)句柄CloseFigure描繪到ー個(gè)路徑時(shí),關(guān)閉當(dāng)前打開的圖形CloseMetaFile關(guān)閉指定的圖元文件設(shè)備場(chǎng)景,并向新建的圖元文件返回一個(gè)句柄CopyEnhMetaFile制作指定增強(qiáng)型圖元文件的ー個(gè)副本(拷貝)CopyMetaFile制作指定(標(biāo)準(zhǔn))圖元文件的ー個(gè)副本CreateBrushlndirect在ー個(gè)LOGBRUSH數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ)上創(chuàng)建一個(gè)刷子CreateDIBPatternBrush用一幅與設(shè)備無關(guān)的位圖創(chuàng)建一個(gè)刷子,以便指定刷子樣式(圖案)CreateEnhMetaFile創(chuàng)建一個(gè)增強(qiáng)型的圖元文件設(shè)備場(chǎng)景CreateHatchBrush創(chuàng)建帶有陰影圖案的ー個(gè)刷子CreateMetaFile創(chuàng)建一個(gè)圖元文件設(shè)備場(chǎng)景CreatePatternBrush用指定了刷子圖案的一幅位圖創(chuàng)建一個(gè)刷子CreatePen用指定的樣式、寬度和顏色創(chuàng)建一個(gè)畫筆CreatePenlndirect根據(jù)指定的LOGPEN結(jié)構(gòu)創(chuàng)建一個(gè)畫筆CreateSolidBrush用純色創(chuàng)建一個(gè)刷子DeleteEnhMetaFile刪除指定的增強(qiáng)型圖元文件DeleteMetaFile刪除指定的圖元文件DeleteObject刪除GDI對(duì)象,對(duì)象使用的所有系統(tǒng)資源都會(huì)被釋放DrawEdge用指定的樣式描繪ー個(gè)矩形的邊框DrawEscape換碼(Escape)函數(shù)將數(shù)據(jù)直接發(fā)至顯示設(shè)備驅(qū)動(dòng)程序DrawFocusRect畫一個(gè)焦點(diǎn)矩形DrawFrameContro!描繪ー個(gè)標(biāo)準(zhǔn)控件DrawState為一幅圖象或繪圖操作應(yīng)用各式各樣的效果Ellipse描繪ー個(gè)橢圓,由指定的矩形圍繞EndPath停止定義一個(gè)路徑EnumEnhMetaFile針對(duì)ー個(gè)增強(qiáng)型圖元文件,列舉其中單獨(dú)的圖元文件記錄EnumMetaFile為ー個(gè)標(biāo)準(zhǔn)的windows圖元文件枚舉單獨(dú)的圖元文件記錄EnumObjects枚舉可隨同指定設(shè)備場(chǎng)景使用的畫筆和刷子ExtCreatePen創(chuàng)建一個(gè)擴(kuò)展畫筆(裝飾或幾何)ExtFloodFil!在指定的設(shè)備場(chǎng)景里,用當(dāng)前選擇的刷子填充一個(gè)區(qū)域FillPath關(guān)閉路徑中任何打開的圖形,并用當(dāng)前刷子填充FillRect用指定的刷子填充一個(gè)矩形FlattenPath將一個(gè)路徑中的所有曲線都轉(zhuǎn)換成線段FloodFill用當(dāng)前選定的刷子在指定的設(shè)備場(chǎng)景中填充一個(gè)區(qū)域FrameRect用指定的刷子圍繞ー個(gè)矩形畫一個(gè)邊框GdiComment為指定的增強(qiáng)型圖元文件設(shè)備場(chǎng)景添加一條注釋信息GdiFlush執(zhí)行任何未決的繪圖操作GdiGetBatchLimit判斷有多少個(gè)GDI繪圖命令位于隊(duì)列中GdiSetBatchLimit指定有多少個(gè)GD!繪圖命令能夠進(jìn)入隊(duì)列GetArcDirection畫圓弧的時(shí)候,判斷當(dāng)前采用的繪圖方向GetBkColor取得指定設(shè)備場(chǎng)景當(dāng)前的背景顏色GetBkMode針對(duì)指定的設(shè)備場(chǎng)景,取得當(dāng)前的背景填充模式GetBrushOrgEx判斷指定設(shè)備場(chǎng)景中當(dāng)前選定刷子起點(diǎn)GetCurrentObject獲得指定類型的當(dāng)前選定對(duì)象GetCurrentPositionEx在指定的設(shè)備場(chǎng)景中取得當(dāng)前的畫筆位置GetEnhMetaFile取得磁盤文件中包含的一個(gè)增強(qiáng)型圖元文件的圖元文件句柄GetEnhMetaFileBits將指定的增強(qiáng)型圖元文件復(fù)制到ー個(gè)內(nèi)存緩沖區(qū)里GetEnhMetaFileDescription返回對(duì)ー個(gè)增強(qiáng)型圖元文件的說明GetEnhMetaFileHeader取得增強(qiáng)型圖元文件的圖元文件頭GetEnhMetaFilePaletteEntries取得增強(qiáng)型圖元文件的全部或部分調(diào)色板GetMetaFile取得包含在ー個(gè)磁盤文件中的圖元文件的圖元文件句柄GetMetaFileBitsEx將指定的圖元文件復(fù)制到ー個(gè)內(nèi)存緩沖區(qū)GetMiterLimit取得設(shè)備場(chǎng)景的斜率限制(Miter)設(shè)置GetNearestColor根據(jù)設(shè)備的顯示能力,取得與指定顏色最接近的ー種純色GetObjectAPI取得對(duì)指定對(duì)象進(jìn)行說明的ー個(gè)結(jié)構(gòu)GetObjectType判斷由指定句柄引用的GD!對(duì)象的類型GetPath取得對(duì)當(dāng)前路徑進(jìn)行定義的一系列數(shù)據(jù)GetPixe!在指定的設(shè)備場(chǎng)景中取得一個(gè)像素的RGB值GetPolyFillMode針對(duì)指定的設(shè)備場(chǎng)景,獲得多邊形填充模式GetROP2針對(duì)指定的設(shè)備場(chǎng)景,取得當(dāng)前的繪圖模式GetStockObject取得一個(gè)固有對(duì)象(Stock)GetSysColorBrush為任何ー種標(biāo)準(zhǔn)系統(tǒng)顏色取得一個(gè)刷子GetWinMetaFileBits通過在ー個(gè)緩沖區(qū)中填充用于標(biāo)準(zhǔn)圖元文件的數(shù)據(jù),將一個(gè)增強(qiáng)型圖元文件轉(zhuǎn)換成標(biāo)準(zhǔn)windows圖元文件InvertRect通過反轉(zhuǎn)每個(gè)像素的值,從而反轉(zhuǎn)ー個(gè)設(shè)備場(chǎng)景中指定的矩形LineDDA枚舉指定線段中的所有點(diǎn)LineTo用當(dāng)前畫筆畫一條線,從當(dāng)前位置連到ー個(gè)指定的點(diǎn)MoveToEx為指定的設(shè)備場(chǎng)景指定一個(gè)新的當(dāng)前畫筆位置PaintDesk在指定的設(shè)備場(chǎng)景中描繪桌面墻紙圖案PathToRegion將當(dāng)前選定的路徑轉(zhuǎn)換到ー個(gè)區(qū)域里Pie畫一個(gè)餅圖PlayEnhMetaFile在指定的設(shè)備場(chǎng)景中畫一個(gè)增強(qiáng)型圖元文件PlayEnhMetaFileRecord回放單獨(dú)一條增強(qiáng)型圖元文件記錄PlayMetaFile在指定的設(shè)備場(chǎng)景中回放ー個(gè)圖元文件PlayMetaFileRecord回放來自圖元文件的單條記錄PolyBezier描繪一條或多條貝塞爾(Bezier)曲線PolyDraw描繪一條復(fù)雜的曲線,由線段及貝塞爾曲線組成Polygon描繪ー個(gè)多邊形Polyline用當(dāng)前畫筆描繪ー系列線段PolyPolygon用當(dāng)前選定畫筆描繪兩個(gè)或多個(gè)多邊形PolyPolyline用當(dāng)前選定畫筆描繪兩個(gè)或多個(gè)多邊形Rectangle用當(dāng)前選定的畫筆描繪矩形,并用當(dāng)前選定的刷子填充RoundRect用當(dāng)前選定的畫筆畫一個(gè)圓角矩形,并用當(dāng)前選定的刷子在其中填充SelectClipPath將設(shè)備場(chǎng)景當(dāng)前的路徑合并到剪切區(qū)域里SelectObject為當(dāng)前設(shè)備場(chǎng)景選擇圖形對(duì)象SetArcDirection設(shè)置圓弧的描繪方向SetBkColor為指定的設(shè)備場(chǎng)景設(shè)置背景顏色SetBkMode指定陰影刷子、虛線畫筆以及字符中的空隙的填充方式SetBrushOrgEx為指定的設(shè)備場(chǎng)景設(shè)置當(dāng)前選定刷子的起點(diǎn)SetEnhMetaFileBits用指定內(nèi)存緩沖區(qū)內(nèi)包含的數(shù)據(jù)創(chuàng)建一個(gè)增強(qiáng)型圖元文件SetMetaFileBitsEx用包含在指定內(nèi)存緩沖區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)創(chuàng)建一個(gè)圖元文件SetMiterLimit設(shè)置設(shè)備場(chǎng)景當(dāng)前的斜率限制SetPixe!在指定的設(shè)備場(chǎng)景中設(shè)置ー個(gè)像素的RGB值SetPixelV在指定的設(shè)備場(chǎng)景中設(shè)置ー個(gè)像素的RGB值SetPolyFillMode設(shè)置多邊形的填充模式SetROP2設(shè)置指定設(shè)備場(chǎng)景的繪圖模式。與vb的DrawMode屬性完全一致SetWinMetaFileBits將一個(gè)標(biāo)準(zhǔn)Windows圖元文件轉(zhuǎn)換成增強(qiáng)型圖元文件StrokeAndFillPath針對(duì)指定的設(shè)備場(chǎng)景,關(guān)閉路徑上打開的所有區(qū)域StrokePath用當(dāng)前畫筆描繪ー個(gè)路徑的輪廓。打開的圖形不會(huì)被這個(gè)函數(shù)關(guān)閉UnrealizeObject將一個(gè)刷子對(duì)象選入設(shè)備場(chǎng)景之前,如刷子的起點(diǎn)準(zhǔn)備用SetBrushOrgEx修改,則必須先調(diào)用本函數(shù)WidenPath根據(jù)選定畫筆的寬度,重新定義當(dāng)前選定的路徑API之設(shè)備場(chǎng)景函數(shù)CombineRgn將兩個(gè)區(qū)域組合為ー個(gè)新區(qū)域CombineTransform驅(qū)動(dòng)世界轉(zhuǎn)換。它相當(dāng)于依順序進(jìn)行兩次轉(zhuǎn)換CreateCompatibleDC創(chuàng)建一個(gè)與特定設(shè)備場(chǎng)景一致的內(nèi)存設(shè)備場(chǎng)景CreateDC為專門設(shè)備創(chuàng)建設(shè)備場(chǎng)景CreateEllipticRgn創(chuàng)建一個(gè)橢圓CreateEllipticRgnlndirect創(chuàng)建一個(gè)內(nèi)切于特定矩形的橢圓區(qū)域CreatelC為專用設(shè)備創(chuàng)建一個(gè)信息場(chǎng)景CreatePolygonRgn創(chuàng)建一個(gè)由一系列點(diǎn)圍成的區(qū)域CreatePolyPolygonRgn創(chuàng)建由多個(gè)多邊形構(gòu)成的區(qū)域。每個(gè)多邊形都應(yīng)是封閉的CreateRectRgn創(chuàng)建一個(gè)矩形區(qū)域CreateRectRgnlndirect創(chuàng)建一個(gè)矩形區(qū)域CreateRoundRectRgn創(chuàng)建一個(gè)圓角矩形DeleteDC刪除專用設(shè)備場(chǎng)景或信息場(chǎng)景,釋放所有相關(guān)窗口資源DPtoLP將點(diǎn)陣從設(shè)備坐標(biāo)轉(zhuǎn)換到專用設(shè)備場(chǎng)景邏輯坐標(biāo)EquaIRgn確定兩個(gè)區(qū)域是否相等ExcludeClipRect從專用設(shè)備場(chǎng)景的剪裁區(qū)中去掉ー個(gè)矩形區(qū)

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論