Preprocessor前置處理器
初稿:2005.04.14, 更新日期:2020.12.05
 
參考資料:
 
在一個C的程式檔中,常會在開頭的幾行,見到以下幾種敘述:
  • #include  <前置處理檔.h>
  • #include  "檔名"
  • #define  PI  3.14
在C程式進行編譯(Compile)之前,會進行前置的處理工作,
包括:引入其他的標頭檔(.h)、常數符號定義、巨集定義等,
前置處理器(preprocessor)會將有 # 字的行,先行進行處理,
簡單說,這種前置處理器,是一種巨集處理,
常用於程式碼中的字串替換;
有些人甚至會用巨集寫簡單類函數的程式。

補充說明:
例如:#define PI 3.14
   定義PI為常數3.14,這巨集名稱PI,命名規則和變數命名規則相似,
   但和變數不一樣的地方,是在程式中,這個巨集名稱PI,是不能夠更改其數值,
   例如在程式中間,想把PI=3.1415; 這樣是不行的,
   所以,較常應用在一些符號常數的替換,
   比如:#define EQ ==
   在寫判斷選擇時,原本應該寫 if(x==3) 可寫成 if(x EQ 3)
   其跟 ANSI C 語法的 const float PI=3.14; 的宣告,是一樣效果。
  
前置處理的工作,有三類,如下:
  • 檔案的引入(source file inclusion)
      #include <系統函式.h>
      #include "自行定義檔.h"

  • 巨集替換(MACRO replacement),也稱 字符替換(Token replacement)
    指令名稱 功能說明 備註
    #define 定義巨集 結束不加分號
    #undefine 取消巨集定義  

  • 條件編譯
    指令名稱 功能說明 備註
    #ifdef  巨集名稱 如果已定義過,則編譯  
    #ifndef  巨集名稱 如未被定義, 則編譯  
    #if 巨集if  
    #else 巨集else  
    #endif 巨集if結束  


  • 範例練習[?]:若將巨集寫成函數,將下列函數輸入並執行
    #include <stdio.h>
    #define square(x) x*x
    int main()
    {
       int a,b;
       a=2;
       b=3;
       printf("x*x=%d\n", square(2+6));
       printf("x*x=%d\n", square(a+b));
    }
    請寫出執行結果為何?
    為什麼結果是這樣呢?
    如何修改?


  • 其他巨集定義範例參考:
    #define abs(a)    (a)>0 ? (a):-(a)  /* abs() 取絕對值 */
    #define max(a,b)  (a>b) ? (a):(b)   /* max() 比大小 */

曾聖超老師製作