#include、#define等以“#”開頭的命令稱為預處理命令。
C語言的編譯預處理程序是一個正文處理程序,它屬於C語言編譯係統的一部分。編譯程序對C語言源程序進行編譯時,首先調用預處理程序對源程序進行一遍掃描,目的是對在源程序中的預處理指令(以“#”開頭的指令)進行識別和處理。處理完畢自動進入對源程序的編譯。合理地使用預處理功能編寫的程序便於閱讀、修改、移植和調試,也有利於模塊化程序設計。
C語言提供了多種預處理功能,如宏定義、文件包含、條件編譯等。本章介紹常用的幾種預處理功能。
宏定義指令(#define)能有效地提高程序的編程效率,增強程序的可讀性、可修改性。
C語言的宏定義指令包括無參宏定義和帶參宏定義。下麵分別介紹這兩種宏定義。
無參宏定義的宏名後不帶參數。
1.指令格式
#define標識符字符串
其中的“#”表示這是一條預處理命令,凡是以“#”開頭的均為預處理命令,“define”為宏定義命令,“標識符”為所定義的宏名,“字符串”可以是常量、表達式、格式串等。
2.作用
為標識符指定字符串。預處理程序處理源程序時,將程序中出現標識符的地方均用其指定的字符串代替。在前麵介紹過的符號常量的定義就是一種無參宏定義。此外,常對程序中反複使用的表達式進行宏定義。
[例91]
#definePI31415926
#defineR31
voidmain()
{floats;
s=2*PI*R;
printf("circumferenceis%f",s);
}
經過編譯預處理後將得到如下程序:
voidmain()
{
floats;
s=2*31415926*31;
printf("circumferenceis%f",s);
}
說明:
(1)宏名通常采用大寫字母,以便與程序中的其他標識符區別開來。
(2)宏定義是用宏名代替一個字符串,隻是作簡單的替換,不作語法檢查,隻有在編譯已被宏展開後的源程序時才開始檢查錯誤。
(3)字符串可以是一個關鍵字、某個符號或為空。例如:
#defineWORDint
#defineSTART{
#defineEND}
(4)一個宏名一旦被定義了,在沒有消除該定義之前,它就不能再被定義為其他不同的值。其作用域是從定義的地方開始到該源文件結束。
(5)#undef命令可以終止宏定義的作用域。若一個宏名消除了原來的定義,便可被重新定義為其他的值。例如,在程序中定義:
#defineYESl
後來又用下列宏定義撤消:
#undefYES
那麼,程序中再出現YES時就是未定義的標識符了。也就是說,YES的作用域是從定義的地方開始到#undef結束。
(6)宏定義不是說明或語句,在行末不必加分號,如加上分號則連分號也一起置換。
(7)在源程序中宏名若用引號括起來,則預處理程序不對其作宏代換。
C語言允許宏帶有參數。在宏定義中的參數稱為形式參數,在宏調用中的參數稱為實際參數。對帶參數的宏,在調用中,不僅要宏展開,而且要用實參去代換形參。
帶參宏定義的一般格式為:
#define宏名(形參表)字符串
其中,“形參表”是用逗號分隔的若幹個形參,在字符串中包含每個形參。
帶參宏調用的一般形式為:
宏名(實參列表)
例如:
#defineF(y)y*y+3*y/*宏定義*/
……
k=F(5);/*宏調用*/
……
在宏調用時,用實參5去代替形參y,經預處理宏展開後得到的語句為:
k=5*5+3*5
[例92]
#defineMAX(a,b)(a>b)?a:b
voidmain()
{