今天來討論下C/C++中的預先處理。
預先處理
(1)概念:預先處理是指在進行編譯的第一遍掃描(詞法掃描和文法分析)之前所作的工作。預先處理的程式設計語言一個重要功能,它由預先處理程式負責完成。當對一個源檔案進行編譯時間,系統將自動引用預先處理程式對來源程式中的預先處理部分進行處理,處理完畢自動進入對來源程式的編譯。
處理預先處理語句的程式稱為預先處理程式,也就是常說的前置處理器,它包含在編譯器中。預先處理程式首先讀源檔案。預先處理的輸出是“翻譯單元”,它是存放在記憶體聽臨時檔案。編譯器接受預先處理的輸出,並把原始碼化成包含機器語言指令的目標檔案。
前置處理器的作用是通過預先處理的內建功能對一個資源進行等價替換。
(2)常見的預先處理:檔案包含、條件編譯、布局控制和宏替換。
<1>檔案包含:
1.#include <檔案名稱> 編譯器從編譯系統設定的包含檔案的目錄中尋找檔案,所以它常用於包含系統的標頭檔,如:iostream.h、math.h等。
2.#include "檔案名稱" 編譯器從當前工作目錄中開始尋找檔案,若未找到再到包含檔案的目錄中去尋找,所以它常用於尋找使用者自己編寫的檔案。
<2>宏替換:#define,可以定義符號常量、函數功能、重新命名、字串的拼接等各種功能。
<3>條件編譯:#if、#ifndef、#ifdef、#endif、#undef等是比較常見的預先處理,主要是編譯時間進行有選擇的挑選,注釋掉一些指定的代碼,以達到版本控制、防止對檔案重複包含的功能。
比如,常用於區別debug和release編譯的#ifdef _DEBUG:
int main(int argc, char* argv[])
{
#ifdef _DEBUG //如果是debug編譯
...
列印詳細日誌的代碼
...
#else //如果是release編譯
...
列印普通日誌代碼
...
#endif
return 0;
}
<4>布局控制:#progma,主要功能是為編譯器提供非常規的控制流程資訊。
1.#progma comment(...):該指令將一個注釋記錄放入一個對象檔案或可執行檔中。常用的lib關鍵字可以用於連結一個庫檔案,如#progma comment(lib,"user32.lib")指令用來將user32.lib庫檔案加入到工程中。
2.#progma once:只要在標頭檔的最開始加入這條指令就能夠保證標頭檔被編譯一次。
3.#pragma pack:有關記憶體對齊知識,這裡不作詳細說明。