基礎(chǔ)C++教學(xué)??011【C中多維數(shù)組指針探究】2019-12-24

←↑→↓↖↙↗↘??
unicode=Geometric Shapes
? 僅僅個別字不同的時候的對比標(biāo)識

? 著重強調(diào)

??◆ 1、
??◆ 2、
??◆ 3、

??
??
??
??
??
??
??
??

Miscellaneous Symbols

?
Dingbats
? 重點記憶,個人總結(jié)的點,或者知識。
??
?

  • ?多維數(shù)組指針探究

??假設(shè)有如下多維數(shù)組定義(數(shù)組名重名,不能在同一個程序中運行):

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維數(shù)組具體圖形結(jié)構(gòu)如下(2維、3維同理可推):

??下面來看各不同維度的數(shù)據(jù),在數(shù)組名(數(shù)組首地址)直接進行加1操作的時候,指針跨內(nèi)存區(qū)域的步長情況:

??根據(jù)上兩個表得出:直接對多維數(shù)組名進行加法操作,跨過的步長是該多維數(shù)組總大小的1\over n(n是數(shù)組的第一維數(shù)字)。那1\over n具體等于多少呢?

??設(shè)數(shù)組為b[n][o][p][q],則1\over n=o*p*q(參看上圖的紅字部分),即等于除第一維以外,剩下的所有維數(shù)大小之積。
??即這個多維數(shù)組的完全的大小也就是n*o*p*q。

??下面將這個數(shù)組結(jié)構(gòu)再次具象化一點,逐步從底層把這個數(shù)組構(gòu)建起來。


??1、從最后一個維度看起,即 b[2][3][3][3] 的 [.][.][.][3]。假設(shè)沒有前3個維度,那么這就是一個3個int構(gòu)成的數(shù)據(jù)塊,即 [.][.][.][3] int。圖示如下:



??2、加入倒數(shù)第二個維度,即 b[2][3][3][3] 的 [.][.][3][3]。嘗試這樣理解:首先把最后一維數(shù)字先去掉,變成 [.][.][3][A]([A]=[3]int),此時整個數(shù)組為一個3xA大小的數(shù)據(jù)塊。



??3、加入倒數(shù)第三個維度,即 b[2][3][3][3] 的 [.][3][3][3]。嘗試這樣理解:首先把最后的兩個維數(shù)字先去掉,變成[.][3][B]([B]=[3][A]),此時整個數(shù)組為一個3xB大小的數(shù)據(jù)塊。



??4、加入倒數(shù)第四個維度(即第一個維度),即 b[2][3][3][3] 的 [2][3][3][3]。嘗試這樣理解:首先把最后的兩個維數(shù)字先去掉,變成[2][C]([C]=[3][B]),此時整個數(shù)組為一個2xC大小的數(shù)據(jù)塊。

??至此,整個數(shù)組的大小已經(jīng)完全構(gòu)建了出來。大致可以顯示如下:
??(注意這里每個格子的大小代表一個int,一般來說1個int占據(jù)4個內(nèi)存單元,即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);

??通過對內(nèi)存的查看,可以發(fā)現(xiàn)多維和單維的存儲結(jié)構(gòu)是完全一致的。



??現(xiàn)在分析一下數(shù)組名和指針的關(guān)系。經(jīng)過上述,可知多維和單維存儲結(jié)構(gòu)完全一致,那么多維存在的概念如何理解?

??個人理解如下
??1、多維數(shù)組底層和單維數(shù)組完全一致。
??2、多維數(shù)組可以看作在單維之上,對原有的數(shù)組元素進行了“包裝”,想要取得多維數(shù)組的元素,就行進行“拆包”(使用*或者[ ])。
??3、n維數(shù)組,就有n層“包裝”,要取值必須“拆包”n次。

??首先看未“拆包”的情況下,b的指向情況。
??“拆包”1次。
??“拆包”2次。
??“拆包”3次。
??“拆包”4次。



??根據(jù)以上分析,分析下圖白色框處,應(yīng)該如何取值?

??按照圖示,首先考慮下標(biāo)法取值,各維度數(shù)值按照圖示應(yīng)該很好確定:
??1、第一維應(yīng)該取0,因為白色塊覆蓋于第一維的橘色塊下。
??2、第二維應(yīng)該取2,因為白色塊覆蓋于第二維的黃色塊下。
??3、第三維應(yīng)該取2,因為白色塊覆蓋于第三維的橘色塊下。
??4、第四維應(yīng)該取0,因為白色塊處于第三位的橘色塊下的第一位置。
??綜上:下標(biāo)取值為:b[0][2][2][0]。

printf("b[0][2][2][0]=%d\n",b[0][2][2][0]);
b[0][2][2][0]=24

??可見輸出結(jié)果與推測完全一致。



??按照圖示,再次考慮“拆包”方式來取值。
??1、未拆包前,b不用加減,取原值。因為一旦加1,b指向的范圍將超出白色塊所在區(qū)域(指向第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


??推導(dǎo)結(jié)論:
??1、pass

??以下代碼演示了使用多維數(shù)組名,以一維方式遍歷數(shù)組元素的方式。

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個

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容