首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言字元陣列與指標的關係:為何 char* 指向字串常量無法修改?

     編輯:程式設計綜合問答

核心問題

初學者常見困惑:char name[] = "abcdef"; 可作為引數傳入 reverse() 反轉成功,但改成 char* name = "abcdef"; 卻導致執行期錯誤(存取違規)。

記憶體模型差異圖解

宣告方式儲存區域可修改性存留期
char name[] = "abcdef";堆疊可讀寫函式結束釋放
char* name = "abcdef";唯讀資料段唯讀程式結束釋放

程式碼逐行解析

void reverse(char* s)
{
    char *p = s, *q = s + strlen(s) - 1, temp;
    while (p < q) { temp = *p; *p = *q; *q = temp; p++; q--; }
}
  • p、q 分別指向字串首尾。
  • *p = *q 嘗試寫入記憶體——若 s 指向唯讀段,即觸發 Segmentation Fault。

正確用法示範

✅ 可修改的區域陣列

char name[] = "abcdef";  // 編譯器在堆疊配置 7 bytes 並複製字面值
reverse(name);           // 安全

✅ 動態配置可寫緩衝區

char* name = malloc(7);
strcpy(name, "abcdef");  // 複製到可寫堆積記憶體
reverse(name);
free(name);

❌ 錯誤:直接指向字串常量

char* name = "abcdef";   // 指標指向 .rodata 段
reverse(name);           // Crash!

指標與陣列的本質關係

  • 陣列名 在大多數語境下轉換為「指向首元素的指標常數」(不可修改指向)。
  • 指標變數 可隨時改變指向,但不擁有資料儲存空間。
  • sizeof(name) 對陣列回傳整個大小,對指標回傳指標大小(4/8 bytes)。

最佳實務建議

  1. 需要修改字串內容時,務必使用陣列或動態配置記憶體。
  2. 函式參數若不修改內容,應宣告為 const char*,編譯器將協助攔截錯誤用法。
  3. 嵌入式系統開發時,留意 const 資料是否真正被編譯器放入 Flash 唯讀區。

延伸閱讀

深入理解 C 語言陣列轉指標規則 與 字串常量儲存類別,是避免此類 Bug 的關鍵。

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