←↑→↓↖↙↗↘↕⏤
unicode=Geometric Shapes
▶ 仅仅个别字不同的时候的对比标识
◆
◉ 着重强调
◆ 1、
◆ 2、
◆ 3、
Miscellaneous Symbols
☞
Dingbats
✍ 重点记忆,个人总结的点,或者知识。
✎✎
⟱
-
多维数组指针探究
假设有如下多维数组定义(数组名重名,不能在同一个程序中运行):
int b[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
int b[3][4][2]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};
int b[2][3][3][3]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53};
其中4维数组具体图形结构如下(2维、3维同理可推):
下面来看各不同维度的数据,在数组名(数组首地址)直接进行加1操作的时候,指针跨内存区域的步长情况:
根据上两个表得出:直接对多维数组名进行加法操作,跨过的步长是该多维数组总大小的(n是数组的第一维数字)。那具体等于多少呢?
设数组为,则=(参看上图的红字部分),即等于除第一维以外,剩下的所有维数大小之积。
即这个多维数组的完全的大小也就是。
下面将这个数组结构再次具象化一点,逐步从底层把这个数组构建起来。
1、从最后一个维度看起,即 b[2][3][3][3] 的 [.][.][.][3]。假设没有前3个维度,那么这就是一个3个int构成的数据块,即 [.][.][.][3] int。图示如下:
2、加入倒数第二个维度,即 b[2][3][3][3] 的 [.][.][3][3]。尝试这样理解:首先把最后一维数字先去掉,变成 [.][.][3][A]([A]=[3]int),此时整个数组为一个3xA大小的数据块。
3、加入倒数第三个维度,即 b[2][3][3][3] 的 [.][3][3][3]。尝试这样理解:首先把最后的两个维数字先去掉,变成[.][3][B]([B]=[3][A]),此时整个数组为一个3xB大小的数据块。
4、加入倒数第四个维度(即第一个维度),即 b[2][3][3][3] 的 [2][3][3][3]。尝试这样理解:首先把最后的两个维数字先去掉,变成[2][C]([C]=[3][B]),此时整个数组为一个2xC大小的数据块。
至此,整个数组的大小已经完全构建了出来。大致可以显示如下:
(注意这里每个格子的大小代表一个int,一般来说1个int占据4个内存单元,即4个Byte,所以每个格子之间的地址增量都是4)
至此可能会有疑问:为什么int全落在的第四维的列上?事实是这样的么?用vs来验证一下:
int b[2][3][3][3] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 };
int a[54] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 };
printf("%x\n", b);
printf("%\n", a);
通过对内存的查看,可以发现多维和单维的存储结构是完全一致的。
现在分析一下数组名和指针的关系。经过上述,可知多维和单维存储结构完全一致,那么多维存在的概念如何理解?
个人理解如下:
1、多维数组底层和单维数组完全一致。
2、多维数组可以看作在单维之上,对原有的数组元素进行了,想要取得多维数组的元素,就行进行(使用*或者[ ])。
3、n维数组,就有n层,要取值必须n次。
首先看未的情况下,b的指向情况。
1次。
2次。
3次。
4次。
根据以上分析,分析下图白色框处,应该如何取值?
按照图示,首先考虑下标法取值,各维度数值按照图示应该很好确定:
1、第一维应该取0,因为白色块覆盖于第一维的橘色块下。
2、第二维应该取2,因为白色块覆盖于第二维的黄色块下。
3、第三维应该取2,因为白色块覆盖于第三维的橘色块下。
4、第四维应该取0,因为白色块处于第三位的橘色块下的第一位置。
综上:下标取值为:b[0][2][2][0]。
printf("b[0][2][2][0]=%d\n",b[0][2][2][0]);
b[0][2][2][0]=24
可见输出结果与推测完全一致。
按照图示,再次考虑方式来取值。
1、未拆包前,b不用加减,取原值。因为一旦加1,b指向的范围将超出白色块所在区域(指向第27处)。
2、第一层“拆包”,为*b。等于*(b+0)。
3、第二层“拆包”,为*(*(b+0)+2)。
3、第三层“拆包”,为*(*(*(b+0)+2)+2)。
4、第四层“拆包”,为*(*(*(*(b+0)+2)+2)+0)。
printf("*(*(*(*(b+0)+2)+2)+0)=%d\n",*(*(*(*(b+0)+2)+2)+0));
*(*(*(*(b+0)+2)+2)+0)=24
推导结论:
1、pass
以下代码演示了使用多维数组名,以一维方式遍历数组元素的方式。
int b[2][3][3][3]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53};
printf("b[0][0][0][0]=%d\n",b[0][0][0][0]);
printf("b[0][0][0][1]=%d\n",b[0][0][0][1]);
printf("b[0][0][0][2]=%d\n",b[0][0][0][2]);
printf("b[0][0][1][0]=%d\n",b[0][0][1][0]);
printf("b[0][0][1][1]=%d\n",b[0][0][1][1]);
printf("b[0][0][1][2]=%d\n",b[0][0][1][2]);
printf("b[0][0][2][0]=%d\n",b[0][0][2][0]);
printf("b[0][0][2][1]=%d\n",b[0][0][2][1]);
printf("b[0][0][2][2]=%d\n",b[0][0][2][2]);
printf("b[0][1][0][0]=%d\n",b[0][1][0][0]);
printf("b[0][1][0][1]=%d\n",b[0][1][0][1]);
printf("b[0][1][0][2]=%d\n",b[0][1][0][2]);
printf("b[0][1][1][0]=%d\n",b[0][1][1][0]);
printf("b[0][1][1][1]=%d\n",b[0][1][1][1]);
printf("b[0][1][1][2]=%d\n",b[0][1][1][2]);
printf("b[0][1][2][0]=%d\n",b[0][1][2][0]);
printf("b[0][1][2][1]=%d\n",b[0][1][2][1]);
printf("b[0][1][2][2]=%d\n",b[0][1][2][2]);
printf("b[0][2][0][0]=%d\n",b[0][2][0][0]);
printf("b[0][2][0][1]=%d\n",b[0][2][0][1]);
printf("b[0][2][0][2]=%d\n",b[0][2][0][2]);
printf("b[0][2][1][0]=%d\n",b[0][2][1][0]);
printf("b[0][2][1][1]=%d\n",b[0][2][1][1]);
printf("b[0][2][1][2]=%d\n",b[0][2][1][2]);
printf("b[0][2][2][0]=%d\n",b[0][2][2][0]);
printf("b[0][2][2][1]=%d\n",b[0][2][2][1]);
printf("b[0][2][2][2]=%d\n",b[0][2][2][2]);
printf("b[1][0][0][0]=%d\n",b[1][0][0][0]);
printf("b[1][0][0][1]=%d\n",b[1][0][0][1]);
printf("b[1][0][0][2]=%d\n",b[1][0][0][2]);
printf("b[1][0][1][0]=%d\n",b[1][0][1][0]);
printf("b[1][0][1][1]=%d\n",b[1][0][1][1]);
printf("b[1][0][1][2]=%d\n",b[1][0][1][2]);
printf("b[1][0][2][0]=%d\n",b[1][0][2][0]);
printf("b[1][0][2][1]=%d\n",b[1][0][2][1]);
printf("b[1][0][2][2]=%d\n",b[1][0][2][2]);
printf("b[1][1][0][0]=%d\n",b[1][1][0][0]);
printf("b[1][1][0][1]=%d\n",b[1][1][0][1]);
printf("b[1][1][0][2]=%d\n",b[1][1][0][2]);
printf("b[1][1][1][0]=%d\n",b[1][1][1][0]);
printf("b[1][1][1][1]=%d\n",b[1][1][1][1]);
printf("b[1][1][1][2]=%d\n",b[1][1][1][2]);
printf("b[1][1][2][0]=%d\n",b[1][1][2][0]);
printf("b[1][1][2][1]=%d\n",b[1][1][2][1]);
printf("b[1][1][2][2]=%d\n",b[1][1][2][2]);
printf("b[1][2][0][0]=%d\n",b[1][2][0][0]);
printf("b[1][2][0][1]=%d\n",b[1][2][0][1]);
printf("b[1][2][0][2]=%d\n",b[1][2][0][2]);
printf("b[1][2][1][0]=%d\n",b[1][2][1][0]);
printf("b[1][2][1][1]=%d\n",b[1][2][1][1]);
printf("b[1][2][1][2]=%d\n",b[1][2][1][2]);
printf("b[1][2][2][0]=%d\n",b[1][2][2][0]);
printf("b[1][2][2][1]=%d\n",b[1][2][2][1]);
printf("b[1][2][2][2]=%d\n",b[1][2][2][2]);
for(int i=0;i<(sizeof(b)/4);i++)
{
printf("****b+%d=%d\n",i,****b+i);
}
b[0][0][0][0]=0
b[0][0][0][1]=1
b[0][0][0][2]=2
b[0][0][1][0]=3
b[0][0][1][1]=4
b[0][0][1][2]=5
b[0][0][2][0]=6
b[0][0][2][1]=7
b[0][0][2][2]=8
b[0][1][0][0]=9
b[0][1][0][1]=10
b[0][1][0][2]=11
b[0][1][1][0]=12
b[0][1][1][1]=13
b[0][1][1][2]=14
b[0][1][2][0]=15
b[0][1][2][1]=16
b[0][1][2][2]=17
b[0][2][0][0]=18
b[0][2][0][1]=19
b[0][2][0][2]=20
b[0][2][1][0]=21
b[0][2][1][1]=22
b[0][2][1][2]=23
b[0][2][2][0]=24
b[0][2][2][1]=25
b[0][2][2][2]=26
b[1][0][0][0]=27
b[1][0][0][1]=28
b[1][0][0][2]=29
b[1][0][1][0]=30
b[1][0][1][1]=31
b[1][0][1][2]=32
b[1][0][2][0]=33
b[1][0][2][1]=34
b[1][0][2][2]=35
b[1][1][0][0]=36
b[1][1][0][1]=37
b[1][1][0][2]=38
b[1][1][1][0]=39
b[1][1][1][1]=40
b[1][1][1][2]=41
b[1][1][2][0]=42
b[1][1][2][1]=43
b[1][1][2][2]=44
b[1][2][0][0]=45
b[1][2][0][1]=46
b[1][2][0][2]=47
b[1][2][1][0]=48
b[1][2][1][1]=49
b[1][2][1][2]=50
b[1][2][2][0]=51
b[1][2][2][1]=52
b[1][2][2][2]=53
****b+0=0
****b+1=1
****b+2=2
****b+3=3
****b+4=4
****b+5=5
****b+6=6
****b+7=7
****b+8=8
****b+9=9
****b+10=10
****b+11=11
****b+12=12
****b+13=13
****b+14=14
****b+15=15
****b+16=16
****b+17=17
****b+18=18
****b+19=19
****b+20=20
****b+21=21
****b+22=22
****b+23=23
****b+24=24
****b+25=25
****b+26=26
****b+27=27
****b+28=28
****b+29=29
****b+30=30
****b+31=31
****b+32=32
****b+33=33
****b+34=34
****b+35=35
****b+36=36
****b+37=37
****b+38=38
****b+39=39
****b+40=40
****b+41=41
****b+42=42
****b+43=43
****b+44=44
****b+45=45
****b+46=46
****b+47=47
****b+48=48
****b+49=49
****b+50=50
****b+51=51
****b+52=52
****b+53=53
这里使用了4个