《C語言程序設計d》課件-第六講 指針_第1頁
《C語言程序設計d》課件-第六講 指針_第2頁
《C語言程序設計d》課件-第六講 指針_第3頁
《C語言程序設計d》課件-第六講 指針_第4頁
《C語言程序設計d》課件-第六講 指針_第5頁
已閱讀5頁,還剩45頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

西安電子科技大學計算機學院1目前的知識不能解決的問題動態存儲管理函數通過return語句返回多個數據一些復雜數據結構的實現鏈表樹圖西安電子科技大學計算機學院2地址與指針程序執行原理圖...加載器外存CPU操作系統內存程序數據數據對象在生存期間都有存儲位置,占據一定數量的存儲單元存儲位置就是內存地址存儲單元的內容就是數據對象的值西安電子科技大學計算機學院3地址與指針如果把地址值也當作一種數據,存儲地址值的變量就是指針變量,簡稱指針變量p的值(0x2000)變量x的值(5)指針變量p(地址0x1000)整數變量x(地址0x2000)內存...intx=5;int*p=&x;西安電子科技大學計算機學院4指針就是內存地址指針沒有類型,但指針指向的對象具有類型[注]無論指針變量指向什么類型的變量,指針自身只占據4個字節(32位系統)的內存單元地址與指針注:通常會把指針指向的對象的類型稱為指針的類型西安電子科技大學計算機學院5地址與指針指針的相關操作指針賦值:將程序對象的地址存入指針變量間接訪問:通過指針變量存儲的地址訪問該地址對應的對象西安電子科技大學計算機學院6主要內容10.1指針變量的定義和使用10.2指針的相關問題10.3指針作為函數參數10.4指針與數組10.5指針數組西安電子科技大學計算機學院710.1指針變量的定義和使用西安電子科技大學計算機學院8定義指針變量語法:目標數據對象類型:指針指向的數據對象的類型,用于確定指針指向的對象占據多少存儲單元指針變量名稱:任何合法標識符表示定義的是指針變量int*p,*q,n;//p和q是指針變量,n是普通整型變量char*s,ch;//s是指針變量,ch是普通字符變量目標數據對象類型*

指針變量名稱;西安電子科技大學計算機學院9指針變量賦值將程序對象的地址存入指針變量,通過取地址運算符(&)可取得程序對象的地址int*p,*q,n=10;p=&n;q=p;???p10n(&n為0x12F0)???q0x12F0p10n???qp0x12F010n0x12F0q西安電子科技大學計算機學院10指針變量賦值int*p,a[10];p=&a[1];???pa[0]a[1]a[9]…&優先級和其他一元運算符相同,從右向左結合pa[0]a[1]a[9]…間接訪問(pointer1.c)訪問指針指向的對象獲取指針所指向對象的值訪問方法:*指針變量優先級和其他一元運算符相同,從右向左結合間接訪問(pointer1.c)int*p,*q,n=10,m,a[10];p=&n;q=p;m=*p+*q*n;++*p;(*p)++;*p+=*q+n;q=&a[0];*q=*p/12;p10nqm=n+n*n=110;//m=110++n;

//n=11n++;

//n=12n+=n+n;

//n=36a[0]=n/12;

//a[0]=3a[0]a[1]a[9]…m西安電子科技大學計算機學院13間接訪問間接訪問的過程(pointer2.c)step1.通過指針的值(地址)找到對應的內存單元step2.通過指針的類型確定數據占據多少內存單元step3.將找到的內存單元內存儲的數據按照指針的類型轉換為相應數據int*p,n=0x00000130;char*q;p=&n;q=p;printf("%d%c",*p,*q);//???30010000npq西安電子科技大學計算機學院1410.2指針的相關問題西安電子科技大學計算機學院15野指針指針在未初始化時指向哪里不確定,不能用*間接引用指針指向的對象,這樣的指針稱為野指針int*p;*p=2;printf("%d",*p);編譯時警告p未初始化,執行時出錯西安電子科技大學計算機學院16另一種類型的野指針intn=10,*p=&n;假設n存儲在地址為0x1000的內存單元p0x100010np0x100017n*p=17;p=17;p1717n地址為17的存儲單元???西安電子科技大學計算機學院17空指針(NULL)定義指針變量時如果暫時不知道要指向哪里,應該先給指針變量賦予空指針NULL(數值0),表示哪里也不指向當指針變量被賦予空指針,不能用*間接引用指針指向的對象int*q=NULL;*q=2;printf(“%d”,*q);編譯器不會警告,執行時出錯西安電子科技大學計算機學院18通用指針與指針類型轉換(pointer3.c)通用指針指向的對象類型不確定,此時用void作為指針的類型可以把任何類型的指針賦值給通用類型指針通用類型指針不能夠用*運算符間接引用被指對象。void*gp;intn=10,*p=&n;floatf=2.5;void*gp1=p,*gp2=&f;intn=10;floatf=2.5;void*gp1=&n,*gp2=&f;printf("%d%f",*gp1,*gp2);//編譯錯誤西安電子科技大學計算機學院19通用指針與指針類型轉換為了訪問通用指針指向的對象需要進行指針類型轉換轉換方法:(類型*)通用指針intn=10,*p1;floatf=2.5,*p2;void*gp1=&n,*gp2=&f;p1=(int*)gp1;p2=(float*)gp2;printf("%d%f",*p1,*p2);//正確西安電子科技大學計算機學院20通用指針與指針類型轉換為了訪問通用指針指向的對象需要進行指針類型轉換轉換方法:(類型*)通用指針intn=10,*p1;floatf=2.5,*p2;void*gp1=&n,*gp2=&f;p1=(int*)gp2;p2=(float*)gp1;printf("%d%f",*p1,*p2);//運行結果不正確一個通用指針可以轉換為任何類型的指針,但是否具有正確的意義,取決于該指針實際指向的數據類型西安電子科技大學計算機學院2110.3指針作為函數參數西安電子科技大學計算機學院22函數調用時實參按值傳遞voidswap(intx,inty){intt;

}intmain(){inta=5,b=3;

printf("a=%d;b=%d\n",a,b);swap(a,b);printf("a=%d;b=%d\n",a,b);return0;}swap函數數據區53xymain函數數據區53abswap函數數據區main函數數據區53ab35xy

t=x;x=y;y=t;執行前執行后西安電子科技大學計算機學院23如果參數傳遞的值是變量地址voidswap(int*x,int*y){intt;

}intmain(){inta=5,b=3;

printf("a=%d;b=%d\n",a,b);

swap(&a,&b);printf("a=%d;b=%d\n",a,b);return0;}

t=*x;*x=*y;*y=t;執行前執行后swap函數數據區xymain函數數據區53abswap函數數據區main函數數據區35abxy西安電子科技大學計算機學院24指針作為函數參數示例用一個函數實現兩個整數除法,要求返回整除的商和余數用return語句不能返回兩個值用參數返回值,參數必須是指針形式voiddivision(intx,inty,

int*qp,int*rp){

*qp=x/y;*rp=x%y;}intmain(){intq,r;

division(40,3,&q,&r);

printf(“40/3yield");printf("quotient=%d",q);printf("remainder=%d\n",r);return0;}西安電子科技大學計算機學院25指針作為函數參數的常見錯誤voidswap(int*x,int*y){intt;t=*x;*x=*y;*y=t;}intmain(){intp,n;scanf(“%d”,n);scanf(“%d”,p);swap(p,&n);return0;}n和p的值會被當作地址傳入函數,但由于n和p的值不確定,因此函數調用可能出錯,即使不出錯,輸入的值也不會保存在n和p中西安電子科技大學計算機學院2610.4指針與數組西安電子科技大學計算機學院27數組在內存中的實現數組名是一個內存地址,稱為數組首地址數組元素從首地址開始連續存放訪問數組元素的方法:數組名[下標]inta[4];????0x10000x10040x10080x100C地址數組元素通過數組名和下標引用數組元素的本質是:&a[i]=a

+i×sizeof(a[0])既然數組名是內存地址,就可以用一個指針變量來表示28指向數組元素的指針數組元素是一個普通變量,具有唯一地址與數組同類型的指針變量可以指向數組的任一元素int*p1,*p2,*p3,*p4;inta[10]={0,1,2,3,4,5,6,7,8,9};p1=&a[0];p2=p1;p3=&a[5];p4=&a[10];0a[0]159……?a[1]a[5]a[9]a[10]p1p2p3p4等價于p1=a;29指針運算1.指針和數值n(變量、常量)的加減法前提:指針變量指向數組中的某個元素意義:表示將指針向前或向后移動n個元素inta[10]={0,1,2,3,4,5,6,7,8,9};int*p1=a,*p2;p1+=2;*p1=5;*(p1+6)=0;p2=p1+3;p2--;p1指向a[2]給a[2]賦值給a[8]賦值p2指向a[5]p2指向a[4]p1指向a[0]指針不指向數組時沒有任何意義30指針運算2.兩個指針變量相減前提:兩個指針變量指向同一個數組意義:得到兩個指針之間的元素個數inta[10]={0,1,2,3,4,5,6,7,8,9};int*p1=a,*p2;intn;p2=&a[5];n=p2-p1;p1++;n=p1-p2;p2指向a[5]n=5兩個指針變量相加沒有任何意義n=-4p1指向a[1]p1指向a[0]31指針運算3.兩個指針變量比較大小前提:兩個指針變量指向同一個數組意義:得到兩個指針之間的位置關系inta[10];int*p1=a,*p2=&a[10];inti=0;while(p1<p2

){

*p1=i;p1++;i++;}兩個指針變量不在同一數組,比較沒有任何意義p1指向a[0],p2指向a[10]通過指針p1依次給a的每個元素賦值i,循環結束條件是p1指向最后一個元素之后32指針運算4.對指針變量使用下標前提:指針變量指向數組意義:得到對應數組元素inta[10];int*p1=a;inti=0;for(i=0;i<10;i++){

p1[i]=i;}指針變量不指向數組時沒有任何意義p1指向a[0]通過指針p1依次給a的每個元素賦值i,循環結束條件是i不超出數組元素個數p1[i]=p1

+i×sizeof(a[0])西安電子科技大學計算機學院33訪問數組元素的幾種模式inta[10];inti;for(i=0;i<10;i++){

a[i]=i;}inta[10];int*p1,*p2;for(p1=a,p2=a+10;p1<p2;p1++){

*p1=i;}inta[10];int*p1,*p2;for(p1=a,p2=a;p1-p2<10;p1++){

*p1=i;}inta[10];int*p1;for(p1=a;p1<a+10;p1++){

*p1=i;}西安電子科技大學計算機學院34取值運算符(*)和遞增運算符(++)混合使用*和++優先級相同*和++都是右結合++有前綴和后綴兩種形式前綴方式先自增再取值參與運算后綴方式先取值參與運算再自增取值運算符(*)和遞增運算符(++)混合使用西安電子科技大學計算機學院35inta[10]={0,1,2,3,4,5,6,7,8,9},*p=a,n;n=*p++;n=*++p;++*p;n=*p;p++;++p;n=*p;a[2]++;n=a[0]p指向a[1]p指向a[2]n=a[2]36數組參數與指針數組作為函數形式參數時,實際是以指針的形式實現doubleaverage(

doublea[],intn){doublesum=0.0;inti;for(i=0;i<n;i++)sum+=a[i];returnsum/n;}doubleaverage(

double*a,intn){doublesum=0.0;inti;for(i=0;i<n;i++)sum+=a[i];returnsum/n;}intmain(){intb[20]={…}

average(b,20);return0;}傳遞的是數組首地址只對b[5]-b[10]求平均值如何處理??西安電子科技大學計算機學院37數組參數與指針doubleaverage(

doublea[],intn){doublesum=0.0;inti;for(i=0;i<n;i++)sum+=a[i];returnsum/n;}doubleaverage(

double*a,intn){doublesum=0.0;inti;for(i=0;i<n;i++)sum+=a[i];returnsum/n;}intmain(){intb[20]={…}

average(b+5,5);return0;}傳遞的是元素b[5]的地址西安電子科技大學計算機學院38示例1:用指針實現求字符串長度的函數intstrlen(char*s

){intn=0;while(*s!='\0'){++s;++n;}returnn;}intstrlen(char*s){char*p=s;while(*p!='\0')++p;returnp-s;}intmain(){chars1[]="hello,world!",*ps=s1;intlen;len=strlen(s1);len=strlen(ps);len=strlen("clanguage");return0;}調用以字符指針為形式參數的函數,實參可以是字符串常量字符數組(其中應存著字符串)指向字符串的指針西安電子科技大學計算機學院39示例2:用指針實現復制字符串的函數voidstrcpy(char*s,constchar*t){while((*s=*t)!='\0'

){s++;t++;}}voidstrcpy(char*s,constchar*t){while(*s=*t){s++;t++;}}voidstrcpy(char*s,constchar*t){while(*s++=*t++);}注意:運算符的優先級與結合順序增量運算的作用與計算出的值賦值表達式的值西安電子科技大學計算機學院4010.5指針數組假設一個班有100人,每個人的姓名不超過20個字符,如何表示所有人的姓名?方法1:二維數組charnames[100][20];每個人的名字長度限定為不超過20個字符方法2:一維指針數組char*names[100]每個人的名字長度不固定…………names[0]names[1]names[99]20個連續字符names[0]names[1]names[99]…LimingLiuxiaodongWangpeng西安電子科技大學計算機學院42二維數組與一維指針數組的區別二維數組的所有元素在內存中連續存放,要求一塊較大的連續內存(行數×列數)一維指針數組各個元素(指針)連續存放,但元素(指針)指向的內存區地址并不連續,只需要一塊能連續存放元素(指針)的內存(行數)西安電子科技大學計算機學院43二維數組與一維指針數組的區別//以下為程序片段charnames1[100][20]={"Liming","Liuxiaodong",…};char*names2[100]={"Liming","Zhangxitong",…};inti=0;for(i=0;i<5;i++)printf("addressofnames1[

溫馨提示

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

評論

0/150

提交評論