常量是表達程序中不變數據的基礎。C++ 提供了字面值、宏 (#define)、const 常變量、constexpr 及 C++11 原生字符串字面值等多種機制。本文系統對比其語法、語義、編譯處理差異與最佳實踐。
| 類型 | 示例 | 說明 |
|---|---|---|
| 十進制整數 | 123, -1, 0 | 無前綴 |
| 八進制整數 | 0123, -022 | 前綴 0,數字 0-7 |
| 十六進制整數 | 0x1A, 0XFF | 前綴 0x/0X,數字 0-9, A-F |
| 浮點數 (小數) | 3.14, .5, 1.0 | 含小數點 |
| 浮點數 (指數) | 1.3e9, 0.123E-4 | 科學記數法,e/E 大小寫均可 |
| 字符常量 | 'a', 'Z', '!' | 單引號,單字符 |
| 轉義字符 | \n, \t, \\, \', \" | 反斜槓開頭,特殊控制意義 |
| 字符串字面值 | "Hello", "Line1\nLine2" | 雙引號,編譯器自動補 \0 結尾 |
#define PI 3.14159 #define MAX_SIZE 1024
#define SQUARE(x) x*x 導致 SQUARE(a+1) 展開錯誤)。##、字符串化 #),條件編譯配合。const double PI = 3.14159; const int MAX_SIZE = 1024;
| 維度 | #define 宏 | const 常變量 |
|---|---|---|
| 類型檢查 | 無 | 編譯器強檢查 |
| 作用域 | 無 (文件級) | 塊/類/命名空間作用域 |
| 調試可見性 | 不可見 (魔術數字) | 符號表可見 |
| 內存分配 | 無 (文本替換) | 可能分配 (或優化為立即數) |
| 推薦場景 | 條件編譯、代碼片段、字符串拼接 | **所有數值/對象常量定義** |
結論:**優先使用 const (或 constexpr) 定義常量**,僅在預處理元編程場景用宏。
解決正則表達式、JSON、文件路徑中大量反斜槓轉義痛苦。
// 傳統寫法:雙重轉義
string regex = "\\\\zeng\\\\\\\\mei"; // 表示 \\zeng\\\\mei
// 原生字符串:R"(...)" 內容所見即所得,無轉義
string regex = R"(\\zeng\\mei)"; // 同樣表示 \\zeng\\mei
// 包含括號的原生字符串:自定義分隔符 R"delim(...)delim"
string json = R"json({"path": "C:\Windows\System32"})json";
規則:R"delimiter(content)delimiter",delimiter 可為空或最多 16 字符不含空格/括號/反斜槓。內容中可任意包含引號、反斜槓、換行,直到遇到 )delimiter" 結束。