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

C 語言初學筆記:二維數組與指針的深度解析 —— 從 board[3][3] 看指針鏈結構

     編輯:關於C語言

緣起:教科書晦澀,自學《C語言入門經典》一夜悟道

課堂上《C語言程序設計教程》(譚浩強版)對數組指針關系講解過於抽象,花了一晚研讀《C語言入門經典》,終於理清二維數組與多級指針的對應關系。記錄核心結論,供同路人參考。

核心代碼實驗

char board[3][3] = {
    {'1','2','3'},
    {'4','5','6'},
    {'7','8','9'}
};

printf("board[0][0] = %c\n", board[0][0]);  // 1
printf("*board[0]   = %c\n", *board[0]);    // 1
printf("**board     = %c\n", **board);      // 1

指針層級逐層拆解

表達式類型語義等價寫法
boardchar (*)[3]指向首個子數組(第 0 行)的指針&board[0]
*board / board[0]char *指向第 0 行第 0 列元素的指針&board[0][0]
**board / *board[0] / board[0][0]char第 0 行第 0 列元素的值('1')—

記憶口訣:指針鏈向下,解引用向上

  • board 是指向一維數組的指針(步長 3×sizeof(char))
  • *board 解引用一次,得到指向元素的指針(步長 sizeof(char))
  • **board 再解引用一次,得到元素值

二維數組在內存中連續佈局,board[i][j] 本質上是 *(*(board + i) + j),編譯器根據類型自動計算偏移。

常見誤區辨析

  1. 誤以為 board == *board == **board:類型完全不同,僅數值相等時地址巧合相同。
  2. 忽略類型檢查:傳參時 void f(char **p) 不能接收 char a[3][3],需用 void f(char (*p)[3]) 或 void f(char p[][3])。
  3. 動態分配混淆:char **p = malloc(3 * sizeof(char *)) 創建的是指針數組,非連續內存,與靜態二維數組佈局不同。

延伸:三維及以上數組

int a[2][3][4] 中,a 指向 int [3][4],*a 指向 int [4],**a 指向 int。每增加一維,指針鏈就多一層,解引用規則同理。

結語

理解「數組名在表達式中退化為指向首元素的指針」是核心。二維數組首元素是一維子數組,故退化為指向一維數組的指針。畫出指針鏈圖,多寫幾個 printf("%p") 觀察地址,自然內化。

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