版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、3.1指針指針的定義和賦值在計(jì)算機(jī)中,所有的數(shù)據(jù)都是存放在存儲(chǔ)器中的。一般把存儲(chǔ)器中的一個(gè)字節(jié)稱為一個(gè)內(nèi)存單元,不同的數(shù)據(jù)類型所占用的內(nèi)存單元數(shù)不同,如整型量占2個(gè)單元,字符量占1個(gè)單元等。為了正確地訪問(wèn)這些內(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è)通俗的例子來(lái)說(shuō)明它們之間的關(guān)系。我們到銀行去存、取款時(shí),銀行工作人員將根據(jù)我們的帳號(hào)去找我們的存款單,找到之后在存單上寫(xiě)入存款、取款的金額。
2、在這里,帳號(hào)就是存單的指針,存款數(shù)是存單的內(nèi)容。對(duì)于一個(gè)內(nèi)存單元來(lái)說(shuō),單元的地址即為指針,其中存放的數(shù)據(jù)才是該單元的內(nèi)容。在+語(yǔ)言中,允許用一個(gè)變量來(lái)存放指針,這種變量稱為指針變量。因此,一個(gè)指針變量的值就是某個(gè)內(nèi)存單元的地址或稱為某內(nèi)存單元的指針。圖3.1.1中,設(shè)有字符變量C,其內(nèi)容為“K”(ASCII碼為十進(jìn)制數(shù)75),C占用了011A號(hào)單元(地址用十六進(jìn)制數(shù)表示)。設(shè)有指針變量P,內(nèi)容為011A, 這種情況我們稱為P指向變量C,或說(shuō)P是指向變量C的指針。嚴(yán)格地說(shuō),一個(gè)指針是一個(gè)地址,它是一個(gè)常量。而一個(gè)指針變量卻可以被賦予不同的指針值,是變量。但常把指針變量簡(jiǎn)稱為指針。為了避
3、免混淆,我們?cè)诒緯?shū)中約定:“指針”是指地址,是常量,“指針變量”是指取值為地址的變量。定義指針的目的是為了通過(guò)指針去訪問(wèn)內(nèi)存單元。指針是存放地址值的變量或者常量。例如:int a=1; &a就表示指針常量(“&”表示取地址運(yùn)算符,也即引用)。int *b; b表示的是指針變量(注意,是b表示指針變量而不是*b),*表示要說(shuō)明的是指針變量。大家注意int *b2和int(*b)2是不同的,int *b2表示b是一個(gè)具有兩個(gè)元素的數(shù)組變量,該數(shù)組中的元素為指針類型,即b是一個(gè)指針數(shù)組,而int(*b)2則表示b是一個(gè)指針,該指針指向一個(gè)含有兩個(gè)int型元素的數(shù)組類型。這里要注意運(yùn)算
4、優(yōu)先級(jí)問(wèn)題,有助于理解指針問(wèn)題。下面是指針定義的例子:int *ip1,*ip2;string *pstring;double *dp;我們通過(guò)在標(biāo)識(shí)符前加一個(gè)解引用操作符(*)來(lái)定義指針。在逗號(hào)分隔的標(biāo)識(shí)符列表中,每個(gè)將被用作指針的標(biāo)識(shí)符前都必須加上解引用操作符。在下面的例子中,lp是一個(gè)指向long型對(duì)象的指針,而lp2則是一個(gè)long型的數(shù)據(jù)對(duì)象,而不是指針:long *lp,lp2;在下面的例子中,fp是一個(gè)float型的數(shù)據(jù)對(duì)象,而fp2是一個(gè)指向float型對(duì)象的指針:float fp,*fp2;為清楚起見(jiàn),最好寫(xiě)成:string *ps; 而不是:string* ps;有可能發(fā)生
5、的情況是,當(dāng)程序員后來(lái)想定義第二個(gè)字符串指針時(shí),他會(huì)錯(cuò)誤的修改定義如下:string *ps,ps2; /錯(cuò)誤:ps2不是一個(gè)字符串指針當(dāng)指針持有0值時(shí),表明它沒(méi)有指向任何對(duì)象,或持有一個(gè)同類型的數(shù)據(jù)對(duì)象的地址。已知ival的定義:int ival=1024;下面的定義以及對(duì)兩個(gè)指針pi和pi2的賦值都是合法的。int *pi=0; /pi被初始化為沒(méi)有指向任何對(duì)象int *pi2=&ival; /pi2被初始化為ival的地址pi=pi2; /ok:pi和pi2現(xiàn)在都指向ivalpi2=0; /現(xiàn)在pi2沒(méi)有指向任何對(duì)象指針不能持有非地址值。例如,下面的賦值將導(dǎo)致編譯錯(cuò)誤:pi=iv
6、al; /錯(cuò)誤:pi被賦以int值ival指針不能被初始化或賦值為其它類型對(duì)象的地址值。例如,已知如下定義:double dval;double *pd=&dval;那么,下面兩條語(yǔ)句都會(huì)引起編譯時(shí)刻錯(cuò)誤:pi=pd; /無(wú)效的類型賦值:int *<=double *pi=&dval;不能說(shuō)pi在物理上不能持有與dval相關(guān)聯(lián)的內(nèi)存地址:它能夠。但是不允許,因?yàn)?,雖然pi和pd能夠持有同樣的地址值,但對(duì)那塊內(nèi)存的存儲(chǔ)布局和內(nèi)容的解釋卻完全不同。當(dāng)然,我們要做的僅僅是持有地址值(可能是一個(gè)地址同另一個(gè)地址作比較),那么指針的實(shí)際類型就不重要了。C+提供了一種特殊的指針類型來(lái)
7、支持這種需求:空(void *)類型指針,它可以被任何數(shù)據(jù)指針類型的地址值賦值(函數(shù)指針除外)。void *pv=pi; /ok:void *可以持有任何指針類型的地址值pv=pd;void *表明相關(guān)的值是個(gè)地址,但該地址的對(duì)象類型不知道。我們不能夠操作空類型指針?biāo)赶虻膶?duì)象,只能傳送該地址值或?qū)⑺c其它地址值作比較。已知一個(gè)int型指針對(duì)象pi,當(dāng)我們寫(xiě)下pi時(shí),表示pi當(dāng)前持有的地址值。當(dāng)我們寫(xiě)下&pi時(shí),表示指針對(duì)象pi被存儲(chǔ)的位置的地址。要想操作指針?biāo)赶驅(qū)ο蟮闹?,我們必須使用解引用操作?*),來(lái)間接的讀和寫(xiě)指針?biāo)赶虻膶?duì)象。例如:已知下列定義:int ival=1024,
8、ival2=2048;int *pi=&ival;下面給出了如何解引用pi以便間接訪問(wèn)ival:*pi=ival2; /解除pi的引用,為它所指向的對(duì)象的ival,賦以ival2的值/對(duì)于右邊的實(shí)例,讀取pi所指對(duì)象的值/對(duì)于左邊的實(shí)例,則把右邊的表達(dá)式賦給對(duì)象*pi=abs(*pi); /ival=abs(ival);*pi=*pi+1; /ival=ival+1;我們知道,當(dāng)取一個(gè)int型對(duì)象的地址時(shí):int *pi=&ival; 結(jié)果是int *即指向int的指針。但我們?nèi)≈赶騣nt型的指針的地址時(shí):int *ppi=π 結(jié)果是int*即指向int指針的指針
9、。當(dāng)我們解引用ppi時(shí):int *pi2=*ppi;這樣,我們就獲得了指針ppi所持有的地址值在本例中,即pi持有的地址值,而pi又是ival的指針。為了實(shí)際訪問(wèn)到ival,我們需要兩次解引用ppi。例如:cout<<"the value of ivaln" <<"direct value:"<<ival<<"n" <<"indirect value:"<<*ppi<<"n" <<"doub
10、ly indirect value:"<<*ppi <<endl;下面兩條賦值語(yǔ)句的行為截然不同,但它們都是合法的。第一條語(yǔ)句增加了pi指向的數(shù)據(jù)對(duì)象的值,而第二條語(yǔ)句增加了pi包含的地址的值。int i,j,k;int *pi=&i;*pi=*pi+2; /i加2(i=i+2)pi=pi+2; /加到pi包含的地址上指針可以讓它的地址值增加或減少一個(gè)整數(shù)值。這類指針操作,被稱為指針的算術(shù)運(yùn)算。這種操作看上去并不樂(lè)觀,我們總認(rèn)為是數(shù)據(jù)對(duì)象的加法,而非離散的十進(jìn)制數(shù)值的加法。指針加2意味著給指針持有的地址值增加了該類型的兩個(gè)對(duì)象的長(zhǎng)度。例如,假設(shè)一個(gè)ch
11、ar是一個(gè)字節(jié),一個(gè)int是4個(gè)字節(jié),double是8個(gè)字節(jié),那么指針加2是給其持有的地址值加2、8還是16,完全取決于指針的類型是char、int還是double。實(shí)際上,只有指針指向數(shù)組元素時(shí),我們才能保證較好的運(yùn)用指針的算術(shù)運(yùn)算。在前面的例子中,我們不能保證三個(gè)整數(shù)變量連續(xù)存儲(chǔ)在內(nèi)存中。因此ip+2可能產(chǎn)生也可能不產(chǎn)生一個(gè)有效的地址,這取決于該位置上實(shí)際存儲(chǔ)的是什么。指針?biāo)阈g(shù)運(yùn)算的典型用法是遍歷一個(gè)數(shù)組,例如:int ia10;int *iter=&ia0;int *iter_end=&ia10;while (iter!=iter_end) do_something_wi
12、th_value(*iter); +iter;指針變量的運(yù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é)合性為自右向左,其功能是取變量的地址。前面介紹指針變量賦值中,我們已經(jīng)了解并使用了&運(yùn)算符。(2)取內(nèi)容運(yùn)算符*取內(nèi)容運(yùn)算符*是單目運(yùn)算符,其結(jié)合性為自右向左,用來(lái)表示指針變量所指的變量。在*運(yùn)算符之后跟的變量必須是指針變量。需要注意的是指針運(yùn)算符*和指針變量說(shuō)明中的指針說(shuō)明符* 不是一回事。在指針變量說(shuō)明中,“*”是類型說(shuō)明符,表示其后的變量是
13、指針類型。而表達(dá)式中出現(xiàn)的“*”則是一個(gè)運(yùn)算符,用以表示指針變量所指的變量。例如:main()int a=5,*p=&a;cout<<*p;.表示指針變量p取得了整型變量a的地址,輸出語(yǔ)句輸出變量a的值。2指針變量的運(yùn)算(1)賦值運(yùn)算指針變量的賦值運(yùn)算有以下幾種形式:指針變量初始化賦值,前面已作介紹。把一個(gè)變量的地址賦予指向相同數(shù)據(jù)類型的指針變量。例如:int a,*pa;pa=&a; /把整型變量a的地址賦予整型指針變量pa把一個(gè)指針變量的值賦予指向相同類型變量的另一個(gè)指針變量。例如:int a,*pa=&a,*pb;pb=p
14、a; /把a(bǔ)的地址賦予指針變量pb由于pa,pb均為指向整型變量的指針變量,因此可以相互賦值。把數(shù)組的首地址賦予指向數(shù)組的指針變量。例如: int a5,*pa;pa=a; /數(shù)組名表示數(shù)組的首地址,故可賦予指向數(shù)組的指針變量pa也可寫(xiě)為:pa=&a0; /數(shù)組第一個(gè)元素的地址也是整個(gè)數(shù)組的首地址,也可賦予pa當(dāng)然也可采取初始化賦值的方法:int a5,*pa=a;把字符串的首地址賦予指向字符類型的指針變量。例如:char *pc; pc="C language"或用初始化賦值的方法寫(xiě)為
15、:char *pc="C Language"這里應(yīng)說(shuō)明的是并不是把整個(gè)字符串裝入指針變量,而是把存放該字符串的字符數(shù)組的首地址裝入指針變量。在后面還將詳細(xì)介紹。把函數(shù)的入口地址賦予指向函數(shù)的指針變量。例如:int (*pf)(); pf=f; /f為函數(shù)名(2)加減算術(shù)運(yùn)算對(duì)于指向數(shù)組的指針變量,可以加上或減去一個(gè)整數(shù)n。設(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ù)
16、組指針變量向前或向后移動(dòng)一個(gè)位置和地址加1或減1 在概念上是不同的。因?yàn)閿?shù)組可以有不同的類型, 各種類型的數(shù)組元素所占的字節(jié)長(zhǎng)度是不同的。如指針變量加1,即向后移動(dòng)1 個(gè)位置表示指針變量指向下一個(gè)數(shù)據(jù)元素的首地址,而不是在原地址基礎(chǔ)上加1。例如:int a5,*pa;pa=a; /pa指向數(shù)組a,也是指向a0pa=pa+2; /pa指向a2,即pa的值為&pa2指針變量的加減運(yùn)算只能對(duì)數(shù)組指針變量進(jìn)行,對(duì)指向其它類型變量的指針變量作加減運(yùn)算是毫無(wú)意義的。(3)兩個(gè)指針變量之間的運(yùn)算只有指向同一數(shù)組的兩個(gè)指針變量之間才能進(jìn)行運(yùn)算
17、,否則運(yùn)算毫無(wú)意義。兩指針變量相減兩指針變量相減所得之差是兩個(gè)指針?biāo)笖?shù)組元素之間相差的元素個(gè)數(shù)。實(shí)際上是兩個(gè)指針值(地址) 相減之差再除以該數(shù)組元素的長(zhǎng)度(字節(jié)數(shù))。例如pf1和pf2 是指向同一浮點(diǎn)數(shù)組的兩個(gè)指針變量,設(shè)pf1的值為2010H,pf2的值為2000H,而浮點(diǎn)數(shù)組每個(gè)元素占4個(gè)字節(jié),所以pf1-pf2的結(jié)果為(2000H-2010H)/4=4,表示pf1和 pf2之間相差4個(gè)元素。兩個(gè)指針變量不能進(jìn)行加法運(yùn)算。例如,pf1+pf2是什么意思呢?毫無(wú)實(shí)際意義。兩指針變量進(jìn)行關(guān)系運(yùn)算指向同一數(shù)組的兩指針變量進(jìn)行關(guān)系運(yùn)算可表示它們所指數(shù)組元素之間的關(guān)系
18、。例如:pf1= =pf2表示pf1和pf2指向同一數(shù)組元素pf1>pf2 表示pf1處于高地址位置pf1<pf2 表示pf1處于低地址位置例3.1 #include <iostream.h>main()int a=10,b=20,s,t,*pa,*pb;pa=&a;pb=&b;s=*pa+*pb;t=*pa*pb;cout<<"a="<<a<<"nb="<<b<<"na+b="<<a+b<<"
19、;na*b="<<a*b<<endl;cout<<"s="<<s<<"nt="<<t<<endl;.程序說(shuō)明如下:說(shuō)明pa,pb為整型指針變量。給指針變量pa賦值,pa指向變量a。給指針變量pb賦值,pb指向變量b。本行的意義是求a+b之和,(*pa就是a,*pb就是b)。本行是求a*b之積。輸出結(jié)果。輸出結(jié)果。.指針變量還可以與0比較。設(shè)p為指針變量,則p= =0表明p是空指針,它不指向任何變量;p!=0表示p不是空指針??罩羔樖怯蓪?duì)指針變量賦予0值而得到的。
20、例如: #define NULL 0int *p=NULL; 對(duì)指針變量賦0值和不賦值是不同的。指針變量未賦值時(shí),可以是任意值,是不能使用的,否則將造成意外錯(cuò)誤。而指針變量賦0值后,則可以使用,只是它不指向具體的變量而已。例3.2#include <iostream.h>main()int a,b,c,*pmax,*pmin;cout<<"input three numbers:"<<endl;cin>>a>>b>>c;if
21、(a>b)pmax=&a;pmin=&b;elsepmax=&b;pmin=&a;if(c>*pmax) pmax=&c;if(c<*pmin) pmin=&c;cout<<"max="<<*pmax<<endl;cout<<"min="<<*pmin<<endl;.程序說(shuō)明如下:說(shuō)明pmax,pmin為整型指針變量。輸入提示。輸入三個(gè)數(shù)字。如果第一個(gè)數(shù)字大于第二個(gè)數(shù)字指針變量賦值指針變量賦值指針變
22、量賦值指針變量賦值判斷并賦值判斷并賦值輸出結(jié)果.指針的應(yīng)用及注意的問(wèn)題1理解指針的關(guān)鍵所在對(duì)指針類型和指針?biāo)赶虻念愋偷睦斫庵羔橆愋停嚎梢园阎羔樏秩サ?,剩下的就是這個(gè)指針,例如:int *a; /指針類型為int *int *a ;/指針類型為int *int *(*a)8; /指針類型為 int *(*)8指針?biāo)赶虻念愋停菏侵妇幾g器將把那一片內(nèi)存所看待成的類型。這里只要把指針聲明語(yǔ)句中的指針名字和名字右邊的“*”號(hào)去掉就可以了,剩下的就是指針?biāo)赶虻念愋汀? 指針的應(yīng)用傳遞參數(shù)實(shí)際上它可以相當(dāng)于隱式的返回值,這比return方法要靈活的多,因?yàn)樗梢苑祷馗嗟闹?,我們看下面的程序:?.
23、3# include <iostream.h>void example(int *a1,int &b1,int c1) *a1*=3; +b1; +c1;void main() int *a; int b,c; *a=6;b=7;c=10; example(a,b,c); cout <<"*a="<<*a<<endl; cout <<"b="<<b<<endl; cout <<"c="<<c<endl;輸出:*a=
24、18b=8c=10我們可以看到,*a和b的值都改變了,而c沒(méi)有變。這是由于a1是指向*a(=6)的指針,也即與a是指向同一個(gè)地址,所以當(dāng)a1指向的值改變了,*a的值也就改變了。在函數(shù)中的參數(shù)使用了引用(int &b1),b1是b的別名,也可以把它當(dāng)作特殊的指針來(lái)理解,所以b的值會(huì)改變。函數(shù)中的參數(shù)int c1只是在函數(shù)中起作用,當(dāng)函數(shù)結(jié)束時(shí)候便消失了,所以在main()中不起作用。3關(guān)于全局變量和局部變量的一個(gè)問(wèn)題我們先看下面的程序:例3.4#include <iostream.h>int a=5;int *example1(int b) a+=b;return &
25、a; int *example2(int b) int c=5;b+=c;return &b;void main()int *a1=example1(10);int *b1=example2(10);cout <<"a1="<<*a1<<endl;cout <<"b1="<<*b1<endl;輸出結(jié)果:a1=15 b1=4135*b1怎么會(huì)是4135,而不是15呢?是程序的問(wèn)題?沒(méi)錯(cuò)吧? 由于a是全局變量,存放在全局變量的內(nèi)存區(qū),它一直是存在的;而局部變量則是存在于函數(shù)的棧區(qū),當(dāng)函數(shù)example2()調(diào)用結(jié)束后便消失,是b指向了一個(gè)不確定的區(qū)域,產(chǎn)生指針懸掛。下面是對(duì)example1()和example2()的反匯編(用TC+ 3.0編譯): 例3.5example1():push bp; /入棧 mov bp,sp; mov ax,bp+04; /傳遞參數(shù)add 00AA,ax; /相加 mov ax,00AA ; /返回了結(jié)果所在的地址pop bp; /恢復(fù)棧,出棧ret; /退出函數(shù)example2():push bp; /入棧 mov bp,sp;sub sp,02; mov word ptr bp-02,0005;mov
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年度年福建省高校教師資格證之高等教育法規(guī)基礎(chǔ)試題庫(kù)和答案要點(diǎn)
- 疫情之下企業(yè)直播告訴發(fā)展遇新機(jī)遇
- 航空模型基礎(chǔ)理論知識(shí)單選題100道及答案解析
- 2024年個(gè)人用工保證協(xié)議參考格式
- 社區(qū)教育志愿者隊(duì)伍建設(shè)研究
- 寫(xiě)給愛(ài)心捐款的感謝信
- 2024年吊車租賃協(xié)議樣本2
- 2024年石灰石批發(fā)銷售協(xié)議范例
- 2024年權(quán)益過(guò)戶協(xié)議模板
- 2024年度商用空調(diào)安裝協(xié)議范本
- GB/T 44352-2024燃油蒸發(fā)排放系統(tǒng)用活性炭通用要求
- 2024山東濟(jì)南軌道交通集團(tuán)限公司招聘49人高頻難、易錯(cuò)點(diǎn)500題模擬試題附帶答案詳解
- 市政道路交通疏導(dǎo)方案施工方案
- “數(shù)字三品”應(yīng)用場(chǎng)景典型案例申報(bào)書(shū)
- 2024秋三年級(jí)語(yǔ)文上冊(cè)第二次月考達(dá)標(biāo)檢測(cè)卷第三四單元新人教版
- 2024年下半年遼寧事業(yè)單位高頻500題難、易錯(cuò)點(diǎn)模擬試題附帶答案詳解
- 中醫(yī)人工智能
- 人教版(2024)八年級(jí)上冊(cè)物理第3章《物態(tài)變化》單元測(cè)試卷(含答案解析)
- 金屬冶煉(鉛、鋅冶煉)主要負(fù)責(zé)人安全資格考試題庫(kù)及答案
- 2024中國(guó)鐵路集團(tuán)全國(guó)招聘高頻考題難、易錯(cuò)點(diǎn)模擬試題(共500題)附帶答案詳解
- (全冊(cè)各類齊全)二年級(jí)數(shù)學(xué)上冊(cè)100道口算題大全54份(100題)
評(píng)論
0/150
提交評(píng)論