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

C語言指針與字符串深度解析:常量區、棧區、sizeof 陷阱全覆蓋

     編輯:關於C語言

核心結論速查

代碼存儲區域類型sizeof 結果可修改性
char str[] = "abc";棧(局部) / 數據段(全局)char[4]4✅ 可修改
char* ptr = "abc";指針在棧,字符串在常量區char*4/8(指針大小)❌ 修改導致崩潰
char str2[10] = "abc";棧/數據段char[10]10✅ 可修改
void func(char sa[100])參數退化為 char*char*4/8視實際指向而定

詳細解析

1. 字符串字面量的本質

"abc" 編譯器自動補 \0 存為 "abc\0"。是否為常量取決於上下文:

  • 初始化字符數組(char str[] = "abc")→ 編譯器視為元素列表 {'a','b','c','\0'},在棧/數據段分配數組空間,非常量,可修改。
  • 賦值給字符指針(char* ptr = "abc")→ 編譯器將字面量放入只讀常量區,ptr 指向該地址。雖類型非 const char*,但寫入觸發段錯誤。建議寫法:const char* ptr = "abc",編譯期捕獲錯誤。

2. 數組類型與 sizeof

  • 數組類型 = 元素類型 + 長度。char[3] ≠ char[4]。
  • sizeof 作用於類型:sizeof(str) = 數組總字節數;sizeof("abc") = 4(含 \0)。
  • 函數參數退化規則:void f(char a[100]) 等價 void f(char* a),sizeof(a) 為指針大小。

3. 實戰驗證

char str[] = "abcdef";     // sizeof=7 
char* ptr = "abcdef";      // sizeof=4/8 
char str2[10] = "abcdef";  // sizeof=10 
void func(char sa[100]) {  // sizeof(sa)=4/8 
    printf("%zu\n", sizeof(sa)); 
}

4. 進階:指針算術與字符串長度

  • strlen 計算 \0 前字符數,不含結束符。
  • sizeof 編譯期常量,strlen 運行期遍歷。

避坑检查清单

  1. ❌ char* p = "hello"; p[0] = 'H'; → 段錯誤
  2. ✅ const char* p = "hello"; 或 char p[] = "hello";
  3. ❌ void f(char a[10]) { sizeof(a); } 以為得 10 → 實得 4/8
  4. ✅ 傳長度參數或用結構體包裹數組
  5. ❌ 混淆 sizeof 與 strlen

總結

字符串字面量存儲位置由定義方式決定:數組初始化 → 棧/數據段可寫;指針指向 → 常量區只讀。sizeof 看類型,數組不退化時得全長,退化為指針得指針大小。牢記這兩點,規避 90% 指針字符串 Bug。本文整理自 51CTO 技術博客筆記。

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