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

C語言數組與指針深度綁定:從內存佈局到指針算術的完全指南

     編輯:關於C語言

數組與指針:C語言靈魂雙子星的深度解析

在 C 語言中,數組與指針的關係既緊密又微妙,是無數開發者從「會用」到「精通」的分水嶺。本文將從內存模型、類型系統、指針算術、函數傳參、多維數組五個維度,構建完整的知識體系,並附帶經典誤區避坑指南。

一、 內存佈局的本質區別

int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr;  // ptr 指向首元素

// 內存圖示:
// arr:  [10][20][30][40][50]  (連續 20 字節,不可移動)
// ptr:  [addr_of_arr[0]]      (單獨 4/8 字節變量,可修改指向)
  • 數組名:在大多數表達式中「退化」為指向首元素的指針(int *),但不是變量,不能賦值、不能 arr++、sizeof(arr) 返回整個數組大小。
  • 指針變量:獨立存儲地址的變量,支持算術運算、解引用、重新賦值,sizeof(ptr) 返回指針本身大小(4/8 字節)。

二、 指針算術與數組遍歷的等價性

// 三種遍歷方式本質相同(編譯器優化後機器碼幾乎一致)
for (int i = 0; i < 5; i++)       printf("%d ", arr[i]);      // 下標法
for (int *p = arr; p < arr+5; p++) printf("%d ", *p);         // 指針算術
for (int i = 0; i < 5; i++)       printf("%d ", *(arr+i));    // 指針偏移

核心規則:指針 + n 表示向後移動 n * sizeof(元素類型) 字節,而非字節偏移。

三、 二維數組與指針的類型系統

int matrix[3][4];  // 3行4列,連續 48 字節

// 關鍵類型推導:
int (*p_row)[4] = matrix;  // 指向「含4個int的數組」的指針(行指針)
int *p_elem = matrix[0];   // 指向首元素(退化為一維)

// 訪問 matrix[i][j] 等價形式:
matrix[i][j]           // 標準下標
*(*(matrix + i) + j)   // 指針解引用全展開
p_row[i][j]            // 行指針下標
*(*(p_row + i) + j)    // 行指針算術

面試高頻點:int **p 不能直接指向二維數組 int a[3][4],因為二維數組在內存中是連續塊,而 int ** 期望的是指針數組(非連續)。

四、 函數傳參:數組退化與形參寫法

// 以下三種聲明在函數參數列表中完全等價(均退化為 int *)
void func1(int arr[]);
void func2(int arr[10]);      // 尺寸被忽略,僅作文檔
void func3(int *arr);         // 本質真相

// 實際傳遞的是首元素地址,函數內 sizeof(arr) 返回指針大小!
// 必須額外傳遞長度參數:
void process(int *arr, size_t len);

五、 經典誤區與最佳實踐

誤區代碼問題正確寫法
int *p = malloc(10); p = arr;內存洩漏:malloc 內存地址丟失直接 int *p = arr; 或 memcpy
void f(int a[][])編譯錯誤:二維數組需指定列數void f(int a[][COLS]) 或 void f(int (*a)[COLS])
return local_array;返回棧上局部數組地址 → 懸空指針動態分配 malloc / 靜態 static / 輸出參數
sizeof(ptr) 獲取數組長度返回指針大小而非元素個數單獨傳遞 len 參數

六、 進階:指針數組 vs 數組指針

int *ptr_arr[5];      // 指針數組:5個 int* 元素,每個可指向不同內存塊
int (*arr_ptr)[5];    // 數組指針:指向「含5個int的數組」的單一指針

// 應用場景:
// 指針數組:字符串數組、不規則矩陣、命令行參數 argv
// 數組指針:處理二維數組整體、矩陣運算庫

總結:數組是「連續內存塊的標籤」,指針是「攜帶類型信息的地址變量」。掌握退化規則、類型推導、指針算術單位,配合圖解內存佈局,即可破解所有數組指針難題。記住:int a[5] 在參數列表裡只是 int *a 的語法糖。

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