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

C 語言 const 關鍵字完全指南:從只讀變量到函數參數契約的四大核心用法

     編輯:關於C語言

核心定位:const 是「只讀承諾」而非「硬體常量」

const 告訴編譯器:「我不會通過這個符號修改該值」。編譯器以此進行靜態檢查,但不保證運行時只讀(可通過指針轉換、硬體映射等繞過)。

四大核心用法詳解

1. 修飾基本類型變量:只讀變量

const int n = 10;    // n 為只讀,編譯期常量傳播優化
// n = 20;            // 編譯錯誤:賦值只讀變量
int arr[n];          // C99 支持 VLA,但 C89/C++ 標準不允許作數組長度(需常量表達式)
  • C++ 中 const int 默認內部連接,可直接作數組長度、模板參數;C 中需配合 #define 或 enum。
  • 嵌入式中常配合 volatile:volatile const int *port = (void*)0x4000;(硬體只讀寄存器)。

2. 修飾指針:左右法則決定鎖定對象

const int *p1;      // p1 可變,*p1 只讀(指向常量的指針)
int const *p2;      // 同 p1,const 修飾左側 int
int *const p3;      // p3 只讀,*p3 可讀寫(常量指針)
const int *const p4; // p4 只讀,*p4 只讀(雙重鎖定)

「沿 * 劃線」口訣

  • const 在 * 左側 → 修飾 *p(指向的值只讀)。
  • const 在 * 右側 → 修飾 p(指針本身只讀)。

典型應用

  • const char *str = "hello"; 字符串字面值區只讀,防止誤寫。
  • int *const ptr = &var; 固定指針指向,防止指針漂移。

3. 修飾函數參數:傳值調用的模擬與契約

void foo(const int *arr, int n);  // 承諾:不修改 arr 指向的內容
void bar(const MyStruct *ctx);    // 承諾:不修改 ctx 內部狀態
  • 本質:接口契約,告訴調用者「此函數為純讀操作」,編譯器輔助檢查函數體內是否違規寫入。
  • 配合指針層級:const int *const p 同時鎖定指針與內容,最嚴格契約。
  • 注意:const 只約束「通過此符號訪問」,若實參實際指向可寫內存,函數內部仍可通過強制類型轉換修改(const_cast / C 風格轉換),屬於違約行為。

4. 修飾函數返回值:防止誤賦值與語義保護

const int foo();              // 返回基本類型:無意義,臨時值本不可賦值
const MyStruct bar();         // 返回結構體:防止 bar().member = val 這類誤操作
const MyStruct& baz();        // 返回引用:極其重要,防止修改被引用對象(如單例、緩存)
  • 返回基本類型加 const:C++ 標準建議不要加,無實際意義且干擾移動語義優化(C++11 起)。
  • 返回用戶定義類型(類/結構體)加 const:有意義,保護對象內部狀態。
  • 返回引用/指針加 const:核心用法,實現「只讀訪問」語義(如 const vector& getData() const)。

const 與指針類型轉換規則

轉換方向是否允許原因
T* → const T*✅ 隱式允許增加約束,安全
const T* → T*❌ 隱式禁止移除約束,危險(需 const_cast)
T** → const T**❌ 禁止間接修改風險:const T** p; *p = &const_obj; **p = val;
T* const* → const T* const*✅ 允許指針本身已鎖定,安全

工程最佳實踐清單

  1. 默認加 const:除非需要修改,所有變量、參數、返回值、成員函數(void foo() const)默認加 const。
  2. 指針參數雙重鎖定:void func(const int *const p) 同時保護指針與數據。
  3. 避免 const_cast:除非對接無 const 設計的舊代碼/庫,否則視為代碼異味。
  4. const 與 volatile 組合:硬體寄存器 volatile const、多線程共享只讀標誌 volatile const(配合原子操作)。
  5. C++11 constexpr 替代:編譯期常量優先用 constexpr,語義更強、優化更激進。

總結

const 是 C/C++ 類型系統中「只讀語義」的基石。從變量定義到指針層級鎖定,再到函數接口契約與返回值保護,const 構建了層層遞進的防禦體系。將 const 內化為「默認加、漏加即缺陷」的肌肉記憶,是寫出健壯、可維護、可優化代碼的關鍵習慣。

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