1、#include指令
包含指定的文件
2、#define指令
預定義,通常用它來(lái)定義常量(包括無(wú)參量與帶參量),以及用來(lái)實(shí)現那些“表面似和善、背后一長(cháng)串”的宏,它本身并不在編譯過(guò)程中進(jìn)行,而是在這之前(預處理過(guò)程)就已經(jīng)完成了
3、#typedef指令
常用來(lái)定義一個(gè)標識符及關(guān)鍵字的別名它是語(yǔ)言編譯過(guò)程的一部分,但它并不實(shí)際分配內存空間。
4、#ifndef #else #endif指令
條件編譯。一般情況下,源程序中所有的行都參加編譯。但是有時(shí)希望對其中一部分內容只在滿(mǎn)足一定條件才進(jìn)行編譯,也就是對一部分內容指定編譯的條件,這就是“條件編譯”。有時(shí),希望當滿(mǎn)足某條件時(shí)對一組語(yǔ)句進(jìn)行編譯,而當條件不滿(mǎn)足時(shí)則編譯另一組語(yǔ)句。
條件編譯命令最常見(jiàn)的形式為:
#ifdef 標識符
程序段1
#else
程序段2
#endif
它的作用是:當標識符已經(jīng)被定義過(guò)(一般是用#define命令定義),則對程序段1進(jìn)行編譯,否則編譯程序段2。
5、#Pragma 指令
在所有的預處理指令中,#Pragma 指令可能是最復雜的了,它的作用是設定編譯器的狀態(tài)或者是指示編譯器完成一些特定的動(dòng)作。其格式一般為
#Pragma Para
其中Para 為參數,下面來(lái)看一些常用的參數。
l message 參數。它能夠在編譯信息輸出窗口中輸出相應的信息,這對于源代碼信息的控制是非常重要的。其使用方法為:
#Pragma message(“消息文本”)
當編譯器遇到這條指令時(shí)就在編譯輸出窗口中將消息文本打印出來(lái)。
當我們在程序中定義了許多宏來(lái)控制源代碼版本的時(shí)候,我們自己有可能都會(huì )忘記有沒(méi)有正確的設置這些宏,此時(shí)我們可以用這條指令在編譯的時(shí)候就進(jìn)行檢查。假設我們希望判斷自己有沒(méi)有在源代碼的什么地方定義了_X86這個(gè)宏可以用下面的方法
#ifdef _X86
#Pragma message(“_X86 macro activated!”)
#endif
當我們定義了_X86這個(gè)宏以后,應用程序在編譯時(shí)就會(huì )在編譯輸出窗口里顯示“_X86 macro activated!”。我們就不會(huì )因為不記得自己定義的一些特定的宏而抓耳撓腮了
l 另一個(gè)使用得比較多的pragma參數是code_seg。格式如:
#pragma code_seg( ["section-name"[,"section-class"] ] )
它能夠設置程序中函數代碼存放的代碼段,當我們開(kāi)發(fā)驅動(dòng)程序的時(shí)候就會(huì )使用到它。
l #pragma once
只要在頭文件的最開(kāi)始加入這條指令就能夠保證頭文件被編譯一次,這條指令實(shí)際上在VC6中就已經(jīng)有了,但是考慮到兼容性并沒(méi)有太多的使用它。
l #pragma hdrstop
表示預編譯頭文件到此為止,后面的頭文件不進(jìn)行預編譯。BCB可以預編譯頭文件以加快鏈接的速度,但如果所有頭文件都進(jìn)行預編譯又可能占太多磁盤(pán)空間,所 以使用這個(gè)選項排除一些頭文件。有時(shí)單元之間有依賴(lài)關(guān)系,比如單元A依賴(lài)單元B,所以單元B要先于單元A編譯。你可以用#pragma startup指 定編譯優(yōu)先級,如果使用了#pragma package(smart_init) ,BCB就會(huì )根據優(yōu)先級的大小先后編譯。
l #pragma resource "*.dfm"
表示把*.dfm文件中的資源加入工程。*.dfm中包括窗體外觀(guān)的定義。
l #pragma warning( disable : 4507 34; once : 4385; error : 164 )
等價(jià)于:
#pragma warning(disable:4507 34) // 不顯示4507和34號警告信息
#pragma warning(once:4385) // 4385號警告信息僅報告一次
#pragma warning(error:164) // 把164號警告信息作為一個(gè)錯誤。
同時(shí)這個(gè)pragma warning 也支持如下格式:
#pragma warning( push [ ,n ] )
#pragma warning( pop )
這里n代表一個(gè)警告等級(1---4)。
#pragma warning( push )保存所有警告信息的現有的警告狀態(tài)。
#pragma warning( push, n)保存所有警告信息的現有的警告狀態(tài),并且把全局警告
等級設定為n。
#pragma warning( pop )向棧中彈出最后一個(gè)警告信息,在入棧和出棧之間所作的
一切改動(dòng)取消。例如:
#pragma warning( push )
#pragma warning( disable : 4705 )
#pragma warning( disable : 4706 )
#pragma warning( disable : 4707 )
//.......
#pragma warning( pop )
在這段代碼的最后,重新保存所有的警告信息(包括4705,4706和4707)。
l pragma comment(...)
該指令將一個(gè)注釋記錄放入一個(gè)對象文件或可執行文件中。
常用的lib關(guān)鍵字,可以幫我們連入一個(gè)庫文件。
每個(gè)編譯程序可以用#pragma指令激活或終止該編譯程序支持的一些編譯功能。例如,對循環(huán)優(yōu)化功能:
#pragma loop_opt(on) // 激活
#pragma loop_opt(off) // 終止
有時(shí),程序中會(huì )有些函數會(huì )使編譯器發(fā)出你熟知而想忽略的警告,如“Parameter xxx is never used in function xxx”,可以這樣:
#pragma warn —100 // Turn off the warning message for warning #100
int insert_record(REC *r)
{ /* function body */ }
#pragma warn +100 // Turn the warning message for warning #100 back on
函數會(huì )產(chǎn)生一條有唯一特征碼100的警告信息,如此可暫時(shí)終止該警告。
每個(gè)編譯器對#pragma的實(shí)現不同,在一個(gè)編譯器中有效在別的編譯器中幾乎無(wú)效??蓮木幾g器的文檔中查看。
6、宏:__LINE__ 和__FILE__
定義源程序文件名和代碼行,這對于調試跟蹤代碼錯誤行很有幫助。
__TIME__ :編譯時(shí)間
__DATE__ :編譯日期
__TIMESTAMP__ :文件修改時(shí)間
7、調試宏:ASSERT()、VERIFY()、TRACE()
這三個(gè)宏在Debug環(huán)境下特別有效,常用于代碼的跟蹤調試。它們是否起作用取決于是否定義了預定義了宏 _DEBUG
l ASSERT
ASSERT(booleanExpression)
說(shuō)明:
計算變量的值。如果結構的值為0,那么此宏便打印一個(gè)診斷消息并且程序運行失敗。如果條件為非0,那么什么也不做。診斷消息的形式為: assertion failed in file in line 其中name是元文件名,num是源文件中運行失敗的中斷號。 在Release 版中,ASSERT不計算表達式的值也就不中斷程序。如果必須計算此表達式的值且不管環(huán)境如何那么用VERIFY代替ASSERT。
這個(gè)宏通常原來(lái)判斷程序中是否出現了明顯非法的數據,如果出現了終止程序以免導致嚴重后果,同時(shí)也便于查找錯誤。
ASSERT_VAILD
ASSERT_VAILD(pObject)
說(shuō)明:
用于檢測關(guān)于對象的內部狀態(tài)的有效性。ASSERT_VALID調用此對象的AssertValid成員函數(把它們作為自己的變量來(lái)傳遞)。在 Release版中ASSERT_VALID什么也不做。在DEBUG版中,他檢查指針,以不同于NULL的方式進(jìn)行檢查,并調用對象自己的 AssertValid成員函數。如果這些檢測中有任何一個(gè)失敗的話(huà),那么他會(huì )以與ASSERT相同的方法顯示一個(gè)警告的消息。
l VERIFY
VERIFY(booleanExpression)
說(shuō)明:
在MFC的DEBUG版中,VERIFY宏計算它的變量值。如果結果為0,那么宏打印一個(gè)診斷消息并中止程序。如果條件不為0,那么什么工作也不作。診斷 有如下形式: assertion failed in file in line 其中name是源文件的名字,num是在源文件中失敗的中止行號。在 MFC的Release版中,VERIFY計算表達式值但不打印或中止程序。例如:如果表達式是個(gè)函數調用,那么調用成功。
l TRACE
TRACE(exp)
說(shuō)明:
把一個(gè)格式化字符串送到轉儲設備,例如,文件或調試監視器,功能上和printf相似,可以說(shuō)就是調試環(huán)境下printf的一個(gè)拷貝。TRACE宏是一個(gè) 在程序運行時(shí)跟蹤變量值的方便形式。在DEBUG環(huán)境中,TRACE宏輸出到afxDump。在Release版中他不做任何工作。另外還有一組可以帶參 數的相似的宏:TRACE0、TRACE1、TRACE2和TRACE3。提供格式如:
TRACE0(exp)
TRACE1(exp,param1)
TRACE2(exp,param1,param2)
TRACE3(exp,param1,param2,param3)
與TRACE相似,但它把跟蹤字符串放在代碼段中,而不是DGROUP,因此使用少的DGROUP空間。這些宏的用法和printf類(lèi)似。
8、消息處理宏:DECLARE_MESSAGE_MAP 、BEGIN_MESSAGE_MAP、END_MESSAGE_MAP
DECLARE_MESSAGE_MAP()
說(shuō)明:
用戶(hù)程序中的每個(gè)CCmdTarget派生類(lèi)必須提供消息映射以處理消息。在類(lèi)定義的末尾使用DECLARE_MESSAGE_MAP宏。接著(zhù),在定義類(lèi) 成員函數的.CPP文件中,使用BEGIN_MESSAGE_MAP宏,每個(gè)用戶(hù)消息處理函數的宏項下面的列表以及END_MESSAGE_MAP宏。
注釋?zhuān)?
如果在DECLARE_MESSAGE_MAP之后定義任何一個(gè)成員,那么必須為他們指定一個(gè)新存取類(lèi)型(公共的,私有的,保護的)。
BEGIN_MESSAGE_MAP(the class,baseclass)
END_MESSAGE_MAP
說(shuō)明:
使用BEGIN_MESSAGE_MAP開(kāi)始用戶(hù)消息映射的定義。在定義用戶(hù)類(lèi)函數的工具(.cpp)文件中,以BEGIN_MESSAGE_MAP宏開(kāi)始消息映射,然后為每個(gè)消息處理函數增加宏項,接著(zhù)以END_MESSAGE_MAP宏完成消息映射。
9、消息映射宏:ON_COMMAND 、ON_CONTROL、ON_MESSAGE、ON_VBXEVENT、ON_Update_COMMAND_UI和ON_REGISTERED_MESSAGE
ON_COMMAND(id,memberFxn)
說(shuō)明:
此宏通過(guò)ClassWizard或手工插入一個(gè)消息映射。它表明那個(gè)函數將從一個(gè)命令用戶(hù)接口(例如一個(gè)菜單項或toolbar按鈕)處理一個(gè)命令消息。 當一個(gè)命令對象通過(guò)指定的ID接受到一個(gè)Windows WM_COMMAND消息時(shí),ON_COMMAND將調用成員函數memberFxn處理此消 息。在用戶(hù)的消息映射中,對于每個(gè)菜單或加速器命令(必須被映射到一個(gè)消息處理函數)應該確實(shí)有一個(gè)ON_COMMAND宏語(yǔ)句。
ON_CONTROL(wNotifyCode,id,memberFxn)
說(shuō)明:
表明哪個(gè)函數將處理一個(gè)常規控制表示消息??刂茦俗R消息是那些從一個(gè)控制夫發(fā)送到母窗口的消息。
ON_MESSAGE(message,memberFxn)
說(shuō)明:
指明哪個(gè)函數將處理一用戶(hù)定義消息。用戶(hù)定義消息通常定義在WM_USER到0x7FF范圍內。用戶(hù)定義消息是那些不是標準 Windows WM_MESSAGE消息的任何消息。在用戶(hù)的消息映射中,每個(gè)必須被映射到一個(gè)消息處理函數。用戶(hù)定義消息應該有一個(gè) ON_MESSAGE宏語(yǔ)句。
ON_Update_COMMAND_UI(id,memberFxn)
說(shuō)明:
此宏通常通過(guò)ClassWizard被插入一個(gè)消息映射,以指明哪個(gè)函數將處理一個(gè)用戶(hù)接口個(gè)更改命令消息。在用戶(hù)的消息映射中,每個(gè)用戶(hù)接口更改命令(比訊被映射到一個(gè)消息處理函數)應該有一個(gè)ON_Update_COMMAND_UI宏語(yǔ)句。
ON_VBXEVENT(wNotifyCode,memberFxn)
說(shuō)明:
此宏通常通過(guò)ClassWizard被插入一個(gè)消息映射,以指明哪個(gè)函數將處理一個(gè)來(lái)自VBX控制的消息。在用戶(hù)的消息映射中每個(gè)被映射到一消息處理函數的VBX控制消息應該有一個(gè)宏語(yǔ)句。
ON_REGISTERED_MESSAGE(nmessageVarible,memberFxn)
說(shuō)明:
Windows的RegisterWindowsMesage函數用于定義一個(gè)新窗口消息,此消息保證在整個(gè)系統中是唯一的。此宏表明哪個(gè)函數處理已注冊消息。變量nMessageViable應以NEAR修飾符來(lái)定義。
10、DEBUG_NEW
#define new DEBUG_NEW
說(shuō)明:
幫助查找內存錯誤。用戶(hù)在程序中使用DEBUG_NEW,用戶(hù)通常使用new運算符來(lái)從堆上分配。在Debug模式下(但定義了一個(gè)DEBUG符號), DEBUG_NEW為它分配的每個(gè)對象記錄文件名和行號。然后,在用戶(hù)使用CMemoryState::DumpAllObjectSince成員函數 時(shí),每個(gè)以DEBUG_NEW分配的對象分配的地方顯示出文件名和行號。為了使用DEBUG_NEW,應在用戶(hù)的資源文件中插入以下指令: #define new DEBUG_NEW 一旦用戶(hù)插入本指令,預處理程序將在使用new的地方插入DEBUG_NEW,而MFC作其余的工作。但 用戶(hù)編譯自己的程序的一個(gè)發(fā)行版時(shí),DEBUG_NEW便進(jìn)行簡(jiǎn)單的new操作,而且不產(chǎn)生文件名和行號消息。
11、異常宏:TRY、CATCH 、THROW、AND_CATCH、THROW_LAST和END_CATCH
TRY
說(shuō)明:
使用此宏建立一TRY塊。一個(gè)TRY識別一個(gè)可排除異常的代碼塊。這些異常在隨后的CATCH和AND_CATCH塊處理。傳遞是允許的:異??梢詡鬟f一個(gè)外部TRY塊,或者忽略它們或者使用THROW_LAST宏。
CATCH(exception_class,exception_object_pointer_name)
說(shuō)明:
使用此用定義一個(gè)代碼塊,此代碼用來(lái)獲取當前TRY塊中都一個(gè)異常類(lèi)型。異常處理代碼可以訪(fǎng)問(wèn)異常對象,如何合適的話(huà),就會(huì )得到關(guān)于異常的特殊原因的更多 消息。調用THROW_LAST宏以把處理過(guò)程一下一個(gè)外部異??蚣?,如果exception-class是類(lèi)CExceptioon,那么會(huì )獲取所有異 常類(lèi)型。用戶(hù)可以使用CObject::IsKindOf成員函數以確定那個(gè)特別異常被排除。一種獲取異常的最好方式是使用順序的AND_CATCH語(yǔ) 句,每個(gè)帶一個(gè)不同的異常類(lèi)型。此異常類(lèi)型的指針由宏定義,用戶(hù)不必定義。
注釋?zhuān)?
此CATCH塊被定義作一個(gè)C++范圍(由花括號描述)。如用戶(hù)在此范圍定義變量,那么它們只在吃范圍內可以訪(fǎng)問(wèn)。他還可以用于異常對象的指針名。
THROW(exception_object_pointer)
說(shuō)明:
派出指定的異常。THROW中斷程序的運行,把控制傳遞給用戶(hù)程序中的相關(guān)的CATCH塊。如果用戶(hù)沒(méi)有提供CATCH塊,那么控制被傳遞到一個(gè)MFC模塊,他打印出一個(gè)錯誤并終止運行。
AND_CATCH(exception_class,exception _object_point_name)
說(shuō)明:
定義一個(gè)代碼塊,它用于獲取廢除當前TRY塊中的附加異常類(lèi)型。使用CATCH宏以獲得一個(gè)異常類(lèi)型,然后使用AND_CATCH宏獲得隨后的異常處理代 碼可以訪(fǎng)問(wèn)異常對象(若合適的話(huà))已得到關(guān)于異常的特別原因的更多消息。在A(yíng)ND_CATCH塊中調用THROW_LAST宏以便把處理過(guò)程移到下個(gè)外部 異??蚣?。AND_CATCH可標記CATCH或AND_CATCH塊的末尾。
注釋?zhuān)?
AND_CATCH塊被定義成為一個(gè)C++作用域(由花括號來(lái)描述)。若用戶(hù)在此作用域定義變量,那么記住他們只在此作用域中可以訪(fǎng)問(wèn)。他也用于exception_object_pointer_name變量。
THROW_LAST()
說(shuō)明:
此宏允許用戶(hù)派出一個(gè)局部建立的異常。如果用戶(hù)試圖排除一個(gè)剛發(fā)現的異常,那么一般此異常將溢出并被刪除。使用THROW_LAST,此異常被直接傳送到下一個(gè)CATCH處理程序。
END_CATCH
說(shuō)明:
標識最后的CATCH或AND_CATCH塊的末尾。
12、DECLARE_DYNAMIC 、IMPLEMENT_DYNAMIC
DECLARE_DYNAMIC(class_name)
說(shuō)明:
但從CObject派生一個(gè)類(lèi)時(shí),此宏增加關(guān)于一個(gè)對象類(lèi)的訪(fǎng)問(wèn)運行時(shí)間功能。把DECLARE_DYNAMIC宏加入類(lèi)的頭文件中,然后在全部需要訪(fǎng)問(wèn) 此類(lèi)對象的.CPP文件中都包含此模塊。如果像所描述那樣使用DELCARE_DYNAMIC和IMPLEMENT_DYNAMIC宏,那么用戶(hù)便可使用 RUNTIME_CLASS宏和CObject::IsKindOf函數以在運行時(shí)間決定對象類(lèi)。如果DECLARE_DYNAMIC包含在類(lèi)定義中,那 么IMPLEMETN_DYNAMIC必須包含在類(lèi)工具中。
IMPLEMENT_DYNAMIC(class_name,base_class_name)
說(shuō)明:
通過(guò)運行時(shí)在串行結構中為動(dòng)態(tài)CObject派生類(lèi)訪(fǎng)問(wèn)類(lèi)名和位置來(lái)產(chǎn)生必要的C++代碼。在.CPP文件中使用IMPLEMENT_DYNAMIC宏,接著(zhù)一次鏈接結果對象代碼
13、DECLARE_DYNCreate、IMPLEMENT_DYNCreate
DECLARE_DYNCreate(class_name)
說(shuō)明:
使用DECLARE_DYNCRETE宏以便允許CObject派生類(lèi)的對象在運行時(shí)刻自動(dòng)建立。使用此功能自動(dòng)建立新對象,例如,但它在串行化過(guò)程中從 磁盤(pán)讀一個(gè)對象時(shí),文件及視圖和框架窗應該支持動(dòng)態(tài)建立,因為框架需要自動(dòng)建立它。把DECLARE_DYNCreate宏加入類(lèi)的.H文件中,然后在全 部需要訪(fǎng)問(wèn)此類(lèi)對象的.CPP文件中包含這一模式。如果DECLARE_DYNCreate包含在類(lèi)定義中,那么IMPLEMENT_DYNCreate 必須包含在類(lèi)工具中。
IMPLEMENT_DYNCreate(class_name,base_class_name)
說(shuō)明:
通過(guò)DECLARE_DYNCreate宏來(lái)使用IMPLEMENT_DYNCreate宏,以允許CObject派生類(lèi)對象在運行時(shí)自動(dòng)建立。主機使用 此功能自動(dòng)建立對象,例如,但它在串行化過(guò)程中從磁盤(pán)讀去一個(gè)對象時(shí),他在類(lèi)工具里加入IMPLEMENT_DYNCreate宏。若用戶(hù)使用 DECLARE_DYNCreate和IMPLEMENT_DYNCreate宏,那么接著(zhù)使用RUNTIME_CLASS宏和CObject:: IsKindOf成員函數以在運行時(shí)確定對象類(lèi)。若declare_dyncreate包含在定義中,那么IMPLEMENT_DYNCreate必須包 含在類(lèi)工具中。
14、DECLARE_SERIAL、IMPLEMENT_SERIAL
DECLARE_SERIAL(class_name)
說(shuō)明:
DECLARE_SERIAL為一個(gè)可以串行化的CObject派生類(lèi)產(chǎn)生必要的C++標題代碼。串行化是把某個(gè)對象的內容從一個(gè)文件讀出和寫(xiě)入一文件。 在.H文件中使用DECLARE_SERIAL宏,接著(zhù)在需要訪(fǎng)問(wèn)此類(lèi)對象的全部.CPP文件中包含此文件。如果DECLARE_SERIAL包含在類(lèi)定 義中,那么IMPLEMENT_SERIAL必須包含在類(lèi)工具中。DECLARE_SERIAL宏包含全部DECLARE_DYNAMIC, IMPLEMENT_DYCreate的功能。
IMPLEMENT_SERIAL(class_name,base_class_name,wSchema)
說(shuō)明:
通過(guò)運行時(shí)在串行結構中動(dòng)態(tài)CObject派生類(lèi)訪(fǎng)問(wèn)類(lèi)名和位置來(lái)建立必要的C++代碼。在.CPP文件中使用IMPLEMENT_SERIAL宏,然后一次鏈接結果對象代碼。
15、RUNTIME_CLASS
RUNTIME_CLASS(class_name)
說(shuō)明:
使用此宏從c++類(lèi)名中獲取運行時(shí)類(lèi)結構。RUNTIME_CLASS為由class_name指定的類(lèi)返回一個(gè)指針到CRuntimeClass結構。 只有以DECLARE_DYNAMIC、DECLARE_DYNCreate或DECLARE_SERIAL定義的CObject派生類(lèi)才返回到一個(gè) CRuntimeClass結構的指針。
聯(lián)系客服