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

C語言陣列名取址深度解析:&a vs a、行指標、指標運算陷阱

     編輯:關於C語言

核心概念:a vs &a

指標運算差異

int a[5] = {1,2,3,4,5};

int *p1 = a;        // p1 = &a[0] = 0x1000
int *p2 = (int*)(&a + 1);  // &a + 1 跨過整個陣列 = 0x1000 + 5*4 = 0x1014

關鍵:&a + 1 的步長是 **整個陣列大小** (sizeof(int[5]) = 20 位元組),而 a + 1 步長是 **單個元素** (4 位元組)。

經典面試題解析

int a[5] = {1,2,3,4,5};
int *p = (int*)(&a + 1);
printf("%d\n", *(p-1));  // 輸出?

逐步推導

  1. &a 類型 int(*)[5],值 0x1000
  2. &a + 1 類型同,值 0x1000 + 20 = 0x1014 (指向陣列結束後)
  3. (int*)(&a + 1) 強轉為 int*,值 0x1014
  4. p - 1 類型 int*,值 0x1014 - 4 = 0x1010
  5. *(p-1) 解引用 0x1010,即 a[4] = 5

記憶體佈局視覺化

位址:    0x1000  0x1004  0x1008  0x100C  0x1010  0x1014
        +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
a[ ]:   |  1  | |  2  | |  3  | |  4  | |  5  | |     |
        +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
索引:      0       1       2       3       4

a:       0x1000 (int*)
&a:      0x1000 (int(*)[5])
&a+1:    0x1014 (int(*)[5])  ----> 跨過 5 個 int
p:       0x1014 (int*)
p-1:     0x1010 (int*)  -----> 指向 a[4]
*(p-1):  5

行指標完整語法

int a[3][4];           // 3行4列
int (*p)[4] = a;       // p 指向「含4個int的陣列」,即第0行
p++;                   // p 指向第1行,步長 16 位元組
int *elem = *(p+1)+2;  // 第1行第2列的位址 (&a[1][2])
int val = *(*(p+1)+2); // 第1行第2列的值 (a[1][2])

常見錯誤與最佳實踐

表達式類型值含義
aint*首元素位址退化為 &a[0]
&aint(*)[5]整個陣列位址行指標,指向含 5 個 int 的陣列
錯誤代碼問題正確寫法
int *p = &a;類型不匹配:int(*)[5] vs int*int (*p)[5] = &a; 或 int *p = a;
sizeof(p) 當作陣列大小p 是指標,sizeof 為 4/8sizeof(a) 才是陣列總大小
函式參數 void f(int a[]) 用 sizeof退化為指標,sizeof 失效傳遞長度參數或用結構體包裹

總結

a 是首元素位址 (int*),&a 是整個陣列位址 (int(*)[N])。指標運算步長由**指標類型**決定:int* 步長 4,int(*)[5] 步長 20。強轉類型改變步長語義,是陣列邊界計算、多維陣列操作的核心技巧。

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