c語言教程 指針_第1頁
c語言教程 指針_第2頁
c語言教程 指針_第3頁
c語言教程 指針_第4頁
c語言教程 指針_第5頁
已閱讀5頁,還剩34頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論