多麼令人愉快的乙個問題啊
就在被帶到編譯器那裡之前,預處理器都會對你的源**瞧上一瞧ypzbatxuy, 做一些格式化的工作,並執行任何你在源**裡面留給它來執行的指令.
像什麼?
好吧,預處理器的指令就被叫做預處理器指令,而他們都以乙個#開頭.
像 #include 這樣?
正確.每乙個被預處理器遇到的 # 命令都會導致在某種方式上對源**的修改. 讓我們來簡單的研究研究它們,然後我們就會之後這背後都是怎麼運轉的了.
#include
包含其他庫、類、介面等的標頭檔案。預處理器實際上就只是把整個標頭檔案複製到你的源**裡面 (是的,這就是包含防禦之所以是件好事的原因了).
#define
誰會不喜程式設計客棧歡巨集呢! 預處理器會把所有定義的實體替換成被定義的**. 定義會一直持續直到發現這個定義的 #undef 指令.
#ifdef
條件行為告訴預處理器包含在遇到宣告的條件成立的條件塊中的**. 你可以就像if-el程式設計客棧se語句一樣使用它們,從這裡面選擇: #ifdef, #ifndef, #if, #else, 以及 #elif, 而你總是要使用乙個 #endif 作為結束。
#error #warning
用來向使用者傳送訊息。預處理器會在 #error 處, 而不會在 #warning 處停下來. 兩種情況下他都會傳送他在指令背後(的括號裡面)發現的字串, 傳送到螢幕作為輸出,因此它是一種確保針對你的平台一切ok的手動方式.
#line
用來在你遇到編譯錯誤時修改顯示的錯誤行號和檔名. 例如,加入你需要檢視乙個來自編譯的中間檔案的原始檔(可能是自動生成的).
#pragma
其它由編譯器解釋的特殊指令。你的編譯器文件會告訴你指令是怎麼用的,而你不要假定他們在全世界都通用哦.
#assert #unassert
這些在老程式裡面總是特別受歡迎的 (好吧,只要我也曾經為這樣乙個程式工作過), 程式設計客棧但是它們在現在已經過時了。強烈建議不使用它們,這意味著不要把他們放到新的**裡面
預定義巨集
有許多可以利用的預定義巨集:
__file__ 給出乙個字串的檔名
__line__ 給出當前的行號(整型)
__date__ 當前編譯日期的字串
__time__ 當前編譯時間的字串
__stdc__ 同編譯器相關的,但常常被定義成1,以宣告同iso c標準相容.
__cplusplus 在編譯乙個c++程式是總是會被定義
特別是開頭兩個在除錯時真的非常有用。只要拿出它們倆,不用你自己編寫檔案和行處理類,就能神奇的讓你獲得豐富的資訊輸出.
你的編譯器可能還支援其它的巨集,例如,你這從 這裡 獲得(面向gcc)的整個巨集清單.
那麼當你執行預處理器時實際會發生什麼呢?
1. 替換所有的三字母組合,我會在將來的一篇文章中談論到他,因為儘管他只是乙個歷史上的特性(而且你也要在gcc中對它進行切換),它仍讓是很有趣的.
2. 將並列的源**分成多行.
3. 移除所有的注釋並用乙個空格替換.
4. 處理(我們上面講到的)的預處理器指令。對於 #include, 他會在新檔案上遞迴執行1 - 3步 :-)
5. 處理轉義序列.
6. 把檔案傳送給編譯器
如果你想看看預處理之後你的檔案會是什麼樣子 (誰不想呢?),你可以向 gcc 傳入 -e 選項. 這將會想stdout標準輸出傳送預處理過的源**,並且沒有編譯和連線就直接終止gcc命令的執行。例如
g++ -e myfile.cpp
你也可以使用這個引數:
-s**e-temps
編譯的後會有乙份臨時檔案。
拿下面這個簡單的程式說吧:
#include
#define one 1
#define two 2
int main()
用下面這行命令編譯
g++ hello.cpp程式設計客棧 -s**e-temps
編譯完後, 會在資料夾中生成兩個檔案: hello.s 和 hello.ii
hello.s 裡面是彙編**, 而 hello.ii 則是預處理過後的源**。
用文字編輯器開啟 hello.ii , 你會發現多出許多**. 那是因為 #include 指令把 stdio 標頭檔案的**加進去了。
如果你把滾動條拉到最底下, 就會發現, printf 那一行的巨集定義 one 和 two 已經被預處理器替換成 1 和 2 了 .
神奇吧!
其實它只是在編譯的時候, 把你的源**檔案複製乙份, 當作臨時檔案, 然後把裡面的預處理指令替換掉. 用完後就把這個臨時檔案刪了. 所以一般情況下我們不知道這個檔案的存在.
本文標題: 簡介c/c++預處理器的一些工作
本文位址:
預處理器簡介
預處理是c編譯器做的第一件事情,主要是做一些文字方面的工作。包括 刪除注釋 插入被 include包含的檔案 定義和替換由 define指令定義的符號以及 的部份內容,和條件編譯。預定義符號 預定義符號如下表所示 file 進行編譯的檔名 line 檔案的當前行號 date 檔案編譯的日期 time...
C預處理器簡介
cpreprocesser,簡稱cpp,是c編譯器在編譯原始碼之前用於轉換 的巨集處理器。之所以稱之為巨集處理器,是因為通過cpp,你可以在程式中定義和使用巨集。cpp是一種文字處理工具,因此也可以用於c c 和objective c之外的原始碼。cpp的作用是對輸入的檔案做一系列的文字處理,這些文...
C C 預處理器的預定義巨集
符合ansi的預定義巨集 date 表示當前原始檔編譯時的日期,格式為 月 天 年 mmm dd yyyy file 表示當前正在處理的原始檔名稱。line 表示當前正在處理的原始檔的行,可以用 line指令修改。stdc 表示是ansi c標準。只有在編譯器選項指定了 za,並且不是編譯c 程式時...