我所理解的二維數組

要對二維數組做一些詳細的理解,那麼我們先要複習下一維數組的幾點知識:

對於一維數組,大家肯定知道,一維數組的數組名可以當成一維指針使用,也就是說,可以用一個一維指針,把數組首地址賦值給這個指針,然後把這個指針當成數組名用.

int arr[5]={1,2,3,4,5};//一維數組

int *p=arr;

然後可以用指針p來處理這個數組裏面的元素,比如說p[0]就是arr[0],p[1]就是arr[1],和數組名的使用都完全一樣.

對於一維數組,*(arr+i)等價於arr[i],可以推出一個特例,*arr等價arr[0];

以上的結論在二維數組中同樣適用,,但是要做一些小小的變形,首先我們定義一個足夠大的二維數組,避免下面的討論中出現越界問題,就像這樣:

int array[M][N];//定義一個M*N的二維數組 M和N都是一個很大的整數

二維數組中,我們一般用行和列來區分,M*N就是一個M行N列的數組.

對於二維數組而言,裏面的元素可以用下標來表示,比如說array[i][j]

二維數組的下標也是從0開始,array[0][0]就是數組的第一個元素

二維數組比一維數組而言更加的複雜,上面說過, 對於一維數組,*(arr+i)等價於arr[i],那麼對於二維數組來說,array[i][j]可以有如下表示方法:

array[i][j] (*(array+i))[j] *(array[i]+j) *(*(array+i)+j)

其中i和j都是可以取0的,也就是說如果i或j等於0,會有如下幾種方式

i等於0的情況(寫法1)

array[0][j] (*array)[j] *(array[0]+j) *(*array+j)

j等於0的情況(寫法2)

array[i][0] (*(array+i))[0] *array[i] **(array+i)

上面的括號都是因爲優先級的原因,去掉的話結果就不一樣了,其中優先級有

小括號()>中括號[]>取值符號*>加號+

對於一個二維數組,我們可以從幾個不同的方向來分析

方向一:數組

數組都是存放在一塊連續的內存中的,也就是說可以用一個一維指針指向其中一個元素

比如說int *p1=&array[0][0];//這裏等價int *p1=arr[0];

然後想要訪問array[i][j],就是*(p1+i*N+j)或者*(p1+j*M+i),這個可以應用到各種地方,比如說想要用一維數組來代替二維數組使用,就可以用上面這種方式;

通過上面的賦值之後p1其實就可以當做array[0]使用,也就是說*(p1+i*N+j)等價*(array[0]+i*N+j),由上面寫法1得到另外一個等價的形式array[0][i*N+j]

假設有m和n和元素array[m][n],m和n可以爲正數或負數,m可以大於M,n也可以大於N,它等價array[0][m*N+n],也就是說如果滿足0<=m*N+n<=M*N-1,那麼這個元素就存在於這個數組當中.轉換爲標準的下標就是i=(m*N+n)/N,j=(m*N+n)%N

二維數組無論是傳參數還是申請內存都要事先指定數組的列的大小,一維數組則不需要,也就是說如果你想要一個x*y大小的二維數組,但是xy的值不是常量的話,可以用申請一維數組,然後用上面的方式當二維數組使用.

方向二:數組的數組

二維數組可以看成數組的數組,因爲array[0]可以視爲一個一維數組的數組名,array[0][0]是array[0]中的第一個元素,array可以看成一個數組的數組名,也就是看成一個常屬性的數組指針.

int (*q)[N];//定義一個數組指針,要指明數組的列

q=array;//這樣的話就可以用q來代替array,用法是一樣的

如果是申請一個數組指針,那麼除了q=array之外,還可以有q=&array[0]這樣,他們的效果是一樣的.區別於array,q是一個指針,所以q可以進行q++這樣的操作,但是需要注意的是,q++之後,q不再指向首地址,雖然可以q[i][j]但是和array[i][j]已經不是同一個元素了

#include<stdio.h>

int main()

{

int array[3][4]={0};

int (*q)[4]=array;

q++;

q[1][2]=4;

printf(“array[1][2]=%d array[2][2]=%d ”,array[1][2],array[2][2]);

getchar();

return 0;}

對於數組指針,q++等於移動了一個數組長度的地址,上面的代碼可以說明,你也可以試着把所有內容全部打印出來.

最後補充下關於二維數組元素地址的問題,用scanf的話需要取地址,我們首先看下關於二維數組的元素

array[i][j] (*(array+i))[j] *(array[i]+j) *(*(array+i)+j)

取地址加一個取地址符&就可以,取值符號和取地址符號相當於逆運算,也就是說可以寫成下面四種方式代表array[i][j]的地址:

&arr[i][j] &(*(array+i))[j] array[i]+j *(array+i)+j

scanf(“%d”,array[i]+j);//四種方式都可以使用

附錄1.字符串數組和字符指針數組

字符串數組也就是char類型的二維數組,使用方式和上面的類似,只是需要注意下字符串後面的’’就可以了.

字符指針數組,一般用來在堆區存放字符串用的,數組元素是指針,這些指針放在一塊相鄰的區域,但是指向的內容不一定在相鄰的區域

char *p[5];

for(int i=0;i<5;i++)

{

p[i]=(char *)malloc(sizeof(char)*i);//指針數組每個p[i]指向的內存大小可以不同

}

//然後可以p[3][2]這樣使用,但是不代表p是二維數組

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章