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

C/C++ 陣列與指標的深層關係:本質、運算與遍歷實戰

     編輯:VC 教學

核心結論:陣列名稱在表達式中退化為指向首元素的指標

對於 int a[] = {1,2,3,4};:

  • a(陣列名稱)在絕大多數表達式中**退化為 int***,值為 &a[0](首元素地址)。
  • &a 類型為 int(*)[4](指向整個陣列的指標),值同 a 但類型不同。
  • sizeof(a) 為整個陣列大小(16 bytes),非指標大小。

地址運算等價關係

表示式類型意義等價寫法
aint*首元素地址&a[0]
a + iint*第 i 元素地址&a[i]
*(a + i)int第 i 元素值a[i]
&a[i]int*第 i 元素地址a + i

指標遍歷陣列:標準慣用語

int a[2] = {1, 2};
int* pb = a;        // 指向開頭
int* pe = a + 2;    // 指向結尾(尾後一位)

cout << a << "|" << a[0] << "|" << *(a+1) << "|" << pb << "|" << *pb << endl;

while (pb != pe) {  // 指標比較判斷結束
    cout << *pb << endl;
    ++pb;           // 移動到下一個元素
}

為何指標運算能自動按元素大小移動?

指標類型攜帶元素類型資訊(int* 知曉 sizeof(int))。pb++ 實際增加 sizeof(int) 位元組,非單純 +1 位元組。這是 C/C++ 指標運算的核心設計。

多維陣列與指標

int m[2][3] = {{1,2,3},{4,5,6}};
int (*p)[3] = m;       // 指向含 3 int 陣列的指標
cout << p[1][2];       // 6,等價 m[1][2]
cout << *(*(p+1)+2);  // 同樣 6

函式參數傳遞:陣列實為指標

void foo(int arr[])   // 實為 void foo(int* arr)
void foo(int* arr)    // 完全等價
void foo(int arr[10]) // 10 被忽略,仍為指標

**陣列大小資訊丟失**,函式內無法用 sizeof(arr) 取得元素數。**解決方案**:傳遞長度參數、使用標準容器、C++20 std::span。

常見誤區

誤區正確認知
int* p = a; 以為複製了陣列僅複製首元素地址,共享同一記憶體
sizeof(p) 以為得到陣列大小得到指標大小(4/8 bytes),非陣列大小
以為 a++ 合法陣列名稱非常數指標,不可修改(a = a+1 錯誤)
以為 int a[] = b; 可複製陣列不可用陣列初始化另一陣列,需 std::copy 或逐元素賦值

現代 C++ 建議

  • 優先使用 std::array(固定大小)、std::vector(動態大小),保留大小資訊、支援範圍 for、邊界檢查。
  • 需與 C API 互操作時,用 data() 取得指標、size() 取得長度。
  • C++20 std::span 提供非擁有權的陣列/容器視圖,完美替代 (ptr, len) 組合。

總結

陣列與指標的「退化」關係是 C/C++ 記憶體模型的基石。理解 a ≡ &a[0]、指標運算按元素大小位移、函式參數實為指標,能避免 90% 的陣列相關 Bug。現代開發應善用標準庫容器封裝底層細節,僅在必要時觸及裸指標。

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