C/C++编译预处理指令
眾所周知,你的程序編譯前要做的事就是掃描源代碼,對其做初步的轉換,產生新的源代碼提供給編譯器,這個過程就叫編譯預處理。這個處理過程由預處理器來完成,預處理器是在程序真正運行前由編譯器調用的預處理程序。
?????
????常見的預處理有以下三種:
?????文件包含:#include 是一種最為常見的預處理,主要是做為文件的引用組合源程序正文。
??????宏替換: #define,這是最常見的用法,它可以定義符號常量、函數功能、重新命名、字符串的拼接等各種功能。????????
??????條件編譯:#if,#ifndef,#ifdef,#elif,#endif,#undef等也是比較常見的預處理,主要是進行編譯時進行有選擇的挑選,注釋掉一些指定的代碼,以達到版本控制、防止對文件重復包含的功能。
??????????????
一,文件包含
????? #include預處理指令的作用是在指令處展開被包含的文件。包含可以是多重的,也就是說一個被包含的文件中還可以包含其他文件。預處理器至多支持15層嵌套包含。
??? 預處理過程不檢查在轉換單元中是否已經包含了某個文件并阻止對它的多次包含。這樣就很容易發生相同的一個文件被包含多次的情況,可以輕易地利用條件式編譯的預處理指令避免多次包含相同的文件,例如:
???????
?
??????
?
????? 文件包含中的<>和" ""的區別就不用說了。
?
二,宏
?
???? 可以利用預處理指令#define來定義宏。使用預處理指令可以把一個名稱指定成任何文字,例如常量值或者語句。當定義宏后,并且此宏的名稱出現在源代碼中,預處理器就會把它替換掉。
???? 由于宏替換是簡單的替換,所以在定義宏的時候務必要加(),如:
???????? #define MAX(x,y)?? ((x)>(y))?(x):(y)
???
?????在宏中還有兩類重要的運算符:字符串化運算符和“粘貼記號”運算符
??????單元運算符#常常被稱為字符串化運算符(stringizing operator),因為它會把一個宏參數轉換為字符串。#的操作數必須是“宏替代文字”中的參數arg,當參數名稱出現在替代文字中,并且前置#字符時,預處理器會把對應的自變量放在一對引號中,形成一個字符串字面值。如下所示:
[cpp]?view plaincopy?
?
???? 上面程序的輸出是:3 *0.5 = 1.500000
?
? ##運算符是一個二元運算符,可以出現在任何宏的替代文字中。此運算符會把左和右操作數結合咋i一起,稱為一個記號,常常被稱為“粘貼記號”運算符。如下所示:
?
[cpp]?view plaincopy?
???? 上面程序的輸出是: hello,world, it's cobing
?
????? 如果不顯示地取消宏的定義,宏的作用域是全局的,即當前編譯單元內所有的文件都是可見的。可以用#undef macro_name 來取消宏定義
?
三?條件編譯
?
???條件式編譯區域始于#if, #ifdef或#ifndef等預處理指令,結束于#endif預處理指令。條件式編譯區域內可以有任意數目的#elif預處理指令,以及最多一個#else預處理指令,以#if開始的條件式編譯區域具有下面的格式:
?? #if?expression1
??????? [group1 ]
?? ?[#elif?expression2
???????? [group2 ]]
??? ...
??? [#elif?expression3
???????? [group3 ]]
??? [#else
???????? [group(n+1) ]]
??? #endif
?? 預處理器會依序計算條件表達式,直到發現某個結果非0的表達式。預處理器會保留對應group內的源代碼,共后續處理。在預處理器結束時,預處理器會刪除程序中沒有被保留的group。下面是一個實例代碼
[cpp]?view plaincopy?
??
?? #ifdef和#ifndef預處理指令可以測試是否某個宏被定義
[c-sharp]?view plaincopy?
?
??? #error預處理指令會讓預處理器發出錯誤信息:
????????????????????????? #error [text]
??? 如果可選性的text出現,這段文字就會被包含在預處理器中有關該錯誤的錯誤信息中。然后編譯器會停止處理源代碼,并結束施行,仿佛遇到了嚴重的錯誤。
??
[c-sharp]?view plaincopy?
?? 如果LEX未被定義,上面的程序編譯不成功,編譯器提示"fatal error:LEX is not defined"
轉載于:https://www.cnblogs.com/cobbliu/archive/2012/03/10/2388552.html
總結
以上是生活随笔為你收集整理的C/C++编译预处理指令的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 贡献一个连jquery都觉的大的时候可以
- 下一篇: 期货交易时间是什么时候