美文网首页
基础C++教学⮱⮱011【C中多维数组指针探究】2019-12-

基础C++教学⮱⮱011【C中多维数组指针探究】2019-12-

作者: 平知 | 来源:发表于2019-12-24 11:53 被阅读0次

    ←↑→↓↖↙↗↘↕⏤
    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操作的时候,指针跨内存区域的步长情况:

      根据上两个表得出:直接对多维数组名进行加法操作,跨过的步长是该多维数组总大小的1\over n(n是数组的第一维数字)。那1\over n具体等于多少呢?

      设数组为b[n][o][p][q],则1\over n=o*p*q(参看上图的红字部分),即等于除第一维以外,剩下的所有维数大小之积。
      即这个多维数组的完全的大小也就是n*o*p*q

      下面将这个数组结构再次具象化一点,逐步从底层把这个数组构建起来。


      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个

    相关文章

      网友评论

          本文标题:基础C++教学⮱⮱011【C中多维数组指针探究】2019-12-

          本文链接:https://www.haomeiwen.com/subject/uflxoctx.html