首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言指標與一維陣列深度解析:指標運算、陣列退化、記憶體佈局圖解

     編輯:程式設計綜合問答

核心觀念:指標儲存位址,陣列名在多數情境下退化為指向首元素的指標

int a[10];      // 10 個 int,連續記憶體,共 40 bytes (假設 int=4)
int *pa = a;    // pa 指向 a[0],等價於 &a[0]
int *pb = &a[0]; // 明確取首元素位址

記憶體佈局視覺化

位址 (假設 a 從 0x1000 開始,int=4 bytes):
a[0]  a[1]  a[2]  a[3]  a[4]  a[5]  a[6]  a[7]  a[8]  a[9]
0x1000 0x1004 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C 0x1020 0x1024
  |     |     |     |     |     |     |     |     |     |
  +-----+-----+-----+-----+-----+-----+-----+-----+-----+
  |  a (陣列名,退化為 int* 指向 0x1000)                     |
  +----------------------------------------------------------+
  |  pa (int*) ────────────────────────────────────────────► 0x1000

指標運算核心規則:ptr + i 移動 i * sizeof(*ptr) 位元組

運算式型別值/意義位址變化 (int=4)
aint* (退化)首元素位址 &a[0]0x1000
a + iint*指向第 i 個元素 &a[i]+ i*4
paint*同 a,指向 a[0]0x1000
pa + iint*指向 a[i]+ i*4
pa++int* (副作用)原值 pa,然後 pa 指向下一個元素pa 變為 0x1004
*paint解參考,取得 a[0] 的值-
*(pa + i)int等價 pa[i]、a[i]-
&a[0]int*首元素位址0x1000
&aint(*)[10]**整個陣列的位址**,型別不同!0x1000 (數值相同,語意不同)
&a + 1int(*)[10]陣列結束後位址 0x1000 + 40+ 40 (整個陣列大小)

關鍵區別:a vs &a

int a[10];
printf("%p\n", a);      // 0x1000  (int*)
printf("%p\n", &a);     // 0x1000  (int(*)[10])
printf("%p\n", a+1);    // 0x1004  移動 1 個 int
printf("%p\n", &a+1);   // 0x1028  移動 1 個 int[10] (40 bytes)
  • a (退化) 型別 int*,步長 sizeof(int)。
  • &a 型別 int(*)[10] (指向陣列的指標),步長 sizeof(int[10])。
  • **陣列名只有兩種情況不退化**:sizeof(a) (得 40)、&a (得陣列指標)。

指標遞增 pa++ 的副作用與陷阱

int *pa = a;
printf("%d\n", *pa);  // a[0]
pa++;
printf("%d\n", *pa);  // a[1]
pa++;
printf("%d\n", *pa);  // a[2]
// pa 現在指向 a[3],原始陣列起始位址已丟失(除非另存)

**最佳實踐**:使用索引 pa[i] 或暫存指標 int *p = pa; while(*p) ...,避免修改唯一指向陣列開頭的指標。

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

void func(int arr[]) { }        // 等價於 int *arr
void func(int *arr) { }         // 同樣
void func(int arr[10]) { }      // 10 被忽略,仍退化為 int*

// 內部 sizeof(arr) 為指標大小 (8 bytes 於 64-bit),非陣列大小!
// 傳遞大小需額外參數:void func(int *arr, size_t n)

二維陣列指標進階(延伸)

int b[3][4];  // 3 行 4 列
// b 型別退化為 int(*)[4] (指向包含 4 個 int 陣列的指標)
// b+1 移動 1 行 (16 bytes)
// *b 等價 b[0],型別退化為 int* (指向第 0 行首元素)
// b[i][j] 等價 *(*(b+i)+j) 等價 *(b[i]+j) 等價 b[i][j]

除錯技巧:GDB/Visual Studio 觀察指標與陣列

  • GDB:print a, print *a@10 (顯示 10 個元素), print /x pa (十六進位位址)。
  • VS:監看視窗輸入 a,10 (顯示 10 元素)、pa,10、記憶體視窗輸入 &a[0]。

總結

C 語言指標與陣列的關係核心在於:**陣列名在表達式中多數退化為指向首元素的指標**,指標運算以**所指型別大小**為步長。理解 a、&a、a+i、pa++ 的型別與語意差異,掌握記憶體連續佈局模型,是寫出正確、高效 C 程式的基石。建議配合圖解記憶體佈局、大量實作指標版字串處理/排序/鏈表操作來內化理解。

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