網(wǎng)站首頁 編程語言 正文
二維數(shù)組
二維數(shù)組在概念上是二維的,有行和列,但在內存中所有的數(shù)組元素都是連續(xù)排列的,它們之間沒有“縫隙”。以下面的二維數(shù)組 a 為例:
int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };
從概念上理解,a 的分布像一個矩陣:
0 1 2 3
4 5 6 7
8 9 10 11
但在內存中,a 的分布是一維線性的,整個數(shù)組占用一塊連續(xù)的內存:
C語言中的二維數(shù)組是按行排列的,也就是先存放 a[0] 行,再存放 a[1] 行,最后存放 a[2] 行;每行中的 4 個元素也是依次存放。數(shù)組 a 為 int 類型,每個元素占用 4 個字節(jié),整個數(shù)組共占用 4×(3×4) = 48 個字節(jié)。
C語言允許把一個二維數(shù)組分解成多個一維數(shù)組來處理。對于數(shù)組 a,它可以分解成三個一維數(shù)組,即 a[0]、a[1]、a[2]。每一個一維數(shù)組又包含了 4 個元素,例如 a[0] 包含 a[0][0]、a[0][1]、a[0][2]、a[0][3]。
假設數(shù)組 a 中第 0 個元素的地址為 1000,那么每個一維數(shù)組的首地址如下圖所示:
為了更好的理解指針和二維數(shù)組的關系,我們先來定義一個指向 a 的指針變量 p:
int (*p)[4] = a;
括號中的*表明 p 是一個指針,它指向一個數(shù)組,數(shù)組的類型為int [4],這正是 a 所包含的每個一維數(shù)組的類型。
[ ]的優(yōu)先級高于*,( )是必須要加的,如果寫作int *p[4],那么應該理解為int *(p[4]),p 就成了一個指針數(shù)組,而不是二維數(shù)組指針。
對指針進行加法(減法)運算時,它前進(后退)的步長與它指向的數(shù)據(jù)類型有關,p 指向的數(shù)據(jù)類型是int [4],那么p+1就前進 4×4 = 16 個字節(jié),p-1就后退 16 個字節(jié),這正好是數(shù)組 a 所包含的每個一維數(shù)組的長度。也就是說,p+1會使得指針指向二維數(shù)組的下一行,p-1會使得指針指向數(shù)組的上一行。
數(shù)組名 a 在表達式中也會被轉換為和 p 等價的指針!
下面我們就來探索一下如何使用指針 p 來訪問二維數(shù)組中的每個元素。按照上面的定義:
1) p指向數(shù)組 a 的開頭,也即第 0 行;p+1前進一行,指向第 1 行。
2) *(p+1)表示取地址上的數(shù)據(jù),也就是整個第 1 行數(shù)據(jù)。注意是一行數(shù)據(jù),是多個數(shù)據(jù),不是第 1 行中的第 0 個元素,下面的運行結果有力地證明了這一點:
#include<stdio.h>
intmain(){
int a[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};
int(*p)[4]= a;
printf("%d\n",sizeof(*(p+1)));
return0;
}
運行結果:
16
3) *(p+1)+1表示第 1 行第 1 個元素的地址。如何理解呢?
*(p+1)單獨使用時表示的是第 1 行數(shù)據(jù),放在表達式中會被轉換為第 1 行數(shù)據(jù)的首地址,也就是第 1 行第 0 個元素的地址,因為使用整行數(shù)據(jù)沒有實際的含義,編譯器遇到這種情況都會轉換為指向該行第 0 個元素的指針;就像一維數(shù)組的名字,在定義時或者和 sizeof、& 一起使用時才表示整個數(shù)組,出現(xiàn)在表達式中就會被轉換為指向數(shù)組第 0 個元素的指針。
4) *(*(p+1)+1)表示第 1 行第 1 個元素的值。很明顯,增加一個 * 表示取地址上的數(shù)據(jù)。
根據(jù)上面的結論,可以很容易推出以下的等價關系:
a+i == p+i
a[i] == p[i] == *(a+i) == *(p+i)
a[i][j] == p[i][j] == *(a[i]+j) == *(p[i]+j) == *(*(a+i)+j) == *(*(p+i)+j)
【實例】使用指針遍歷二維數(shù)組。
#include<stdio.h>
intmain(){
int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
int(*p)[4];
int i,j;
p=a;
for(i=0; i<3; i++){
for(j=0; j<4; j++)printf("%2d ",*(*(p+i)+j));
printf("\n");
}
return0;
}
運行結果:
0 1 2 3
4 5 6 7
8 9 10 11
指針數(shù)組和二維數(shù)組指針的區(qū)別
指針數(shù)組和二維數(shù)組指針在定義時非常相似,只是括號的位置不同:
int*(p1[5]);//指針數(shù)組,可以去掉括號直接寫作 int *p1[5];
int(*p2)[5];//二維數(shù)組指針,不能去掉括號
指針數(shù)組和二維數(shù)組指針有著本質上的區(qū)別:指針數(shù)組是一個數(shù)組,只是每個元素保存的都是指針,以上面的 p1 為例,在32位環(huán)境下它占用 4×5 = 20 個字節(jié)的內存。二維數(shù)組指針是一個指針,它指向一個二維數(shù)組,以上面的 p2 為例,它占用 4 個字節(jié)的內存。
原文鏈接:https://blog.csdn.net/Elanie1024/article/details/128889077
相關推薦
- 2022-05-13 Linux操作系統(tǒng)筆記——GCC編譯器
- 2022-05-20 ASP.NET?MVC模式簡介_基礎應用
- 2022-07-14 python輸出小數(shù)精度控制的方法_python
- 2021-12-14 nginx.pid打開失敗以及失效的解決方案_nginx
- 2022-10-02 iOS實現(xiàn)簡易的抽屜效果_IOS
- 2023-10-16 element組件autofocus( 自動獲取焦點)失效
- 2022-06-12 C#泛型接口的協(xié)變和逆變_C#教程
- 2022-09-30 QT實現(xiàn)多文件拖拽獲取路徑的方法_C 語言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結構-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支