版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
高級語言程序設(shè)計主講教師:丁丁計算機與信息技術(shù)學(xué)院dding@2023/2/4高級語言程序設(shè)計2主要內(nèi)容:指針7.1地址與指針7.2指針變量的定義和使用7.3指針與數(shù)組7.4指針數(shù)組7.5多維數(shù)組作為參數(shù)的通用函數(shù)7.6動態(tài)存儲管理7.7定義類型7.8指向函數(shù)的指針3要點回顧如何定義一個指針變量?指針變量在使用時為什么一定要指定指向的數(shù)據(jù)類型?指針變量在使用時為什么一定要初始化?未經(jīng)初始化的指針變量稱為?指針變量上的兩種主要操作是什么?變量的兩種訪問方式是什么?指針變量做函數(shù)參數(shù)時傳遞的是什么?通過使用指針變量做為函數(shù)參數(shù)可以返回多于一返回值改變函數(shù)調(diào)用時的環(huán)境變量空指針有什么用?2023/2/4高級語言程序設(shè)計4主要內(nèi)容:指針7.1地址與指針7.2指針變量的定義和使用7.3指針與數(shù)組7.4指針數(shù)組7.5多維數(shù)組作為參數(shù)的通用函數(shù)7.6動態(tài)存儲管理7.7定義類型7.8指向函數(shù)的指針指針(數(shù)值型/字符型)與一維數(shù)組(數(shù)值型數(shù)組/字符串)的關(guān)系5C指針與數(shù)組關(guān)系密切,以指針為媒介可以完成各種數(shù)組操作用指針做數(shù)組操作同樣要特別注意越界錯誤。指針和數(shù)組的關(guān)系是C語言特有的,除了由C派生出的語言(如C++),一般語言中沒有這種關(guān)系。如何利用指針訪問數(shù)組。6int*p1,*p2,*p3,*p4;inta[10]={1,2,3,4,5,6,7,8,9,10};
1指向數(shù)組元素的指針可以寫:p1=&a[0];p2=p1;p3=&a[5];p4=&a[10];
這個地址存在,但寫*p4是錯誤的。P4沒有指向合法元素p1=&a[0];可簡寫為:p1=a;數(shù)組名是表示數(shù)組首地址的地址常量區(qū)別?7當(dāng)指針p指向數(shù)組元素時說p指到了數(shù)組里。這時由p可以訪問被p指的元素,還可訪問數(shù)組的其他元素。例:p1=&a[0],則p1+1合法,為a[1]的地址
p1+2、p1+3、…也合法,分別為a[2]、a[3]的地址使用:*(p1+2)=3;/*給a[2]賦值*/ p2=p1+5;/*使p2指向a[5]*/*(p2+2)=5;/*給a[7]賦值*/*(p2-2)=4;/*給a[3]賦值*/p2=p2-2;/*這使p2改指向a[3]*/通過指針訪問數(shù)組元素時必須保證不越界。
2指針運算8指針運算原理一個指針指向某數(shù)組里的元素時,為什么能算出下一元素位置?(這是指針運算的基礎(chǔ))指針有指向類型,p指向數(shù)組a時,由于p的指向類型與a的元素類型一致,數(shù)據(jù)對象的大小可以確定。p+1的值可根據(jù)p的值和數(shù)組元素大小算出。由一個數(shù)組元素位置可以算出下一元素位置,或幾個元素之后的元素位置。指針運算的基礎(chǔ)。通用指針即使指到數(shù)組里,因沒有確定指向類型,因此不能做一般指針計算,只能做指針比較。9可進行增/減量操作(指針應(yīng)指在數(shù)組里):
p3=p2;++p3;--p2;p3+=2;如果兩指針指在同一個數(shù)組里,可以求差,得到它們間的數(shù)組元素個數(shù)(帶符號整數(shù))。
n=p3–p2;/*也可以求p2–p3*/在同一個數(shù)組里的指針可以比較大小:
if(p3>p2)....當(dāng)p3所指的元素在p2所指的元素之后時條件成立(值為1),否則不成立(值為0)。兩個指針不指在同一數(shù)組里時,比較大小沒有意義。3其他常用指針運算10兩個同類型指針可用==和!=比較相等或不等;任何指針都能與通用指針比較相等或不等;任何指針可與空指針值(0或NULL)比較相等或不等兩指針指向同一數(shù)據(jù)元素,或同為空值時它們相等。11當(dāng)一個指針指向數(shù)組時的數(shù)組寫法與指針寫法:指針的兩種用法設(shè)p1=&a[0],p3=&a[5]p1和p3相當(dāng)于數(shù)組名
可寫:p1[3]=5;相當(dāng)于*(p1+3)=5;或a[3]=5;
p3[2]=8;相當(dāng)于*(p3+2)=8;或a[7]=8;
p1[3]稱為數(shù)組寫法,*(p1+3)稱為指針寫法兩類寫法有等價效力,可以自由選用。12a[0]a[1]a[2]a[3]a[9]...aa+9a+1a+2地址元素下標(biāo)法a[0]a[1]a[2]a[9]a[0]a[1]a[2]a[3]a[9]...pp+9p+1p+2地址元素指針法*p*(p+1)*(p+2)*(p+9)[]變址運算符a[i]
*(a+i)a[i]p[i]
*(p+i)*(a+i)*a*(a+1)*(a+2)*(a+9)p[0]p[1]p[2]p[9]13對數(shù)組名求值得到指向數(shù)組首元素的指針值數(shù)組名可以“看作”常量指針,可參與一些指針運算,與其他指針比大小,比較相等與不相等。通過數(shù)組名的元素訪問也可以采用指針寫法。
a[3]可寫為*(a+3)。注意:數(shù)組名不是指針變量,特別是不能賦值,不能更改。若a為數(shù)組,下面操作都是錯誤的:
a++; a+=3; a=p;有些運算雖不賦值但也可能沒意義。如a–3不可能得到合法指針值,因其結(jié)果超出數(shù)組界限14a[0]a[1]a[2]a[3]a[4]intmain(){inta[5],*pa,i;for(i=0;i<5;i++) a[i]=i+1;pa=a;for(i=0;i<5;i++) printf("*(pa+%d):%d\n",i,*(pa+i));
//通過指針找地址法
for(i=0;i<5;i++) printf("*(a+%d):%d\n",i,*(a+i));
//通過指針找地址法
for(i=0;i<5;i++) printf("pa[%d]:%d\n",i,pa[i]);
//下標(biāo)法
for(i=0;i<5;i++) printf("a[%d]:%d\n",i,a[i]); //下標(biāo)法
return0;}12345pa例數(shù)組元素的引用方法(1)15//指針法intmain(){ inta[10]; int*p,i; for(i=0;i<10;i++) scanf(“%d”,&a[i]); printf(“\n”); for(p=a;p<a+10;p++) printf(“%d,”,*p); return0;}例數(shù)組元素的引用方法(2)三種方法的比較:下標(biāo)法和地址法的執(zhí)行效率相同,都是先計算數(shù)組元素的地址,再訪問數(shù)組元素的值,費時。指針法利用指針變量直接訪問數(shù)組元素的值,不必計算數(shù)組元素的地址,執(zhí)行效率高。下標(biāo)法直觀,指針法與地址法不夠直觀。16基于指針的數(shù)組程序設(shè)計指針運算是處理數(shù)組元素的一種有效方式。設(shè)有int數(shù)組a和指針p1,p2,下面代碼都打印a的元素:for(p1=a;p1<a+10;++p1)
printf("%d\n",*p1);for(p1=a;p1-a<10;++p1) printf("%d\n",*p1);for(p1=a,p2=a+10;p1<p2;++p1)printf("%d\n",*p1);for(p1=p2=a;p1-p2<10;++p1)printf("%d\n",*p1);17數(shù)組參數(shù)的意義C規(guī)定,數(shù)組參數(shù)就是相應(yīng)類型的指針參數(shù):
intf(intn,intd[]){......}和intf(intn,int*d){......}
意義相同。數(shù)組參數(shù)就是利用指針實現(xiàn)的!這也使采用數(shù)組參數(shù)的函數(shù)能修改實參數(shù)組。18函數(shù)里也可用指針方式做元素訪問。intintsum(intn,inta[]){inti,m=0;for(i=0;i<n;++i)m+=*(a+i);returnm;}函數(shù)里不能用sizeof確定數(shù)組實參大?。汉瘮?shù)的數(shù)組形參實際是指針,求sizeof算出的是指針的大小。另一方面,sizeof的計算是在編譯中完成的。實參是動態(tài)運行中確定的東西。m+=a[i];intintsum(intn,int*a){inti,m=0;for(i=0;i<n;++i)m+=*(a+i);returnm;}19使用數(shù)組的一段元素以數(shù)組為參數(shù)的函數(shù)可處理一段元素。求元素和:doublesum(intn,doublea[]);設(shè)有雙精度數(shù)組b,40個元素已有值:用sum可求b所有元素之和/前一段元素之和:
x=sum(40,b); y=sum(20,b);sum不知道b的大小,它由參數(shù)得到數(shù)組首元素地址,從這里開始求連續(xù)40或20個元素的和。也可用sum求b中下標(biāo)12到24的一段元素之和。
z=sum(13,b+12);
20例1下面的程序的輸出結(jié)果是什么?#include<stdio.h>inta[]={2,4,7,8,9};intmain(){inti,*p=a;for(i=0;i<4;i++)a[i]=*(++p);printf("%d\n",a[2]);return0;}運行結(jié)果為:821例2inta[]={1,2,3,4,5,6,7,8,9,10},*p=a,i;
數(shù)組元素地址的正確表示:
(A)&(a+1)(B)a++(C)&p(D)&p[i]數(shù)組名是地址常量p++,p--()a++,a--()a+1,*(a+2)()22例intmain(){inta[]={5,8,7,6,2,7,3};inty,*p=&a[1];
y=(*--p)++;printf(“%d”,y);printf(“%d”,a[0]);return0;}輸出:56pp58762730123456a6例3注意指針變量的運算*p++(*p)++:*++p:*p++*(p++):*p++先取p指向變量的值再指針變量加1(*p)++:(*p)++使p指向的元素值加1*++p:*++p先使指針變量加1再取*p23intmain(){inti,*p,a[7];p=a;for(i=0;i<7;i++)scanf("%d",p++);printf("\n");for(i=0;i<7;i++,p++)printf("%d",*p);return0;}p=a;pp58762730123456apppppp指針變量可以指到數(shù)組后的內(nèi)存單元例4
注意指針的當(dāng)前值24要點:1、指針變量可以實現(xiàn)自身值的改變:如:p++;但數(shù)組名則不能進行改變:a++是錯誤的用法。2、應(yīng)注意指針變量的當(dāng)前值。3、指針變量可以指向數(shù)組以后的內(nèi)存單元。4、注意以下的指針運算:若:inta[10],*p=a;則:p++
等價于
&a[1]
*p++
等價于
*(p++)
但
*(p++)與*(++p)卻不同
(*p)++等價于
a[0]++25例1利用指針,輸出int數(shù)組里一段元素:voidprt_seq(int*begin,int*end){for(;begin!=end;++begin)printf("%d\n",*begin);}prt_seq(a,a+10);prt_seq(a+5,a+10);prt_seq(a,a+3);prt_seq(a+2,a+6);prt_seq(a+4,a+4);prt_seq(a+10,a+10);最后兩個調(diào)用對應(yīng)空序列。完備嗎?26例2:“設(shè)置”函數(shù):voidset_seq(int*b,int*e,intv){ for(;b!=e;++b)*b=v;
}例3:把序列中每個元素都用其平方根取代:voidsqrt_seq(double*b,double*e){for(;b!=e;++b)*b=sqrt(*b);}例4:求平均值:doubleavrg(double*b,double*e){double*p,x=0.0;if(b==e)return0.0;for(p=b;p!=e;++p)x+=*p;returnx/(e-b);}27數(shù)組名作函數(shù)參數(shù),是地址傳遞數(shù)組名作函數(shù)參數(shù),實參與形參的對應(yīng)關(guān)系實參形參數(shù)組名指針變量數(shù)組名指針變量數(shù)組名數(shù)組名指針變量指針變量數(shù)組名作函數(shù)參數(shù)28ij379110675420123456789ijijijji11760594723實參與形參均用數(shù)組voidinv(intx[],intn){intt,i,j,m=(n-1)/2;for(i=0;i<=m;i++){j=n-1-i; t=x[i];x[i]=x[j];x[j]=t;}}intmain(){inti,a[10]={3,7,9,11,0,6,7,5,4,2};inv(a,10);printf("Thearrayhasbeenreverted:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");return0;}m=4例5將數(shù)組a中的n個整數(shù)按相反順序存放(1)29voidinv(int*x,intn){intt,*p,*i,*j,m=(n-1)/2;i=x;j=x+n-1;p=x+m;for(;i<=p;i++,j--){t=*i;*i=*j;*j=t;}}intmain(){inti,a[10]={3,7,9,11,0,6,7,5,4,2};inv(a,10);printf("Thearrayhasbeenreverted:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");return0;}實參用數(shù)組,形參用指針變量37911067542a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]xp=x+ma數(shù)組60711594723ijijijjiji例5將數(shù)組a中的n個整數(shù)按相反順序存放(2)30voidinv(int*x,intn){intt,*i,*j,*p,m=(n-1)/2;i=x;j=x+n-1;p=x+m;for(;i<=p;i++,j--){t=*i;*i=*j;*j=t;}}intmain(){inti,a[10],*p=a;for(i=0;i<10;i++,p++)scanf("%d",p);
p=a;
inv(p,10);printf("Thearrayhasbeenreverted:\n");for(p=a;p<a+10;p++)printf("%d",*p);return0;}實參與形參均用指針變量例5將數(shù)組a中的n個整數(shù)按相反順序存放(3)31voidinv(intx[],intn){intt,i,j,m=(n-1)/2;for(i=0;i<=m;i++){j=n-1-i; t=x[i];x[i]=x[j];x[j]=t;}}intmain(){inti,a[10],*p=a;for(i=0;i<10;i++,p++)scanf("%d",p);
p=a;
inv(p,10);printf("Thearrayhasbeenreverted:\n");for(p=a;p<a+10;p++)printf("%d",*p);return0;}實參用指針變量形參用數(shù)組例5將數(shù)組a中的n個整數(shù)按相反順序存放(4)32#include<stdio.h>#defineMAX5voidfun1();voidfun2(int[]);inta[MAX];intmain(){fun1();fun2(a);printf("\n");return0;}voidfun1(){intk,t=0;for(k=0;k<MAX;k++,t++)a[k]=t+t;}voidfun2(intb[]){intk;for(k=0;k<MAX;k+=2)printf("%4d",*(b+k));}例6分析程序?qū)懗鼋Y(jié)果
運行結(jié)果為:04833#include<stdio.h>voidfun(int*s){staticintj=0;do{s[j]+=s[j+1];}while(++j<2);}intmain(){intk,a[10]={1,2,3,4,5};for(k=1;k<3;k++)fun(a);for(k=0;k<5;k++)printf(“%4d”,a[k]);return0;}例7分析程序?qū)懗鼋Y(jié)果
運行結(jié)果為:3574534int*p與intq[10]數(shù)組名是指針(地址)常量p=q;p+i是q[i]的地址數(shù)組元素的表示方法:下標(biāo)法和指針法,即若p=q,則p[i]q[i]*(p+i)*(q+i)
形參數(shù)組實質(zhì)上是指針變量,即intq[]int*q在定義指針變量(不是形參)時,不能把int*p寫成intp[];系統(tǒng)只給p分配能保存一個指針值的內(nèi)存區(qū)(一般2字節(jié));而給q分配sizeof(int)*10字節(jié)的內(nèi)存區(qū)一級指針變量與一維數(shù)組的關(guān)系35定義字符指針時可用字符串常量初始化,如:char*p="Programming";1)定義了指針p2)建立了一個字符串常量,內(nèi)容為"Programming"3)令p指向該字符串常量。圖(a)chara[]="Programming";
1)定義了一個12個字符元素的數(shù)組2)用"Programming"各字符初始化a的元素,圖(b)字符指針與字符數(shù)組常用字符指針指向字符數(shù)組元素361)指針p可重新賦值(數(shù)組不能賦值:a=“…”):
p="ProgrammingLanguageC";2)p和a類型不同,大小不同。a占12個字符的空間。3)a的元素可以重新賦值。如:a[8]='e';a[9]='r';a[10]='\0'; a的內(nèi)容現(xiàn)在變成“Programmer”37IloveChistring[0]string[1]string[2]string[3]string[4]string[5]string[6]string[7]string[8]string[9]stringstring[10]string[11]string[12]string[13]n!a\0//字符串用字符數(shù)組實現(xiàn)intmain(){charstring[]=“IloveChina!”;printf(“%s\n”,string);printf(“%s\n”,string+7);return0;}//字符串用字符指針實現(xiàn)intmain(){char*string=“IloveChina!”;printf(“%s\n”,string);
string+=7;while(*string){putchar(string[0]);string++;}return0;}IloveChina!China!38#include<stdio.h>intmain(){ chararr[]="ABCDE"; char*ptr; for(ptr=arr;ptr<arr+5;ptr++) printf("%s\n",ptr); return0;}運行結(jié)果:ABCDE
BCDE
CDE
DE
E例1分析以下程序的運行結(jié)果39#include<stdio.h>intmain(){ char*p1="programming",*p2="language"; inti; for(i=0;i<7;i++) if(*(p1+i)==*(p2+i)) printf("%c",*(p1+i)); return0;}運行結(jié)果:ga例2分析以下程序的運行結(jié)果
40例3,輸入一行到數(shù)組里:enum{NLINE=256};charline[NLINE];intcount;char*p;/*-----------------------------------------*/p=line;while(p–line<NLINE-1&&(*p=gerchar())!='\n')++p;*p='\0';/*做成字符串*//*-----------------------------------------*/for(count=0,p=line;*p!='\0';++p)if(*p=='e')++count;/*統(tǒng)計e的個數(shù)*/41例1,用指針方式實現(xiàn)字符串長度函數(shù)。一種方式:intstrLength(constchar*s){intn=0;/*通過局部指針掃描串中字符*/while(*s!='\0'){s++;n++;}returnn;}另一實現(xiàn):intstrLength(constchar*s){char*p=s;while(*p!='\0')p++;returnp-s;}參數(shù)類型(char*),實參應(yīng)是字符串或存字符串的數(shù)組指針與數(shù)組操作函數(shù)實例指針使用非常靈活42voidstrCopy(char*s,constchar*t){while((*s=*t)!='\0'){s++;t++;}}把指針更新操作也寫在循環(huán)測試條件里,voidstrCopy(char*s,constchar*t){while(*s++=*t++);//空語句}賦值表達式有值,'\0'就是0,可簡化:voidstrCopy(char*s,constchar*t){while(*s=*t){s++;t++;}}例2,用指針實現(xiàn)字符串復(fù)制函數(shù)。43例用函數(shù)調(diào)用實現(xiàn)字符串復(fù)制(1)用字符數(shù)組作參數(shù)aIamateaceh\0r.fromabyuarasutndetoboet.\0Iaaeceh\0r.t.\0mtavoidcopy_string(charfrom[],charto[]){inti=0;while(from[i]!='\0'){to[i]=from[i];i++;}to[i]='\0';}intmain(){chara[]="Iamateacher.";charb[]="Youareastudent.";printf("string_a=%s\nstring_b=%s\n",a,b);
copy_string(a,b);printf("\nstring_a=%s\nstring_b=%s\n",a,b);return0;}字符指針作函數(shù)參數(shù)44例用函數(shù)調(diào)用實現(xiàn)字符串復(fù)制(2)用字符指針變量作參數(shù)aIamateaceh\0r.fromabyuarasutndetoboet.\0Iaaeceh\0r.t.\0mtavoidcopy_string(char*from,char*to){for(;*from!='\0';from++,to++)*to=*from;*to='
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《教學(xué)課件急性胃炎》課件
- 初中數(shù)學(xué)解題方法-配方法課件
- 提升外部合作伙伴關(guān)系的管理措施計劃
- 水資源保護與社區(qū)發(fā)展的融合計劃
- 節(jié)水型城市的建設(shè)標(biāo)準(zhǔn)計劃
- 長期項目跟進的秘書工作計劃
- 帶式壓榨過濾機相關(guān)項目投資計劃書
- 醫(yī)療儀器設(shè)備制造相關(guān)行業(yè)投資方案
- 智慧城市相關(guān)行業(yè)投資規(guī)劃報告范本
- 《液壓與氣動》課件 3徑向柱塞泵的結(jié)構(gòu)和工作原理
- 一年級小學(xué)數(shù)學(xué)下冊應(yīng)用題800道
- 12D401-3 爆炸危險環(huán)境電氣線路和電氣設(shè)備安裝
- 軍隊文職公共科目(人文與社會)模擬試卷3(共258題)
- 2024廣西繼續(xù)教育公需科目(高質(zhì)量共建“一帶一路”)
- 輸電線路工頻參數(shù)測試儀校準(zhǔn)規(guī)范
- APS系統(tǒng)設(shè)計藍(lán)圖與方案
- 心愛之物五年級作文精彩開頭和結(jié)尾10篇
- 我是記憶小達人(課件)-心理健康六年級
- 非ST段抬高型急性冠脈綜合征診斷和治療指南(2024)解讀
- YBT 6266-2024《高溫純化爐》規(guī)范要求
- 美國文學(xué)概論智慧樹知到期末考試答案章節(jié)答案2024年吉林師范大學(xué)
評論
0/150
提交評論