前導
請看以下程式碼 :
char *p = "Hello";
*p = 'h';
現代編譯器多將字符串常量放在唯讀區,因此上面的程式碼 *p = 'h';
會導致未定義行為,因為嘗試修改唯讀的記憶體內容。
const
:const char *p = "Hello";
好,繼續 :
const char * p
三個重點:
- 指標
p
指向的東西是「不可變的字元資料」。 - 換句話說,你不能透過
p
去修改記憶體中的字元值。 - 但是
p
本身是可以改變的,意即你可以讓p
指向別的字串或字元。
你可以這樣讀,從右讀到左: 即char *p
指向const char。
範例:
const char *p = "Hello";
// *p = 'h'; // 不可行,因為透過p修改目標內容不允許
p = "World"; // 可行,p本身可改變指向的位置
常見用途:
- 函式參數宣告為
const char *
,表示該函式承諾不會修改呼叫者傳入的字串內容。
觀念釐清
注意:
const char *str = "Hello";
str = "World"; // ✅ 允許:指標變數可以指向另一個字串
但:
str[0] = 'W'; // ❌ 錯誤!字串內容不可改
- 這是因為
str
存放的是唯讀字串的地址,但指標本身可以變動。
相對地:
char str[] = "Hello";
str = "World"; // ❌ 錯誤!陣列變數不可更改地址
- 這是因為
str
是一個固定的陣列變數,其指向的地址不能更改。
規則
const char *str = "Hello";
→ 不可改內容,但可改指向。char str[] = "Hello";
→ 內容可改,但指向不可改。
char * const p
- 這表示
p
是一個「const pointer」,指標本身不可改變,而指標所指向的內容可以修改。 p
一旦初始化後就不能再指向其他位址,但是透過p
可以修改p
所指向的記憶體內容(若該區域是可寫的)。- 你可以這樣讀,從右讀到左: 即
* const p
指向char。
範例:
char c = 'A';
char * const p = &c;
*p = 'B'; // 可行,修改c的值
// p = "some_other_char"; // 不可行,因為p是const pointer,不能改變p的位址值
const char * const p
- 將上述兩種const組合起來。
p
是一個「const pointer」,指向「const char」。- 代表:
p
本身不可以修改指向的位置。p
(所指向的字元內容) 也不可以被修改。
範例:
const char * const p = "Hello";
// *p = 'h'; // 不可行,內容不可改變
// p = "World"; // 不可行,指標本身不可改變指向