



版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1C語(yǔ)言的預(yù)處理程序ANS!標(biāo)準(zhǔn)定義的C語(yǔ)言預(yù)處理程序包括下列命令:#definetterrorttinclude#if#else#elifttendif#ifdefSifndefSundef#lineSpragma非常明顯,所有預(yù)處理命令均以符號(hào)#開頭,下面分別加以介紹。2#define命令#define定義了一個(gè)標(biāo)識(shí)符及ー個(gè)串。在源程序中每次遇到該標(biāo)識(shí)符時(shí),均以定義的串代換它。ANSI標(biāo)準(zhǔn)將標(biāo)識(shí)符定義為宏名,將替換過(guò)程稱為宏替換。命令的一般形式為:#defineidentifierstring注意,該語(yǔ)句沒(méi)有分號(hào)。在標(biāo)識(shí)符和串之間可以有任意個(gè)空格,串一旦開始,僅由一新行結(jié)束。例如,如希望TURE取值1,FALSE取值〇,可說(shuō)明兩個(gè)宏#define#defineTURE1#defineFALSE0這使得在源程序中每次遇到TURE或FALSE就用0或1代替。例如,在屏幕上打印‘‘012”:printfC%d%d%d",FALSE,TRUE,TRUE+1);宏名定義后,即可成為其它宏名定義中的一部分。例如,下面代碼定義了ONE、TWO及THREE的值。SdefineONE1SdefineTWOONE+ONE#defineTHREEONE+TWO懂得宏替換僅僅是以串代替標(biāo)識(shí)符這點(diǎn)很重要。因此,如果希望定義ー個(gè)標(biāo)準(zhǔn)錯(cuò)誤信息,可編寫如下代碼:#defineE_MS,zstandarderroroninput\n"printf(E_MS);編譯程序遇到標(biāo)識(shí)符E_MS時(shí),就用"standarderroroninput\n”替換。對(duì)于編譯程序,printfO語(yǔ)句實(shí)際是如下形式:printf("standarderroroninput\n;")如果在串中含有標(biāo)識(shí)符,則不進(jìn)行替換。例如:#defineXYZthisisatestprintf("XYZ");該段不打印"thisisatest"而打印"XYZ"。如果串長(zhǎng)于一行,可以在該行末尾用一反斜杠續(xù)行,例如:#defineLONG_STRING*thisisaverylong\stringthatisusedasanexampleC語(yǔ)言程序普遍使用大寫字母定義標(biāo)識(shí)符。這種約定可使人讀程序時(shí)很快發(fā)現(xiàn)哪里有宏替換。最好是將所有的#define放到文件的開始處或獨(dú)立的文件中(用#include訪問(wèn)),而不是將它們分散到整個(gè)程序中。宏代換的最一般用途是定義常量的名字和程序中的“游戲數(shù)”。例如,某ー程序定義了一個(gè)數(shù)組,而它的兒個(gè)子程序要訪問(wèn)該數(shù)組,不應(yīng)直接以常量定數(shù)組大小,最好是用名字定義之(需改變數(shù)組大小時(shí))。#defineMAX_SIZE100floatbalance[MAXSIZE;]#define命令的另ー個(gè)有用特性是,宏名可以取參量。每次遇到宏名時(shí),與之相連的形參均由程序中的實(shí)參代替。例如:當(dāng)編譯該程序時(shí),由MlN(a,b)定義的表達(dá)式被替換,x和y用作操作數(shù),即printf()語(yǔ)句被代換后取如下形式:printf("theminimumis:%,d"(xくy)?x:y);用宏代換代替實(shí)在的函數(shù)的一大好處是宏替換增加了代碼的速度,因?yàn)椴淮嬖诤瘮?shù)調(diào)用的開銷。但增加速度也有代價(jià):由于重復(fù)編碼而增加了程序長(zhǎng)度。3#error處理器命令#error強(qiáng)迫編譯程序停止編譯,主要用于程序調(diào)試。4#include命令#include使編譯程序?qū)⒘硪辉次募度霂в?include的源文件,被讀入的源文件必須用雙引號(hào)或尖括號(hào)括起來(lái)。例如:#include"stdio.h"#includeくstdio.h>這兩行代碼均使用C編譯程序讀入并編譯用于處理磁盤文件庫(kù)的子程序。將文件嵌入#include命令中的文件內(nèi)是可行的,這種方式稱為嵌套的嵌入文件,嵌套層次依賴于具體實(shí)現(xiàn)。如果顯式路徑名為文件標(biāo)識(shí)符的一部分,則僅在哪些子目錄中搜索被嵌入文件。否則,如果文件名用雙引號(hào)括起來(lái),則首先檢索當(dāng)前工作目錄。如果未發(fā)現(xiàn)文件,則在命令行中說(shuō)明的所有目錄中搜索。如果仍未發(fā)現(xiàn)文件,則搜索實(shí)現(xiàn)時(shí)定義的標(biāo)準(zhǔn)目錄。如果沒(méi)有顯式路徑名旦文件名被尖括號(hào)括起來(lái),則首先在編譯命令行中的目錄內(nèi)檢索。如果文件沒(méi)找到,則檢索標(biāo)準(zhǔn)目錄,不檢索當(dāng)前工作目錄。5條件編譯命令有幾個(gè)命令可對(duì)程序源代碼的各部分有選擇地進(jìn)行編譯,該過(guò)程稱為條件編譯。商業(yè)軟件公司廣泛應(yīng)用條件編譯來(lái)提供和維護(hù)某ー程序的許多顧客版本。1.#if>#else,#elif及#endif#if的一般含義是如果#if后面的常量表達(dá)式為true,則編譯它與#endif之間的代碼,否則跳過(guò)這些代碼。命令#endif標(biāo)識(shí)ー個(gè)#if塊的結(jié)束,參見例4-130#ifconstant-expressionstatementsequence#endif由于MAX大于99,以上程序在屏幕上顯示一串消息。該例說(shuō)明了一個(gè)重點(diǎn):跟在#if后面的表達(dá)式在編譯時(shí)求值,因此它必須僅含常量及已定義過(guò)的標(biāo)識(shí)符,不可使用變量。表達(dá)式不許含有操作符sizeof。#else命令的功能有點(diǎn)象C語(yǔ)言中的else;#else建立另ー選擇(在#if失敗的情況下)。因而上面的例子可擴(kuò)充,參見例4T4。在此例中,因?yàn)镸AX小于99,所以,不編譯#if塊,而是編譯#else塊,因此,屏幕上顯示‘'compiledforsmallarray?消息。注意,#else既是#if塊又是#else塊頭。這是因?yàn)槿魏?if僅有一個(gè)Sendif〇#elif命令意義與ELSEIF相同,它形成一個(gè)ifelse-if階梯狀語(yǔ)句,可進(jìn)行多種編譯選擇。#elif后跟ー個(gè)常量表達(dá)式。如果表達(dá)式為true,則編譯其后的代碼塊,不對(duì)其它#elif表達(dá)式進(jìn)行測(cè)迖。否則,順序測(cè)試下ー塊。#ifexpressionstatementsequence#elifexpressionlstatementsequence#elifexpression2statementsequence#elifexpressionsstatementsequenceelifexpression4elifexpression3Nstatementsequence#endif例如:下面程序利用ACTIVe_COUNTRY定義貨幣符號(hào)。defineUS0defineENGLAND1defineFRANCE2defineACTIVE_COUNTRYUSifACTIVE_COUNTRY==UScharcurrency[]-dollar;elifACTIVE_COUNTRY==ENGLANDcharcurrency[]="pound;"#elsecharcurrency[]=*franc;"Sendifif與#elif命令可能一直嵌套到實(shí)現(xiàn)規(guī)定的權(quán)限,其中#endif、#else或#elif與最近#if或#elif關(guān)聯(lián)。例如,下面程序是完全有效的。#ifMAX>100#ifSERIAL_VERSIONintport=198;#elifintport=200;#elif#elsecharoutbuffer[100];#endif2.#ifdef和#ifndef條件編譯的另一種方法是用#ifdef與#ifndef命令,它們分別表示“如果有定義”及“如果無(wú)定義”。ifdef的一?般形式是:ifdefmacronamestatementsequencettendif如果宏名在前面#define語(yǔ)句中已定義過(guò),則該語(yǔ)句后的代碼塊被編譯。ifndef的一般形式是:#ifndefmacronamestatementsequencettendif如果宏名在#define語(yǔ)句中無(wú)定義,則編譯該代碼塊。ttifde!與#ifndef可以用于#else語(yǔ)句中,但#elif不行。參見4-15〇上述代碼打印“HiTed”及“RALPHnotdefinedw〇如果TED沒(méi)有定義,則顯示“Hiany〇ne",后面是"RALPHnotdefinedM〇可以像嵌套#if那樣將#ifdef與#ifndef嵌套至任意深度。#undef命令#undef取消其后那個(gè)前面已定義過(guò)有宏名定義。一般形式為:#undefmacroname例如:defineLEN100difineWIDTH100chararray[LEN][WIDTH];undefLENundefWIDTH*atthispointbothLENandWIDTHareundefined*/直到遇到#undef語(yǔ)句之前,LEN與WIDTH均有定義。undef的主要目的是將宏名局限在僅需要它們的代碼段中。#Iine命令#line改變_LINE一與一FILE一的內(nèi)容,它們是在編譯程序中預(yù)先定義的標(biāo)識(shí)符。命令的基本形式如下:#linenumber[/zfi1ename"]其中的數(shù)字為任何正整數(shù),可選的文件名為任意有效文件標(biāo)識(shí)符。行號(hào)為源程序中當(dāng)前行號(hào),文件名為源文件的名字。命令#line主要用于調(diào)試及其它特殊應(yīng)用。例如,下面說(shuō)明行計(jì)數(shù)從1〇〇開始;printf()語(yǔ)句顯示數(shù)102I因?yàn)樗钦Z(yǔ)句#line100后的第3行。#line100/?初始化行計(jì)數(shù)器*/main()/*行號(hào)100*/{/?行號(hào)101*/printf(/z%d\n/z,_line_);/?行號(hào)102*/)Spragma命令#pragma為實(shí)現(xiàn)時(shí)定義的命令,它允許向編譯程序傳送各種指令。例如,編譯程序可能有一ー種選擇,它支持對(duì)程序執(zhí)行的跟蹤??捎?pragma語(yǔ)句指定一個(gè)跟蹤選擇。在所有的預(yù)處理指令中,Spragma指令可能是最復(fù)雜的了,它的作用是設(shè)定編譯器的狀態(tài)或者是指示編譯器完成一些特定的動(dòng)作。#pragma指令對(duì)每個(gè)編譯器給出了一個(gè)方法,在保持與C和生語(yǔ)言完全兼容的情況下,給出主機(jī)或操作系統(tǒng)專有的特征。依據(jù)定義,編譯指示是機(jī)器或操作系統(tǒng)專有的,且對(duì)于每個(gè)編譯器都是不同的。其格式一般為:Spragmapara其中para為參數(shù),下面來(lái)看?些常用的參數(shù)。(1)message參數(shù)message參數(shù)是我最喜歡的ー個(gè)參數(shù),它能夠在編譯信息輸出窗口中輸出相應(yīng)的信息,這對(duì)于源代碼信息的控制是非常重要的。其使用方法為:#pragmamessage("消息文本”)當(dāng)編譯器遇到這條指令時(shí)就在編譯輸出窗口中將消息文本打印出來(lái)。當(dāng)我們?cè)诔绦蛑卸x了許多宏來(lái)控制源代碼版本的時(shí)候,我們自己有可能都會(huì)忘記有沒(méi)有正確的設(shè)置這些宏,此時(shí)我們可以用這條指令在編譯的時(shí)候就進(jìn)行檢査。假設(shè)我們希望判斷自己有沒(méi)有在源代碼的什么地方定義了一X86這個(gè)宏,可以用下面的方法:#ifdef_X86ttpragmamessage(ZZ_X86macroactivated!zz)#endif我們定義了一X86這個(gè)宏以后,應(yīng)用程序在編譯時(shí)就會(huì)在編譯輸出窗口里顯不86macroactivated!zzo我們就不會(huì)因?yàn)椴挥浀米约憾x的ー些特定的宏而抓耳撓腮了。(2)另--個(gè)使用得比較多的pragma參數(shù)是code_seg格式如:Spragmacode_seg(["section-name”[,"section-class"]])它能夠設(shè)置程序中函數(shù)代碼存放的代碼段,當(dāng)我們開發(fā)驅(qū)動(dòng)程序的時(shí)候就會(huì)使用到它。(3)#pragmaonce仕匕較常用)只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次,這條指令實(shí)際上在VC6中就已經(jīng)有了,但是考慮到兼容性并沒(méi)有太多的使用它。⑷#pragmahdrstop表示預(yù)編譯頭文件到此為止,后面的頭文件不進(jìn)行預(yù)編譯。BCB可以預(yù)編譯頭文件以加快鏈接的速度,但如果所有頭文件都進(jìn)行預(yù)編譯又可能占太多磁盤空間,所以使用這個(gè)選項(xiàng)排除一些頭文件。有時(shí)單元之間有依賴關(guān)系,比如單元A依賴單元B,所以單元B要先于單元A編譯。你可以用#pragmastartup指定編譯優(yōu)先級(jí),如果使用了#pragmapackage(smart_init),BCB就會(huì)根據(jù)優(yōu)先級(jí)的大小先后編譯。(5)#pragmaresource dfm"表示把?.dfm文件中的資源加入工程。*.dfm中包括窗體外觀的定義。(6)ftpragmawarning(disable:450734;once:4385;error:164)等價(jià)于:#pragmawarning(disable:450734) //不顯示4507和34號(hào)警告信息Spragmawarning(once:4385) //4385號(hào)警告信息僅報(bào)告ー次ttpragmawarning(error:164) 〃把!64號(hào)警告信息作為一1個(gè)錯(cuò)誤。同時(shí)這個(gè)pragmawarning也支持如下格式:#pragmawarning(push[,n])Spragmawarning(pop)這里n代表ー個(gè)警告等級(jí)(1一一4)〇pragmawarning(push)保存所有警告信息的現(xiàn)有的警告狀態(tài)。Spragmawarning(push,n)保存所有警告信息的現(xiàn)有的警告狀態(tài),并且把全局警告等級(jí)設(shè)定為n。Spragmawarning(pop)向棧中彈出最后ー個(gè)警告信息,在入棧和出棧之間所作的一切改動(dòng)取消。例如:pragmawarning(push)pragmawarning(disable:4705)ttpragmawarning(disable:4706)Spragmawarning(disable:4707)// Spragmawarning(pop)在這段代碼的最后,重新保存所有的警告信息(包括4705,4706和4707)。(7)#pragmacomment(...)該指令將一個(gè)注釋記錄放入ー個(gè)對(duì)象文件或可執(zhí)行文件中。常用的lib關(guān)鍵字,可以幫我們連入ー個(gè)庫(kù)文件。如:ttpragmacomment(lib,"comctl32.lib)pragmacomment(lib,〃vfw32.lib")ttpragmacomment(lib,"wsock32,lib)每個(gè)編譯程序可以用#pragma指令激活或終止該編譯程序支持的ー些編譯功能。例如,對(duì)循環(huán)優(yōu)化功能:Spragmaloop_opt(on) //激活ttpragmaloop_opt(off) /Z終止有時(shí),程序中會(huì)有些函數(shù)會(huì)使編譯器發(fā)出你熟知而想忽略的警告,如aParameterxxxisneverusedinfunctionxxx”,可以這樣:ttpragmawarn-100 //Turnoffthewarningmessageforwarning#100intinsert_record(REC*r){/*functionbody*/)pragmawarn+100 //Turnthewarningmessageforwarning#100backon函數(shù)會(huì)產(chǎn)生一條有唯一特征碼!00的警告信息,如此可暫時(shí)終止該警告。每個(gè)編譯器對(duì)#pragma的實(shí)現(xiàn)不同,在ー個(gè)編譯器中有效在別的編譯器中兒乎無(wú)效??蓮木幾g器的文檔中查看。補(bǔ)充 #pragmapack與內(nèi)存對(duì)齊問(wèn)題許多實(shí)際的計(jì)算機(jī)系統(tǒng)對(duì)基本類型數(shù)據(jù)在內(nèi)存中存放的位置有限制,它們會(huì)要求這些數(shù)據(jù)的首地址的值是某個(gè)數(shù)k(通常它為4或8)的倍數(shù),這就是所謂的內(nèi)存對(duì)齊,而這個(gè)k則被稱為該數(shù)據(jù)類型的對(duì)齊模數(shù)(alignmentmodulus)〇Win32平臺(tái)下的微軟C編譯器(cl.exefor80x86)在默認(rèn)情況下采用如下的對(duì)齊規(guī)則:任何基本數(shù)據(jù)類型T的對(duì)齊模數(shù)就是T的大小,即sizeof(T)o比如對(duì)于double類型(8字節(jié)),就要求該類型數(shù)據(jù)的地址總是8的倍數(shù),而char類型數(shù)據(jù)(!字節(jié))則可以從任何ー個(gè)地址開始。Linux下的GCC奉行的是另外一套規(guī)則(在資料中查得,并未驗(yàn)證,如錯(cuò)誤請(qǐng)指正):任何2字節(jié)大?。ò▎巫止?jié)嗎?)的數(shù)據(jù)類型仕匕如short)的對(duì)齊模數(shù)是2,而其它所有超過(guò)2字節(jié)的數(shù)據(jù)類型(比如long,double)都以4為對(duì)齊模數(shù)。ANSIC規(guī)定一種結(jié)構(gòu)類型的大小是它所有字段的大小以及字段之間或字段尾部的填充區(qū)大小之和。填充區(qū)就是為了使結(jié)構(gòu)體字段滿足內(nèi)存對(duì)齊要求而額外分配給結(jié)構(gòu)體的空間。那么結(jié)構(gòu)體本身有什么對(duì)齊要求嗎?有的,ANSIC標(biāo)準(zhǔn)規(guī)定結(jié)構(gòu)體類型的對(duì)齊要求不能比它所有字段中要求最嚴(yán)格的那個(gè)寬松,可以更嚴(yán)格。如何使用C/C++中的對(duì)齊選項(xiàng)vc6中的編譯選項(xiàng)有/Zp[l]2|4|8|16],/Zpl表示以1字節(jié)邊界對(duì)齊,相應(yīng)的,/Zpn表示以n字節(jié)邊界對(duì)齊。n字節(jié)邊界對(duì)齊的意思是說(shuō),ー個(gè)成員的地址必須安排在成員的尺寸的整數(shù)倍地址上或者是n的整數(shù)倍地址上,取它們中的最小值。也就是:min(sizeof(member),n)實(shí)際上,I字節(jié)邊界對(duì)齊也就表示了結(jié)構(gòu)成員之間沒(méi)有空洞。/Zpn選項(xiàng)是應(yīng)用于整個(gè)工程的,影響所有的參與編譯的結(jié)構(gòu)。要使用這個(gè)選項(xiàng),可以在vc6中打開工程屬性頁(yè),c/c++頁(yè),選擇CodeGeneration分類,在Structmemberalignment可以選擇。要專門針對(duì)某些結(jié)構(gòu)定義使用對(duì)齊選項(xiàng),可以使用#pragmapack編譯指令:Spragmapack([n])該指令指定結(jié)構(gòu)和聯(lián)合成員的緊湊對(duì)齊。而ー個(gè)完整的轉(zhuǎn)換單元的結(jié)構(gòu)和聯(lián)合的緊湊對(duì)齊由/Zp選項(xiàng)設(shè)置。緊湊對(duì)齊用pack編譯指示在數(shù)據(jù)說(shuō)明層設(shè)置。該編譯指示在其出現(xiàn)后的第ー個(gè)結(jié)構(gòu)或聯(lián)合說(shuō)明處生效。該編譯指示對(duì)定義無(wú)效。當(dāng)你使用#pragmapack(n)時(shí),這里n為1、2、4、8或16〇第一個(gè)結(jié)構(gòu)成員之后的每個(gè)結(jié)構(gòu)成員都被在値在更小的成員類型或n字節(jié)界限內(nèi)。如果你使用無(wú)參量的#pragmapack,結(jié)構(gòu)成員被緊湊為以/Zp指定的值。該缺省/Zp緊湊值為/Zp8。(2)編譯器也支持以下增強(qiáng)型語(yǔ)法:#pragmapack([[{push|pop},][identifier,]][n])若不同的組件使用pack編譯指示指定不同的緊湊對(duì)齊,這個(gè)語(yǔ)法允許你把程序組件組合為ー個(gè)單獨(dú)的轉(zhuǎn)換單元。帶push參量的pack編譯指示的每次出現(xiàn)將當(dāng)前的緊湊對(duì)齊立磕到ー個(gè)內(nèi)部編譯器堆棧中。編譯指示的參量表從左到右讀取。如果你使用push,則當(dāng)前緊湊值被存儲(chǔ)起來(lái);如果你給出ー個(gè)n的值,該值將成為新的緊湊值。若你指定一個(gè)標(biāo)識(shí)符,即你選定一個(gè)名稱,則該標(biāo)識(shí)符將和這個(gè)新的的緊湊值聯(lián)系起來(lái)。帶ー個(gè)pop參量的pack編譯指示的每次出現(xiàn)都會(huì)檢索內(nèi)部編譯器堆棧頂?shù)闹?并且使該值為新的緊湊對(duì)齊值。如果你使用pop參量且內(nèi)部編譯器堆棧是空的,則緊湊值為命令行給定的值,并且將產(chǎn)生一個(gè)警告信息。若你使用pop且指定一個(gè)n的值,該值將成為新的緊湊值。若你使用p〇p且指定一個(gè)標(biāo)識(shí)符,所有存儲(chǔ)在堆棧中的值將從棧中刪除,直到找到ー個(gè)匹配的標(biāo)識(shí)符,這個(gè)與標(biāo)識(shí)符相關(guān)的緊湊值也從棧中移出,并且這個(gè)僅在標(biāo)識(shí)符入棧之前存在的緊湊值成為新的緊湊值。如果未找到匹配的標(biāo)識(shí)符,將使用命令行設(shè)置的緊湊值,并且將產(chǎn)生一個(gè)一級(jí)警告。缺省緊湊對(duì)齊為8。pack編譯指示的新的增強(qiáng)功能讓你編寫頭文件,確保在遇到該頭文件的前后的緊湊值是一樣的。(3)棧內(nèi)存對(duì)齊在vc6中棧的對(duì)齊方式不受結(jié)構(gòu)成員對(duì)齊選項(xiàng)的影響。它總是保持對(duì)齊,而且對(duì)齊在4字節(jié)邊界上。9預(yù)定義的宏名ANSI標(biāo)準(zhǔn)說(shuō)明了五個(gè)預(yù)定義的宏名。它們是:_line__FILE__DATE__TIME__STDC_如果編譯不是標(biāo)準(zhǔn)的,則可能僅支持以上宏名中的兒個(gè),或根本不支持。記住編譯程序也許還提供其它預(yù)定義的宏名。line_及ーFILE一宏指令在有關(guān)#line的部分中已討論,這里討論其余的宏名。DATE一宏指令含有形式為月/日/年的串,表示源文件被翻譯到代碼時(shí)的日期。源代碼翻譯到目標(biāo)代碼的時(shí)間作為串包含在一TIME_中。串形式為時(shí):分:秒。如果實(shí)現(xiàn)是標(biāo)準(zhǔn)的,則宏一sTDC―含有十進(jìn)制常量lo如果它含有任何其它數(shù),則實(shí)現(xiàn)是非標(biāo)準(zhǔn)的。注意:宏名的書寫由標(biāo)識(shí)符與兩邊各二條下劃線構(gòu)成。10注釋在C語(yǔ)言中,所有的注釋由字符/?開始,以?/結(jié)束。在星號(hào)及斜杠之間不允許有空格。編譯程序忽略注釋開始符到注釋結(jié)束符間的任何文本。例如,下面程序在屏幕上只打印"hell〇”〇main()(printf("hello");/*printf("Thisisasampletoprinthell;0"*/)}注釋可出現(xiàn)在程序的任何位置,但它不能出現(xiàn)在關(guān)鍵字或標(biāo)識(shí)符中間。即,注釋x=10+/*addthenumbers*/5:是有效的,但swi/*thiswillnotwork*/tch(c){...是不正確的,因?yàn)镃的關(guān)鍵字不能含有注釋。通常也不希望表達(dá)式中間出現(xiàn)注釋,因?yàn)檫@會(huì)使意義含混不清。注釋不可嵌套,即ー個(gè)注釋內(nèi)不可含有另ー個(gè)注釋。例如,下面代碼段在編譯時(shí)出錯(cuò):/?thisisanoutercommentx=y/a;/*thisisaninnercomment-andcausesanerror*//當(dāng)需要解釋程序的行為時(shí),注釋應(yīng)簡(jiǎn)明扼要。除了最簡(jiǎn)單和最直觀的函數(shù)外,都應(yīng)有注釋,在函數(shù)開始處說(shuō)明其功能,如何調(diào)用以及返回何處pragma預(yù)處理指令作用說(shuō)明在所有的預(yù)處理指令中,#pragma指令可能算是比較復(fù)雜的一條,它的作用是設(shè)定編譯器的狀態(tài)或者是指示編譯器完成?些特定的動(dòng)作。#pragma指令對(duì)每個(gè)編譯器給出了一個(gè)方法,在保持與C和C++語(yǔ)言完全兼容的情況下,給出主機(jī)或操作系統(tǒng)專有的特征。依據(jù)定義,編譯指示是機(jī)器或操作系統(tǒng)專有的,且對(duì)于每個(gè)編譯器都是不同的。其格式一般為:#pragmapara:其中para為參數(shù),下面我們就一些常用的參數(shù)作一?些說(shuō)明。message參數(shù):message參數(shù)主要用于在編譯信息輸出窗口中輸出相應(yīng)的信息;當(dāng)編譯器遇到這條指令時(shí)就在編譯輸出窗口中將消息文本打印出來(lái);這對(duì)于源代碼信息的控制是非常重要的;其格式如下:#pragmamessage("消息文本”)當(dāng)我們?cè)诔绦蛑卸x了許多宏來(lái)控制源代碼版本的時(shí)候,我們自己有可能都會(huì)忘記有沒(méi)有正確的設(shè)置這些宏,此時(shí)我們可以用這條指令在編譯的時(shí)候就進(jìn)行檢查。假設(shè)我們希望判斷自己有沒(méi)有在源代碼的什么地方定義了一X86這個(gè)宏可以用下面的方法:#ifdef_X86#pragmamessage("_X86macroactivated!w)#endif當(dāng)我們定義了一X86這個(gè)宏以后,應(yīng)用程序在編譯時(shí)就會(huì)在編譯輸出窗口里顯示"_X86macroactivated!v。我們就不會(huì)因?yàn)椴挥浀米约憾x的ー些特定的宏市抓耳撓腮了。code_seg參數(shù):此參數(shù)主要用于設(shè)置程序中函數(shù)代碼存放的代碼段,當(dāng)我們開發(fā)驅(qū)動(dòng)程序的時(shí)候就會(huì)使用到它。其格式如下:#pragmacode_seg([[{pushpop),][identifier,」」Lsegment-name”[,"segment-class"]])該指令用來(lái)指定函數(shù)在?obj文件中存放的節(jié),觀察OBJ文件可以使用VC自帶的dumpbin命令行程序,函數(shù)在?obj文件中默認(rèn)的存放節(jié)為.text節(jié),如果code_seg沒(méi)有帶參數(shù)的話,則函數(shù)存放在.text節(jié)中;push(可選參數(shù))將一個(gè)記錄版到內(nèi)部編譯器的堆棧中;可選參數(shù)可以為…個(gè)標(biāo)識(shí)符或者節(jié)名;pop(可選參數(shù))將一個(gè)記錄從堆棧頂端彈出,該記錄可以為ー個(gè)標(biāo)識(shí)符或者節(jié)名;identifier(可選參數(shù))當(dāng)使用push指令時(shí),為壓入堆棧的記錄指派的ー個(gè)標(biāo)識(shí)符,當(dāng)該標(biāo)識(shí)符被刪除的時(shí)候和其相關(guān)的堆棧中的記錄將被彈出堆棧;"segment-name”(可選參數(shù))表示函數(shù)存放的節(jié)名。例如:〃默認(rèn)情況下,函數(shù)被存放在.text節(jié)中voidfund(){//storedin.text)〃將函數(shù)存放在.my_datal節(jié)中#pragmacode_seg(".my_datal")voidfunc2(){//storedinmydatal)//rl為標(biāo)識(shí)符,將函數(shù)放入.my_data2節(jié)中#pragmacode_seg(push,rl,".my_data2")voidfunc3(){ //storedinmy_data2}intmain(){)once參數(shù):這是ー個(gè)比較常用的能數(shù),只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次;其用法如下:#pragmaoncehdrstop參數(shù):hdrstop表示預(yù)編譯頭文件到此為止,后面的頭文件不進(jìn)行預(yù)編譯;BCB可以預(yù)編譯頭文件以加快鏈接的速度,但如果所有頭文件都進(jìn)行預(yù)編譯又可能占太多磁盤空間,所以使用這個(gè)選項(xiàng)排除ー些頭文件;有時(shí)單元之間有依賴關(guān)系,比如單元A依賴單元B,所以單元B要先于單元A編譯;你可以用#pragmastartup指定編譯優(yōu)先級(jí),如果使用了#pragmapackage(smart一init),BCB就會(huì)根據(jù)優(yōu)先級(jí)的大小先后編譯;其用法如下:#pragmahdrstop
5.warning5.warning參數(shù):該指令允許有選擇性的修改編譯器的警告消息的行為;指令格式如下:ttpragmawarning(warning-spec:warning-number-list[;warning-spec:warning-number-list...])#pragmawarning(push[,n])#pragmawarning(pop)主要用到的警告表示有如下幾個(gè):once:只顯示一次(警告/錯(cuò)誤等)消息default:重置編譯器的警告行為到默認(rèn)狀態(tài)1,2,3,4:四個(gè)警告級(jí)別disable:禁止指定的警告信息error:將指定的警告信息作為錯(cuò)誤報(bào)告如果大家對(duì)上面的解釋不是很理解,可以參考一下下面的例子及說(shuō)明:#pragmawarning(disable:450734;once:4385;error:164)這條指令等價(jià)于如下指令:ttpragmawarning(disable:450734)//不顯示4507和34號(hào)警告信息#pragmawarning(once:4385) //4385號(hào)警告信息僅報(bào)告一次ttpragmawarning(error:164)/Z把164號(hào)警告信息作為ー個(gè)錯(cuò)誤。同時(shí)這個(gè)pragmawarning也支持如下格式:#pragmawarning(push[,n])ttpragmawarning(pop)這里n代表一個(gè)警告等級(jí)(1一一4)〇ttpragmawarning(push)保存所有警告信息的現(xiàn)有的警告狀態(tài)。#pragmawarning(push,n)保存所有警告信息的現(xiàn)有的警告狀態(tài),并且把全局警告等級(jí)設(shè)定為n。#pragmawarning(pop)向棧中彈出最后一,個(gè)警告信息,在入棧和出棧之間所作的一切改動(dòng)取消。例如:#pragmawarning(push)pragmawarning(disable:4705)pragmawarning(disable:4706)pragmawarning(disable:4707)pragmawarning(pop)在這段代碼的最后,重新保存所有的警告信息(包括4705,4706和4707);在使用標(biāo)準(zhǔn)C++進(jìn)行編程的時(shí)候經(jīng)常會(huì)得到很多的警告信息,而這些警告信息都是不必要的提示,所以我們可以使用#pragmawarning(disable:4786)來(lái)禁止該類型的警告;在vc中使用AD0的時(shí)候也會(huì)得到不必要的警告信息,這個(gè)時(shí)候我們可以通過(guò)#pragmawarning(disable:4146)來(lái)消除該類型的警告信息。comment參數(shù):該參數(shù)將一個(gè)注釋記錄放入ー個(gè)對(duì)象文件或可執(zhí)行文件中;格式如下:#pragmacomment(comment-type[,commentstring])comment-type(注釋類型):可以指定為五種預(yù)定義的標(biāo)識(shí)符的其中一種五種預(yù)定義的標(biāo)識(shí)符如下:0 compiler:將編譯器的版本號(hào)和名稱放入目標(biāo)文件中,本條注釋記錄將被編譯器忽略如果你為該記錄類型提供了commentstring參數(shù),編譯器將會(huì)產(chǎn)生一個(gè)警告。例如:ftpragmacomment(compiler)0 exestr將commentstring參數(shù)放入目標(biāo)文件中,在鏈接的時(shí)候這個(gè)字符串將被放入到可執(zhí)行文件中,當(dāng)操作系統(tǒng)加載可執(zhí)行文件的時(shí)候,該參數(shù)字符串不會(huì)被加載到內(nèi)存中.但是,該字符串可以被dumpbin之類的程序查找出并打印出來(lái),你可以用這個(gè)標(biāo)識(shí)符將版本號(hào)碼之類的信息嵌入到可執(zhí)行文件中!0 lib這是一個(gè)非常常用的關(guān)鍵字,用來(lái)將一個(gè)庫(kù)文件鏈接到目標(biāo)文件中常用的lib關(guān)鍵字,可以幫我們連入ー個(gè)庫(kù)文件。例如:#pragmacomment(lib,“user32.lib")該指令用來(lái)將user32.1ib庫(kù)文件加入到本工程中。0 linker將一個(gè)鏈接選項(xiàng)放入目標(biāo)文件中,你可以使用這個(gè)指令來(lái)代替由命令行傳入的或者在開發(fā)環(huán)境中設(shè)置的鏈接選項(xiàng),你可以指定/include選項(xiàng)來(lái)強(qiáng)制包含某個(gè)對(duì)象,例如:ttpragmacomment(linker,"/include: mySymbol")你可以在程序中設(shè)置下列鏈接選項(xiàng):/DEFAULTLIB/EXPORT/INCLUDE/MERGE/SECTION這些選項(xiàng)在這里就不一,ー說(shuō)明了,詳細(xì)信息請(qǐng)看msdn!0 user將一般的注釋信息放入目標(biāo)文件中commentstring參數(shù)包含注釋的文本信息,這個(gè)注釋記錄將被鏈接器忽略。例如:#pragmacomment(user,"Compiledon"_DATE"at"_TIME)pack參數(shù):此參數(shù)主要用于設(shè)置結(jié)構(gòu)體中變量的對(duì)齊方式:如果設(shè)置的值比結(jié)構(gòu)體中字節(jié)最長(zhǎng)的類型還要大,則這個(gè)變量(注意僅針對(duì)這ー個(gè)變量)只按照它的字節(jié)長(zhǎng)度對(duì)齊,即不會(huì)出現(xiàn)內(nèi)存浪費(fèi)的情況;其對(duì)齊有1、2、4、8、16,其中默認(rèn)值為8;其用格式如下:#pargmapack(n)例子例如:〃每個(gè)變量按照1字節(jié)對(duì)齊Wpragmapack(1)structA〃每個(gè)變量按照1字節(jié)對(duì)齊inty; //alignedonbyteboundary1);sizeof(A)==5^pragmapack(2) 〃每個(gè)變量按照2字節(jié)對(duì)齊structA(charx; //alignedonbyteboundary0inty; //alignedonbyteboundary2};sizeof(A)==6#pragmapack(4) 〃每個(gè)變量按照4字節(jié)對(duì)齊structA(charx; //alignedonbyteboundary0inty; //alignedonbyteboundary4};sizeof(A)ニニ8Spragmapack() 〃默認(rèn),相當(dāng)于#pragmapack(8)每個(gè)變量按照8字節(jié)對(duì)齊structAcharx; //alignedonbyteboundary0inty; //alignedonbyteboundary4};sizeof(A)==8但是這里y的大小是4字節(jié),所以不會(huì)按照8字節(jié)對(duì)齊,否則將造成1個(gè)int空間的浪費(fèi):在本人的工作當(dāng)中這條指令主要用于網(wǎng)絡(luò)數(shù)據(jù)包傳輸中用的比較多,畢竟現(xiàn)在的計(jì)算機(jī)上內(nèi)存都比較大,所以浪費(fèi)一點(diǎn)空間也是可以忍受的,更何況浪費(fèi)的同時(shí)能給我們的處理速度帶來(lái)一定的提高剛接觸到MFC編程的人往往會(huì)被MFC向?qū)傻母鞣N宏定義和預(yù)處理指令所嚇倒,但是預(yù)處理和宏定義又是C語(yǔ)言的ー個(gè)強(qiáng)大工具。使用它們可以進(jìn)行簡(jiǎn)單的源代碼控制,版本控制,預(yù)警或者完成?些特殊的功能。ー個(gè)經(jīng)典的例子使用預(yù)處理與宏定義最經(jīng)典的例子莫過(guò)于加在一個(gè)頭文件中以避免頭文件被兩次編譯。試想這種的情況,有一ー個(gè)文件headerfile,h它被包含在headerfilel.h中,同時(shí)在headerfile2.h中也被包含了,現(xiàn)在有一個(gè)CPP文件,implement,cpp包含了headerfilel.h和headerfile2.h:#includeKheaderfilel.hw#include"headerfile2.h”假設(shè)headerfile.h中定義了一個(gè)全局變量iglobal〇intiglobal;在編譯的時(shí)候編譯器兩次編譯headerfile,也就會(huì)發(fā)現(xiàn)iglobal被定義了兩次,這時(shí)就會(huì)發(fā)生變量重定義的編譯錯(cuò)誤。傳統(tǒng)的解決辦法是使用#ifdef以及#endif來(lái)避免頭文件的重復(fù)編譯,在上面的例子中,只需要加上這么幾行:#ifndefsmartnose_2002_6_2Iheaderfi1eh#definesmartnose_2002_6_2l_headerfile_hintiglobal;#endif仔細(xì)的考慮上面的宏定義,會(huì)發(fā)現(xiàn)當(dāng)編譯器編譯過(guò)一次headerfile.h以后,smartnose_2002_6_21_headerfile_h這個(gè)宏就被定義了,以后對(duì)headerfile,h的編譯都會(huì)跳過(guò)intiglobal這一行。當(dāng)然smartnose_2002_6_21_headerfile_h這個(gè)宏是可以任意定義的,但是這個(gè)宏本身不能和其它文件中見義的宏重復(fù),由以MFC在自動(dòng)生成的文件中總是使用一個(gè)隨機(jī)產(chǎn)生的長(zhǎng)度非常長(zhǎng)的宏,但我覺得這沒(méi)有必要,我建議在這個(gè)宏中加入ー些有意義的信息,比方作者,文件名,文件創(chuàng)建時(shí)間等等,因?yàn)槲覀冇袝r(shí)候會(huì)忘記在注釋中加入這些信息。在VC.Net中我們不會(huì)再看見這些宏定義了,因?yàn)樵谶@里會(huì)普遍使用ー個(gè)預(yù)處理指令:#pragmaonce只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次,這條指令實(shí)際上在VC6中就已經(jīng)有了,但是考慮到兼容性并沒(méi)有太多的使用它。源代碼版本控制當(dāng)我們?yōu)樵S多平臺(tái)開發(fā)多個(gè)版本的時(shí)候預(yù)編譯指令和宏定義也能夠幫我們的忙。假設(shè)我們現(xiàn)在為WINDOWS和LINUX開發(fā)了一套軟件,由于這兩種系統(tǒng)的不同,我們不得不在程序控制源代碼的版本。比方內(nèi)存的分配,我們可以在LINUX上使用標(biāo)準(zhǔn)C的malloc函數(shù),但是我們希望在WINDOWS上使用HeapAllocAPI〇下面的代碼演示了這種情況:main()#ifdef_WINDOWS_PLATFORMHeapAlloc(5);#elsemalloc(5);Sendif當(dāng)我們?cè)赪INDOWS平臺(tái)上編譯此程序的時(shí)候,只需要定義WINDOWS-PLATFORM這個(gè)宏,那么HeapAlloc這條語(yǔ)句就能夠起作用了。這樣就能夠讓我們?cè)谕粋€(gè)文件中為不同的平臺(tái)實(shí)現(xiàn)不同版本的代碼,同時(shí)保持程序的良好結(jié)構(gòu)。在許多情況下,我們還可以為ー個(gè)方法使用不同的算法,然后用宏定義來(lái)針對(duì)不同的情況選擇其中的ー個(gè)進(jìn)行編譯。這在MFC應(yīng)用程序中是使用得最多的。最明顯的就是文件中經(jīng)常存在的#ifdef_DEBUG some code Sendif這樣的代碼,這些代碼在應(yīng)用程序的調(diào)試版(DEBUG)中會(huì)發(fā)揮其作用。SPragma指令在所有的預(yù)處理指令中,SPragma指令可能是最復(fù)雜的了,它的作用是設(shè)定編譯器的狀態(tài)或者是指示編譯器完成一些特定的動(dòng)作。其格式一般為SPragmaPara其中Para為參數(shù),下面來(lái)看一些常用的參數(shù)。message參數(shù)。Message參數(shù)是我最喜歡的一個(gè)參數(shù),它能夠在編譯信息輸出窗口中輸出相應(yīng)的信息,這對(duì)于源代碼信息的控制是非常重要的。其使用方法為:一?message參數(shù)。message它能夠在編譯信息輸出窗口中輸出相應(yīng)的信息,這對(duì)于源代碼信息的控制是非常重要的。其使用方法為:Spragmamessage("消息文本”)當(dāng)編譯器遇到這條指令時(shí)就在編譯輸出窗口中將消息文本打印出來(lái)。當(dāng)我們?cè)诔绦蛑卸x了許多宏來(lái)控制源代碼版本的時(shí)候,我們自己有可能都會(huì)忘記有沒(méi)有正確的設(shè)置這些宏,此時(shí)我們可以用這條指令在編譯的時(shí)候就進(jìn)行檢査。假設(shè)我們希望判斷自己有沒(méi)有在源代碼的什么地方定義了一X86這個(gè)宏可以用下面的方法#ifdef_X86^pragmamessage("_X86macroactivated!")Sendif當(dāng)我們定義了一X86這個(gè)宏以后,應(yīng)用程序在編譯時(shí)就會(huì)在編譯輸出窗口里顯示X86macroactivated!"〇我們就不會(huì)因?yàn)椴挥浀米约憾x的ー些特定的宏而抓耳撓腮了二.另一個(gè)使用得比較多的#pragma參數(shù)是code_seg。格式如:Spragmacode_seg([[{push|pop},][identifier,]][segment-name[,"segment-class*])該指令用來(lái)指定函數(shù)在.obj文件中存放的節(jié),觀察OBJ文件可以使用VC自帶的dumpbin命令行程序,函數(shù)在.obj文件中默認(rèn)的存放節(jié)為.text節(jié)如果code_seg沒(méi)有帶參數(shù)的話,則函數(shù)存放在.text節(jié)中push(可施參數(shù))將一個(gè)記錄放到內(nèi)部編譯器的堆棧中,可選參數(shù)可以為ー個(gè)標(biāo)識(shí)符或者節(jié)名pop(可選參數(shù))將一個(gè)記錄從堆棧頂端彈出,該記錄可以為ー個(gè)標(biāo)識(shí)符或者節(jié)名identifier(可選參數(shù))當(dāng)使用push指令時(shí),為壓入堆棧的記錄指派的ー個(gè)標(biāo)識(shí)符,當(dāng)該標(biāo)識(shí)符被刪除的時(shí)候和其相關(guān)的堆棧中的記錄將被彈出堆棧"segment-name”(可選參數(shù))表示函數(shù)存放的節(jié)名例如:〃默認(rèn)情況下,函數(shù)被存放在.text節(jié)中voidfund(){//storedin.text〃將函數(shù)存放在.my_datal節(jié)中Spragmacode_seg(".my_datal")voidfunc2(){//storedinmy_datal}//rl為標(biāo)識(shí)符,將函數(shù)放入.my_data2節(jié)中#pragmacode_seg(push,rl,.my_data2")voidfunc3(){//storedinmy_data2)intmain(){)三.Spragmaonce仕匕較常用)這是ー個(gè)比較常用的指令,只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次四.#pragmahdrstop表示預(yù)編譯頭文件到此為止,后面的頭文件不進(jìn)行預(yù)編譯。BCB可以預(yù)編譯頭文件以加快鏈接的速度,但如果所有頭文件都進(jìn)行預(yù)編譯又可能占太多磁盤空間,所以使用這個(gè)選項(xiàng)排除一些頭文件。有時(shí)單元之間有依賴關(guān)系,比如單元A依賴單元B,所以單元B要先于單元A編譯。你可以用#pragmastartup指定編譯優(yōu)先級(jí),如果使用了#pragmapackage(smart_init),BCB就會(huì)根據(jù)優(yōu)先級(jí)的大小先后編譯。五.#pragmawarning指令該指令允許有選擇性的修改編譯器的警告消息的行為指令格式如下:^pragmawarning(warning-specifier:warning-number-list[;warning-specifier:warning-number-list...]#pragmawarning(push[,n])#pragmawarning(pop)主要用到的警告表示有如下幾個(gè):once:只顯示一次(警告/錯(cuò)誤等)消息default:重置編譯器的警告行為到默認(rèn)狀態(tài)1,2,3,4:四個(gè)警告級(jí)別disable:禁止指定的警告信息error:將指定的警告信息作為錯(cuò)誤報(bào)告如果大家對(duì)上面的解釋不是很理解,可以參考ー?下下面的例子及說(shuō)明Spragmawarning(disable:450734;once:4385;error:164)等價(jià)于:#pragmawarning(disable:450734)//不顯示4507和34號(hào)警告信息Spragmawarning(once:4385)//4385號(hào)警告信息僅報(bào)告一次Spragmawarning(error:164)/Z把164號(hào)警告信息作為ー個(gè)錯(cuò)誤。同時(shí)這個(gè)pragmawarning也支持如下格式:#pragmawarning(push[,n])#pragmawarning(pop)這里n代表ー個(gè)警告等級(jí)(1—4)〇Spragmawarning(push)保存所有警告信息的現(xiàn)有的警告狀態(tài)。#pragmawarning(push,n)保存所有警告信息的現(xiàn)有的警告狀態(tài),并且把全局警告等級(jí)設(shè)定為n。ttpragmawarning(pop)向棧中彈出最后ー個(gè)警告信息,在入棧和出棧之間所作的一切改動(dòng)取消。例如:Spragmawarning(push)#pragmawarning(disable:4705)#pragmawarning(disable:4706)Spragmawarning(disable:4707)Spragmawarning(pop)在這段代碼的最后,重新保存所有的警告信息(包括4705,4706和4707)在使用標(biāo)準(zhǔn)C++進(jìn)行編程的時(shí)候經(jīng)常會(huì)得到很多的警告信息,面這些警告信息都是不必要的提示,所以我們可以使用#pragmawarning(disable:4786)來(lái)禁止該類型的警告在vc中使用ADO的時(shí)候也會(huì)得到不必要的警告信息,這個(gè)時(shí)候我們可以通過(guò)Spragmawarning(disable:4146)來(lái)消除該類型的警告信息六?pragmacomment(...)該指令的格式為#pragmacomment("comment-type*[,commentstring])該指令將一個(gè)注釋記錄放入ー個(gè)對(duì)象文件或可執(zhí)行文件中,comment-type(注釋類型):可以指定為五種預(yù)定義的標(biāo)識(shí)符的其中一種五種預(yù)定義的標(biāo)識(shí)符為:compiler:將編譯器的版本號(hào)和名稱放入目標(biāo)文件中,本條注釋記錄將被編譯器忽略如果你為該記錄類型提供了commentstring參數(shù),編譯器將會(huì)產(chǎn)生?■一個(gè)警告例如:#pragmacomment(compiler)exestr:將commentstring參數(shù)放入目標(biāo)文件中,在鏈接的時(shí)候這個(gè)字符串將被放入到可執(zhí)行文件中,當(dāng)操作系統(tǒng)加載可執(zhí)行文件的時(shí)候,該參數(shù)字符串不會(huì)被加載到內(nèi)存中.但是,該字符串可以被dumpbin之類的程序査找出并打印出來(lái),你可以用這個(gè)標(biāo)識(shí)符將版本號(hào)碼之類的信息嵌入到可執(zhí)行文件中!1ib:這是ー個(gè)非常常用的關(guān)鍵字,用來(lái)將一個(gè)庫(kù)文件鏈接到目標(biāo)文件中常用的lib關(guān)鍵字,可以幫我們連入ー個(gè)庫(kù)文件。例如:#pragmacomment(lib,“user32.lib")該指令用來(lái)將user32.lib庫(kù)文件加入到本工程中l(wèi)inker:將一個(gè)鏈接選項(xiàng)放入目標(biāo)文件中,你可以使用這個(gè)指令來(lái)代替由命令行傳入的或者在開發(fā)環(huán)境中設(shè)置的鏈接選項(xiàng),你可以指定/include選項(xiàng)來(lái)強(qiáng)制包含某個(gè)對(duì)象,例如:#pragmacomment(linker,"/include:_mySymbol")你可以在程序中設(shè)置下列鏈接選項(xiàng)/DEFAULTLIB/EXPORT/INCLUDE/MERGE/SECTION這些選項(xiàng)在這里就不ー,ー說(shuō)明了,詳細(xì)信息請(qǐng)看msdn!user:將一般的注釋信息放入目標(biāo)文件中commentstring參數(shù)包含注釋的文本信息,這個(gè)注釋記錄將被鏈接器忽略例如:Spragmacomment(user,"Compiledon"DATE *at* TIME)補(bǔ)充一個(gè)Spragmapack(n)控制對(duì)齊如Spragmapack(push)ttpragmapack(1)structs_l{charszname[l];inta;);#pragmapack(pop)structs_2{charszname[l];inta;);則printf(,zs_lsize:%d\n〃,sizeof(structs_l));printf(/zs_2size:%d\n〃,sizeof(structs_2));得到5,8〇#pragma的用法#pragma是ー個(gè)C語(yǔ)言中的預(yù)處理指令,它的作用是設(shè)定編譯器的狀態(tài)或者是指示編譯器完成一些特定的動(dòng)作。依據(jù)定義,編譯指示是機(jī)器或操作系統(tǒng)專有的,且對(duì)于每個(gè)編譯器都是不同的。其格式一般為:ttpragmaPara其中Para為參數(shù),下面來(lái)看ー些常用的參數(shù)。(l)message參數(shù)。Message參數(shù)是我最喜歡的ー個(gè)參數(shù),它能夠在編譯信息輸出]窗口中輸出相應(yīng)的信息,這對(duì)于源代碼信息的控制是非常重要的。其使用方法為:SPragmamessage("消息文本”)當(dāng)編譯器遇到這條指令時(shí)就在編譯輸出窗口中將消息文本打印出來(lái)。當(dāng)我們?cè)诔绦蛑卸x了許多宏來(lái)控制源代碼版本的時(shí)候,我們自己有可能都會(huì)忘記有沒(méi)有正確的設(shè)置這些宏,此時(shí)我們可以用這條指令在編譯的時(shí)候就進(jìn)行檢査。假設(shè)我們希望判斷自己有沒(méi)有在源代碼的什么地方定義了一X86這個(gè)宏可以用下面的方法#ifdef_X86SPragmamessage("_X86macroactivated!")ftendif當(dāng)我們定義了一X86這個(gè)宏以后,應(yīng)用程序在編譯時(shí)就會(huì)在編譯輸出窗口里顯示X86macroactivated!"〇我們就不會(huì)因?yàn)椴挥浀米约憾x的ー些特定的宏而抓耳撓腮了(2)另?個(gè)使用得比較多的pragma參數(shù)是code_seg0格式如:Spragmacode_seg([“section-name“しsection-class"]])它能夠設(shè)置程ホ中函數(shù)代碼存放的代碼段,當(dāng)我們開發(fā)驅(qū)動(dòng)程序的時(shí)候就會(huì)使用到它。(3)#pragmaonce(比較常用)只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次,這條指令實(shí)際上在VC6中就已經(jīng)有了,但是考慮到兼容性并沒(méi)有太多的使用它。(4)#pragmahdrstop表示預(yù)編譯頭文件到此為止,后面的頭文件不進(jìn)行預(yù)編譯。BCB可以預(yù)編譯頭文件以加快鏈接的速度,但如果所有頭文件都進(jìn)行預(yù)編譯又可能占太多磁盤空間,所以使用這個(gè)選項(xiàng)排除ー些頭文件。有時(shí)單元之間有依賴關(guān)系,比如單元A依賴單元B,所以單元B要先于單元A編譯。你可以用#pragmastartup指定編譯優(yōu)先級(jí),如果使用了#pragmapackage(smart_init),BCB就會(huì)根據(jù)優(yōu)先級(jí)的大小先后編譯。(5)ftpragmaresource dfm”表示把?.dfm文件中的資源加入工程。*.dfm中包括窗體外觀的定義。(6)#pragmawarning(disable:450734;once:4385;error:164)等價(jià)于:Spragmawarning(disable:450734)//不顯示4507和34號(hào)警告信息Spragmawarning(once:4385)//4385號(hào)警告信息僅報(bào)告ー一次Spragmawarning(error:164)/Z把164號(hào)警告信息作為ー個(gè)錯(cuò)誤。同時(shí)這個(gè)pragmawarning也支持如下格式:Spragmawarning(push[,n])Spragmawarning(pop)這里n代表ー個(gè)警告等級(jí)(1一一4)。#pragmawarning(push)保存所有警告信息的現(xiàn)有的警告狀態(tài)。#pragmawarning(push,n)保存所有警告信息的現(xiàn)有的警告狀態(tài),并且把全局警告等級(jí)設(shè)定為n。#pragmawarning(pop)向棧中彈出最后ー個(gè)警告信息,在入棧和出棧之間所作的一切改動(dòng)取消。例如:#pragmawarning(push)#pragmawarning(disable:4705)Spragmawarning(disable:4706)Spragmawarning(disable:4707)// #pragmawarning(pop)在這段代碼的最后,重新保存所有的警告信息(包括4705,4706和4707)。pragmacomment(...)該指令將一個(gè)注釋記錄放入ー個(gè)對(duì)象文件或可執(zhí)行文件中。常用的lib關(guān)鍵字,可以幫我們連入ー個(gè)庫(kù)文件。progmapack(n)指定結(jié)構(gòu)體對(duì)齊方式!Spragmapack(n)來(lái)設(shè)定變量以n字節(jié)對(duì)齊方式。n字節(jié)對(duì)齊就是說(shuō)變量存放的起始地址的偏移量有兩種情況:第一、如果n大于等于該變量所占用的字節(jié)數(shù),那么偏移量必須滿足默認(rèn)的對(duì)齊方式,第二、如果n小于該變量的類型所占用的字節(jié)數(shù),那么偏移量為n的倍數(shù),不用滿足默認(rèn)的對(duì)齊方式。結(jié)構(gòu)的總大小也有個(gè)約束條件,分下面兩種情況:如果n大于所有成員變量類型所占用的字節(jié)數(shù),那么結(jié)構(gòu)的總大小必須為占用空間最大的變量占用的空間數(shù)的倍數(shù);否則必須為n的倍數(shù)。下面舉例說(shuō)明其用法。Spragmapack(push)〃保存對(duì)齊狀態(tài)Spragmapack(4)〃設(shè)定為4字節(jié)對(duì)齊structtest(charml;doublem4;intm3;};Spragmapack(pop)〃恢復(fù)對(duì)齊狀態(tài)為測(cè)試該功能,可以使用sizeof()測(cè)試結(jié)構(gòu)體的長(zhǎng)度!VC預(yù)定義的宏在VC中有一類宏并不是由用戶用#define語(yǔ)句定義的,而是編譯器本身就能夠識(shí)別它們。這些宏的作用也是相當(dāng)大的。讓我們來(lái)看第一個(gè),也是MFC中使用得最頻繁的ー個(gè):_FILE_〇當(dāng)編譯器遇到這個(gè)宏時(shí)就把它展開成當(dāng)前被編譯文件的文件名。好了,我們馬上就可以想到可以用它來(lái)做什么,當(dāng)應(yīng)用程序發(fā)生錯(cuò)誤時(shí),我們可以報(bào)告這個(gè)錯(cuò)誤發(fā)生的程序代碼在哪個(gè)文件里,比方在文件test,cpp中有這樣的代碼:try{'char*p=new(char[10]);)catch(CException*e)(TRACE(athereisanerrorinfile:%s\n”,_FILE );在程序運(yùn)行的時(shí)候,如果內(nèi)存分配出現(xiàn)了錯(cuò)誤,那么在調(diào)試窗口中會(huì)出現(xiàn)thereisanerrorinfile:test,cpp這句話,當(dāng)然,我們還可以把這個(gè)錯(cuò)誤信息顯示在別的地方。如果我們還能夠記錄錯(cuò)誤發(fā)生在哪一行就好了,幸運(yùn)的是,與_FILE_宏定義ー樣,還有一個(gè)宏記錄了當(dāng)前代碼所在的行數(shù),這個(gè)宏是_LINE_。使用上面的兩個(gè)宏,我們可以寫出ー個(gè)類似于VC提供的ASSERT語(yǔ)句。下面是方法#defineMyAssert(x)\if(!(x))\MessageBox(_FILE_,_LINE_,NULL,MB_OK);我們?cè)趹?yīng)用程序中可以象使用ASSERT語(yǔ)句ー樣使用它,在錯(cuò)誤發(fā)生時(shí),它會(huì)彈出ー個(gè)對(duì)話框,其標(biāo)題和內(nèi)容告訴了我們錯(cuò)誤發(fā)生的文件和代碼行號(hào),方便我們的調(diào)試,這對(duì)于不能使用ASSERT語(yǔ)句的項(xiàng)目來(lái)說(shuō)是非常有用的。除了這兩個(gè)宏以外,還有記錄編譯時(shí)間的_TIME_,記錄日期的_DATE_,以及記錄文件修改時(shí)間的ーTIMESTAMP_宏。使用這些預(yù)定義的宏,我們兒乎可以生成和VC能夠生成的一樣完整的源代碼信息報(bào)表。結(jié)論翻開MFC和Linux的源代碼,宏定義幾乎占據(jù)了半邊天,消息映射,隊(duì)列操作,平臺(tái)移植,版本管理,甚至內(nèi)核模塊的拆卸安裝都用宏定義完成。毫不夸張的說(shuō),有些文件甚至就只能看見宏定義。所以學(xué)習(xí)宏定義,熟練的使用宏定義對(duì)于學(xué)習(xí)C語(yǔ)言乃至VC都是非常關(guān)鍵的。在上一篇文章中,我演示了兒個(gè)常用的宏定義和預(yù)處理指令,但可以說(shuō)這些都是相當(dāng)常規(guī)的技巧。下面要介紹的宏定義與預(yù)處理指令的用法也是ATL,MFC以及LINUX中使用得比較多的非常重要的技巧。##連接符與#符##連接符號(hào)由兩個(gè)井號(hào)組成,其功能是在帶參數(shù)的宏定義中將兩個(gè)子串(token)聯(lián)接起來(lái),從而形成一個(gè)新的子串。但它不可以是第一個(gè)或者最后一個(gè)子串。所謂的子串(token)就是指編譯器能夠識(shí)別的最小語(yǔ)法單元。具體的定義在編譯原理里有詳盡的解釋,但不知道也無(wú)所謂。同時(shí)值得注意的是#符是把傳遞過(guò)來(lái)的參數(shù)當(dāng)成字符串進(jìn)行替代。下面來(lái)看看它們是怎樣工作的。這是MSDN上的ー個(gè)例子。假設(shè)程序中已經(jīng)定義了這樣ー個(gè)帶參數(shù)的宏:Sdefinepaster(n)printf("token"#n"=%d",token##n)同時(shí)又定義了一個(gè)整形變量:inttoken9=9;現(xiàn)在在主程序中以下面的方式調(diào)用這個(gè)宏:paster(9);那么在編譯時(shí),上面的這句話被擴(kuò)展為:printf("token""9""=%d",token9);注意到在這個(gè)例子中,paster(9);中的這個(gè)"9"被原封不動(dòng)的當(dāng)成了一個(gè)字符串,與“token”連接在了一起,從而成為了token9o而#n也被“9”所替代。可想而知,上面程序運(yùn)行的結(jié)果就是在屏幕上打印出token9=9在ATL的編程中,我們查看它的源代碼就會(huì)經(jīng)??匆娺@樣的一段:#defineIMPLEMENTS_INTERFACE(Itf)\{&IID_##Itf,ENTRY_IS_OFFSET,BASE_OFFSET(_ITCls,Itf)},我們經(jīng)常不假思索的這樣使用它:IMPLEMENTS_INTERFACE(ICat)實(shí)際上IID」Cat已經(jīng)在別的地方由ATL向?qū)Фx了。當(dāng)沒(méi)有向?qū)У臅r(shí)候,你只要遵循把IIDJJロ在你的接口名前面來(lái)定義GUID的規(guī)則就也可以使用這個(gè)宏。在實(shí)際的開發(fā)過(guò)程中可能很少用到這種技巧,但是ATL使用得如此廣泛,而其中又出現(xiàn)了不少這樣的源代碼,所以明白它是怎么一回事也是相當(dāng)重要的。我的?個(gè)朋友就是因?yàn)椴恢繧MPLEMENTSJNTERFACE宏是怎么定義的,而又不小心改動(dòng)了!ID_ICat的定義而忙活了一整天。Linux的怪圈在剛開始閱讀Linux的時(shí)候有一個(gè)小小的宏讓我百思不得其解:#definewaitevent(wq,condition)\do{\if(condition)\break;\_wait_event(wq,condition);\}while(0)這是一個(gè)奇怪的循環(huán),它根本就只會(huì)運(yùn)行一次,為什么不去掉外面的do{..}while結(jié)構(gòu)呢?我曾一度在心里把它叫做“怪圈”。原來(lái)這也是非常巧妙的技巧。在工程中可能經(jīng)常會(huì)引起麻煩,而上面的定義能夠保證這些麻煩不會(huì)出現(xiàn)。下面是解釋:假設(shè)有這樣一個(gè)宏定義Sdefinemacro(condition)\if(condition)dosomethingO;現(xiàn)在在程序中這樣使用這個(gè)宏:if(temp)macro(i);elsedoanotherthing();一切看起來(lái)很正常,但是仔細(xì)想想。這個(gè)宏會(huì)展開成:if(temp)if(condition)dosomethingO;elsedoanotherthing();這時(shí)的else不是與第一個(gè)if語(yǔ)句匹配,而是錯(cuò)誤的與第二個(gè)if語(yǔ)句進(jìn)行了匹配,編譯通過(guò)了,但是運(yùn)行的結(jié)果一定是錯(cuò)誤的。為了避免這個(gè)錯(cuò)誤,我們使用do{….}while(0)把它包裹起來(lái),成為…個(gè)獨(dú)立的語(yǔ)法單元,從而不會(huì)與上下文發(fā)生混淆。同時(shí)因?yàn)榻^大多數(shù)的編譯器都能夠識(shí)別do{…}while(O)這種無(wú)用的循環(huán)并進(jìn)行優(yōu)化,所以使用這種方法也不會(huì)導(dǎo)致程序的性能降低。幾個(gè)小小的警告正如微軟聲稱的ー樣,宏定義與預(yù)編譯器指令是強(qiáng)大的,但是它又使得程序難以調(diào)試。所以在定義宏的時(shí)候不要節(jié)省你的字符串,一定要力爭(zhēng)完整的描述這個(gè)宏的功能。同時(shí)在定義宏的時(shí)候如有必要(比方使用了if語(yǔ)句)就要使用do{…}while(O)將它封閉起來(lái)。在宏定義的時(shí)候一定要注意各個(gè)宏之間的相互依賴關(guān)系,盡量避免這種依賴關(guān)系的存在。下面就有這樣?個(gè)例子。設(shè)有一個(gè)靜態(tài)數(shù)組組成的整型隊(duì)列,在定義中使用了這樣的方法:intarray[]={5,6,7,8};我們還需要在程序中遍歷這個(gè)數(shù)組。通常的做法是使用?個(gè)宏定義#defineELE一NUM4for(intI=O;KELE_NUM;I++)(coutくくarray[I];由于某種偶然的原因,我們刪除了定義中的ー個(gè)元素,使它變成:array[]={5,6,7}而卻忘了修改ELE_NUM的值。那么在上面的代碼中馬上就會(huì)發(fā)生訪問(wèn)異常,程序崩潰。然后是徹夜ネ眠的調(diào)試,最后發(fā)現(xiàn)問(wèn)題出在這個(gè)宏定義上。解決這個(gè)問(wèn)題的方法是不使用array[]={….}這樣的定義,而顯式的申明數(shù)組的大?。篴rray[ELENUM]={?,,.}這樣在改動(dòng)數(shù)組定義的時(shí)候,我們就不會(huì)不記得去改宏定義了??傊?就是在使用宏定義的時(shí)候能夠用宏定義的地方統(tǒng)統(tǒng)都用上。我發(fā)現(xiàn)的另ー個(gè)有趣的現(xiàn)象是這樣的:假設(shè)現(xiàn)在有一個(gè)課程管理系統(tǒng),學(xué)生的人數(shù)用宏定義為:SdefineSTU_NUM50而老師的人數(shù)恰好也是50人,于是很多人把所有涉及到老師人數(shù)的地方通通用上STLNUM這個(gè)宏。另ー個(gè)學(xué)期過(guò)去,學(xué)生中的一個(gè)被開除了,系統(tǒng)需要改變。怎么辦呢?簡(jiǎn)單的使用#defineSTU_NUM49么?如果是這樣,ー個(gè)老師也就被開除了,我們不得不手エ在程序中去找那些STU_NUM宏然后判斷它是否是表示學(xué)生的數(shù)目,如果是,就把它改成49。天哪,這個(gè)宏定義制造的麻煩比使用它帶來(lái)的方便還多。正確的方法應(yīng)該是為老師的數(shù)目另外定義ー個(gè)宏:^defineTEANUM50當(dāng)學(xué)生的數(shù)目改變以后只要把STU_NUM定義為49就完成了系統(tǒng)的更改。所以,當(dāng)程序中的兩個(gè)量之間沒(méi)有必然聯(lián)系的時(shí)候一定不要用其中的ー個(gè)宏去替代另ー個(gè),那只會(huì)讓你的程序根本無(wú)法改動(dòng)。最后,建議C/C++語(yǔ)言的初學(xué)者盡可能多的在你的程序中使用宏定義和預(yù)編譯指令。多看看MFC,ATL或者LINUX的源代碼,你會(huì)發(fā)現(xiàn)C語(yǔ)言強(qiáng)大的原因所在。在#Pragma是預(yù)處理指令它的作用是設(shè)定編譯器的狀態(tài)或者是指示編譯器完成ー些特定的動(dòng)作。#pragma指令對(duì)每個(gè)編譯器給出了一個(gè)方法,在保持與C和C++語(yǔ)言完全兼容的情況下,給出主機(jī)或操作系統(tǒng)專有的特征。依據(jù)定義,編譯指示是機(jī)器或操作系統(tǒng)專有的,且對(duì)于每個(gè)編譯器都是不同的。其格式ー一般為:^PragmaPara其中Para為參數(shù),下面來(lái)看一些常用的參數(shù)。(1)message參數(shù)。Message參數(shù)是我最喜歡的?,個(gè)參數(shù),它能夠在編譯信息輸出窗口中輸出相應(yīng)的信息,這對(duì)于源代碼信息的控制是非常重要的。其使用方法為:#Pragmamessage("消息文本”)當(dāng)編譯器遇到這條指令時(shí)就在編譯輸出窗口中將消息文本打印出來(lái)。當(dāng)我們?cè)诔绦蛑卸x了許多宏來(lái)控制源代碼版本的時(shí)候,我們自己有可能都會(huì)忘記有沒(méi)有正確的設(shè)置這些宏,此時(shí)我們可以用這條指令在編譯的時(shí)候就進(jìn)行檢查。假設(shè)我們希望判斷自己有沒(méi)有在源代碼的什么地方定義了一X86這個(gè)宏可以用下面的方法#ifdef_X86^Pragmamessage("_X86macroactivated!")#endif當(dāng)我們定義了一X86這個(gè)宏以后,應(yīng)用程序在編譯時(shí)就會(huì)在編譯輸出窗口里顯示X86macroactivated!"〇我們就不會(huì)因?yàn)椴挥浀米约憾x的ー些特定的宏而抓耳撓腮了。(2)另ー個(gè)使用得比較多的pragma參數(shù)是code_sego格式如:#pragmacode_seg([\section-name\[,ヽsection-classヽ[])它能夠設(shè)置程序中函數(shù)代碼存放的代碼段,使用沒(méi)有section-name字符串的#pragmacode_seg可在編譯開始時(shí)將其復(fù)位,當(dāng)我們開發(fā)驅(qū)動(dòng)程序的時(shí)候就會(huì)使用到它。(3)#pragmaonce(比較常用)只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次,這條指令實(shí)際上在VC6中就已經(jīng)有了,但是考慮到兼容性并沒(méi)有太多的使用它。(4)#pragmahdrstop表示預(yù)編譯頭文件到此為止,后面的頭文件不進(jìn)行預(yù)編譯。BCB可以預(yù)編譯頭文件以加快鏈接的速度,但如果所有頭文件都進(jìn)行預(yù)編譯又可能占太多磁盤空間,所以使用這個(gè)選項(xiàng)排除一些頭文件。有時(shí)單元之間有依賴關(guān)系,比如單元A依賴單元B,所以單元B要先于單元A編譯。你可以用#Pragmastartup指定編譯優(yōu)先級(jí),如果使用了#pragmapackage(smart_init),BCB就會(huì)根據(jù)優(yōu)先級(jí)的大小先后編譯。(5)#pragmaresource\*.dfmゝ表示把?.dfm文件中的資源加入工程。?.dfm中包括窗體外觀的定義。#pragmawarning(disable:450734;once:4385;error:164)等價(jià)于:Spragmawarning(disable:450734)//不顯示4507和34號(hào)警告信息#pragmawarning(once:4385)//4385號(hào)警告信息僅報(bào)告一次Spragmawarning(error:164)/Z把164號(hào)警告信息作為ー個(gè)錯(cuò)誤。同時(shí)這個(gè)pragmawarning也支持如下格式:#pragmawarning(push[,n])這里n代表ー個(gè)警告等級(jí)(1—4)〇#pragmawarning(push)保存所有警告信息的現(xiàn)有的警告狀態(tài)。#pragmawarning(push,n)保存所有警告信息的現(xiàn)有的警告狀態(tài),并且把全局警告等級(jí)設(shè)定為n。#pragmawarning(pop)向棧中彈出最后ー個(gè)警告信息,在入棧和出棧之間所作的一切改動(dòng)取消。例如:#pragmawarning(push)Spragmawarning(disable:4705)#pragmawarning(disable:4706)#pragmawarning(disable:4707)// #pragmawarning(pop)在這段代碼的最后,重新保存所有的警告信息(包括4705,4706和4707)。pragmacomment(...)該指令將一個(gè)注釋記錄放入ー個(gè)對(duì)象文件或可執(zhí)行文件中。常用的lib關(guān)鍵字,可以幫我們連入ー個(gè)庫(kù)文件。?通過(guò)#pragmapack(n)改變C編譯器的字節(jié)對(duì)齊方式在C語(yǔ)言中,結(jié)構(gòu)是ー種復(fù)合數(shù)據(jù)類型,其構(gòu)成元素既可以是基本數(shù)據(jù)類型(如int、long、float等)的變量,也可以是ー些復(fù)合數(shù)據(jù)類型(如數(shù)組、結(jié)構(gòu)、聯(lián)合等)的數(shù)據(jù)單元。在結(jié)構(gòu)中,編譯器為結(jié)構(gòu)的每個(gè)成員按其自然對(duì)界(alignment)條件分配空間。各個(gè)成員按照它們被聲明的順序在內(nèi)存中順序存儲(chǔ),第一個(gè)成員的地址和整個(gè)結(jié)構(gòu)的地址相同。例如,下面的結(jié)構(gòu)各成員空間分配情況:structtest(charxl;shortx2;floatx3;charx4;);結(jié)構(gòu)的第一個(gè)成員xl,其偏移地址為〇,占據(jù)了第1個(gè)字節(jié)。第二個(gè)成員x2為short類型,其起始地址必須2字節(jié)對(duì)界,因此,編譯器在x2和xl之間填充了ー個(gè)空字節(jié)。結(jié)構(gòu)的第三個(gè)成員
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 電子商務(wù)教師資格重要考試試題及答案集
- 明確金融產(chǎn)品設(shè)計(jì)的試題及答案
- 電子商務(wù)師考試的復(fù)習(xí)策略試題及答案
- 中職電子商務(wù)學(xué)習(xí)方法探討試題及答案
- 2024年國(guó)際物流師成功案例試題及答案
- 2024年計(jì)算機(jī)二級(jí)考試解題思路試題及答案
- 中職資格認(rèn)證試題及答案大全
- 2024監(jiān)理工程師考試答題技巧分享試題及答案
- 2024計(jì)算機(jī)二級(jí)軟件應(yīng)用試題及答案
- 全球氣候變化影響分析-試題及答案
- 澳大利亞PSC檢查經(jīng)過(guò)
- 01-14江蘇大學(xué)車輛工程考研復(fù)試真題答案
- TMYZX 001-2021 釀酒專用小麥原糧
- 2023年湖北國(guó)土資源職業(yè)學(xué)院高職單招(數(shù)學(xué))試題庫(kù)含答案解析
- GB/T 37910.1-2019焊縫無(wú)損檢測(cè)射線檢測(cè)驗(yàn)收等級(jí)第1部分:鋼、鎳、鈦及其合金
- 雷鋒叔叔你在哪里教學(xué)反思
- (新版)國(guó)家統(tǒng)計(jì)執(zhí)法證資格考試備考題庫(kù)(含答案)
- 項(xiàng)目驗(yàn)收單標(biāo)準(zhǔn)模板
- 24式太極拳教案(1~4課)
- 小學(xué) 三年級(jí) 心理健康《最好的老師-興趣的作用》教學(xué)設(shè)計(jì)
- DB12T 1040-2021 建筑工程規(guī)劃管理技術(shù)規(guī)范
評(píng)論
0/150
提交評(píng)論