const 是 C 語言中最常用也最易誤解的關鍵字之一。它不僅修飾「常量」,更核心語義是「只讀」。本文系統梳理 const 修飾變量、指針、函數參數、返回值的規則,揭示其「偽常量」本質,並給出嵌入式開發中的最佳實踐。
const int MAX_SIZE = 100; // MAX_SIZE = 200; // 編譯錯誤:賦值左值為只讀 // 等價寫法(風格偏好) int const MAX_SIZE = 100; // 同義,讀作 "MAX_SIZE 是 const int"
&MAX_SIZE 類型為 const int *,強制轉型去 const 後寫入屬於未定義行為(可能觸發硬件異常或靜默失效)。口訣:const 修飾左側最近的類型;若左側無類型則修飾右側最近的類型。
| 聲明 | 讀法 | 指針可變 | 指向值可變 | 典型用途 |
|---|---|---|---|---|
| const int *p int const *p | 指向 const int 的指針 | ✅ | ❌ | 函數參數防修改 void foo(const int *p) |
| int *const p | const 指針指向 int | ❌ | ✅ | 固定指向某塊內存(如硬件寄存器映射) |
| const int *const p | const 指針指向 const int | ❌ | ❌ | 只讀查表、常量字符串指針 |
| int const *const p | 同上 | ❌ | ❌ | 同上 |
const int val = 10; int *p = (int *)&val; // 強制去 const *p = 20; // UB:可能修改成功(棧上),可能崩潰(.rodata 段只讀頁),可能無效果(編譯器優化假設 val 不變) // 結論:絕不可去 const 寫入,除非極少數硬件寄存器映射場景(volatile 配合)。
const int n = 10; int arr[n]; // 合法,n 是常量表達式static,C 需顯式 static const。(C++11 起非 const 賦值已棄用)。
void process(const BigStruct *p);const 是 C 語言類型系統中表達「只讀意圖」的核心工具。掌握指針組合規則、理解其與 C++ 的差異、善用 const + volatile 建模硬件,能顯著提升代碼健壯性、可讀性與優化機會。記住:const 是給編譯器和讀代碼的人看的契約,不是給運行時硬件強制執行的鎖。