編譯預處理是 C/C++ 編譯流程的第一階段,在正式編譯(詞法分析、語法分析、代碼生成)之前執行。預處理器(如 GCC 的 cpp,MSVC 的 cl.exe /E)處理以 # 開頭的預處理指令。
核心目的:源代碼的「文本級」變換與擴展,為編譯器提供「乾淨」的編譯單元。
#include 將頭文件內容展開到當前文件#define 定義常量、函數式宏,預處理器執行文本替換#if/#ifdef/#ifndef 根據條件包含/排除代碼段#error/#warning 輸出編譯時錯誤/警告#line 改變編譯器報告的行號/文件名#pragma 向編譯器傳遞特定指令(如 #pragma once)# 開頭的指令(前允許空白字符)#include <stdio.h> → 讀取系統頭文件內容,插入當前位置#define MAX 100 → 在符號表記錄 MAX → 100MAX → 替換為 100#ifdef DEBUG ... #endif → 根據宏定義決定保留/刪除代碼段源文件 test.c:
#define PI 3.14
#define AREA(r) (PI * (r) * (r))
#include <stdio.h>
int main() {
int r = 5;
printf("Area: %f\n", AREA(r));
return 0;
}
執行 gcc -E test.c -o test.i 後,test.i 內容(節選):
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdio.h" 1 3 4
... stdio.h 完整內容展開 ...
# 1 "test.c" 2
int main() {
int r = 5;
printf("Area: %f\n", (3.14 * (5) * (5)));
return 0;
}
可見:
#define 宏被展開替換#include 頭文件內容被完整插入# 指令消失,只保留 #line 標記供調試用#define SQUARE(x) x*x 存在運算符優先級陷阱,應用括號 (x)*(x)#ifndef GUARD_H / #define GUARD_H / #endif 或 #pragma once 防護編譯預處理是文本處理階段,通過宏展開、文件包含、條件編譯等機制,將分散、參數化的源代碼「鋪平」為編譯器可直接處理的單一編譯單元。理解預處理行為,是掌握 C/C++ 構建系統、跨平台編譯、條件編譯技巧的基礎。