(c c 學習筆記十一)預處理命令

2021-06-26 13:09:02 字數 2982 閱讀 8171

預處理是指在進行編譯的第一遍掃瞄(語法掃瞄和語法分析)之前所做的工作。預處理是c語言的乙個重要功能,它由預處理器負責完成。當對乙個原始檔進行編譯時,系統將自動引用預處理程式對程式中的預處理部分作處理,處理完畢後自動進入對源程式的編譯。c語言提供了多種預處理功能,如巨集定義、檔案包含、條件編譯等。

一.巨集c語言允許用乙個表示法來表示乙個字串,稱為「巨集」。被定義為「巨集」的表示符稱為「巨集名」,對程式中所有出現的「巨集名」,都用巨集定義中的字串去替換,這稱為「巨集替換」和「巨集展開」。

1.無引數巨集

定義的一般形式為: #define 標示符 字串

例:

#define add (a+b)                     //定義乙個巨集  不用加分號 如果有分號則一起替換

int main(int argc, char *argv)

巨集定義使用巨集明表示乙個字串,在巨集展開時又以該字串取代巨集名,這是一種簡單的替換,字串中可以包含任何字元,可以是常數,也可以使表示式,預處理程式對它不作任何檢查,如有錯誤,只能在編譯已被巨集展開後的程式是發現。

巨集定義必須寫在函式之外,其作用域為巨集定義命令起到源程式結束,要終止其作用域可以使用#undef命令

例:

#define pi 3.14

int main(int argc, char *argv)

#undef pi

void function()

巨集明在源程式中若用引號括起來,則預處理程式不對其做巨集替換

巨集定義允許巢狀,在巨集定義的字串中可以使用已經定義的巨集明。在巨集展開時由預處理程式層層替換。

例:

#define pi 3.14

#define n 2*pi*r

int main(int argc, char *argv)

注意#define和typedef的區別,巨集是預處理完成的,typedef是在編譯時處理的。typedef不是簡單的替換,而是對型別說明符重新命名。

例:

#define intptr1 int*

typedef int* intptr2;

int main(int argc, char *argv)

二.帶引數的巨集

c語言允許帶有引數的巨集。在巨集定義中的引數稱為形式引數,在巨集呼叫中的引數稱為形式引數,在巨集呼叫中的引數稱為實際引數。對帶引數的巨集,在呼叫中,不僅要巨集展開,而且要用實參去代替形參。

帶參巨集定義的一般形式為:  #define 巨集名(形參表) 字串   呼叫形式為: 巨集名(實參表)

例:

#define add(a,b) a+b

int main(int argc, char *argv)

帶參巨集定義中,巨集名和形參表之間不能有空格,如果有空格則會被當做無引數巨集,例如把 #define add(a,b) a+b 寫作 #define add (a,b) a+b 在上述巨集展開後是 c=(a,b) a+b

在帶參巨集定義中,形參不分配記憶體單元,因此不必作型別定義。而巨集呼叫中的實參有具體的值。要用他們去替換形參因此必須做型別說明。這是與函式中的情況不同的。在函式匯中,形參和實參是兩個不同的量,各有自己的作用域,呼叫時要把實參值賦予形參,進行「值傳遞」。而帶參巨集中,只是符合代換,不存在值傳遞問題。

在巨集定義的形參識別符號,而巨集呼叫可以使表示式

#define mut(x) (x)*(x)

int main(int argc, char *argv)

帶參巨集和帶參函式很相似,但有本質不同,除了上面談到的幾點之外,把同一表示式用函式處理與用巨集處理的結果有可能是不同的

例:(函式呼叫)

int mut(int x)

int main(int argc, char *argv)

例(帶參巨集)

#define mut(x) ((x)*(x))

int main(int argc, char *argv)

函式呼叫中,i作為函式引數傳入到函式內,計算完返回 i加1進入下次迴圈,共執行5次迴圈  帶參巨集中,巨集展開為(i++)*(i++) 計算完i做兩次自加操作,只迴圈三次

巨集定義也可以來定義多個語句,在巨集呼叫時,把這些語句又代換到源程式內。

例:

#define def int a = 2; int b = 3; int c = a + 2;

int main(int argc, char *argv)

三.條件編譯

預處理程式提供了條件編譯的功能,可以按不同的條件去編譯不同的程式部分,因而產品不同的目標**檔案。這對程式的移植和除錯是很有用的,條件編譯有三種形式。

第一種:

#ifdef 識別符號

程式段1

#else

程式段2

#endif

它的功能是,如果識別符號已經被#define命令定義過則對程式段1進行編譯,否則對程式段2進行編譯。如果沒有程式段2,本格式中的#else可以沒有,即可以寫為:

#ifdef 識別符號

程式段1

#elseif

第二種:

#ifndef 識別符號

程式段1

#else

程式段2

#endif

它的功能和第一種正相反,如果識別符號未被#define命令定義過則對程式段1進行編譯,否則對程式段2進行編譯

此功能多用於避免標頭檔案多重包含

第三種:

#if 常量表示式

程式段1

#else

程式段2

#endif

它的功能是,如果常量表示式的值為真(非0),則對程式段1進行編譯,否則對程式段2進行編譯。

C C 學習筆記 預處理命令

巨集定義命令 define 條件編譯 if ifdef ifndef 以 號開頭的命令稱為預處理命令 在編譯之前對原始檔進行簡單加工的過程,就稱為預處理 即預先處理 提前處理 如 include 引入標頭檔案 define max 100 巨集定義 c語言開發者們編寫了很多常用函式,並分門別類的放在...

C C 預處理命令

1.和 和 操作符是和 define 巨集使用的。使用 使在 後的首個引數返回為乙個帶引號的字串 例如 defineto string s s defineconcatenate x,y x y 2.define 命令用於把指定字串替換檔案中的巨集名稱 3.error 可以簡單的使編譯器在發生錯誤時...

十一 預處理

凡是以 號開頭的均為預處理命令 在源程式中這些命令都放在函式之外,而且一般都放在原始檔的前面 1 無參巨集定義 無參巨集的巨集名後不帶引數 一般形式為 define 識別符號 字串 例 define pi 3.1415926 其中 define 為巨集定義命令。識別符號 為所定義的巨集名。字串 可以...