首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言預處理指令完整指南:宏定義、文件包含與條件編譯

     編輯:關於C語言

前言

ANSI C 標準規定在 C 源程式中可加入「預處理命令」,以改善程式設計環境、提高編程效率。這些命令並非 C 語言本身的組成部分,無法直接編譯。編譯器會先對程式中的特殊命令進行「預處理」,移除所有預處理指令後,再對處理過的源程式進行常規編譯,產生可執行的目標代碼。

C 語言提供的預處理功能主要有三種:

  1. 宏定義
  2. 文件包含
  3. 條件編譯

分別由宏定義命令、文件包含命令、條件編譯命令實現,這些命令皆以「#」開頭。

宏定義

不帶參數的宏定義

用一個指定的標識符代表一個字串,一般形式:

#define 識別符 字串

範例:

#define PI 3.1415926

說明:

  • 作用是在本程式檔案中用指定的標識符 PI 取代「3.1415926」這個字串。預處理時,將程式中該命令出現後的所有 PI 替換為「3.1415926」;這些標識符稱為「宏名」。
  • 宏名慣用大寫,以便與變數名區別。
  • 宏定義在預編譯時不作正確性檢查。
  • 宏定義不是 C 敘述,行尾不加分號;若加上分號會連同分號一起置換,極易導致錯誤。

錯誤範例:

#define PI 3.14;
...
area = PI * r * r;

宏展開後變為:

area = 3.14; * r * r; // 語法錯誤

帶參數的宏定義

帶參數的宏定義不僅進行字串替換,還要進行參數替換,一般形式:

#define 宏名(參數表) 字串

範例:

// 定義矩形面積 S,a 和 b 為變長
#define S(a,b) a*b
...
area = S(3,2);

展開過程:程式中若帶有實參的宏(如 S(3,2)),按 #define 命令列中指定的字串從左到右置換。字串中包含形參(如 a、b)則用相應實參取代;非參數字符(如 *)則保留。

因此賦值語句展開為:

area = 3*2;

進階範例:

#define PI 3.14
#define S(r) PI*(r)*(r)

int _tmain(int argc, _TCHAR* argv[]) {
    float a, area;
    a = 2;
    area = S(a+1); // 展開為 3.14*(a+1)*(a+1)
    printf("r=%.2f,area=%.2f\n", a, area);
}

運行結果:

r=2.00,area=28.26

注意:宏名與帶參數的括號之間不應加空格,否則會變成不帶參數的宏定義,導致錯誤。例如:

#define S (r) 3.14*(r)*(r)
...
area = S(a+1); // 展開為 3.14*(r)*(r)(a+1) 錯誤

文件包含

所謂「文件包含」是指一個源檔案可將另一個源檔案的內容全部包含進本檔案。C 語言提供 #include 命令實現,一般形式:

#include <檔名> (一般為庫檔案)
#include "檔名" (使用者自定義檔案)

條件編譯

一般情況下,源程式中所有行都參與編譯,但有時只希望在滿足特定條件下才編譯,這就是「條件編譯」。可在滿足條件時編譯一組敘述,不滿足時編譯另一組。

常見形式

  1. 若定義「標識符」則執行「程式段1」
    #ifdef 識別符
    程式段1
    #endif
  2. 若定義「標識符」執行「程式段1」,否則執行「程式段2」
    #ifdef 識別符
    程式段1
    #else
    程式段2
    #endif
  3. 若未定義「標識符」則執行「程式段1」
    #ifndef 識別符
    程式段1
    #endif
  4. 若「表達式」為真執行「程式段1」,否則執行「程式段2」
    #if 表達式
    程式段1
    #else
    程式段2
    #endif

總結:預編譯功能是 C 語言特有的,有利於程式的可移植性,增加程式的靈活性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved