首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

經典筆試陷阱:字符數組 vs 字符指針初始化字符串的本質區別

     編輯:關於C

這道題考察字符串字面值存儲區別與修改權限,是 C/C++ 筆試面試高頻必考點。

代碼對比

情況 1:字符數組初始化

char s[10] = "mysohu";
s[0] = 0;           // ✅ 合法:修改數組內容
printf("%s\n", s);  // 輸出:空行(首字符為 \0)

記憶體模型:"mysohu" 字面值在編譯期存入只讀數據段;數組 s 在棧上分配 10 位元組,**運行時將字面值內容複製到數組中**。數組擁有完全所有權,可讀可寫。

情況 2:字符指針初始化

char *s = "mysohu";
s[0] = 0;           // ❌ 未定義行為:嘗試修改只讀內存
printf("%s\n", s);  // 可能崩潰、輸出亂碼、或看似正常(視平台)

記憶體模型:s 是棧上指針,直接指向只讀數據段中的字面值「mysohu」。**未發生複製**,指針僅持有地址。修改 s[0] 即修改只讀段 → 段錯誤。

核心區別總結表

維度char s[] = "..."char *s = "..."
存儲位置棧(數組內容)只讀數據段(字面值)
內容來源運行時從字面值**複製**直接指向字面值**無複製**
可修改性✅ 完全可讀寫❌ 嚴禁修改(UB)
sizeof(s)數組大小(含 \\0)指針大小(4/8 位元組)
賦值操作s = "new" ❌ 錯誤s = "new" ✅ 合法(改指向)

最佳實踐鐵律

  1. 需修改字符串 → 必須用數組:char buf[100] = "init"; 或 malloc 動態分配。
  2. 僅讀取/傳遞 → 用 const char*:const char *msg = "hello"; 編譯器會攔截修改嘗試。
  3. 字面值永遠視為只讀,即使編譯器不報錯(如舊標準允許 char* 接字面值),運行期修改也是 UB。

現代 C++ 建議

// 需修改、擁有所有權
std::string s = "mysohu";
s[0] = '\0';  // 安全、自動管理內存

// 僅讀取、非擁有
std::string_view sv = "mysohu";  // C++17,零開銷視圖
// sv[0] = 'x';  // 編譯錯誤,const

總結

char s[] = **擁有內容的可變緩衝區**;char *s = **指向只讀字面值的觀察者**。這道題不僅考語法,更考察對程序內存佈局(代碼段/數據段/棧/堆)的理解。牢記:「字面值住在只讀區,數組住在棧上,指針只存地址」,即可輕鬆破解所有變體題目。

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