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

C/C++ 字串指標陣列與指向指標的指標:記憶體佈局圖解與實戰

     編輯:VC 教學

兩個核心概念

  • 字串指標陣列:char* arr[] = {"abc", "cde", "fgh"}; — 陣列元素類型為 char*,儲存各字串常量的**首地址**。
  • 指向指標的指標:char** p = arr; — 指向陣列首元素(即第一個 char*)的指標。

記憶體佈局圖解

棧區 (Stack)                          唯讀資料段 (Read-only Data)
┌─────────────────────┐               ┌──────────────┐
│ arr[0] ─────────────┼──────────────►│ "abc\0"      │
│ arr[1] ─────────────┼──────────────►│ "cde\0"      │
│ arr[2] ─────────────┼──────────────►│ "fgh\0"      │
└─────────────────────┘               └──────────────┘
        ▲
        │
     char** p  (指向 arr[0] 的指標)
  • 陣列 arr 本身在棧上,佔 3 × sizeof(char*) 位元組。
  • 字串常量 "abc" 等在唯讀區,**地址不連續**,由編譯器安排。
  • p 指向 arr[0],p+1 指向 arr[1](跨越 sizeof(char*) 位元組)。

程式碼逐行解析


char *a[] = {"abc", "cde", "fgh"};  // 字串指標陣列
char** b = a;                       // b 指向 a[0]

cout << *b      << "|"   // *b = a[0] = "abc" 首址 → 印 "abc"
     << *(b+1)  << "|"   // *(b+1) = a[1] = "cde" 首址 → 印 "cde"
     << *(b+2)  << endl;  // *(b+2) = a[2] = "fgh" 首址 → 印 "fgh"

函式傳遞:陣列退化為指向指標的指標


void print_char(char* array[], int len) {  // 等價 char** array
    for (int i = 0; i < len; ++i)
        cout << *array++ << endl;  // array 為區域指標變數,可修改
}

int main() {
    char* test[] = {"abc", "cde", "fgh"};
    int num = sizeof(test) / sizeof(char*);  // 編譯期計算元素數 = 3
    print_char(test, num);  // 傳遞 test 首元素地址(即 &test[0])
}

關鍵觀察

  • sizeof(test) 在陣列定義作用域內 = 完整陣列大小(12/24 bytes)。
  • 傳入函式後,sizeof(array) = 指標大小(4/8 bytes),**失去長度資訊** → 必須額外傳 len。
  • *array++ 利用指標遞增遍歷,等價 array[i] 但避免索引運算。

常見錯誤

現代 C++ 替代方案


// 推薦:std::vector 或 std::array
std::vector vec = {"abc", "cde", "fgh"};
for (const auto& s : vec) cout << s << endl;

// 僅需唯讀視圖
std::array arr = {"abc", "cde", "fgh"};

優點:自動管理記憶體、知道大小、支援範圍 for、避免手動指標運算錯誤。

總結

char* arr[] 與 char** p 是 C 風格字串集合的經典表示。理解**陣列在棧、字串在唯讀區、指標運算按 sizeof(char*) 位移**的記憶體模型,是正確操作它們的關鍵。新代碼請優先使用標準容器封裝,僅在介接 C API 時轉換。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
錯誤代碼問題修正
char* b = a;類型不符:a 是 char*[3],退化為 char**,不可賦值給 char*char** b = a;
cout << **(b+1);解引用兩次得到 char,印單一字元 'c'cout << *(b+1); 印整字串
函式內 sizeof(array) 取長度得到指標大小,非元素數傳遞長度參數或用哨兵 NULL