第 八 章 C 的 前 置 處 理 器

8-1 前 置 處 理 器 (preprocessor)

我 們 在 寫 程 式 的 時 候 , 常 常 會 碰 到 某 些 資 料 重 覆 使 用 或 是 某 些 程 式 片 段 因 特 定 的 條 件 下 須 放 棄 , 如 果 以 正 常 的 方 式 來 寫 作 程 式 , 可 能 會 增 加 無 謂 的 程 式 片 段 , 使 的 程 式 笨 重 不 堪 , 但 如 果 能 好 好 運 用 C 語 言 所 提 供 的 前 置 處 理 器 , 則 上 述 的 狀 況 將 改 善 許 多 . 這 個 功 能 並 非 C 語 言 本 身 的 格 式 , 但 仍 為 編 譯 程 式 所 能 接 受 . 對 前 置 處 理 器 的 解 釋 , 如 圖 一 所 示 , 因 為 它 是 在 程 式 編 譯 之 前 執 行 , 所 以 顧 名 思 義 稱 之 前 置 處 理 .

              前置處理         編譯處理        連結處理

     ┌────┐    ┌────┐    ┌────┐    ┌────┐
     │ 原  始 │    │ 原  始 │    │ 目  的 │    │ 執  行 │
     │        ├─→│        ├─→│        ├─→│        │
     │ 檔  案 │  ↑│ 程  式 │    │ 檔  案 │  ↑│ 檔  案 │
     └────┘  │└────┘    └────┘  │└────┘
                   │                              │
     ┌────┐  │                ┌────┐  │
     │include │  │                │ 目  的 │  │
     │        ├─┘                │        ├─┘
     │ 檔  案 │                    │ 檔  案 │
     └────┘                    └────┘



                        圖一 .  編譯流程


8-2 前 置 處 理 器 格 式 與 種 類

<1> 前 置 處 理 器 的 格 式 如 下:

           #前置處理器名稱    處理內容
<2> 前 置 處 理 器 敘 述 可 寫 在 程 式 中 的 任 何 地 方 .
<3> 前 置 處 理 器 的 種 類 如 下 表 一 所 列 , 其 各 種 前 置 處 理 器 之 使 用 方 法 , 我 們 將 在 以 下 的 章 節 中 一 一 介 紹 .
     ┌──────────┬────────────────────┐
     │      功 能         │         前置處理器之敘述               │
     ├──────────┼────────────────────┤
     │    檔案的含入      │#include                                │
     ├──────────┼────────────────────┤
     │字串的置換/巨集定義 │#define / #undef                        │
     ├──────────┼────────────────────┤
     │                    │#if .... #elif .... #else .... #endif   │
     │   條 件 編 譯      │                                        │
     │                    │#ifdef (#ifndef) .... #else .... #endif │
     └──────────┴────────────────────┘

                         表一 前置處理器的種類


8-3 #include(檔 案 的 含 入)

此 敘 述 之 主 要 目 的 是 讓 我 們 將 某 個 程 式 檔 或 標 頭 檔 包 括 在 目 前 的 程 式 內 , 使 目 前 的 程 式 可 引 用 該 檔 內 的 資 料 或 程 式 . 語 法 如 下 :

     <1> #include "檔案名稱" : 此表示系統將會到目前的目錄 (路徑 )
                               下尋找所指定的檔案 ,如果找不到 ,則
                               會去系統設定的目錄底下尋找 .

     <2> #include <檔案名稱> : 此表示系統將會到系統設定的目錄底下
                               尋找所指定的檔案 .

有關 #include 的使用範例 ,請參考 Example 8-3-1 .

     Example 8-3-1 :

         #include < stdio.h >
         #include "def.h"
         main()
         {
            printf("PI=%2.5f\n",PI);
            printf("a+b=%d\n",a+b);
         }

         -- def.h 的檔案內容 --

         #define PI  3.14159
         #define a   10
         #define b   20
         ----------------------


      執行結果 :

                   PI=3.14159
                   a+b=30


8-4 #define(字 串 的 置 換 / 巨 集 定 義)與 #undef

<1> 巨 集 #define 的 使 用 :其 主 要 之 功 能 是 以 簡 單 的 名 稱 取 代 某 些 特 定 的 常 數 或 字 串 , 函 數 , 建 立 更 簡 單 更 易 懂 的 程 式 . 語 法 如 下 :

               #define 巨集名稱 常數或函式或字串
<2> 巨 集 #undef 的 使 用 :其 主 要 之 功 能 則 是 取 消 最 接 近 之 #define 所 定 義 的 敘 述 .
               #undef  巨集名稱
<3> 有 關 #define 與 #undef 的 使 用 方 式 , 請 參 考 Example 8-4-1 , 8-4-2 , 8-4-3 , 8-4-4 .

     Example 8-4-1 :

         #include < stdio.h >
         #define PI 3.14159
         main()
         {
           printf("PI=%2.5f",PI);
         }

      執行結果 :

                   PI=3.14159


      Example 8-4-2 :

          #include < stdio.h >
          #define add(a,b) a+b
          main()
          {
             int i,j,k;
             i=2;
             j=3;
             k=add(i,j);

             printf("i+j=%d\n",k);
          }


       執行結果 :

                    i+j=5


      Example 8-4-3 :

          #include < stdio.h >
          #define pstring "This is my first C program.\n"
          main()
          {
            printf(pstring,1);
          }

       執行結果 :

                    This is my first C program.


      Example 8-4-4 :

          #include < stdio.h >
          #define  compare(a,b)             \
                    if ( a > b )            \
                      printf("a > b");      \
                    else                    \
                      if ( a < b )          \
                        printf("a < b");    \
                      else                  \
                        printf("a = b");
          main()
          {
             int a,b;
             a=5;
             b=10;
             compare(a,b);
          }


       執行結果 :
                    a < b


      Example 8-4-5 :

          #include < stdio.h >
          #define TURBOC
          main()
          {
            #ifdef TURBOC
              printf("Borland C compiler.\n");
            #endif

            #undef TURBOC

            #ifndef TURBOC
              printf("MircoSoft C compiler.\n");
            #endif
          }

       執行結果 :

                    Borland C compiler.
                    MircoSoft C compiler.



8-5 條 件 式 的 編 譯

<1> 條 件 式 的 編 譯 , 此 用 法 的 最 大 特 色 在 於 其 敘 述 不 僅 可 以 放 在 程 式 的 頂 端 , 亦 可 將 其 敘 述 放 置 於 程 式 中 . 以 下 所 列 (1) ,(2) ,(3) 項 為 條 件 式 編 譯 的 成 員 .

                    (1) #if 和 #endif
                    (2) #else / #elif
                    (3) #ifdef 和 #ifndef
<2> 由 以 上 的 敘 述 , 我 們 不 難 發 現 這 些 條 件 式 編 譯 的 成 員 與 前 幾 章 控 制 流 程 所 提 到 if ... then ... else 的 語 法 十 分 相 似 , 且 連 使 用 方 法 與 原 理 都 非 常 相 似 .
<3> 條 件 式 的 編 譯 處 理 , 請 參 考 Example 8-5-1 , 8-5-2 , 8-4-5 .

     Example 8-5-1 :

         #include < stdio.h >
         #define value  99
         main()
         {
           #if value < 100
             printf("value < 100");
           #else
             printf("value >= 100");
           #endif
         }

      執行結果 :

                   value < 100


     Example 8-5-2 :

         #include < stdio.h >
         #define value  100
         main()
         {
           #if value < 100
             printf("value < 100");
           #elif value > 100
             printf("value > 100");
           #else
             printf("value = 100");
           #endif
         }

      執行結果 :

                   value = 100



回 到 C 語 言 入 門 教 室 首 頁