程式碼示例
#include <stdio.h>
int main() {
const int n = 10; // 唯讀變數,具備常量屬性
int *p = (int *)&n; // 去除 const 資格,取得位址
*p = 20; // 透過指標修改內容
printf("%d\n", n); // 輸出:20 (但屬未定義行為)
return 0;
}
現象解析
const int n 告訴編譯器「此變數不應被修改」,編譯器可能將其放入唯讀記憶體區段 (如 .rodata)。
- 強制轉型
(int *)&n 移除 const,屬於「去除 const 資格」,C 標準規定:**嘗試修改原本宣告為 const 的物件,行為未定義**。
- 實際執行結果視平台而定:
- 一般作業系統 (Linux/Windows) 下,全域/區域 const 可能仍在可寫記憶體 → 修改成功。
- 嵌入式系統、最佳化等級高時,可能置於唯讀區 → 觸發硬體例外 (Segmentation Fault / Hard Fault)。
標準規定 (C99 6.7.3/5)
若嘗試修改以 const 限定的物件,行為未定義。
正確做法
- 若需修改,**勿加 const**。
- 若需「不可修改」語意,**嚴格遵守**,不嘗試通過指標繞過。
- 函數參數用
const int *p 表達「不修改指向內容」,屬契約式設計,非強制執行。
const 與指標的組合語意
| 宣告 | 含義 | 可修改指標? | 可修改指向值? |
const int *p / int const *p | 指向常數的指標 | 是 | 否 |
int *const p | 常數指標 (指標本身不可改) | 否 | 是 |
const int *const p | 常數指標指向常數 | 否 | 否 |
總結
範例雖能在某些環境輸出 20,但屬**未定義行為**,不可依賴。嚴謹程式設計應尊重 const 契約,避免強制轉型修改唯讀物件。
- 上一篇文章: C語言輸出單引號與雙引號:轉義字元實戰
- 下一篇文章: C語言轉義字元陷阱:路徑字串與 strlen 計算
Copyright ©
程式碼之家 All Rights Reserved