




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
靳潤(rùn)昭C語言教程講義2001年2月17日
10指針.....................................................................1
10.1地址指針的基本概念.................................................2
10.2變量的指針和指向變量的指針變量.....................................2
10.2.1定義一個(gè)指針變量................................................3
10.2.2指針變量的引用..................................................3
10.2.3指針變量作為函數(shù)參數(shù)............................................7
10.2.4指針變量幾個(gè)問題的進(jìn)一步說明..................................10
10.3數(shù)組指針和指向數(shù)組的指針變量.......................................13
10.3.1指向數(shù)組元素的指針.............................................13
10.3.2通過指針引用數(shù)組元素...........................................14
10.3.3數(shù)組名作函數(shù)參數(shù)...............................................16
10.3.4指向多維數(shù)組的指針和指針變量.................................22
10.4字符串的指針指向字符串的針指變量.................................25
10.4.1字符串的表示形式...............................................25
10.4.2使用字符串指針變量與字符數(shù)組的區(qū)別............................28
10.5函數(shù)指針變量.......................................................29
10.6指針型函數(shù).........................................................30
10.7指針數(shù)組和指向指針的指針...........................................31
10.7.1指針數(shù)組的概念.................................................31
10.7.2指向指針的指針.................................................34
10.7.3main函數(shù)的參數(shù)................................................36
10.8有關(guān)指針的數(shù)據(jù)類型和指針運(yùn)算的小結(jié)................................37
10.8.1有關(guān)指針的數(shù)據(jù)類型的小結(jié)......................................37
10.8.2指針運(yùn)算的小結(jié).................................................38
10.8.3void指針類型...................................................38
10指針
指針是c語言中廣泛使用的一種數(shù)據(jù)類型。運(yùn)用指針編程是C語言最主要的風(fēng)格之一。
利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu);能很方便地使用數(shù)組和字符串;并能象匯編語言一樣
處理內(nèi)存地址,從而編出精練而高效的程序。指針極大地豐富了C語言的功能。學(xué)習(xí)指針是
學(xué)習(xí)C語言中最重要的一環(huán),能否正確理解和使用指針是我們是否掌握C語言的一個(gè)標(biāo)志。
同時(shí),指針也是C語言中最為困難的一部分,在學(xué)習(xí)中除了要正確理解基本概念,還必須要
多編程,上機(jī)調(diào)試。只要作到這些,指針也是不難掌握的。
第1頁
靳潤(rùn)昭C語言教程講義2001年2月17日
10.1地址指針的基本概念
在計(jì)算機(jī)中,所有的數(shù)據(jù)都是存放在存儲(chǔ)器中的。一般把存儲(chǔ)器中的一個(gè)字節(jié)稱為一個(gè)
內(nèi)存單元,不同的數(shù)據(jù)類型所占用的內(nèi)存單元數(shù)不等,如整型量占2個(gè)單元,字符量占1
個(gè)單元等,在前面已有詳細(xì)的介紹。為了正確地訪問這些內(nèi)存單元,必須為每個(gè)內(nèi)存單元編
上號(hào)。根據(jù)一個(gè)內(nèi)存單元的編號(hào)即可準(zhǔn)確地找到該內(nèi)存單元。內(nèi)存單元的編號(hào)也叫做地址。
既然根據(jù)內(nèi)存單元的編號(hào)或地址就可以找到所需的內(nèi)存單元,所以通常也把這個(gè)地址稱為指
針。內(nèi)存單元的指針和內(nèi)存單元的內(nèi)容是兩個(gè)不同的概念??梢杂靡粋€(gè)通俗的例子來說明
它們之間的關(guān)系。我們到銀行去存取款時(shí),銀行工作人員將根據(jù)我們的帳號(hào)去找我們的存
款單,找到之后在存單上寫入存款、取款的金額。在這里,帳號(hào)就是存單的指針,存款數(shù)
是存單的內(nèi)容。對(duì)于一個(gè)內(nèi)存單元來說,單元的地址即為指針,其中存放的數(shù)據(jù)才是該單元
的內(nèi)容。在C語言中,允許用一個(gè)變量來存放指針,這種變量稱為指針變量。因此,一個(gè)指
針變量的值就是某個(gè)內(nèi)存單元的地址或稱為某內(nèi)存單元的指針。
Pc
011A---------?,K'
011A
圖中,設(shè)有字符變量C,其內(nèi)容為、'K"(ASCH碼為十進(jìn)制數(shù)75),C占用了011A號(hào)單元
(地址用十六進(jìn)數(shù)表示)。設(shè)有指針變量P,內(nèi)容為0UA,這種情況我們稱為P指向變量C,
或說P是指向變量C的指針。
嚴(yán)格地說,一個(gè)指針是一個(gè)地址,是一個(gè)常量。而一個(gè)指針變量卻可以被賦予不同的指
針值,是變量。但常把指針變量簡(jiǎn)稱為指針。為了避免混淆,我們中約定:“指針”是指地
址,是常量,“指針變量”是指取值為地址的變量。定義指針的目的是為了通過指針去訪問
內(nèi)存單元。
既然指針變量的值是?個(gè)地址,那么這個(gè)地址不僅可以是變量的地址,也可以是其它數(shù)
據(jù)結(jié)構(gòu)的地址。在一個(gè)指針變量中存放一個(gè)數(shù)組或一個(gè)函數(shù)的首地址有何意義呢?因?yàn)閿?shù)
組或函數(shù)都是連續(xù)存放的。通過訪問指針變量取得了數(shù)組或函數(shù)的首地址,也就找到了該數(shù)
組或函數(shù)。這樣一來,凡是出現(xiàn)數(shù)組,函數(shù)的地方都可以用一個(gè)指針變量來表示,只要該指
針變量中賦予數(shù)組或函數(shù)的首地址即可。這樣做,將會(huì)使程序的概念十分清楚,程序本身也
精練,高效。在C語言中,一種數(shù)據(jù)類型或數(shù)據(jù)結(jié)構(gòu)往往都占有一組連續(xù)的內(nèi)存單元。用
''地址〃這個(gè)概念并不能很好地描述一種數(shù)據(jù)類型或數(shù)據(jù)結(jié)構(gòu),而''指針”雖然實(shí)際上也是一
個(gè)地址,但它卻是一個(gè)數(shù)據(jù)結(jié)構(gòu)的首地址,它是''指向〃一個(gè)數(shù)據(jù)結(jié)構(gòu)的,因而概念更為清
楚,表示更為明確。這也是引入''指針"概念的一個(gè)重要原因。
10.2變量的指針和指向變量的指針變量
變量的指針就是變量的地址。存放變量地址的變量是指針變量。即在c語言中,允許用
一個(gè)變量來存放指針,這種變量稱為指針變量。因此,一個(gè)指針變量的值就是某個(gè)變量的地
址或稱為某變量的指針。
為了表示指針變量和它所指向的變量之間的關(guān)系,在程序中用“*”符號(hào)表示“指向”,
例如,i_pointer代表指針變量,而*i_pointer是i_pointer所指向的變量。
第2頁
靳潤(rùn)昭C語言教程講義2001年2月17日
i_pointer*i_pointer
011A
因此,下面兩個(gè)語句作用相同:
i=3;
*i_pointer=3;
第二個(gè)語句的含義是將3賦給指針變量i_pointer所指向的變量。
10.2.1定義一個(gè)指針變量
對(duì)指針變量的定義包括三個(gè)內(nèi)容:
(1)指針類型說明,即定義變量為一個(gè)指針變量;
(2)指針變量名;
(3)變量值(指針)所指向的變量的數(shù)據(jù)類型。
其一般形式為:
類型說明符*變量名;
其中,*表示這是一個(gè)指針變量,變量名即為定義的指針變量名,類型說明符表示本指
針變量所指向的變量的數(shù)據(jù)類型。
例如:int*pl;
表示pl是一個(gè)指針變量,它的值是某個(gè)整型變量的地址。或者說pl指向一個(gè)整型變量。
至于P1究竟指向哪一個(gè)整型變量,應(yīng)由向P1賦予的地址來決定。
再如:
int*p2;/*p2是指向整型變量的指針變量*/
float*p3;/*p3是指向浮點(diǎn)變量的指針變量*/
char*p4;/*p4是指向字符變量的指針變量*/
應(yīng)該注意的是,一個(gè)指針變量只能指向同類型的變量,如P3只能指向浮點(diǎn)變量,不能
時(shí)而指向一個(gè)浮點(diǎn)變量,時(shí)而又指向一個(gè)字符變量。
10.2.2指針變量的引用
指針變量同普通變量一樣,使用之前不僅要定義說明,而且必須賦予具體的值。未經(jīng)賦
值的指針變量不能使用,否則將造成系統(tǒng)混亂,甚至死機(jī)。指針變量的賦值只能賦予地址,
決不能賦予任何其它數(shù)據(jù),否則將引起錯(cuò)誤。在C語言中,變量的地址是由編譯系統(tǒng)分配的,
對(duì)用戶完全透明,用戶不知道變量的具體地址.
兩個(gè)有關(guān)的運(yùn)算符:
1)&:取地址運(yùn)算符。
2)*:指針運(yùn)算符(或稱''間接訪問"運(yùn)算符)。
C語言中提供了地址運(yùn)算符&來表示變量的地址。
第3頁
靳潤(rùn)昭C語言教程講義2001年2月17日
其一般形式為:
&變量名;
如&a表示變量a的地址,&b表示變量b的地址。變量本身必須預(yù)先說明。
設(shè)有指向整型變量的指針變量P,如要把整型變量a的地址賦予p可以有以下兩種方式:
(1)指針變量初始化的方法
inta;
int*p=&a;
(2)賦值語句的方法
inta;
int*p;
p=&a;
不允許把一個(gè)數(shù)賦予指針變量,故卜面的賦值是錯(cuò)誤的:
int*p;
p=1000;
被賦值的指針變量前不能再加“*〃說明符,如寫為*p二&a也是錯(cuò)誤的。
假設(shè):
inti=200,x;
int*ip;
我們定義了兩個(gè)整型變量i,X,還定義了一個(gè)指向整型數(shù)的指針變量ip。i,x中可存放
整數(shù),而ip中只能存放整型變量的地址。我們可以把i的地址賦給ip:
ip=&i;
此時(shí)指針變量ip指向整型變量i,假設(shè)變量i的地址為1800,這個(gè)賦值可形象理解為下
圖所示的聯(lián)系。
■?
ip1
1800--------->200
1800
以后我們便可以通過指針變量ip間接訪問變量i,例如:
x=*ip;
運(yùn)算符*訪問以ip為地址的存貯區(qū)域,而ip中存放的是變量i的地址,因此,*ip訪問的
是地址為1800的存貯區(qū)域(因?yàn)槭钦麛?shù),實(shí)際上是從1800開始的兩個(gè)字節(jié)),它就是i所占用
的存貯區(qū)域,所以上面的賦值表達(dá)式等價(jià)于
x=i;
另外,指針變量和一般變量一樣,存放在它們之中的值是可以改變的,也就是說可以改變
它們的指向,假設(shè)
inti,j,*pl,*p2;
.,,
1=a;
j='b':
pl=&i;
p2=&j;
則建立如下圖所示的聯(lián)系:
第4頁
靳潤(rùn)昭C語言教程講義2001年2月17日
p2j
這時(shí)賦值表達(dá)式:
p2=pl
就使P2與pl指向同一對(duì)象i,此時(shí)*p2就等價(jià)于i,而不是j,圖所示:
pli
如果執(zhí)行如下表達(dá)式:
*p2=*pl;
則表示把pl指向的內(nèi)容賦給P2所指的區(qū)域,此時(shí)就變成圖所示
p2
通過指針訪問它所指向的一個(gè)變量是以間接訪問的形式進(jìn)行的,所以比直接訪問一個(gè)變
量要費(fèi)時(shí)間,而且不直觀,因?yàn)橥ㄟ^指針要訪問哪一個(gè)變量,取決于指針的值(即指向),例如
第5頁
靳潤(rùn)昭C語言教程講義2001年2月17日
”*p2=*pl實(shí)際上就是"j=i前者不僅速度慢而且目的不明。但由于指針是變量,我們可以
通過改變它們的指向,以間接訪問不同的變量,這給程序員帶來靈活性,也使程序代碼編寫得
更為簡(jiǎn)潔和有效。
指針變量可出現(xiàn)在表達(dá)式中,設(shè)
intx,y,*px=&x;
指針變量PX指向整數(shù)X,貝I」*px可出現(xiàn)在X能出現(xiàn)的任何地方。例如:
y=*px+5;/*表示把x的內(nèi)容加5并賦給y*/
y=十+*px;/*px的內(nèi)容加上1之后賦給y,++*px相當(dāng)于++(*px)*/
y二*px++;/*相當(dāng)于y=*px;px++*/
【例10.1]
main()
{inta,b;
int*pointer_l,*pointer_2;
a=100;b=10;
pointer」二&a;
pointer_2=&b;
printf(〃%d,%d\n〃,a,b);
printf(z,%d,%d\nz/,"pointer」,*pointer_2);
)
對(duì)程序的說明:
1)在開頭處雖然定義了兩個(gè)指針變量pointer1和pointer2,擔(dān)它們并未指向任何一個(gè)
整型變量。只是提供兩個(gè)指針變量,規(guī)定它們可以指向整型變量。程序第5、6行的作
用就是使pointer1指向a,pointer2指向b。
pointer_la
&a------?*pointer_l
pointer_2b
&b------?*pointer_2
2)最后一行的*pointer」和*pointer_2就是變量a和bo最后兩個(gè)printf函數(shù)作用是相
同的。
3)程序中有兩處出現(xiàn)*pointer」和*pointer_2,請(qǐng)區(qū)分它們的不同含義。
4)程序第5、6行的、'pointer」二&a〃和、'pointer_2=&b〃不能寫成''"pointer」二&a〃和
''*pointer_2=&b〃°
請(qǐng)對(duì)下面再的關(guān)于和的問題進(jìn)行考慮:
1)如果已經(jīng)執(zhí)行了"pointer_l=&a;"語句,則&*pointer_l是什么含義?
第6頁
靳潤(rùn)昭C語言教程講義2001年2月17日
2)*&a含義是什么?
3)(pointer_l)++和pointer」++的區(qū)別?
【例10.2]輸入a和b兩個(gè)整數(shù),按先大后小的順序輸出a和bo
main()
{int*pl,*p2,*p,a,b;
scanf(〃%d,%d",&a,&b);
pl=&a;p2=&b;
if(a<b)
{p=pl;pl=p2;p2=p;}
printf(,z\na=%d,b=%d\n〃,a,b);
printf("max二%d,min=%d\n〃,*pl,*p2);
10.2.3指針變量作為函數(shù)參數(shù)
函數(shù)的參數(shù)不僅可以是整型、實(shí)型、字符型等數(shù)據(jù),還可以是指針類型。它的作用是將
一個(gè)變量的地址傳送到另一個(gè)函數(shù)中。
【例10.3】題目同例10.2,即輸入的兩個(gè)整數(shù)按大小順序輸出。今用函數(shù)處理,而且用指
針類型的數(shù)據(jù)作函數(shù)參數(shù)。
swap(int*pl,int*p2)
{inttemp;
temp=*pl;
*pl=*p2;
*p2=temp;
main()
inta,b;
int*pointer_l,*pointer_2;
scanf("%d,%d",&a,&b);
pointer」=&a;pointer_2=&b;
if(a<b)swap(pointer1,pointer2);
printf(z,\n%d,%d\n”,a,b);
對(duì)程序的說明:
swap是用戶定義的函數(shù),它的作用是交換兩個(gè)變量(a和b)的值。swap函數(shù)的形參
pl、p2是指針變量。程序運(yùn)行時(shí),先執(zhí)行main函數(shù),輸入a和b的值。然后將a和b的地
址分別賦給指針變量pointer1和pointer2,使pointer1指向a,pointer_2指向b。
第7頁
靳潤(rùn)昭C語言教程講義2001年2月17日
pointer_l
*pointer_2b
接著執(zhí)行if語句,由于a<b,因此執(zhí)行swap函數(shù)。注意實(shí)參pointer」和pointer_2是
指針變量,在函數(shù)調(diào)用時(shí),將實(shí)參變量的值傳遞給形參變量。采取的依然是''值傳遞〃方式。
因此虛實(shí)結(jié)合后形參pl的值為&a,p2的值為&b。這時(shí)pl和pointer」指向變量a,p2和
pointer_2指向變量bo
Plp2
接著執(zhí)行執(zhí)行swap函數(shù)的函數(shù)體使*pl和*p2的值互換,也就是使a和b的值互換。
Plp2
函數(shù)調(diào)用結(jié)束后,Pl和p2不復(fù)存在(已釋放)如圖。
pointer_la
&a9
pointer_2b
&b----5
最后在main函數(shù)中輸出的a和b的值是已經(jīng)過交換的值。
請(qǐng)注意交換*P1和*P2的值是如何實(shí)現(xiàn)的。請(qǐng)找出下列程序段的錯(cuò)誤:
swap(int*pl,int*p2)
{int*temp;
*lemp=*pl;/*此語句有問題*/
*pl=*p2;
*p2=temp;
第8頁
靳潤(rùn)昭C語言教程講義2001年2月17日
}
請(qǐng)考慮下面的函數(shù)能否實(shí)現(xiàn)實(shí)現(xiàn)a和b互換。
swap(intx,inty)
{inttemp;
temp=x;
y=temp;
}
如果在main函數(shù)中用、'swap(a,b);”調(diào)用swap函數(shù),會(huì)有什么結(jié)果呢?請(qǐng)看下圖所示。
.ab
E□
EEZ
Xy
【例10.4]請(qǐng)注意,不能企圖通過改變指針形參的值而使指針實(shí)參的值改變。
swap(int*pl,int*p2)
{int*p;
p二pl;
pl=p2;
p2=p;
)
main()
inta,b;
int*pointer_l,*pointer_2;
scanf("%d,%d",&a,&b);
pointer_l=&a;pointer_2=&b;
if(a<b)swap(pointer1,pointer2);
printf(/z\n%d,%d\n,z,*pointer_l,*pointer_2);
其中的問題在于不能實(shí)現(xiàn)如圖所示的第四步(d)o
pointer_l
apointer_la
EZHQ
pointer2b_
Ewn
(a)(b)(c)(d)
【例10.5】輸入a、b、c3個(gè)整數(shù),按大小順序輸出。
第9頁
靳潤(rùn)昭C語言教程講義2001年2月17日
swap(int*ptl,int*pt2)
{inttemp;
temp=*ptl;
*ptl=*pt2;
*pt2=temp;
)
exchange(int*ql,int*q2,int*q3)
{if(*ql<*q2)swap(ql,q2);
if(*ql〈*q3)swap(ql,q3);
if(*q2〈*q3)swap(q2,q3);
}
main()
(
inta,b,c,*pl,*p2,*p3;
scanf(〃%d,%d,%d〃,&a,&b,&c);
pl=&a;p2=&b;p3=&c;
exchange(pl,p2,p3);
printf(z,\n%d,%d,%d\nz,,a,b,c);
)
10.2.4指針變量幾個(gè)問題的進(jìn)一步說明
指針變量可以進(jìn)行某些運(yùn)算,但其運(yùn)算的種類是有限的。它只能進(jìn)行賦值運(yùn)算和部分算
術(shù)運(yùn)算及關(guān)系運(yùn)算。
1.指針運(yùn)算符
1)取地址運(yùn)算符&:取地址運(yùn)算符&是單目運(yùn)算符,其結(jié)合性為自右至左,其功能是取變量
的地址。在scanf函數(shù)及前面介紹指針變量賦值中,我們已經(jīng)了解并使用了&運(yùn)算符。
2)取內(nèi)容運(yùn)算符*:取內(nèi)容運(yùn)算符*是單目運(yùn)算符,其結(jié)合性為自右至左,用來表示指針變
量所指的變量。在*運(yùn)算符之后跟的變量必須是指針變量。
需要注意的是指針運(yùn)算符*和指針變量說明中的指針說明符*不是一回事。在指針變量說
明中,''*〃是類型說明符,表示其后的變量是指針類型。而表達(dá)式中出現(xiàn)的則是一個(gè)運(yùn)
算符用以表示指針變量所指的變量。
【例10.6】
main(){
inta=5,*p=&a;
printf*p);
表示指針變量P取得了整型變量a的地址。printf*p)語句表示輸出變量a的值。
2.指針變量的運(yùn)算
1)賦值運(yùn)算:指針變量的賦值運(yùn)算有以下幾種形式。
第10頁
靳潤(rùn)昭C語言教程講義2001年2月17日
①指針變量初始化賦值,前面已作介紹。
②把一個(gè)變量的地址賦予指向相同數(shù)據(jù)類型的指針變量。
例如:
inta,*pa;
pa=&a;/*把整型變量a的地址賦予整型指針變量pa*/
③把一個(gè)指針變量的值賦予指向相同類型變量的另一個(gè)指針變量。
如:
inta,*pa=&a,*pb;
pb=pa;/*把a(bǔ)的地址賦予指針變量pb*/
由于pa,pb均為指向整型變量的指針變量,因此可以相互賦值。
④把數(shù)組的首地址賦予指向數(shù)組的指針變量。
例如:
inta[5],*pa;
pa=a;
(數(shù)組名表示數(shù)組的首地址,故可賦予指向數(shù)組的指針變量pa)
也可寫為:
pa=&a[0];/*數(shù)組第一個(gè)元素的地址也是整個(gè)數(shù)組的首地址,
也可賦予pa*/
當(dāng)然也可采取初始化賦值的方法:
inta[5],*pa=a;
⑤把字符串的首地址賦予指向字符類型的指針變量。
例如:
char*pc;
pc="CLanguage”;
或用初始化賦值的方法寫為:
char*pc="CLanguage/z;
這里應(yīng)說明的是并不是把整個(gè)字符串裝入指針變量,而是把存放該字符串的字符數(shù)
組的首地址裝入指針變量。在后面還將詳細(xì)介紹。
⑥把函數(shù)的入口地址賦予指向函數(shù)的指針變量。
例如:
int(*pf)();
pf=f;/*f為函數(shù)名*/
2)加減算術(shù)運(yùn)算
對(duì)于指向數(shù)組的指針變量,可以加上或減去一個(gè)整數(shù)no設(shè)pa是指向數(shù)組a的指針變
量,則pa+n,pa-n,pa++,++pa,pa—,—pa運(yùn)算都是合法的。指針變量加或減一個(gè)整數(shù)n的意
義是把指針指向的當(dāng)前位置(指向某數(shù)組元素)向前或向后移動(dòng)n個(gè)位置。應(yīng)該注意,數(shù)組指
針變量向前或向后移動(dòng)一個(gè)位置和地址加1或減1在概念上是不同的。因?yàn)閿?shù)組可以有不同
的類型,各種類型的數(shù)組元素所占的字節(jié)長(zhǎng)度是不同的。如指針變量加1,即向后移動(dòng)1個(gè)
位置表示指針變量指向下一個(gè)數(shù)據(jù)元素的首地址。而不是在原地址基礎(chǔ)上加U例如:
inta[5],*pa;
pa=a;/*pa指向數(shù)組a,也是指向a[0]*/
pa=pa+2;/*pa指向a[2],即pa的值為&pa[2]*/
指針變量的加減運(yùn)算只能對(duì)數(shù)組指針變量進(jìn)行,對(duì)指向其它類型變量的指針變量作加減
運(yùn)算是毫無意義的。
第11頁
靳潤(rùn)昭C語言教程講義2001年2月17日
3)兩個(gè)指針變量之間的運(yùn)算:只有指向同一數(shù)組的兩個(gè)指針變量之間才能進(jìn)行運(yùn)算,否則
運(yùn)算毫無意義。
①兩指針變量相減:兩指針變量相減所得之差是兩個(gè)指針?biāo)笖?shù)組元素之間相差的元
素個(gè)數(shù)。實(shí)際上是兩個(gè)指針值(地址)相減之差再除以該數(shù)組元素的長(zhǎng)度(字節(jié)數(shù))。
例如pfl和pf2是指向同一浮點(diǎn)數(shù)組的兩個(gè)指針變量,設(shè)pfl的值為2010II,pf2
的值為2000H,而浮點(diǎn)數(shù)組每個(gè)元素占4個(gè)字節(jié),所以pfl-pf2的結(jié)果為
(200011-201011)/4=4,表示pfl和pf2之間相差4個(gè)元素。兩個(gè)指針變量不能進(jìn)行
加法運(yùn)算。例如,pfl+pf2是什么意思呢?毫無實(shí)際意義。
②兩指針變量進(jìn)行關(guān)系運(yùn)算:指向同一數(shù)組的兩指針變量進(jìn)行關(guān)系運(yùn)算可表示它們所
指數(shù)組元素之間的關(guān)系。
例如:
pfl—pf2表示pfl和pf2指向同一數(shù)組元素;
pfl>pf2表示pfl處于高地址位置;
pfl<pf2表示pf2處于低地址位置。
指針變量還可以與0比較。
設(shè)P為指針變量,則P==0表明p是空指針,它不指向任何變量;
p!=0表示p不是空指針。
空指針是由對(duì)指針變量賦予0值而得到的。
例如:
JtdefineNULL0
int*p=NULL;
為指針變量賦0值和不賦值是不同的。指針變量未賦值時(shí),可以是任意值,是
不能使用的。否則將造成意外錯(cuò)誤。而指針變量賦0值后,則可以使用,只是它不
指向具體的變量而已。
【例10.7]
main(){
inta=10,b=20,s,t,*pa,*pb;/*說明pa,pb為整型指針變量*/
pa=&a;/*給指針變量pa賦值,pa指向變量a*/
pb=&b;/*給指針變量pb賦值,pb指向變量b*/
s=*pa+*pb;/*求a+b之和,(*pa就是a,*pb就是b)*/
t=*pa**pb;/*本行是求a*b之積*/
printf(/,a=%d\nb=%d\na+b=%d\na*b=%d\n,/,a,b,a+b,a*b);
printf(,/s=%d\nt=%d\n/,,s,t);
【例10.8】
mainO{
inta,b,c,*pmax,*pmin;/*pmax,pmin為整型指針變量*/
printf(z/inputthreenumbers:\n,?);/*輸入提示*/
scanfC%d%d%dz/,&a,&b,&c);/*輸入三個(gè)數(shù)字*/
if(a>b){/*如果第一個(gè)數(shù)字大于第二個(gè)數(shù)字...*/
pmax=&a;/*指針變量賦值*/
pmin=&b;}/*指針變量賦值*/
第12頁
靳潤(rùn)昭C語言教程講義2001年2月17日
else{
pmax=&b;/*指針變量賦值*/
pmin=&a;}/*指針變量賦值*/
if(c>*pmax)pmax=&c;/*判斷并賦值*/
if(c<*pmin)pmin=&c;/*判斷并賦值*/
printf(,zmax=%d\nmin=%d\nz/,*pmax,*pmin);/*輸出結(jié)果*/
10.3數(shù)組指針和指向數(shù)組的指針變量
一個(gè)變量有一個(gè)地址,一個(gè)數(shù)組包含若干元素,每個(gè)數(shù)組元素都在內(nèi)存中占用存儲(chǔ)單元,
它們都有相應(yīng)的地址。所謂數(shù)組的指針是指數(shù)組的起始地址,數(shù)組元素的指針是數(shù)組元素的
地址。
10.3.1指向數(shù)組元素的指針
一個(gè)數(shù)組是由連續(xù)的一塊內(nèi)存單元組成的。數(shù)組名就是這塊連續(xù)內(nèi)存單元的首地址。--
個(gè)數(shù)組也是由各個(gè)數(shù)組元素(下標(biāo)變量)組成的。每個(gè)數(shù)組元素按其類型不同占有幾個(gè)連續(xù)的
內(nèi)存單元?一個(gè)數(shù)組元素的首地址也是指它所占有的兒個(gè)內(nèi)存單元的首地址。
定義一個(gè)指向數(shù)組元素的指針變量的方法,與以前介紹的指針變量相同。
例如:
inta[10];/*定義a為包含10個(gè)整型數(shù)據(jù)的數(shù)組*/
int*p;/*定義p為指向整型變量的指針*/
應(yīng)當(dāng)注意,因?yàn)閿?shù)組為int型,所以指針變量也應(yīng)為指向int型的指針變量。下面是對(duì)
指針變量賦值:
p=&a[0];
把a(bǔ)[0]元素的地址賦給指針變量p。也就是說,p指向a數(shù)組的第0號(hào)元素。
P
第13頁
靳潤(rùn)昭C語言教程講義2001年2月17日
C語言規(guī)定,數(shù)組名代表數(shù)組的首地址,也就是第。號(hào)元素的地址。因此,下面兩個(gè)語
句等價(jià):
P=&a[0];
P=a;
在定義指針變量時(shí)可以賦給初值:
int*p=&a[0];
它等效于:
int*p;
P=&a[0];
當(dāng)然定義時(shí)也可以寫成:
int*p=a;
從圖中我們可以看出有以下關(guān)系:
p,a,&a[0]均指向同一單元,它們是數(shù)組a的首地址,也是0號(hào)元素a[0]的首地址。應(yīng)
該說明的是P是變量,而a,&a[0]都是常量。在編程時(shí)應(yīng)予以注意。
數(shù)組指針變量說明的一般形式為:
類型說明符*指針變量名;
其中類型說明符表示所指數(shù)組的類型。從一般形式可以看出指向數(shù)組的指針變量和指向普通
變量的指針變量的說明是相同的。
1032通過指針引用數(shù)組元素
c語言規(guī)定:如果指針變量p已指向數(shù)組中的一個(gè)元素,則P+1指向同一數(shù)組中的下一
個(gè)元素。
引入指針變量后,就可以用兩種方法來訪問數(shù)組元素了。
如果P的初值為&a[0],則:
1)p+i和a+i就是a[i]的地址,或者說它們指向a數(shù)組的第i個(gè)元素。
蹶組
P■—
p+1,a+1a[0]
a[l]
a⑵
—
p+i,a+i
*(p+i)a[i]
p+9,a+9
a⑼
—
2)*(p+i)或*(a+i)就是p+i或a+i所指向的數(shù)組元素,即a[i]。例如,*(p+5)或*(a+5)
就是a[5]。
3)指向數(shù)組的指針變量也可以帶下標(biāo),如p[i]與*(p+i)等價(jià)。
根據(jù)以上敘述,引用一個(gè)數(shù)組元素可以用:
第14頁
靳潤(rùn)昭C語言教程講義2001年2月17日
1)下標(biāo)法,即用a[i]形式訪問數(shù)組元素。在前面介紹數(shù)組時(shí)都是采用這種方法。
2)指針法,即采用*(a+i)或*(p+i)形式,用間接訪問的方法來訪問數(shù)組元素,其中a
是數(shù)組名,p是指向數(shù)組的指針變量,其處值p二a。
【例10.9】輸出數(shù)組中的全部元素。(下標(biāo)法)
main(){
inta[10],i;
for(i=0;i<10;i++)
a[i]=i;
for(i=0;i<5;i++)
printf(,,a[%d]=%d\n,z,i,a[i]);
【例10.10]輸出數(shù)組中的全部元素。(通過數(shù)組名計(jì)算元素的地址,找出元素的值)
main(){
inta[10],i;
for(i=0;i<10;i++)
*(a+i)=i;
for(i=0;i<10;i++)
printfCza[%d]=%d\n,/,i,*(a+i));
)
【例10.11]輸出數(shù)組中的全部元素。(用指針變量指向元素)
main(){
inta[10],I,*p;
P=a;
for(i=0;i<10;i++)
*(p+i)=i;
for(i=0;i<10;i++)
printfCa[%d]=%d\n",i,*(p+i));
}
【例10.12]
main(){
inta[10],i,*p=a;
for(i=0;i<10;){
*P=i;
printfCa[%d]=%d\n//,i++,*p++);
}
第15頁
靳潤(rùn)昭C語言教程講義2001年2月17日
幾個(gè)注意的問題:
1)指針變量可以實(shí)現(xiàn)本身的值的改變。如P++是合法的;而a++是錯(cuò)誤的。因?yàn)閍是數(shù)組
名,它是數(shù)組的首地址,是常量。
2)要注意指針變量的當(dāng)前值。請(qǐng)看下面的程序。
【例10.13】找出錯(cuò)誤。
main(){
int*p,i,a[10];
P=a;
for(i=0;i<10;i++)
*p++=i;
for(i=0;i<10;i++)
printfCza[%d]=%d\nzz,i,*p++);
}
【例10.14]改正。
main(){
int*p,i,a[10];
P=a;
for(i=0;i<10;i++)
*p++=i;
P=a;
for(i=0;i<10;i++)
printfCa[%d]=%d\n/,,i,*p++);
)
3)從上例可以看出,雖然定義數(shù)組時(shí)指定它包含10個(gè)元素,但指針變量可以指到數(shù)組以
后的內(nèi)存單元,系統(tǒng)并不認(rèn)為非法。
4)*p++,由于++和*同優(yōu)先級(jí),結(jié)合方向自右而左,等價(jià)于*(p++)。
5)*(p++)與*(++p)作用不同。若P的初值為a,則*(p++)等價(jià)a[0],*(++p)等價(jià)
6)(*p)++表示p所指向的元素值加lo
7)如果p當(dāng)前指向a數(shù)組中的第i個(gè)元素,則
*(p—)相當(dāng)于a[i—];
*(++p)相當(dāng)于a[++i];
*(—p)相當(dāng)于a[—i]o
1033數(shù)組名作函數(shù)參數(shù)
數(shù)組名可以作函數(shù)的實(shí)參和形參。如:
main()
{intarray[10];
第16頁
靳潤(rùn)昭C語言教程講義2001年2月17日
f(array,10);
f(intarr[],intn);
array為實(shí)參數(shù)組名,arr為形參數(shù)組名。在學(xué)習(xí)指針變量之后就更容易理解這個(gè)問題
了。數(shù)組名就是數(shù)組的首地址,實(shí)參向形參傳送數(shù)組名實(shí)際上就是傳送數(shù)組的地址,形參得
到該地址后也指向同一數(shù)組。這就好象同一件物品有兩個(gè)彼此不同的名稱一樣。
array,arr
array[0]
arr[0]
同樣,指針變量的值也是地址,數(shù)組指針變量的值即為數(shù)組的首地址,當(dāng)然也可作為函
數(shù)的參數(shù)使用。
【例10.15]
floataver(float*pa);
main(){
floatsco[5],av,*sp;
inti;
sp=sco;
printf(z,\ninput5scores:\n,z);
for(i=0;i<5;i++)scanf&sco[i]);
av=aver(sp);
printf(z,averagescoreis%5.2f,z,av);
}
floataver(float*pa)
(
inti;
floatav,s=0;
for(i=0;i<5;i++)s=s+*pa++;
av=s/5;
returnav;
第17頁
靳潤(rùn)昭C語言教程講義2001年2月17日
【例10.16】將數(shù)組a中的n個(gè)整數(shù)按相反順序存放。
算法為:將a[0]與a[n-l]對(duì)換,再a[l]與a[n-2]對(duì)換……,直到將a[(n-l/2)]與
a[n-int((n-l)/2)]對(duì)換。今用循環(huán)處理此問題,設(shè)兩個(gè)''位置指示變量"i和j,i的初值為
0,j的初值為n-h將a[i]與a[j]交換,然后使i的值加1,j的值減1,再將a[i]與a[j]
交換,直到i=(nT)/2為止,如圖所示。
程序如下:
voidinv(intx[],intn)/*形參x是數(shù)組名*/
(
inttemp,i,j,m=(n-l)/2;
for(i=0;i<=m;i++)
{j=n-l-i;
temp=x[i];x[i]=x[j];x[j]=temp;}
return;
}
main()
{inti,a[10]={3,7,9,11,0,6,7,5,4,2};
printf(y/Theoriginalarray:\n/z);
for(i=0;i<10;i++)
printf("%d,",a[i]);
printf;
inv(a,10);
printf(,zThearrayhasbenninverted:\n,,);
for(i=0;i<10;i++)
printf("%d,",a[i]);
printf("\n");
對(duì)此程序可以作一些改動(dòng)。將函數(shù)inv中的形參x改成指針變量。
【例10.17)對(duì)例10.16可以作一些改動(dòng)。將函數(shù)inv中的形參x改成指針變量。
程序如下:
voidinv(int*x,intn)/*形參x為指針變量*/
int*p,temp,*i,*j,m=(n-l)/2;
第18頁
靳潤(rùn)昭C語言教程講義2001年2月17日
i=x;j=x+n_l;p=x+m;
for(;i<=p;i++,j—)
{temp=*i;*j=temp;}
return;
)
main()
{inti,a[10]={3,7,9,11,0,6,7,5,4,2};
printf(/zTheoriginalarray:\n/z);
for(i=0;i<10;i++)
printf("%d,",a[i]);
printf(〃\n〃);
inv(a,10);
printf("Thearrayhasbenninverted:\nz,);
for(i=0;i<10;i++)
printf("%d,",a[i]);
printf(〃\n〃);
運(yùn)行情況與前一程序相同。
【例10.18】從0個(gè)數(shù)中找出其中最大值和最小值。
調(diào)用一個(gè)函數(shù)只能得到一個(gè)返回值,今用全局變量在函數(shù)之間“傳遞”數(shù)據(jù)。程序如下:
intmax,min;/*全局變量*/
voidmax_min_value(intarray[],intn)
{int*p,*array_end;
array_end=array+n;
max=min=*array;
for(p=array+l;p<array_end;p++)
if(*p>max)max=*p;
elseif(*p〈min)min=*p;
return;
)
main()
{inti,number[10];
printf("enter10integerumbers:\n,z);
for(i=0;i<10;i++)
scanf(,z%dz/,&number[i]);
max_min_value(number,10);
printf(,,\nmax=%d,min=%d\n,z,max,min);
)
說明:
1)在函數(shù)max_min_value中求出的最大值和最小值放在max和min中。山于它們是全局,
第19頁
靳潤(rùn)昭C語言教程講義2001年2月17日
因此在主函數(shù)中可以直接使用。
2)函數(shù)max_min_value中的語句:
max=min=*array;
array是數(shù)組名,它接收從實(shí)參傳來的數(shù)組numuber的首地址。
*array相當(dāng)于*(&array[0])。上述語句與max=min=array[0];等價(jià)。
3)在執(zhí)行for循環(huán)時(shí),p的初值為array+1,也就是使p指向array[1]。以后每次執(zhí)行p++,
使P指向下一個(gè)元素。每次將*P和max與min比較。將大者放入max,小者放min。
數(shù)蛆number,array
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 四川省宜賓市六中2025年高三(最后沖刺)化學(xué)試卷含解析
- 微課培訓(xùn)講座
- 2025年生活垃圾焚燒發(fā)電項(xiàng)目建議書
- 陜西省安康市高新中學(xué)2024-2025學(xué)年高二下學(xué)期第一次月考(3月)英語試卷(含答案無聽力原文及音頻)
- 2025年山東省濟(jì)南市市中區(qū)中考物理一模試卷(無答案)
- 山東省東營(yíng)市墾利區(qū)第一中學(xué)2025屆高考全國統(tǒng)考預(yù)測(cè)密卷化學(xué)試卷含解析
- 2025屆湖南省湘潭市湘機(jī)中學(xué)高考化學(xué)五模試卷含解析
- 2025屆山東省棗莊市現(xiàn)代實(shí)驗(yàn)學(xué)校高三3月份第一次模擬考試化學(xué)試卷含解析
- 2025年數(shù)顯儀表項(xiàng)目發(fā)展計(jì)劃
- 中考數(shù)學(xué)高頻考點(diǎn)專項(xiàng)練習(xí):專題14 考點(diǎn)32 正方形 (3)及答案
- 2025年國家公務(wù)員錄用考試公共基礎(chǔ)知識(shí)預(yù)測(cè)押題試卷及答案(共七套)
- 2025-2030中國兒童服裝行業(yè)市場(chǎng)發(fā)展分析及投資前景預(yù)測(cè)研究報(bào)告
- 部編版語文教材培訓(xùn)講座-口語交際
- 2025年全國中小學(xué)生安全教育日專題
- 2025年工程力學(xué)筆試試題及答案
- 2025年電子設(shè)備裝接工崗位職業(yè)技能資格證考試題(附答案)
- 2025年河南航空港發(fā)展投資集團(tuán)有限公司社會(huì)招聘45人筆試參考題庫附帶答案詳解
- 企業(yè)一季一課安全教育記錄(2篇)
- 2025-2030年中國工業(yè)廢水處理產(chǎn)業(yè)十三五發(fā)展規(guī)劃及戰(zhàn)略規(guī)劃分析報(bào)告
- 2024年全國高考新課標(biāo)Ⅱ卷數(shù)學(xué)試題含答案解析
- 2025年山東國際信托股份限公司社會(huì)招聘高頻重點(diǎn)提升(共500題)附帶答案詳解
評(píng)論
0/150
提交評(píng)論