李紅英
摘 要:數(shù)組和指針是C語(yǔ)言的兩個(gè)最重要的概念,它們?nèi)艚Y(jié)合起來(lái)使用,非常靈活,初學(xué)者往往感到無(wú)所適從,筆者根據(jù)多年的經(jīng)驗(yàn),利用典型實(shí)例和圖表對(duì)指向一維數(shù)組的指針的定義和數(shù)組元素的引用、指針與自增自減運(yùn)算符相結(jié)合的一些常見表達(dá)式的具體含義及區(qū)別、二維數(shù)組中各數(shù)組元素的多種地址表示方式及訪問二維數(shù)組時(shí)如何定義指向數(shù)組元素的指針和指向某行數(shù)據(jù)的指針等進(jìn)行了描述和分析,所有實(shí)例都在VC6.0環(huán)境下通過,希望初學(xué)者能快速理解和掌握。
關(guān)鍵詞:C語(yǔ)言 指針 數(shù)組 自增自減
中圖分類號(hào):TP31 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1672-3791(2015)11(c)-0003-02
在C語(yǔ)言中數(shù)組表示一組數(shù)據(jù)類型都一樣的有序數(shù)據(jù)的集合,在內(nèi)存中,它們占有連續(xù)的存儲(chǔ)單元,數(shù)組分一維數(shù)組和多維數(shù)組,一維數(shù)組是數(shù)組中最簡(jiǎn)單的,比較容易理解,用一個(gè)數(shù)組名和一個(gè)下標(biāo)就能唯一地確定一個(gè)元素。多維數(shù)組理解相對(duì)抽象些,以二維數(shù)組舉例,二維數(shù)組在內(nèi)存中雖然是占一個(gè)連續(xù)的存儲(chǔ)單元,但是習(xí)慣上把它寫成矩陣的形式,更有助于理解其邏輯結(jié)構(gòu),二維數(shù)組每一行都可以看成一個(gè)一維數(shù)組。任何數(shù)組它們的數(shù)組名代表數(shù)組的首地址。而指針是C語(yǔ)言的另一個(gè)重要概念,指針代表地址,并且指針是可以移動(dòng)的,對(duì)于數(shù)組和指針的使用,初學(xué)者往往感到無(wú)所適從,筆者根據(jù)多年經(jīng)驗(yàn),利用等級(jí)考試中的典型實(shí)例來(lái)進(jìn)行描述和分析,所有實(shí)例如都在VC6.0環(huán)境下通過,希望初學(xué)者能快速理解和掌握。
1 指向一維數(shù)組指針的定義及數(shù)組元素的引用
定義指向數(shù)組元素的指針變量的方法,與定義指向變量的指針變量相同,假設(shè)定義了一個(gè)一維數(shù)組int a[5]和一個(gè)指針變量int *p,如何讓指針變量指向數(shù)組呢?對(duì)于一維數(shù)組來(lái)說(shuō),只要讓指針變量指向它的數(shù)組元素就可以,因?yàn)閿?shù)組名a代表數(shù)組的首地址,所以p=&a[0] 或p=a都表示指針指向數(shù)組的第一個(gè)元素,直接定義可以寫成int *p=a。而p+1表示指向下一個(gè)元素,p-1表示指向數(shù)組上一個(gè)元素,這樣,其后面第i個(gè)元素它的地址就可以表示成p+i,也可以表示成a+i。
若p指向a[0],而a[i]的地址可以用p+i或a+i表示,所以,引用數(shù)組元素的時(shí)候,既可以用普通的下標(biāo)法如a[i]形式,也可以用指針法,這時(shí)*(p+i)和*(a+i)都可以表示a[i]元素。
例1: #include
void main( )
{ int a[6]={10,20,30,40,50,60},*p,i=3;
p=&a[1];
printf(“%d,%d\n”,a[i],p[i]);}
實(shí)例分析:此實(shí)例中,定義了一個(gè)指針指向a[1],i的值為3,輸出a[3]和p[3]的值,很多初學(xué)者以為p[i]的寫法是錯(cuò)誤的,有的初學(xué)者則認(rèn)為a[3]和p[3]等價(jià),輸出結(jié)果是40,40,但實(shí)際上,在C語(yǔ)言中,指針變量可以帶下標(biāo),程序在編譯時(shí),會(huì)把下標(biāo)的處理轉(zhuǎn)換為地址的,p[i]處理成*(p+i),因?yàn)橐婚_始的時(shí)候p指向a[1],那么p+i則表示往后數(shù)第三個(gè)元素,也就是a[4],故此程序輸p出結(jié)果為40,50。若一開始p=a,也就是說(shuō)指針指向第一個(gè)元素,那么a[i]和p[i]的值就是相等的。
2 指針與自增自減運(yùn)算符的結(jié)合
指針若與自增自減運(yùn)算符結(jié)合起來(lái)使用,初學(xué)者最容易出錯(cuò),以自增運(yùn)算符為例,若程序中出現(xiàn)*p++、*(p++)、*(++p)、++(*p)等算式,看起來(lái)差不多,很多初學(xué)者搞不懂它們之間的區(qū)別,殊不知“失之毫厘,謬以千里”,因?yàn)椴欢鼈兊膮^(qū)別,分析程序時(shí)往往得到錯(cuò)誤的結(jié)果。
首先,大家要知道“*”和“++”都是單目運(yùn)算符,它們同一個(gè)優(yōu)先級(jí),其結(jié)合方向是自右向左的,所以*p++和*(p++)等價(jià),根據(jù)自增運(yùn)算符的“名前先取”原則,要先取*p的值,再使p自增1,即指向下一個(gè)數(shù)組元素,*(++p)則是先使p指向下一個(gè)元素,再取*p的值,這幾個(gè)算式都是對(duì)所指的地址加1。 ++(*p)表示先取*p,再在這個(gè)值的基礎(chǔ)上加1,也就是對(duì)所指的元素的值加1。
例2: #include
void main( )
{ int a[5]={2,4,6,8,10},*p,**k;
p=a;k=&p;
printf(“%d ”,*(p++));
printf(“%d\n”,**k);}
實(shí)例分析:此實(shí)例中,自先定義了數(shù)組a,指針p和指向指針的指針k,通過p=a和k=&p語(yǔ)句,使指針p指向數(shù)組a的首地址,k指向指針p,接下來(lái)printf(“%d ”,*(p++))語(yǔ)句,是先輸出*p的值為2,再使指針往后指,再輸出**k的指也就是*p的值,此時(shí),p指向4,輸出4,程序的輸出結(jié)果為“2 4”。
3 指向二維數(shù)組指針的定義及數(shù)組元素的引用
在使用指針指向二維數(shù)組時(shí)首先要了解多維數(shù)組元素的地址表示方式,假設(shè)有二維數(shù)組a[3][3],那么在邏輯上可以把這個(gè)二維數(shù)組看作是一個(gè)3行3列的表格,也可以看成是一個(gè)有3個(gè)元素的一維數(shù)組,該數(shù)組的每個(gè)元素也是一個(gè)一維數(shù)組,序號(hào)為0的行的首地址可以用a[0]、&a[0]或a表示,序號(hào)為1的行的首地址可表示為a[1]、&a[1]或a+1,如圖1所示。根據(jù)一維數(shù)組指針的定義,a[0]的值可以又表示成為*a,a[1]可以表示為*(a+1),a[i]即為*(a+i)。序號(hào)為0的行的首地址也就是元素a[0][0]的地址,即&a[0][0],它后面幾個(gè)元素的地址可以表示為a[0]+1,a[0]+2 ,若用指針法表示為*(a+0)、*(a+0)+1和*(a+0)+2,以此類推,第i行第j列元素的地址&a[i][j]可以表示成為a[i]+j,指針法表示為*(a+i)+j,也就是說(shuō)&a[i][j]、a[i]+j、*(a+i)+j是等價(jià)的。這樣,對(duì)于一個(gè)二維數(shù)組來(lái)說(shuō),元素a[i][j]可用指針法表示為*(a[i]+j)或*(*(a+i)+j)。
指針變量指向二維數(shù)組中的元素,可以有兩種定義指針方法,一種是直接定義成指向數(shù)組元素的指針變量,如int *p,再讓p指向數(shù)組中某個(gè)具體元素;還有一種是定義成指向二維數(shù)組某一行的指針變量,假設(shè)一行有M個(gè)數(shù)據(jù),則可以定義成int (*p)[M]=a,這樣就可以讓指針指向第一行。
例3:#include
void main( )
{ int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int (*p)[4]=a,i,j,k=0;
for(i=0;i<3;i++)
for(j=0;j<2;j++)
k=k+*(*(p+i)+j);
printf(“k=%d\n”,k);}
程序分析:此實(shí)例中,指針p指向二維數(shù)組a的首地址,然后執(zhí)行循環(huán),首先i=0,j=0,累加*(*(p+0)+0),即a[0][0],接著i=0,j=1,累加*(*(p+0)+1),即a[0][1],然后j=2時(shí)跳出內(nèi)循環(huán),以此類推,執(zhí)行下一次外循環(huán)i=1時(shí),累加a[1][0]和a[1][1],執(zhí)行外循環(huán)i=2時(shí)累加a[2][0]和a[2][1]……最后i=3時(shí)跳出整個(gè)循環(huán),由此看出,語(yǔ)句在這里其實(shí)就是累加二維數(shù)組第一列和第二列的元素。最后結(jié)果為1+3+9+11+17+19=60,輸出“k=60”。
總之,指針和數(shù)組結(jié)合起來(lái)使用非常靈活,同一地址有多種表示方法,而指針根據(jù)地址表示的不同可定義成指向數(shù)組元素的指針和指向某行數(shù)據(jù)的指針,初學(xué)者很難理解,大家一定要從C語(yǔ)言的數(shù)組和指針的概念出發(fā),仔細(xì)琢磨,反復(fù)思考,多比較,多應(yīng)用, 如果能很好地應(yīng)用指針訪問數(shù)組,對(duì)C語(yǔ)言后面的知識(shí)學(xué)習(xí)有很大幫助,如C語(yǔ)言的結(jié)構(gòu)體、共用體、鏈表等,都是跟指針和數(shù)組相關(guān)的,正確靈活地運(yùn)用指針,可以使程序更加簡(jiǎn)潔、緊湊、高效。
參考文獻(xiàn)
[1] 譚浩強(qiáng).C程序設(shè)計(jì)[M].4版.北京:清華大學(xué)出版社,2010.
[2] 未來(lái)教育.全國(guó)計(jì)算機(jī)等級(jí)考試模擬考場(chǎng)二級(jí)C[M].成都:電子科技大學(xué)出版社,2015.
[3] 教育部考試中心.全國(guó)計(jì)算機(jī)等級(jí)考試二級(jí)教程-C語(yǔ)言程序設(shè)計(jì)[M].北京:高等教育出版社,2002.