首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言 const 與指針:為何 const 變數仍可被修改?

     編輯:關於C

現象

const int n = 10;
int *p = (int *)&n;
*p = 20;
printf("%d\n", n); // 輸出 20 (GCC/Clang -O0),或 10 (優化後)

核心解析

  1. const int n:告訴編譯器「我不會直接修改 n」,編譯器可將其放入唯讀段,並對直接存取 n 的代碼進行常數傳播優化(直接嵌入 10)。
  2. (int *)&n:強制類型轉換移除 const 資格,取得可寫指針。
  3. *p = 20:透過指針寫入記憶體。若 n 在唯讀段 → 段錯誤;若在資料段 (未優化/嵌入式) → 修改成功。
  4. printf("%d", n):若編譯器已常數傳播,印 10;若未優化,讀記憶體印 20。行為未定義。

標準規定

C 標準 (ISO/IEC 9899) 明確指出:嘗試修改 const 限定的物件屬於未定義行為 (UB)。編譯器不保證任何結果。

正確理解 const

  • 編譯期契約:防止程式設計師「直接」寫 n = 20,編譯器報錯。
  • 非執行期保護:不保證硬體/記憶體層面不可寫(需 MMU/MPU 支援放入唯讀頁)。
  • 指針傳遞:const int *p 承諾「透過 p 不修改指向物件」,但物件本身可能非 const。

實際應用模式

void func(const int *ptr) { /* 只讀 ptr */ }
int main() {
    int a = 10; func(&a);      // 非 const 物件傳給 const 指針:合法
    const int b = 20; func(&b); // const 物件傳給 const 指針:合法
    // int *p = &b; // 錯誤:const 物件不可轉非 const 指針 (需強轉,但極度危險)
}

結論

const 是給編譯器和維護者看的「承諾」,不是給硬體看的「鎖」。絕不透過強轉修改 const 物件,否則觸發 UB,導致程式在不同優化等級/平台表現不一。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved