預處理命令以 # 開頭,雖非 C 語言核心語法,但極大增強了代碼的可維護性、可移植性與調試能力。ANSI C 定義了 12 條指令,本文系統梳理核心用法。
#define 標識符 字符串
// 無分號,標識符與字符串間任意空格,換行結束
#define TRUE 1
#define FALSE 0
#define MAX_SIZE 100
float balance[MAX_SIZE];
宏替換本質: 純文本替換,發生在編譯預處理階段。printf("%d%d%d", FALSE, TRUE, TRUE+1); → printf("%d%d%d", 0, 1, 1+1);
#define TWO ONE+ONE → 展開為 1+1。#define ERR_MSG "Error\n",調用 printf(ERR_MSG); 替換為 printf("Error\n");。#define MIN(a,b) ((a)<(b)?(a):(b)),調用 MIN(x,y) 展開為 ((x)<(y)?(x):(y))。優點:無函數調用開銷,速度快;缺點:代碼膨脹。\ 續行。
#error 編譯器停止,輸出錯誤信息
// 用於調試、版本檢查
#include "filename" // 先搜當前目錄,再搜指定目錄,最後搜標準目錄
#include // 先搜編譯器指定目錄,再搜標準目錄,不搜當前目錄
支持嵌套包含,層數受實現限制。標準庫頭文件常用尖括號,用戶頭文件用雙引號。
#if 常量表達式
// 表達式真(非0)編譯此段
#elif 常量表達式1
// 前面假,此真則編譯
#else
// 以上全假編譯此段
#endif
關鍵限制: 表達式必須為**常量表達式**(僅含常量、已定義宏),**不能含變量**,不能用 sizeof。
#ifdef MACRO_NAME // 若已定義則編譯
#ifndef MACRO_NAME // 若未定義則編譯
#endif
可配合 #else,但不能用 #elif。常用於防止頭文件重複包含:
#ifndef HEADER_H
#define HEADER_H
// 頭文件內容
#endif
#if、#ifdef 可按實現限制嵌套,#endif/#else/#elif 與最近的 #if/#elif 配對。
#define LEN 100
#define WIDTH 100
char arr[LEN][WIDTH];
#undef LEN
#undef WIDTH
// 此後 LEN、WIDTH 未定義,限制作用域
#line 100 "myfile.c" // 後續 __LINE__ 從100開始,__FILE__ 為 "myfile.c"
// 主要用於調試、生成代碼工具
#pragma 實現定義的指令
// 如啟用/禁用警告、對齊設置、優化控制等,編譯器特定
| 宏名 | 含義 |
|---|---|
| __LINE__ | 當前行號(整數) |
| __FILE__ | 當前文件名(字符串) |
| __DATE__ | 編譯日期 "Mmm dd yyyy" |
| __TIME__ | 編譯時間 "hh:mm:ss" |
| __STDC__ | 標準編譯器為1,非標準為其他 |
寫法:雙下劃線包圍標識符。非標準編譯器可能不支持全部。
/* 註釋內容 */,/* 與 */ 間無空格。/* 外層 /* 內層 */ */ 會報錯。善用預處理器實現常量集中管理、平台差異隔離、調試代碼條件編譯、頭文件防重複包含,能顯著提升代碼質量與開發效率。