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

C 語言 const 關鍵字完全指南:指針常量、常量指針、右左讀法、實戰陷阱

     編輯:關於C語言

C 語言 const 關鍵字完全指南

const 承諾「不通過此符號修改值」,但組合指針時極易混淆。本文提供右左讀法、四大組合模式表、編譯期/運行期行為、常見陷阱與修正,一次講透。

核心口訣:從右向左讀

const char *p → p is a pointer to const char (指針常量:指向常量的指針)
char * const p → p is a const pointer to char (常量指針:指針本身是常量)
const char * const p → p is a const pointer to const char (雙重常量)

四大組合模式速查表

聲明口訣p 可修改?*p 可修改?典型用途
const int *p
int const *p
pointer to const int✅❌函數參數防修改:void foo(const int *p)
int * const pconst pointer to int❌✅固定緩衝區指針:int * const buf = malloc(N);
const int * const pconst pointer to const int❌❌只讀只指:const int * const p = &global_const;
int *ppointer to int✅✅完全可變

編譯期 vs 運行期

  • 編譯期:任何通過 const 修飾的左值賦值、++/--、傳給非 const 參數 → 編譯錯誤。
  • 運行期:const 變量若存儲在 .rodata (全局/靜態),嘗試通過指針強制修改 → 段錯誤 (SIGSEGV)。棧上 const 可能被修改 (未定義行為)。

實戰陷阱與修正

陷阱代碼問題修正
void f(int *p) { *p = 1; }
const int x = 5; f(&x);
棄用 const 護衛,編譯警告但可能運行期崩潰void f(const int *p) 或傳遞副本
char *str = "literal"; str[0] = 'L';字符串字面量在 .rodata,不可寫char str[] = "literal"; (棧上副本) 或 const char *str
const int *p = &x; *p = 10;直接違反 const 承諾去掉 const 或用非 const 指針 (需確保原對象非真常量)
int const *p = &x; p = &y;以為 p 不可改記住:int const * 只保護 *p,p 本身可改
int * const p = &x; p = &y;以保護 *p 為由修改 pint * const 只保護 p,*p 可改

進階:const 與指針參數傳遞

// 1. 輸入指針:承諾不修改指向數據
size_t strlen(const char *s);  // 標準庫規範

// 2. 輸出指針:不加 const,調用者負責分配
int read_line(char *buf, size_t n);

// 3. 輸入輸出指針:不加 const
int parse_int(char **str, int *out);  // *str 推進,*out 寫結果

// 4. 指針本身不變 (罕見)
void use_buffer(int * const buf, size_t n);  // buf 不會被重新指向

const 與 constexpr / 宏 對比 (C++ 擴展)

特性C constC++ constexpr#define
類型安全✅✅❌
編譯期常量❌ (非字面量類型)✅✅ (文本替換)
可取地址✅✅❌
作用域塊/文件塊/命名空間文件 (無作用域)

小結

const 是 C 語言類型系統的契約。牢記 「從右向左讀」,區分 「指針常量」 (保護被指對象) 與 「常量指針」 (保護指針本身)。函數參數盡量加 const 表達意圖,編譯器將幫你攔截違約代碼。

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