兩種宣告本質不同
char *ptr = "hello"; // ptr 指向**唯讀區**的字串字面量
char arr[] = "hello"; // arr 在**堆疊**複製字串內容 (含 \0)
關鍵差異表
| 特性 | char *ptr | char arr[] |
| 儲存位置 | 唯讀資料段 (.rodata) | 堆疊 (或靜態區) |
| 可修改內容 | **否** (UB/段錯誤) | **是** |
| 指針可重新指向 | 是 (ptr = "world") | 否 (arr 為常量地址) |
| sizeof 結果 | 指針大小 (4/8) | 陣列總大小 (含 \0) |
| 賦值語法 | ptr = "str" 合法 | arr = "str" **編譯錯誤** |
實證代碼
int main() {
char *p = "ABC";
char a[] = "ABC";
a[0] = 'X'; // 合法,a 變 "XBC"
// p[0] = 'X'; // 運行時崩潰 (SIGSEGV)
printf("sizeof(p)=%zu, sizeof(a)=%zu\n", sizeof(p), sizeof(a));
// 64位: 8, 4
return 0;
}
動態分配模擬指針可寫
char *p = malloc(100);
strcpy(p, "hello"); // 現在可修改 p[0]
free(p);
最佳實踐
- 只讀字串常量:
const char *p = "..." (編譯器強制保護)。
- 需修改字串:用陣列
char buf[] = "..." 或 malloc。
- 函數參數:
void func(const char *s) 表示不修改;void func(char *s) 表示可能修改。