const 在不同位置、與指針組合時語義截然不同。本文通過七大情景、可編譯驗證代碼,讓每種用法「深入人心」。
[c]
int const a = 5; // 正確:定義時初始化
// int const a; a = 5; // 錯誤:賦值時刻已過,編譯報錯 "assignment of read-only variable"
int const 與 const int 完全等價。但與指針混用時**順序決定語義**,不可隨意顛倒。
[c]
#define MAX 100 // 預處理器文本替換,無類型檢查,不進符號表
const int MAX = 100; // 有類型、有作用域、進符號表,調試器可見,優先選擇
| 聲明 | 口訣 | 指針可變? | 指向值可變? |
|---|---|---|---|
const int *pint const *p | const 修飾 *p(右側) | ✅ 是 | ❌ 否 |
int *const p | const 修飾 p(左側) | ❌ 否 | ✅ 是 |
const int *const p | 雙向 const | ❌ 否 | ❌ 否 |
閱讀技巧:從變量名向左讀,遇到 * 說「指向」,遇到 const 說「只讀」。
[c]
int num = 12, tmp = 100;
const int *p = #
// (*p)++; // 錯誤:increment of read-only location '*p'
p = &tmp; // 正常:修改指針指向
printf("%d\n", *p); // 100
tmp = 3; // 正常:通過原變量修改值
printf("%d\n", *p); // 3 —— const 只保護 *p 這條訪問路徑
[c]
int num = 12;
int *const p = #
// p = &tmp; // 錯誤:assignment of read-only variable 'p'
(*p) = 100; // 正常:修改指向的值
printf("%d\n", *p); // 100
[c]
int num = 12;
const int *const p = #
// (*p) = 100; // 錯誤
// p = &tmp; // 錯誤
// 指針與指向值均不可修改
[c]
int addto(const int num, int a, int b) {
// num = 3; // 錯誤:形參不可修改
return (num == 1) ? a + b : 0;
}
作用:
const 變量,擴大調用範圍。const。const 變量在 C 中默認內部鏈接(每編譯單元一份),C++ 默認外部鏈接。跨文件共享需配合 extern。const 不難,**關鍵在於「誰被 const 修飾」**。掌握「從右向左讀」口訣,配合實驗驗證,即可輕鬆駕馭所有情景。善用 const,讓編譯器成為你最忠實的代碼審查員。