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

C語言指標與陣列深度關聯:降級規則、sizeof 陷阱、記憶體模型完整解析

     編輯:關於C語言

C語言指標與陣列深度關聯:降級規則、sizeof 陷阱、記憶體模型完整解析

指標與陣列的關係是 C 語言最核心也最易混淆的主題。本文系統闡述**陣列降級規則**、**指標算術**、**sizeof 非降級例外**、**記憶體佈局差異**,並修正原始碼中「多個指標指向同一目標」的表述不精確問題。

核心定律:陣列名在「多數情況」下降級為首元素指標

int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int *p = arr;  // 降級:arr → &arr[0],型別 int*

// 等價操作:
arr[i]    ≡ *(arr + i)  ≡ *(p + i)  ≡ p[i]
&arr[i]   ≡ arr + i     ≡ p + i

兩大「不降級」例外 (必須背誦)

其他所有場合:函數參數、賦值、算術、下標、`*arr`、`arr+1`... **全部降級為 `int*`**。

sizeof 完整對比表 (假設 64 位系統,int=4 bytes)

運算子運算式結果型別說明
sizeofsizeof(arr)size_t (40)整個陣列大小,非指標大小
& (取址)&arrint (*)[10]陣列指標,指向整個陣列
運算式值型別說明
sizeof(arr)40size_t10×4,陣列完整大小 (不降級)
sizeof(p)8size_t指標大小 (64位=8)
sizeof(arr[0])4size_t單元素大小 (降級後取元素)
sizeof(&arr)8size_t陣列指標大小 (不降級)
sizeof(&arr[0])8size_t元素指標大小
sizeof(*&arr)40size_t&arr 為陣列指標,*解參考得陣列,sizeof 不降級

記憶體佈局本質差異

陣列 int arr[10]:
+----+----+----+----+----+----+----+----+----+----+
|  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 | 10 |  連續 40 位元組
+----+----+----+----+----+----+----+----+----+----+
  ^                                                      ^
arr (降級為 &arr[0])                                arr+9

指標 int *p = arr:
+----+
|    |  ← 8 位元組 (64位),儲存位址值 (如 0x7fff...)
+----+
  ^
  p (獨立變數,有自己的位址 &p)

關鍵認知修正

  • 指標 ≠ 陣列:指標是獨立變數 (儲存位址,8 位元組);陣列是連續記憶體區塊 (N×元素大小)。
  • 降級是單向的:陣列名可作指標用,**指標不可作陣列名用** (無 `sizeof(p)` 得陣列大小、無 `&p` 得陣列指標)。
  • 函數參數退化:`void f(int arr[10])` 等同 `void f(int *arr)`,編譯器內部統一為指標,**尺寸資訊丟失**。
  • 多個指標可指向同一陣列:`int *p1=arr, *p2=arr+5`,指向同一記憶體不同位置,非「指向同一目標」。

進階:陣列指標與二維陣列降級

int matrix[3][4];
int (*p)[4] = matrix;      // 正確:matrix 降級為 int(*)[4] (指向 4 個 int 的陣列)
int *p2 = matrix[0];       // 第一行降級為 int*
int *p3 = &matrix[0][0];   // 同前

// 函數參數
void f(int arr[3][4])  ≡  void f(int (*arr)[4])  // 必須保留列數
void f(int *arr)       // 錯誤:丟失列數,無法正確索引 arr[i][j]

常見面試題:輸出下列結果

int a[5] = {1,2,3,4,5};
printf("%p\n", a);        // 首元素位址
printf("%p\n", &a);       // 陣列位址 (數值相同,型別不同)
printf("%p\n", a+1);      // 首元素位址 + sizeof(int)
printf("%p\n", &a+1);     // 陣列位址 + sizeof(int[5]) = +20 位元組
printf("%zu\n", sizeof(a));   // 20
printf("%zu\n", sizeof(&a));  // 8 (指標大小)

總結

**陣列降級規則**是 C 指標系統的基石:**多數情況降級為首元素指標,僅 `sizeof` 和 `&` 保留陣列完整型別資訊**。指標與陣列在記憶體佈局上本質不同:前者是獨立位址變數,後者是連續資料區塊。掌握 `sizeof` 非降級例外、函數參數退化、二維陣列指標型別,是從「會用指標」進化為「懂記憶體模型」的關鍵門檻。

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