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

C語言指針數組與數組指針深度解析:訪問二維數組的兩種方式

     編輯:關於C

「指針數組」與「數組指針」一字之差,本質天壤之別。本文從定義語法、優先級解析、二維數組訪問演示、內存佈局圖解四個維度徹底釐清。

定義語法對比

名稱聲明本質優先級結合
指針數組int *p[8];**數組**,元素為指針p 先結合 [] → 數組,再結合 * → 元素是指針
數組指針int (*p)[8];**指針**,指向數組p 先結合 * → 指針,再結合 [8] → 指向 8 元素數組

右左法則機械解析

  1. 從變量名 p 出發。
  2. 向右看:遇到 [] 或 () (高優先級) 先結合。
  3. 向左看:遇到 * 或類型關鍵字結合。
  4. 遇到括號組 () 反向,解析完跳出繼續。

例:int (*p)[8] → p 右無高優先級 → 左 * (指針) → 跳出括號 → 右 [8] (指向 8 元素數組) → 左 int (元素類型)。

二維數組內存佈局

int arr[4][4] = { ... }; // 行主序連續存儲
地址遞增: arr[0][0] → arr[0][1] → ... → arr[0][3] → arr[1][0] → ...
每行佔 4*4=16 字節
行起始地址: arr, arr+1, arr+2, arr+3 (類型 int(*)[4],步長 16 字節)
等價表達: arr+i, &arr[i], *(arr+i), arr[i] (均為第 i 行首地址,類型 int*)

訪問二維數組代碼演示


int arr[4][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}};

// 方式一:數組指針
int (*p1)[4] = arr; // p1 指向首行
for (int i=0; i<4; ++i)
    for (int j=0; j<4; ++j)
        printf("%d ", *(*(p1+i)+j)); // p1+i → 第i行首地址,解引用 → 行首元素,+j → 第j列

// 方式二:指針數組
int *p2[4];
for (int i=0; i<4; ++i) p2[i] = arr[i]; // 每個元素指向對應行首
for (int i=0; i<4; ++i)
    for (int j=0; j<4; ++j)
        printf("%d ", *(p2[i]+j)); // p2[i] 已是行首指針,直接 +j

核心區別總結

特性數組指針 int (*p)[N]指針數組 int *p[N]
類型單一指針指針集合 (N個)
sizeof(p)指針大小 (4/8)N * 指針大小
算術步長整行大小 (N*sizeof(int))指針大小
初始化p = arr; 一次性需循環 p[i] = arr[i];
適用場景函數參數傳遞二維數組、遍歷整個矩陣行長度不一 (鋸齒數組)、需單獨操作某幾行

函數參數傳遞最佳實踐


// 推薦:數組指針,保留列數信息,編譯器可做邊界檢查
void process(int (*matrix)[COLS], int rows);

// 避免:指針數組 (除非鋸齒數組)
void process(int **matrix, int rows, int cols); // 退化為指針的指針,丟失列數
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved