C 語言本身不具備檔案包含、宏定義、條件編譯等功能,這些由預處理器在編譯前完成。預處理指令以 # 開頭,常見指令如下:
| 指令 | 用途 |
|---|---|
#include | 包含原始檔 |
#define | 定義宏 |
#undef | 取消宏定義 |
#if / #elif / #else / #endif | 條件編譯區塊 |
#ifdef / #ifndef | 檢查宏是否定義 |
#error | 停止編譯並報錯 |
#pragma | 編譯器專用指令 |
#include兩種包含格式差異:
#include <header.h>:搜尋系統標準庫目錄#include "header.h":優先搜尋當前專案目錄,再搜尋系統目錄防止重複包含的標準護衛模式:
/* my.h */
#ifndef MY_H
#define MY_H
/* 內容 */
#endif
#define#define MAX_NUM 10
#define VERSION "Version 1.0"
慣用全大寫命名,提升可讀性且易於維護。宏可引用前序宏:
#define ONE 1
#define TWO 2
#define THREE (ONE + TWO) /* 建議加括號避免運算優先級問題 */
#define CUBE(x) ((x) * (x) * (x))
關鍵規則:參數與整體表達式皆需加括號,防止副作用與優先級錯誤。絕對避免傳遞有副作用的運算式(如 CUBE(i++))。
# 與連接 ## 運算子#define STR(s) #s /* 字串化:STR(abc) → "abc" */
#define CONCAT(a,b) a##b /* 連接:CONCAT(12,34) → 1234 */
#if / #elif / #else / #endif
#define DEBUG 1
#if DEBUG
printf("Debug mode\n");
#elif RELEASE
printf("Release mode\n");
#else
printf("Unknown\n");
#endif
#ifdef / #ifndef檢查宏定義存在與否,等價於 #if defined(MACRO) / #if !defined(MACRO)。常用於標頭檔護衛與平台差異處理。
#error 強制編譯錯誤
#ifndef CONFIG_H
#error "缺少組態檔 config.h"
#endif
inline 函數或 constexpr (C++11)#pragma once(編譯器支援時)簡化標頭檔護衛