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