6.3.1指針運(yùn)算符與指針表達(dá)式
在C中有兩個(gè)關(guān)于指針的運(yùn)算符:
?&運(yùn)算符:取地址運(yùn)算符,&m即是變量m的地址。
?*運(yùn)算符:指針運(yùn)算符,*ptr表示其所指向的變量。
[例6-2]從鍵盤輸入兩個(gè)整數(shù),按由大到小的順序輸出。
main()
{
int*p1,*p2,a,b,t;/*定義指針變量與整型變量*/
scanf(“%d,%d”,&a,&b);
p1=&a;/*使指針變量指向整型變量*/
p2=&b;
if(*p1<*p2)
{/*交換指針變量指向的整型變量*/
t=*p1;
*p1=*p2;
*p2=t;
}
printf(“%d,%dn”,a,b);
}
在程序中,當(dāng)執(zhí)行賦值操作p1=&a和p2=&b后,指針實(shí)實(shí)在在地指向了變量a與b,這時(shí)
引用指針*p1與*p2,就代表了變量a與b。
運(yùn)行程序:
RUN
3,4
4,3
在程序運(yùn)行過程中,指針與所指的變量之間的關(guān)系如圖6-4所示:
當(dāng)指針被賦值后,其在內(nèi)存的安放如a),當(dāng)數(shù)據(jù)比較后進(jìn)行交換,這時(shí),指針變量與所指向的變量的關(guān)系如b)所示,在程序的運(yùn)行過程中,指針變量與所指向的變量其指向始終沒變。
下面對(duì)程序做修改。
[例6-3]
main()
{
int*p1,*p2,a,b,*t;
scanf(“%d,%d”,&a,&b);
p1=&a;
p2=&b;
if(*p1<*p2)
{/*指針交換指向*/
t=p1;
p1=p2;
p2=t;
}
printf(“%d,%dn”,*p1,*p2);
}
程序的運(yùn)行結(jié)果完全相同,但程序在運(yùn)行過程中,實(shí)際存放在內(nèi)存中的數(shù)據(jù)沒有移動(dòng),而是將指向該變量的指針交換了指向。其示意如圖6-5:
當(dāng)指針交換指向后,p1和p2由原來指向的變量a和b改變?yōu)橹赶蜃兞縝和a,這樣一來,*p1就表示變量b,而*p2就表示變量a。在上述程序中,無論在何時(shí),只要指針與所指向的變量滿足p=&a;我們就可以對(duì)變量a以指針的形式來表示。此時(shí)p等效于&a,*p等效于變量a。
6.3.2指針變量作函數(shù)的參數(shù)
函數(shù)的參數(shù)可以是我們?cè)谇懊鎸W(xué)過的簡(jiǎn)單數(shù)據(jù)類型,也可以是指針類型。使用指針類型做函數(shù)的參數(shù),實(shí)際向函數(shù)傳遞的是變量的地址。由于子程序中獲得了所傳遞變量的地址,在該地址空間的數(shù)據(jù)當(dāng)子程序調(diào)用結(jié)束后被物理地保留下來。
[例6-4]利用指針變量作為函數(shù)的參數(shù),用子程序的方法再次實(shí)現(xiàn)上述功能。
main()
{
void chang();/*函數(shù)聲明*/
int*p1,*p2,a,b,*t;
scanf(“%d,%d”,&a,&b);
p1=&a;
p2=&b;
chang(p1,p2);/*子程序調(diào)用*/
printf(“%d,%dn”,*p1,*p2);
return0;
}
void chang(int*pt1,int*pt2)
{/*子程序?qū)崿F(xiàn)將兩數(shù)值調(diào)整為由大到小*/
intt;
if(*pt1<*pt2)/*交換內(nèi)存變量的值*/
{
t=*pt1;*pt1=*pt2;*pt2=t;}
return;
}
由于在調(diào)用子程序時(shí),實(shí)際參數(shù)是指針變量,形式參數(shù)也是指針變量,實(shí)參與形參相結(jié)合,傳值調(diào)用將指針變量傳遞給形式參數(shù)pt1和pt2。但此時(shí)傳值傳遞的是變量地址,使得在子程序中pt1和pt2具有了p1和p2的值,指向了與調(diào)用程序相同的內(nèi)存變量,并對(duì)其在內(nèi)存存放的數(shù)據(jù)進(jìn)行了交換,其效果與[例6-2]相同。
思考下面的程序,是否也能達(dá)到相同的效果呢?
main()
{
void chang();
int*p1,*p2,a,b,*t;
scanf(“%d,%d”,&a,&b);
p1=&a;
p2=&b;
chang(p1,p2);
printf(“%d,%dn”,*p1,*p2);
}
void chang(int*pt1,int*pt2)
{
int*t;
if(*pt1<*pt2)
{
t=pt1;pt1=pt2;pt2=t;
}
return;
}
程序運(yùn)行結(jié)束,并未達(dá)到預(yù)期的結(jié)果,輸出與輸入完全相同。其原因是對(duì)子程序來說,函數(shù)內(nèi)部進(jìn)行指針相互交換指向,而在內(nèi)存存放的數(shù)據(jù)并未移動(dòng),子程序調(diào)用結(jié)束后,main()函數(shù)中p1和p2保持原指向,結(jié)果與輸入相同。