在前面各章中,已多次使用過以「#」號開頭的預處理命令。如包含命令#include,巨集定義命令#define等。在源程式中這些命令都放在函式之外,而且一般都放在原始檔的前面,它們稱為預處理部分。
所謂預處理是指在進行編譯的第一遍掃瞄(詞法掃瞄和語法分析)之前所作的工作。預處理是c語言的乙個重要功能,它由預處理程式負責完成。當對乙個原始檔進行編譯時,系統將自動引用預處理程式對源程式中的預處理部分作處理,處理完畢自動進入對源程式的編譯。
c語言提供了多種預處理功能,如巨集定義、檔案包含、條件編譯等。合理地使用預處理功能編寫的程式便於閱讀、修改、移植和除錯,也有利於模組化程式設計。本章介紹常用的幾種預處理功能。
在c語言源程式中允許用乙個識別符號來表示乙個字串,稱為「巨集」。被定義為「巨集」的識別符號稱為「巨集名」。在編譯預處理時,對程式中所有出現的「巨集名」,都用巨集定義中的字串去代換,這稱為「巨集代換」或「巨集展開」。
巨集定義是由源程式中的巨集定義命令完成的。巨集代換是由預處理程式自動完成的。
在c語言中,「巨集」分為有引數和無引數兩種。下面分別討論這兩種「巨集」的定義和呼叫。
無參巨集的巨集名後不帶引數。
其定義的一般形式為:
#define 識別符號 字串
其中的「#」表示這是一條預處理命令。凡是以「#」開頭的均為預處理命令。「define」為巨集定義命令。「識別符號」為所定義的巨集名。「字串」可以是常數、表示式、格式串等。
在前面介紹過的符號常量的定義就是一種無參巨集定義。此外,常對程式中反覆使用的表示式進行巨集定義。
例如:#define m (y*y+3*y)
它的作用是指定識別符號m來代替表示式(y*y+3*y)。在編寫源程式時,所有的(y*y+3*y)都可由m代替,而對源程式作編譯時,將先由預處理程式進行巨集代換,即用(y*y+3*y)表示式去置換所有的巨集名m,然後再進行編譯。
【例8.1】
#define m (y*y+3*y)
main() *ps;
ps=(struct stu*)malloc(sizeof(struct stu));
ps->num=102;
ps->name="zhang ping";
ps->***='m';
ps->score=62.5;
#ifdef num
printf("number=%d\nscore=%f\n",ps->num,ps->score);
#else
printf("name=%s\n***=%c\n",ps->name,ps->***);
#endif
free(ps);
2. 第二種形式:
#ifndef
識別符號
程式段1
#else
程式段2
#endif
與第一種形式的區別是將「ifdef」改為「ifndef」。它的功能是,如果識別符號未被#define命令定義過則對程式段1進行編譯,否則對程式段2進行編譯。這與第一種形式的功能正相反。
3. 第三種形式:
#if 常量表示式
程式段1
#else
程式段2
#endif
它的功能是,如常量表示式的值為真(非0),則對程式段1 進行編譯,否則對程式段2進行編譯。因此可以使程式在不同條件下,完成不同的功能。
【例8.6】
#define r 1
main(){
float c,r,s;
printf ("input a number: ");
scanf("%f",&c);
#if r
r=3.14159*c*c;
printf("area of round is: %f\n",r);
#else
s=c*c;
printf("areaof square is: %f\n",s);
#endif
本例中採用了第三種形式的條件編譯。在程式第一行巨集定義中,定義r為1,因此在條件編譯時,常量表示式的值為真,故計算並輸出圓面積。
上面介紹的條件編譯當然也可以用條件語句來實現。 但是用條件語句將會對整個源程式進行編譯,生成的目標**程式很長,而採用條件編譯,則根據條件只編譯其中的程式段1或程式段2,生成的目標程式較短。如果條件選擇的程式段很長,採用條件編譯的方法是十分必要的。
1. 預處理功能是c語言特有的功能,它是在對源程式正式編譯前由預處理程式完成的。程式設計師在程式中用預處理命令來呼叫這些功能。
2. 巨集定義是用乙個識別符號來表示乙個字串,這個字串可以是常量、變數或表示式。在巨集呼叫中將用該字串代換巨集名。
3. 巨集定義可以帶有引數,巨集呼叫時是以實參代換形參。而不是「值傳送」。
4. 為了避免巨集代換時發生錯誤,巨集定義中的字串應加括號,字串中出現的形式引數兩邊也應加括號。
5. 檔案包含是預處理的乙個重要功能,它可用來把多個原始檔連線成乙個原始檔進行編譯,結果將生成乙個目標檔案。
6. 條件編譯允許只編譯源程式中滿足條件的程式段,使生成的目標程式較短,從而減少了記憶體的開銷並提高了程式的效率。
7. 使用預處理功能便於程式的修改、閱讀、移植和除錯,也便於實現模組化程式設計。
8 pragma指令:編譯器按其自定義的方式處理如下的預處理指令:# pragma
pp-tokens
opt
new-line
C C 預處理命令
1.和 和 操作符是和 define 巨集使用的。使用 使在 後的首個引數返回為乙個帶引號的字串 例如 defineto string s s defineconcatenate x,y x y 2.define 命令用於把指定字串替換檔案中的巨集名稱 3.error 可以簡單的使編譯器在發生錯誤時...
C C中的預處理命令
分析 預編譯又稱為預處理 是做些 文字的替換工作。處理 開頭的指令 比如拷貝 include包含的檔案 define 巨集定義的替換 條件編譯等,就是為編譯做的預備工作的階段,主要處理 開始的預編譯指令,預編譯指令指示了在程式正式編譯前就由編譯器進行的操作,可以放在程式中的任何位置。c c 編譯系統...
C C 學習筆記 預處理命令
巨集定義命令 define 條件編譯 if ifdef ifndef 以 號開頭的命令稱為預處理命令 在編譯之前對原始檔進行簡單加工的過程,就稱為預處理 即預先處理 提前處理 如 include 引入標頭檔案 define max 100 巨集定義 c語言開發者們編寫了很多常用函式,並分門別類的放在...