地址和指針課件_第1頁
地址和指針課件_第2頁
地址和指針課件_第3頁
地址和指針課件_第4頁
地址和指針課件_第5頁
已閱讀5頁,還剩33頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

地址和指針

7.1地址和指針的概念7.1.1地址和指針的概念1.“地址”的概念2.存儲單元“地址”的表示3.“指針”的概念7.1.2為什么使用指針 使用指針,實現(xiàn)了“間接訪問”變量,這只是一個過程,其實質(zhì)是可以達(dá)到方便地引用數(shù)組,提高計算機(jī)的運行效率,調(diào)用函數(shù)時可以修改或返回多個參數(shù)值,還可以描述更復(fù)雜的數(shù)據(jù)結(jié)構(gòu),……為了加深讀者對指針重要性的理解,下面我們舉一函數(shù)調(diào)用的實例。例7.1欲想調(diào)用fun函數(shù),計算出兩個數(shù)相加和相減的值,然后在main函數(shù)中顯示結(jié)果。程序如下:fun(intx,inty){intadd=0,sub=0;add=x+y;sub=x–y;}main(){inta,b,add=0,sub=0;scanf("%d%d",&a,&b);printf("a=%d,b=%d\n",a,b);fun(a,b);printf("%d+%d=%d\n",a,b,add);printf("%d–%d=%d\n",a,b,sub);}假設(shè)程序運行時給變量a輸入8,給變量b輸入5,程序運行結(jié)果:a=8,b=58+5=08–5=0 程序運行結(jié)果與我們“想象”的不一致,為什么呢?其原因是fun函數(shù)中變量add和sub與main函數(shù)中變量add和sub各自占用自己的存儲單元,因此fun函數(shù)中變量add存放的兩個數(shù)的求和值無法傳回到main函數(shù)的變量add中,同理,fun函數(shù)中變量sub存放的兩個數(shù)的相減值也無法傳回到main函數(shù)的變量中。下面我們修改一下源程序,借助指針,將fun函數(shù)中運行的結(jié)果傳回到main函數(shù)中。7.2指針變量的定義和指針變量的基類型7.2.1指針變量的定義和指針變量的基類型 定義指針變量的一般形式如下:類型名*指針變量名1,*指針變量名2,……;例如:int*pi,*pj;以上定義語句中,pi和pj都是用戶標(biāo)識符,表示具體的變量名,現(xiàn)在每個變量名前加一星號“*”說明符,用來說明所定義的變量是指針變量。注意:變量名前的星號“*”不可省略,若省略了星號“*”說明符,就變成了普通整型變量。int是數(shù)據(jù)類型名,在這里,說明了pi和pj是兩個指向整型(int類型)變量的指針,也就是說變量pi和pj中只能存放int類型變量的地址,這時我們稱int是指針變量pi和pj的基類型。又如:double*pd;char*s1,*s2;在這里定義了三個指針變量pd、s1和s2,其中指針變量pd的基類型為double類型,在指針變量pd中,只能存放double類型變量的地址,指針變量s1和s2的基類型為char類型,在指針變量s1和s2中只能存放char類型變量的地址。又如:int**p;以上是定義了一個指向指針的指針變量p,該指針變量p只能存放基類型為int類型的指針變量的地址。又如:int*pi,**p,k;以上語句是在同一語句中,同時定義了指針變量pi、指向指針的指針變量p和變量k,這是允許的。7.2.2指針變量的基類型的作用 任何一個指針變量都是用于存放它所指向變量的地址,只要能存放地址就可以了,為何還要區(qū)別不同的基類型呢? 其原理是:不同的數(shù)據(jù)類型變量,C語言系統(tǒng)為它們開辟的存儲空間的字節(jié)數(shù)是不同的,int類型的數(shù)據(jù)存儲空間是2個字節(jié),float類型的數(shù)據(jù)存儲空間是4個字節(jié),……,系統(tǒng)表示每一個存儲空間的地址時,是取該存儲空間的第1個字節(jié)的地址作為該變量存儲空間的地址。那么當(dāng)一個基類型為int類型的指針變量p指向了一個int類型的變量a時,是將該變量a所占的2個字節(jié)的存儲空間中的第1個字節(jié)存儲空間的“地址”存入指針變量p中,如圖7-2(b)所示。圖7-2指針和指針?biāo)赶虻膶ο笏愿鶕?jù)指針變量p中存放的“地址”,只能尋找到變量a第1個字節(jié)的存儲空間,如果只提取變量a所占存儲空間第1個字節(jié)的數(shù)據(jù),顯而易見不是int類型變量a的原值,因為變量a的原值是通過2個字節(jié)來存儲的數(shù)據(jù)。此時我們可以通過指針變量p的基類型解決問題,知道了變量a的第1個字節(jié)的地址,再根據(jù)指針變量p的基類型為int類型,系統(tǒng)就將從變量a的第1個字節(jié)所在的地址開始,連續(xù)提取2個字節(jié)中的數(shù)據(jù),此時的數(shù)據(jù)就是int類型變量a的原值。同理,基類型為float類型的指針變量,根據(jù)指針變量中存放float類型變量的地址值,可以尋找到所需存儲空間中的第1個字節(jié)所在位置,然后再根據(jù)基類型為float類型,連續(xù)地提取4個字節(jié)中的數(shù)據(jù),作為被訪問的數(shù)據(jù),這才是float類型變量中存放的真實數(shù)據(jù)。由此,我們可以看到指針變量在定義時,其基類型是何等的重要。因此,定義什么樣的基類型指針變量,該指針變量只能存放什么樣類型變量的地址,兩者必須一致,否則就可能出現(xiàn)了張冠李戴的錯誤現(xiàn)象。7.3給指針變量賦值7.3.1使指針指向一個對象1.通過求地址運算符(&)把一個變量的地址賦給指針變量 “&”是求地址運算符,該運算符為單目運算符,用于求變量的地址,且該變量必須為內(nèi)存變量。例如:intk=1,j=2,*q1,*q2,*p;floatx=4.5;q1=&k;q2=&j;以上第三條語句,是把變量k的地址賦給了指針變量q1,使指針變量q1中存放了變量k的地址,或稱指針變量q1指向了變量k。同理,以上第四條語句,是把變量j的地址賦給了指針變量q2,使指針變量q2中存放了變量j的地址,或稱指針變量q2指向了變量j。注意:在使用&運算符求變量的地址,并賦給指針變量時,一定要確保所求地址的變量數(shù)據(jù)類型與存放該變量地址的指針變量基類型一致。接上例,如執(zhí)行p=&x;語句,則是絕對錯誤的。為什么?請讀者想一想!讀者還記得在前面調(diào)用scanf函數(shù)時,其函數(shù)調(diào)用格式中,輸入數(shù)據(jù)所對應(yīng)的各變量名之前都必須加運算符&,這就是我們所說的求地址運算符。scanf函數(shù)把從終端讀入的數(shù)據(jù)依次放入這些地址所代表的存儲單元中,也就是說scanf函數(shù)要求輸入項是地址值。因此接上例,scanf("%d%d",&k,&j);語句和scanf("%d%d",q1,q2);語句是等價的,都是將終端輸入的整型數(shù)據(jù)存入到變量k和變量j所在的存儲單元中。2.同類型指針變量之間可以直接賦值 可以把指針變量的值賦給指針變量,但一定要確保這兩個指針變量的基類型是相同的。 接上例:p=q1; 執(zhí)行以上語句后,使指針變量p也存放了變量k的地址,也就是說指針變量p和q1同時指向了變量k。7.3.2給指針變量賦“空”值 為了使指針變量有一確定的數(shù)值,除了給指針變量賦一地址值外,當(dāng)指針變量沒有指向的對象時,也可以給指針變量賦NULL值,此值為空值。例如:int*p;p=NULL;表示指針變量p的值為空。NULL是在stdio.h頭文件中定義的預(yù)定義符,因此在使用NULL時,應(yīng)該在程序的前面出現(xiàn)預(yù)定義命令行:#include"stdio.h"。NULL的代碼值為0,所以語句p=NULL;等價于:p=0;,都是表示指針變量p是一個空指針,沒有指向任何對象。7.4對指針變量的操作7.4.1通過指針或地址引用一個存儲單元 當(dāng)指針變量中存放了一個確切的地址值時,通過指針可以用“間接運算符”(*)來引用該地址所代表的存儲單元。1.在賦值號右邊由“*”運算符和指針變量組成的表達(dá)式,代表指針?biāo)复鎯卧膬?nèi)容 例如:int*p,i=10,j; p=&i; j=*p;第二條語句是把變量i的地址賦給了指針變量p,第三條語句是把指針變量p所指向的變量i存儲單元的值10賦給變量j?!?”號在這里是一個“間接運算符”,它為單目運算符,與運算對象自右至左結(jié)合,且運算對象必須為一個地址對象。例如:j=*&i;該語句中“&”運算符求出變量i的地址,“*”運算符取變量i地址中的值10賦給變量j。例如:int**pp,*p,k=20,j;p=&k;pp=&p;j=**pp;以上語句執(zhí)行后的結(jié)果是:把變量k的地址賦給了指針變量p,把指針變量p的地址賦給了指向指針的指針變量pp,這種關(guān)系如圖7-4所示。最后一條語句是把變量k中的值20賦給了變量j,這條語句使用了兩個“間接運算符”,**p表示獲取指針變量p中的值(此值為變量k的地址值),**pp表示通過指針變量p,再獲取變量k中的值20。圖7-4變量pp、p和k之間的關(guān)系2.在賦值號左邊由“*”和指針變量組成的表達(dá)式,代表指針?biāo)傅拇鎯卧?例如:int*p,k=0; p=&k; *p=150; 以上第三條語句是把整數(shù)150存入變量k中。 *p=*p+1;或*p+=1;以上語句是獲取指針變量p所指向的存儲單元k中的值150,然后加1再放入指針變量p所指向的存儲單元k中,此時變量k中存放的數(shù)值為151。例如:int**p,*p,k;p=&k;pp=&p;**pp=200;以上第四條語句是將整數(shù)200存入變量k中。例7.3指針指向三個變量,通過指針運算選出數(shù)值最小的那個數(shù)并打印出來。main(){inta,b,c,min,*pa,*pb,*pc,*pmin;pa=&a;pb=&b;pc=&c;pmin=&min;scanf("%d%d%d",pa,pb,pc);/*將鍵盤輸入的三個整數(shù)依次放入變量a、b、c中*/

printf("a=%d,b=%d,c=%d\n",a,b,c);*pmin=*pa;/*假定變量a中的數(shù)值最小,將其放入變量min*/if(*pmin>*pb)*pmin=*pb;/*若b中的數(shù)值比min小,將其放入變量min*/if(*pmin>*pc)*pmin=*pc;/*若c中的數(shù)值比min小,將其放入變量min*/printf("min=%d\n",min);/*通過直接訪問方式輸出變量min中的值*/

printf("min=%d\n",*pmin);/*通過間接訪問方式輸出變量min中的值*/}當(dāng)運行程序時輸入251236↙程序運行結(jié)果:a=25,b=12,c=36min=12min=12程序運行結(jié)果說明,當(dāng)指針指向變量后,可以通過指針對所指向的存儲單元進(jìn)行數(shù)據(jù)的存取,直接訪問方式和間接訪問方式的結(jié)果是相同的。7.4.2指針(變量)的運算1.指針的移動2.指針的比較7.5指針在函數(shù)方面的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論