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

C/C++ 陣列與指標的本質關係:從記憶體佈局到遍歷實戰

     編輯:關於C++

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

int a[] = {1, 2, 3, 4};
// a          → &a[0]  (型別 int*)
// a + 1      → &a[1]  (指標運算:+1 移動 sizeof(int) bytes)
// *a         → a[0]   (解引用)
// *(a + i)   → a[i]   (等價關係)

記憶體佈局圖解

棧區記憶體:
地址:   0x7ffe...10  0x7ffe...14  0x7ffe...18  0x7ffe...1c
值:          1            2            3            4
         a[0]         a[1]         a[2]         a[3]
         ↑
         a (陣列名,常量地址,不可修改)
         &a[0] (型別 int*)
         a + 0

實戰:指標遍歷陣列的三種寫法

1. 索引風格(最直觀)

for (int i = 0; i < 4; ++i)
    cout << a[i] << ' ';

2. 指標算術風格(本質相同)

for (int *p = a; p != a + 4; ++p)
    cout << *p << ' ';  // p 遞增 sizeof(int) bytes

3. 範圍基礎 for (C++11,推薦)

for (int val : a)
    cout << val << ' ';  // 編譯器自動轉為指標迴圈

完整範例:指標實現陣列反轉

void reverse(int *begin, int *end) {  // [begin, end) 左閉右開
    --end;  // 指向最後一個元素
    while (begin < end) {
        std::swap(*begin, *end);
        ++begin; --end;
    }
}

int main() {
    int a[] = {0,1,2,3,4,5,6,7,8,9};
    reverse(a, a + 10);  // 傳遞首尾指標
    for (int v : a) cout << v << ' ';  // 9 8 7 6 5 4 3 2 1 0
}

易混淆關鍵點對比表

表達式型別值/含義可修改?
aint* (退化)首元素地址❌ 陣列名是常量
&aint(*)[4]整個陣列地址❌
a + 1int*第二個元素地址✅ 臨時值可賦予指標變數
*aint第一個元素值✅ 左值
sizeof(a)size_t整個陣列大小 (16 bytes)—
sizeof(p) (p=a)size_t指標大小 (4/8 bytes)—

函數參數傳遞:陣列退化為指標

void foo(int arr[]);        // 等價於
void foo(int *arr);         // 等價於
void foo(int arr[10]);      // 10 被忽視,仍退化為指標

// 內部無法得知原始陣列長度,必須額外傳遞 size 參數
void foo(int *arr, size_t n);

現代 C++ 應優先用 std::span<T> (C++20) 或 std::vector 保留長度資訊與邊界檢查。

多維陣列指標退化

int m[2][3] = {{1,2,3},{4,5,6}};
int (*p)[3] = m;     // 指向「含 3 個 int 的陣列」的指標
// m 退化為 int(*)[3],而非 int**
// 訪問:p[1][2] → *(*(p+1)+2) → 6

總結

  1. 陣列名在**絕大多數表達式**中退化為指向首元素的指標(sizeof、&、alignof 除外)。
  2. 指標運算 p + i 自動按 sizeof(*p) 位移,這是陣列高效隨機存取的硬體基礎。
  3. 函數參數無法傳遞陣列長度,現代 C++ 用 std::span/std::vector/std::array 替代裸陣列指標。
  4. 理解退化規則是讀懂 C 庫代碼、避免 sizeof 陷阱、正確設計介面的前提。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved