二維數(shù)組和指針⑴ 用指針表示二維數(shù)組元素说榆。
要用指針處理二維數(shù)組,首先要解決從存儲的角度對二維數(shù)組的認識問題寸认。我們知道签财,一個二維數(shù)組在計算機中存儲時,是按照先行后列的順序依次存儲的偏塞,當把每一行看作一個整體唱蒸,即視為一個大的數(shù)組元素時,這個存儲的二維數(shù)組也就變成了一個一維數(shù)組了灸叼。而每個大數(shù)組元素對應二維數(shù)組的一行神汹,我們就稱之為行數(shù)組元素庆捺,顯然每個行數(shù)組元素都是一個一維數(shù)組
下面我們討論指針和二維數(shù)組元素的對應關(guān)系,清楚了二者之間的關(guān)系慎冤,就能用指針處理二維數(shù)組了疼燥。
設p是指向二維數(shù)組a[m][n]的指針變量,則有:
int* p=a[0];//此時P是指向一維數(shù)組的指針蚁堤。P++后,p指向 a[0][1]但狭。
如果定義int (*p1)[n];p1=a;p1++后披诗,p1指向a[1][0];
則p+j將指向a[0]數(shù)組中的元素a[0][j]。
由于a[0]立磁、a[1]┅a[M-1]等各個行數(shù)組依次連續(xù)存儲呈队,則對于a數(shù)組中的任一元素a[i][j],指針的一般形式如下:
p+iN+j 相應的如果用p1來表示唱歧,則為(p1+i)+j
元素a[i][j]相應的指針表示為:
( p+iN+j) 相應的如果用p1來表示宪摧,則為((p1+i)+j)
同樣,a[i][j]也可使用指針下標法表示颅崩,如下:
p[iN+j]
例如几于,有如下定義:
int a[3][4]={{10,20,30,40,},{50,60,70,80},{90,91,92,93}};
則數(shù)組a有3個元素,分別為a[0]沿后、a[1]沿彭、a[2]。而每個元素都是一個一維數(shù)組尖滚,各包含4個元素喉刘,如a[1]的4個元素是a[1][0]、a[1][1]漆弄、a[1]2]睦裳、a[1][3]。
若有:
int p=a[0];
則數(shù)組a的元素a[1][2]對應的指針為:p+14+2
元素a[1][2]也就可以表示為:( p+14+2)
用下標表示法撼唾,a[1][2]表示為:p[14+2]
特別說明:
對上述二維數(shù)組a廉邑,雖然a[0]、a都是數(shù)組首地址券坞,但二者指向的對象不同鬓催,a[0]是一維數(shù)組的名字,它指向的是a[0]數(shù)組的首元素恨锚,對其進行“”運算宇驾,得到的是一個數(shù)組元素值,即a[0]數(shù)組首元素值猴伶,因此课舍,a[0]與a[0][0]是同一個值塌西;而a是一個二維數(shù)組的名字,它指向的是它所屬元素的首元素筝尾,它的每一個元素都是一個行數(shù)組捡需,因此,它的指針移動單位是“行”筹淫,所以a+i指向的是第i個行數(shù)組站辉,即指向a[i]。對a進行“”運算损姜,得到的是一維數(shù)組a[0]的首地址饰剥,即a與a[0]是同一個值。當用int p;定義指針p時摧阅,p的指向是一個int型數(shù)據(jù)汰蓉,而不是一個地址,因此棒卷,用a[0]對p賦值是正確的顾孽,而用a對p賦值是錯誤的。這一點請讀者務必注意比规。
⑵ 用二維數(shù)組名作地址表示數(shù)組元素若厚。
另外,由上述說明苞俘,我們還可以得到二維數(shù)組元素的一種表示方法:
對于二維數(shù)組a盹沈,其a[0]數(shù)組由a指向,a[1]數(shù)組則由a+1指向吃谣,a[2]數(shù)組由a+2指向乞封,以此類推。因此岗憋,a與a[0]等價肃晚、(a+1)與a[1]等價、(a+2)與a[2]等價仔戈,┅关串,即對于a[i]數(shù)組,由*(a+i)指向监徘。由此晋修,對于數(shù)組元素a[i][j],用數(shù)組名a的表示形式為:
((a+i)+j)
指向該元素的指針為:
*(a+i)+j
數(shù)組名雖然是數(shù)組的地址凰盔,但它和指向數(shù)組的指針變量不完全相同墓卦。
第一,指針變量的值可以改變户敬,即它可以隨時指向不同的數(shù)組或同類型變量落剪,而數(shù)組名自它定義時起就確定下來睁本,不能通過賦值的方式使該數(shù)組名指向另外一個數(shù)組。
第二忠怖,數(shù)組名是指針呢堰,類型是指向元素類型的指針,但值是指針常量凡泣,聲明數(shù)組時編譯器會為聲明所指定的元素數(shù)量保留內(nèi)存空間枉疼。數(shù)組指針是指向數(shù)組的指針,聲明指針變量時編譯器只為指針本身保留內(nèi)存空間鞋拟。
例4 求二維數(shù)組元素的最大值往衷。
該問題只需對數(shù)組元素遍歷,即可求解严卖。因此,可以通過順序移動數(shù)組指針的方法實現(xiàn)布轿。
main()
{
int a[3][4]={{3,17,8,11},{66,7,8,19},{12,88,7,16}};
int p,max;
for(p=a[0],max=p;p<a[0]+12;p++)
if(p>max)
max=p;
printf("MAX=%d/n",max);
}
執(zhí)行結(jié)果:
MAX=88
這個程序的主要算法都是在for語句中實現(xiàn)的:p是一個int型指針變量哮笆;p=a[0]是置數(shù)組的首元素地址為指針初值;max=p將數(shù)組的首元素值a[0][0]作為最大值初值汰扭;p<a[0]+12是將指針的變化范圍限制在12個元素的位置內(nèi)稠肘;p++使得每比較一個元素后,指針后移一個元素位置萝毛。
例5 求二維數(shù)組元素的最大值项阴,并確定最大值元素所在的行和列。
本例較之上例有更進一步的要求笆包,需要在比較的過程中环揽,把較大值元素的位置記錄下來,顯然僅用上述指針移動方法是不行的庵佣,需要使用能提供行列數(shù)據(jù)的指針表示方法歉胶。
main()
{
int a[3][4]={{3,17,8,11},{66,7,8,19},{12,88,7,16}};
int p=a[0],max,i,j,row,col;
max=a[0][0];
row=col=0;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
if((p+i4+j)>max)
{
max=(p+i4+j);
row=i;
col=j;
}
printf("a[%d][%d]=%d/n",row,col,max);
}
程序運行結(jié)果:
a[2][1]=88
⑶ 行數(shù)組指針
在上面的說明中我們已經(jīng)知道,二維數(shù)組名是指向行的巴粪,它不能對如下說明的指針變量p直接賦值:
int a[3][4]={{10,11,12,13},{20,21,22,23},{30,31,32,33}},p;
其原因就是p與a的對象性質(zhì)不同通今,或者說二者不是同一級指針。C語言可以通過定義行數(shù)組指針的方法肛根,使得一個指針變量與二維數(shù)組名具有相同的性質(zhì)辫塌。行數(shù)組指針的定義方法如下:
數(shù)據(jù)類型 (指針變量名)[二維數(shù)組列數(shù)];
例如派哲,對上述a數(shù)組臼氨,行數(shù)組指針定義如下:
int (p)[4];
它表示,數(shù)組p有4個int型元素狮辽,分別為(p)[0]一也、(p)[1]巢寡、(p)[2]、(p)[3] 椰苟,亦即p指向的是有4個int型元素的一維數(shù)組抑月,即p為行指針
此時,可用如下方式對指針p賦值:
p=a;
(4)指針數(shù)組的定義
指針數(shù)組是指每個元素中存放的是指針舆蝴。定義為 int *p[4];sizeof(p)=16,返回的是數(shù)組的總空間