預處理指令編譯
編譯,編譯程序讀取源程序(字元流),對之進行詞法和語法的分析,將高級語言指令轉換為功能等效的匯編代碼,再由匯編程序轉換為機器語言,並且按照操作系統對可執行文件格式的要求鏈接生成可執行程序。
如果用一張圖來表示:
讀取c源程序,對其中的偽指令(以#開頭的指令)和特殊符號進行處理
[析] 偽指令主要包括以下四個方面
(1)宏定義指令,如#define Name TokenString,#undef等。對於前一個偽指令,預編譯所要做的是將程序中的所有Name用TokenString替換,但作為字元串常量的Name則不被替換。對於後者,則將取消對某個宏的定義,使以後該串的'出現不再被替換。
(2)條件編譯指令,如#ifdef,#ifndef,#else,#elif,#endif,等等。這些偽指令的引入使得程序員可以通過定義不同的宏來決定編譯程序對哪些代碼進行處理。預編譯程序將根據有關的文件,將那些不必要的代碼過濾掉
(3)頭文件包含指令,如#include "FileName"或者#include 等。在頭文件中一般用偽指令#define定義了大量的宏(最常見的是字元常量),同時包含有各種外部符號的聲明。採用頭文件的目的主要是為了使某些定義可以供多個不同的C源程序使用。因為在需要用到這些定義的C源程序中,只需加上一條#include語句即可,而不必再在此文件中將這些定義重復一遍。預編譯程序將把頭文件中的定義統統都加入到它所產生的輸出文件中,以供編譯程序對之進行處理。
包含到c源程序中的頭文件可以是系統提供的,這些頭文件一般被放在/usr/include目錄下。在程序中#include它們要使用尖括弧(<>)。另外開發人員也可以定義自己的頭文件,這些文件一般與c源程序放在同一目錄下,此時在#include中要用雙引號("")。
(4)特殊符號,預編譯程序可以識別一些特殊的符號。例如在源程序中出現的LINE標識將被解釋為當前行號(十進制數),FILE則被解釋為當前被編譯的C源程序的名稱。預編譯程序對於在源程序中出現的這些串將用合適的值進行替換。
注意:
預編譯程序所完成的基本上是對源程序的「替代」工作。經過此種替代,生成一個沒有宏定義、沒有條件編譯指令、沒有特殊符號的輸出文件。這個文件的含義同沒有經過預處理的源文件是相同的,但內容有所不同。下一步,此輸出文件將作為編譯程序的輸出而被翻譯成為機器指令。
㈡ 預編譯的編譯指令
預編譯指令指示了在程序正式編譯前就由編譯器進行的操作,可以放在程序中的任何位置。常見的預編譯指令有:
(1)#include 指令
該指令指示編譯器將xxx.xxx文件的全部內容插入此處。若用<>括起文件則在系統的INCLUDE目錄中尋找文件,若用 括起文件則在當前目錄中尋找文件。一般來說,該文件是後綴名為h或cpp的頭文件。
注意:<>不會在當前目錄下搜索頭文件,如果我們不用<>而用把頭文件名擴起,其意義為在先在當前目錄下搜索頭文件,再在系統默認目錄下搜索。
(2)#define指令
該指令有三種用法:
第一種是定義標識,標識有效范圍為整個程序,形如#define XXX,常與#if配合使用;
第二種是定義常數,如#define max 100,則max代表100(這種情況下使用const定義常數更好,原因見注1);
第三種是定義函數,如#define get_max(a, b) ((a)>(b)?(a):(b)) 則以後使用get_max(x,y)就可以得到x和y中較大的數(這種方法存在一些弊病,見注2)。
第四種是定義宏函數,如#define GEN_FUN(type) type max_##type(type a,type b){return a>b?a:b;} ,使用時,用GEN_FUN(int),則此處預編譯後就變成了 max_int(int a,int b){return a>b?a:b;},以後就可以使用max_int(x,y)就可以得到x和y中較大的數.比第三種,增加了類型的說明。
(3)#if、#else和#endif指令
這些指令一般這樣配合使用:
#if defined(標識) //如果定義了標識
要執行的指令
#else
要執行的指令
#endif
在頭文件中為了避免重復調用(比如說兩個頭文件互相包含對方),常採用這樣的結構:
#if !(defined XXX) //XXX為一個在你的程序中唯一的標識符,
//每個頭文件的標識符都不應相同。
//起標識符的常見方法是若頭文件名為abc.h
//則標識為abc_h
#define XXX
真正的內容,如函數聲明之類
#endif
注1:因為:const常量有數據類型,而宏常量沒有數據類型。編譯器可以對前者進行類型安全檢查,而對後者只進行字元替換,沒有類型安全檢查,並且在字元替換時可能會產生意料不到的錯誤(邊際效應)。
注2:例如get_max(a++, b)時,a++會被執行多少次取決於a和b的大小!所以建議還是用內聯函數而不是這種方法提高速度。雖然有這樣的弊病,但這種方法的確非常靈活,因為a和b可以是各種數據類型。
注3:可以查看網路的預處理命令,編排的比較簡明。
㈢ C語言提供的預編譯處理命令主要有哪三種
1.宏定義:用一個指定的標識符(即名字)來代表一個字元串,如:用PI代表3.1415926,#define PI 3.1415926
2.文件包含:指一個源文件可以將另外一個源文件的全部內容包含進來,#include<文件名>
3.條件編譯:對一部分內容指定編譯的條件,即滿足一定的條件才編譯,主要有:
(1)#ifdef標識符
程序段1
#eles
程序段2
#endif
(2)#ifndef標識符
程序段1
#eles
程序段2
#endif
(3))#if標識符
程序段1
#eles
程序段2
#endif
㈣ C語言「編譯預處理命令」,是什麼意思
您好,
宏定義
c程序提供的預處理功能之一。包括帶參數的宏定義和不帶參數的宏定義。具體是指用一個指定的標志符來進行簡單的字元串替換或者進行闡述替換。形式為:
#define
標志符(參數表)
字元串
宏名
在上定義中的標志符被稱為「宏名」。
宏展開
在c程序編譯時將宏名替換成字元串的過程稱為「宏展開」。
define
是對宏的定義:如定義了一個宏m,代表100.也就在下面的程序中只要是遇到變數m,它的值就是100
㈤ C語言 四個過程:預處理,編譯,匯編,鏈接,分別進行了什麼過程別度娘。
1.預處理
這個階段用來處理所有的預處理指令
-
主要是一些宏替換,頭文件導入
2.編譯
對預處理後的代碼進行翻譯工作,得到計算機
所認識的格式編譯工作得到的結果文件叫做目標文件,
擴展名是.o(編譯得到匯編文件(.s)
->經過匯編後得到.o目標文件)
3.鏈接
把所有的目標文件和其他必要的文件合並在一起
得到最終的可執行文件
㈥ 編譯程序預處理干什麼
編譯預處理是C語言區別於其它高級程序設計語言的特徵之一,它屬於C語言編譯系統的一部分。C程序中使用的編譯預處理命令均以#開頭,它在C編譯系統對源程序進行編譯之前,先對程序中這些命令進行「預處理」。編譯預處理命令的三種不同形式:宏定義、文件包含和條件編譯。
㈦ 預處理命令的條件編譯
有些語句希望在條件滿足時才編譯。
格式:(1)
#ifdef 標識符
程序段1
#else
程序段2
#endif
或
#ifdef
程序段1
#endif
當標識符已經定義時,程序段1才參加編譯。
格式:(2)
#ifndef 標識符
#define 標識1
程序段1
#endif
如果標識符沒有被定義,則重定義標識1,且執行程序段1。
格式:(3)
#if 表達式1
程序段1
#elif 表達式2
程序段2
……
#elif 表達式n
程序段n
#else
程序段n+1
#endif
當表達式1成立時,編譯程序段1,當不成立時,編譯程序段2。
使用條件編譯可以使目標程序變小,運行時間變短。
預編譯使問題或演算法的解決方案增多,有助於我們選擇合適的解決方案。
此外,還有布局控制:#pragma,這也是我們應用預處理的一個重要方面,主要功能是為編譯程序提供非常規的控制流信息。