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

C 語言經典筆試題:字元陣列 vs 字元指標修改字串常量的差異

     編輯:關於C語言

這是 C 語言面試筆試的必考經典:字元陣列與字元指標初始化字串時,記憶體佈局與可修改性的本質區別。看懂這道題,就理解了 C 語言字串存儲的核心機制。

題目:對比兩程式輸出

程式一:字元陣列

char s[10] = "mysohu";
s[0] = 0;  // 或 s[0] = '\0'
printf("%s\n", s);

輸出: (空行) — 字串被截斷為空字串

程式一運行結果

程式二:字元指標

char *s = "mysohu";
s[0] = 0;  // 嘗試修改首字元
printf("%s\n", s);

輸出: 運行時崩潰 (Segmentation Fault / Access Violation)

程式二崩潰

記憶體佈局本質差異

特性char s[10] = "mysohu"char *s = "mysohu"
儲存位置棧 (Stack) 或數據段 (全域/靜態)指標在棧,字串常量在唯讀數據段 (.rodata)
記憶體權限可讀寫字串區域唯讀
初始化過程編譯器生成代碼將常量逐字元複製到陣列指標直接指向常量區地址,無複製
修改合法性合法,修改陣列內容非法,嘗試寫入唯讀區 → 硬體異常
sizeof(s)10 (陣列大小)4/8 (指標大小)

圖解記憶體模型

程式一:棧區
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| 'm'    | 'y'    | 's'    | 'o'    | 'h'    | 'u'    | '\0'   |  ?     |  ?     |  ?     |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
  s[0]   s[1]   s[2]   s[3]   s[4]   s[5]   s[6]   s[7]   s[8]   s[9]
  ↑
  修改為 0 → 字串結束

程式二:
棧區:          唯讀數據區:
+--------+      +--------+--------+--------+--------+--------+--------+--------+
| s ──────────→ | 'm'    | 'y'    | 's'    | 'o'    | 'h'    | 'u'    | '\0'   |
+--------+      +--------+--------+--------+--------+--------+--------+--------+
  指標          唯讀!寫入觸發保護錯誤

正確做法與最佳實踐

  1. 需修改字串:必須用陣列 char s[] = "..."; 或動態分配 malloc/strdup
  2. 只讀字串:用 const char *s = "..."; — 編譯器會報錯防止誤修改
  3. 函數參數:不修改字串的函數參數應聲明為 const char *

延伸陷阱

char *p1 = "hello";
char *p2 = "hello";
// p1 == p2 可能為真 (編譯器優化合併相同常量),也可能為假 — 不可依賴

char a[] = "hello";
char b[] = "hello";
// a == b 永遠為假 (不同陣列實例)

總結

陣列 = 容器 (可寫),指標 = 地址 (指向唯讀常量區)。這道題考察的不是語法,而是記憶體模型理解。牢記:「雙引號字串常量進入 .rodata,陣列初始化會複製,指標初始化只取址。」

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