C++编译预处理:宏定义指令、文件包含指令和条件编译指令
生活随笔
收集整理的這篇文章主要介紹了
C++编译预处理:宏定义指令、文件包含指令和条件编译指令
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
◆ 不帶參數(shù)的宏定義:用來產(chǎn)生與一個(gè)字符串(即宏名)對(duì)應(yīng)的常量字符串,格式為:
?? #define 宏名 常量串
◆ 帶參數(shù)的宏定義:帶參宏定義的形式很象定義一個(gè)函數(shù),格式為:
?? #define 宏名(形參表) 表達(dá)式串
◆ 處理過程:編譯預(yù)處理后產(chǎn)生一個(gè)中間文件,文件中所有宏名(如果是帶參數(shù)的宏,則宏名包括參數(shù)表在內(nèi))均用其對(duì)應(yīng)的常量串或表達(dá)式串代替。替換過程稱為“宏替換”或“宏展開”。
舉例:
幾點(diǎn)注意:
一個(gè)被包含的頭文件中還可以有#include指令,即include指令可以嵌套。但是,如果同一個(gè)頭文件在同一個(gè)源程序文件中被重復(fù)包含,就會(huì)出現(xiàn)標(biāo)識(shí)符重復(fù)定義的錯(cuò)誤。
例如:頭文件f2.h中包含了f1.h,如果文件f3.cpp中既包含f1.h,又包含f2.h,那么編譯將提示錯(cuò)誤,原因是f1.h被包含了兩次,那么其中定義的標(biāo)識(shí)符在f3.cpp中就被重復(fù)定義。
避免重復(fù)包含可以用“條件編譯”指令。
條件編譯指令包括:#if、#else、#ifdef、#ifndef、#endif、#undef等。可分為兩類:用宏名作為編譯的條件,格式為:
?? #ifdef<宏名>
??< 程序段1>
?? [#else
??< 程序段2>]
?? #endif 用表達(dá)式的值作為編譯條件,格式為:
?? #if< 表達(dá)式>
??< 程序段1>
?? [#else
??< 程序段2>]
?? #endif
其中,“程序段”可以是程序也可以是編譯預(yù)處理指令。
實(shí)際中,在調(diào)試程序時(shí)常常要輸出調(diào)試信息,而調(diào)試完后不需要輸出這些信息,則可以把輸出調(diào)試信息的語句用條件編譯指令括起來,通過在該指令前面安排宏定義來控制編譯不同的程序段。形式如下:
??#ifdef DEBUG
?? cout<<″a=″<<a<<′\t′<<″x=″<<x<<endl;
?? #endif
在程序調(diào)試期間,在該條件編譯指令前增加宏定義:
??#define DEBUG
調(diào)試好后,刪除DEBUG宏定義,將源程序重新編譯一次。
幾點(diǎn)說明:
?? #define 宏名 常量串
◆ 帶參數(shù)的宏定義:帶參宏定義的形式很象定義一個(gè)函數(shù),格式為:
?? #define 宏名(形參表) 表達(dá)式串
◆ 處理過程:編譯預(yù)處理后產(chǎn)生一個(gè)中間文件,文件中所有宏名(如果是帶參數(shù)的宏,則宏名包括參數(shù)表在內(nèi))均用其對(duì)應(yīng)的常量串或表達(dá)式串代替。替換過程稱為“宏替換”或“宏展開”。
舉例:
- 使用指令:#define PI 3.1415926
則程序中可以使用標(biāo)識(shí)符PI,編譯預(yù)處理后產(chǎn)生一個(gè)中間文件,文件中所有PI被替換3.1415926。 - 使用指令:#define S(a,b) (a)*(b)/2
則程序中可使用S(a,b),編譯預(yù)處理后產(chǎn)生中間文件,其中S(a,b)被替換成(a)*(b)/2。
幾點(diǎn)注意:
- 宏替換只是字符串和標(biāo)識(shí)符之間的簡(jiǎn)單替換,預(yù)處理本身不做任何數(shù)據(jù)類型和合法性檢查,也不分配內(nèi)存單元。
- 宏定義時(shí),形參通常要用括號(hào)括起來,否則容易導(dǎo)致邏輯錯(cuò)誤。例如,如果定義:
?? #define S(a,b) a*b/2
那么程序中的S(3+5,4+2)就會(huì)被宏展開為3+5*4+2/2,不符合定義的真正的意圖。 - 帶參宏定義形式上象定義函數(shù),但它與函數(shù)的本質(zhì)不同。宏定義只是產(chǎn)生字符串替代,不存在分配內(nèi)存和參數(shù)傳遞。
文件包含指令
文件包含用#include指令,預(yù)處理后將指令中指明的源程序文件嵌入到當(dāng)前源程序文件的指令位置處。有2種格式:- 第一種方式,格式為:
??#include< 文件名>
預(yù)處理器將在include子目錄下搜索由文件名所指明的文件。這種方式稱為“標(biāo)準(zhǔn)方式”,適用于嵌入C++提供的頭文件,因?yàn)檫@些頭文件一般都存在C++系統(tǒng)目錄的include子目錄下。 - 第二種方式,格式為:
??#include ″文件名″
預(yù)處理器將首先在當(dāng)前文件所在目錄下搜索,如果找不到再按標(biāo)準(zhǔn)方式搜索。這種方式適用于嵌入用戶自己建立的頭文件。
一個(gè)被包含的頭文件中還可以有#include指令,即include指令可以嵌套。但是,如果同一個(gè)頭文件在同一個(gè)源程序文件中被重復(fù)包含,就會(huì)出現(xiàn)標(biāo)識(shí)符重復(fù)定義的錯(cuò)誤。
例如:頭文件f2.h中包含了f1.h,如果文件f3.cpp中既包含f1.h,又包含f2.h,那么編譯將提示錯(cuò)誤,原因是f1.h被包含了兩次,那么其中定義的標(biāo)識(shí)符在f3.cpp中就被重復(fù)定義。
避免重復(fù)包含可以用“條件編譯”指令。
條件編譯指令
當(dāng)希望在不同條件下編譯程序的不同部分,這種情況就要使用“條件編譯”指令。條件編譯指令包括:#if、#else、#ifdef、#ifndef、#endif、#undef等。可分為兩類:
?? #ifdef<宏名>
??< 程序段1>
?? [#else
??< 程序段2>]
?? #endif
?? #if< 表達(dá)式>
??< 程序段1>
?? [#else
??< 程序段2>]
?? #endif
其中,“程序段”可以是程序也可以是編譯預(yù)處理指令。
實(shí)際中,在調(diào)試程序時(shí)常常要輸出調(diào)試信息,而調(diào)試完后不需要輸出這些信息,則可以把輸出調(diào)試信息的語句用條件編譯指令括起來,通過在該指令前面安排宏定義來控制編譯不同的程序段。形式如下:
??#ifdef DEBUG
?? cout<<″a=″<<a<<′\t′<<″x=″<<x<<endl;
?? #endif
在程序調(diào)試期間,在該條件編譯指令前增加宏定義:
??#define DEBUG
調(diào)試好后,刪除DEBUG宏定義,將源程序重新編譯一次。
幾點(diǎn)說明:
- #ifndef與#ifdef作用一樣,只是選擇的條件相反。
- #undef指令用來取消#define指令所定義的符號(hào),這樣可以根據(jù)需要打開和關(guān)閉符號(hào)。?
總結(jié)
以上是生活随笔為你收集整理的C++编译预处理:宏定义指令、文件包含指令和条件编译指令的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FFPLAY的原理(二)
- 下一篇: 驱动开发基础知识 偶然发现的,很全面