宏操作符
| 操作符 | 功能 | 示例 | 結果 |
|---|---|---|---|
| `#` | 字符串化 | `#define STR(x) #x` | `STR(hello)` → `"hello"` |
| `##` | 標記粘連 | `#define CAT(a,b) a##b` | `CAT(var, 1)` → `var1` |
| `#@` | 字符化 (GCC 擴展) | `#define CHAR(c) #@c` | `CHAR(a)` → `'a'` |
實用宏模式
(b) ? (a) : (b)) // 變參宏 (C99/C++11) #define LOG_FMT(fmt, ...) fprintf(stderr, "[%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)斷言與契約式編程
0]] [[post r: r > x]] { return x + 1; } */位運算實戰技巧
基礎操作
struct Flags { unsigned int flag1 : 1; // 1 位 unsigned int flag2 : 3; // 3 位 (0-7) unsigned int flag3 : 4; // 4 位 (0-15) unsigned int : 0; // 強制對齊到下一個整數邊界 unsigned int flag4 : 8; }; // sizeof(Flags) 通常為 4 或 8 字節,視編譯器而定實用位運算算法
命令 功能 `break main` / `b 10` 設置斷點 `run` / `r` 開始/重新運行 `next` / `n` 單步跳過 (不進入函數) `step` / `s` 單步進入 `continue` / `c` 繼續運行 `print var` / `p var` 打印變量值 `watch var` 設置監視點 (變量變化時停下) `bt` / `backtrace` 查看調用棧 `info registers` 查看寄存器 `disassemble` / `disas` 查看匯編代碼 `x/10xw addr` 查看內存 (10 個 16 進制字) Valgrind 內存檢測
# GCC/Clang g++ -fsanitize=address -g -O1 main.cpp -o main ./main # 檢測:緩衝區溢出、Use-after-free、雙重釋放、內存洩漏 # 運行時開銷 ~2x,內存開銷 ~3x靜態分析工具
UB 類型 錯誤代碼 正確做法 有符號整數溢出 `int x = INT_MAX; x++;` 用無符號數或檢查邊界 解引用空/懸空指針 `int* p = nullptr; *p = 1;` 斷言/檢查、智能指針 數組越界 `int a[3]; a[3] = 0;` 用 `std::array`/`vector` + `at()` 移位超過位寬 `1 << 32` (32位 int) 用 `1ULL << 32` 或檢查 無序副作用 `a[i++] = i;` 拆分為多條語句 除零 `int x = 1/0;` 檢查除數 讀取未初始化值 `int x; if(x) ...` 聲明即初始化 總結
C++ 雜項技術看似零散,實則是工程落地的關鍵拼圖:
- 預處理器:條件編譯、宏元編程、調試輔助
- 斷言/契約:文檔化假設、運行期守衛、C++20 原生支持
- 位運算:底層優化、標誌位壓縮、算法技巧
- 調試工具鏈:GDB/LLDB 交互式、Valgrind/ASan 動態、Cppcheck 靜態
- UB 意識:敬畏未定義行為,用現代 C++ 特性從源頭消除
將這些技巧內化為肌肉記憶,能讓你在排查疑難雜症、優化熱點路徑、建立質量防線時游刃有餘。