| 宣告 | 讀法(從右向左) | p (指標值) | *p (指向內容) |
|---|---|---|---|
char *const p | p is a const pointer to char | ❌ 不可修改 | ✅ 可修改 |
const char *p(等同 char const *p) | p is a pointer to const char | ✅ 可修改 | ❌ 不可修改 |
const char *const p | p is a const pointer to const char | ❌ 不可修改 | ❌ 不可修改 |
「const 貼著誰,誰就被鎖住」
char *const p → const 貼著 *(指標本身)→ 指標唯讀。const char *p → const 貼著 char(指向的型別)→ 指向內容唯讀。#include <stdio.h>
int main() {
char a = 'A', b = 'B';
// 情況 1:常數指標
char *const p1 = &a;
// p1 = &b; // ❌ 編譯錯誤:不能修改指標指向
*p1 = 'C'; // ✅ 合法:修改指向的內容
printf("p1: %c\n", *p1); // 輸出 C
// 情況 2:指向常數的指標
const char *p2 = &a;
p2 = &b; // ✅ 合法:修改指標指向
// *p2 = 'C'; // ❌ 編譯錯誤:不能透過 p2 修改內容
printf("p2: %c\n", *p2); // 輸出 B
// 情況 3:雙重 const
const char *const p3 = &a;
// p3 = &b; // ❌
// *p3 = 'C'; // ❌
printf("p3: %c\n", *p3); // 輸出 A
return 0;
}
const char *str:承諾函數不會修改輸入字串,呼叫端可安心傳入字串常量或重要資料。Config *const g_config:指標本身固定指向同一設定物件,但物件內部可更新數值。volatile uint32_t *const REG:位址固定,數值由硬體變動。const char *p 代表「p 指向的字串在執行期不會變」——**錯**。它只表示**透過 p 不能修改**;若有另一個非 const 指標指向同一記憶體,內容仍可能被修改。const 與 constexpr:後者要求編譯期常量,前者僅承諾執行期不透過此路徑寫入。掌握指標 const 位置,是 C/C++ 程式設計師的基本功,亦是程式碼契約清晰度的關鍵。