指针数组和指向指针的指针.ppt

指针数组和指向指针的指针.ppt

ID:48784739

大小:339.00 KB

页数:35页

时间:2020-01-27

上传者:U-3713
指针数组和指向指针的指针.ppt_第1页
指针数组和指向指针的指针.ppt_第2页
指针数组和指向指针的指针.ppt_第3页
指针数组和指向指针的指针.ppt_第4页
指针数组和指向指针的指针.ppt_第5页
资源描述:

《指针数组和指向指针的指针.ppt》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库

§10.3指针数组和指向指针的指针10.3.1指针数组指针数组数组的每个元素均存放地址,即每个元素是一个指针变量格式类型标识符*数组名[数组长度]例如int*p[4];定义了p是数组,有4个元素,每个元素均为整型指针变量操作指针数组的元素使用同单个指针变量。1 例10-9指针数组示例main(){inti=1,j=2,k=3,m=4;int*p[4],n;p[0]=&i;p[1]=&j;p[2]=&k;p[3]=&m;for(n=0;n<4;n++)printf("%d",*p[n]);for(n=0;n<4;n++)printf("%x",p[n]);}1234&i&j&k&mijkmpp[0]p[1]p[2]p[3]输出1234i、j、k、m的地址2 例10-10写出下列程序的运行结果voidmain(){inti=1,j=2,k=3,m=4,n,t;int*p[4],*pt;p[0]=&i;p[1]=&j;p[2]=&k;p[3]=&m;pt=p[0];p[0]=p[3];p[3]=pt;for(n=0;n<4;n++)printf("%d",*p[n]);printf(" ");p[0]=&i;p[1]=&j;p[2]=&k;p[3]=&m;t=*p[0];*p[0]=*p[3];*p[3]=t;for(n=0;n<4;n++)printf("%d",*p[n]);printf(" ");}运行结果如下:423142311234&i&k&j&mijkmpp[0]p[1]p[2]p[3]1234&m&k&j&iijkmpp[0]p[1]p[2]p[3]输出:4231输出:42311234&m&k&j&iijkmpp[0]p[1]p[2]p[3]3 10.3.2指向指针的指针变量指向指针的指针变量一个指针变量指向另一个指针变量如设i为整型变量,p为指针变量,pp为指向指针的指针变量a=10;p=&a;pp=&p;则ppp&aa10指向指针的指针变量的定义格式类型标识符**指针变量名;如int**pp;char**gg;使用时有三种形式pp,*pp,**pppp表示指向指针的指针变量的地址值如&p*pp表示指向指针变量的地址值如&a**pp表示指向指针变量所指单元的值如10&p4 例10-11写出运行结果#includevoidmain(){inta,*p,**pp;p=&a;pp=&p;a=10;printf("a=%d,*p=%d,**pp=%d ",a,*p,**pp);**p=20;printf("a=%d,*p=%d,**pp=%d ",a,*p,**pp);**pp=30;printf("a=%d,*p=%d,**pp=%d ",a,*p,**pp);}运算输出a=10,*p=10,**pp=10ppp&aa&p*pp**ppa=20,*p=20,**pp=20a=30,*p=30,**pp=305 例10-12对如下变量定义和初始化,依次执行操作(1)~(3)后,请分析部分变量的值。inta=10,b=20,t;int*pa=&a,*pb=&b,*pt;int**ppa=&pa,**ppb=&pb,**ppt;操作(1):ppt=ppb;ppb=ppa;ppa=ppt;ppbpb&bb20&pbppapa&aa10&pa**ppa**ppb*pa*pbab102010201020ppbpb&bb20&pbppapa&aa10&pa**ppa**ppb*pa*pbab201010201020ppbpb&bb20&pa&a10&pbppapaa6 再操作(2):pt=pb;pb=pa;pa=pt;ppbpb&bb20&pappapa&aa10&pb**ppa**ppb*pa*pbab102020101020再操作(3):t=b;b=a;a=t;**ppa**ppb*pa*pbab201010202010ppbpb&ab20&pappapa&ba10&pbppbpb&ab20&pappapa&ba10&pbppbpb&ab10&pappapa&ba20&pb7 间接访问利用指针变量访问另一个变量利用指针变量访问一个变量值,称为间接访问,叫单级间址利用指向指针的指针变量访问一个变量值称为间接的间接访问,叫二级间址。依次类推可以延伸更多的多级间址。指针变量地址变量变量值单级间址指针变量地址2变量变量值二级间址指向指针的指针地址1指针变量地址3变量变量值三级间址指向指针的指针地址2指向指针的指针的指针地址18 例main(){inti,*q,**p,***s;i=10;q=&i;p=&q;s=&p;printf("s=%o ",s);printf("*s=%o ",*s);printf("**s=%o ",**s);printf("***s=%o ",***s);}注使用三级间址在二级间址的“**”再加上一个“*”,多级间址依次类推。运行结果s=4577564*s=4577570**s=4577574***s=129 10.3.3指针数组、二维字符数组和字符串如chara[][6]={"Wang","Li","Zheng","Jin","Xian"};存储多个字符串,通常使用二维字符数组(字符串数组)。a字符串具有两个要点:起始地址和结束符''二维数组的行元素是行起始地址显然二维数组一行是一个字符串a[0]a[1]a[2]a[3]a[4]例main(){inti;chara[5][6]={"Wang","Li","Zheng","Jin","Xian"};for(i=0;i<5;i++)printf("%s",a[i]);}输出:WangLiZhengJinXian10 由于二维数组的列必须确定长度,要按字符串中的最大长度确定列数,这样做浪费了内存资源a如改用指向字符串的指针数组char*pname[]={"Wang","Li","Zheng","Jin","Xian"};WangLiZhengXianJinpname例main(){inti;char*pname[]={"Wang","Li","Zheng","Jin","Xian"};for(i=0;i<5;i++)printf("%s",pname[i]);}输出:WangLiZhengJinXian11 例10-13输入月份,输出对应的英文名称。例如,输入5,输出May分析定义一个有13个元素的指针数组month_name,首元素指向一个空字符串,其系元素依次指向一个英文月份的名称,数组下标对应月份,输出对应的字符串voidmain(){intmonth;char*month_name[]={"","January","February","March","April","May","June","July","August","September","October","November","December"};printf("Entermonth: ");scanf("%d",&month);if(month>=1&&month<=12)printf("%s ",month_name[month];elseprintf("Illegalmonth");}month_name[0]month_name[1]month_name[2]month_name[3]month_name[4]month_name[5]month_name[6]month_name[7]month_name[8]month_name[9]12 例10-14将5个字符串从小到大排序后输出。(用冒泡法)分析与整数排序类同,但数据类型不同voidsort(inta[],intn){inti,j;intt;for(i=0;ia[j+1]){t=a[j];a[j]=a[j+1];a[j+1]=t;}}main(){inti;inta[5]={6,5,2,81};sort(a,5);for(i=0;i<5;i++)printf("%d",a[i]);}voidsort(char*a[],intn){inti,j;char*t;for(i=0;i0){t=a[j];a[j]=a[j+1];a[j+1]=t;}}main(){inti;char*a[5]={"Wang","Li","Zheng","Jin","Xian"};sort(a,5);for(i=0;i<5;i++)printf("%s",a[i]);}13 voidsort(char*a[],intn){inti,j;char*t;for(i=0;i0){t=a[j];a[j]=a[j+1];a[j+1]=t;}}main(){inti;char*a[5]={"Wang","Li","Zheng","Jin","Xian"};sort(a,5);for(i=0;i<5;i++)printf("%s",a[i]);}WangLiZhengXianJinaa[0]a[1]a[2]a[3]a[4]注:指针数组的元素所指向各自的字符串的,需要交换时,直接交换指针数组元素的值,即改变它们的指向。WangLiZhengXianJinaa[0]a[1]a[2]a[3]a[4]14 改为二维字符数组做voidsort(chara[][6],intn){inti,j;chart[6];for(i=0;i0){strcpy(t,a[j]);strcpy(a[j],a[j+1]);strcpy(a[j+1],t);}}main(){inti;chara[5][6]={"Wang","Li","Zheng","Jin","Xian"};sort(a,5);for(i=0;i<5;i++)printf("%s",a[i]);}voidsort(char*a[],intn){inti,j;char*t;for(i=0;i0){t=a[j];a[j]=a[j+1];a[j+1]=t;}}main(){inti;char*a[5]={"Wang","Li","Zheng","Jin","Xian"};sort(a,5);for(i=0;i<5;i++)printf("%s",a[i]);}指针数组做15 WangLiZhengXianJinaa[0]a[1]a[2]a[3]a[4]指针数组做二维字符数组做WangLiZhengXianJinaa[0]a[1]a[2]a[3]a[4]aa[0]a[1]a[2]a[3]a[4]a[0]a[1]a[2]a[3]a[4]注二维字符数组多用了内存二维字符数组直接改变存储单元字符串内容,而指针数组改变指针所指的方向16 10.3.4指针数组和二级指针指针数组的每个元素是指针变量,指向指针数组元素的指针变量必须是二级指针例main(){inta[5]={1,3,5,7};int*n[4]={&a[0],&a[1],&a[2],&a[3]};int**p,i;p=n;for(i=0;i<4;i++){printf("%dt",**p);p++;}}运算结果13571357&m&k&j&ia[0]pn[0]n[1]n[2]n[3]a[1]a[2]a[3]17 main(){inti,j;char*a[5]={"Wang","Li","Zheng","Jin","Xian"},**p;p=a;for(i=0;i<5;i++)printf("%s%s%s%s ",a[i],*(a+i),p[i],*(p+i));i=0;j=2;printf("%c%c%c%c ",*(a[i]+j),*(*(a+i)+j),*(p[i]+j),*(*(p+i)+j));}a[0]a[1]a[2]a[3]a[4]p,a,a+0a+1a+2a+3a+4a[0]+2WangLiZhengXianJin输出:WangWangWangWangLiLiLiLiZhengZhengZhengZhengJinJinJinJinXianXianXianXiannnnn例18 a[0]a[1]a[2]a[3]a[4]a,a+0a+1a+2a+3a+4chara[][6]={"Wang","Li","Zheng","Jin","Xian"};a[0]+2,&a[0][2]注:a+i,a[i]是行指针,也可用*(a+i)表示但不能用指向指针的指针变量(二级指针)指向二维数组的字符串chara[5][6],**p;p=a;不允许而是用要用行指针指向字符串,行指针定义:char(*p)[6];下标表示字符串的长度改为二维数组存放字符串组19 main(){inti,j;chara[5][6]={"Wang","Li","Zheng","Jin","Xian"},(*p)[6];p=a;for(i=0;i<5;i++)printf("%s%s%s%s%s ",a+i,*(a+i),a[i],p[i],*(p+i));i=0;j=2;printf("%c%c%c%c%c ",a[i][j],*(a[i]+j),*(*(a+i)+j),*(p[i]+j),*(*(p+i)+j));}输出:WangWangWangWangWangLiLiLiLiLiZhengZhengZhengZhengZhengJinJinJinJinJinXianXianXianXianXiannnnnn20 10.3.5命令行参数(指针数组作为main()函数的形参)一般使用main函数无参数定义main(){...}其实main()函数可以带2个参数定义main(intargc,char*argv[]){...}其中argc是整型变量*argv[]是指向字符串的指针数组注argc,argv这两个参数是系统规定的;但参数名可以任取,习惯上按上述名取。21 利用命令行传递参数格式命令名参数1,参数2,...,参数nC语言程序经过编译、连接产生执行文件文件名.exe则文件名就是命令名,而后的实参相应传递给这两个参数其中argc存放命令行的字符串个数,包括命令名n+1argv[0]存放命令名(tc包括路径)argv[1]存放参数1argv[2]存放参数2...argv[n]存放参数n22 voidmain(argc,argv)intargc;char*argv[];{inti;for(i=0;ifileChinaBeijingargv输出:fileChinaBeijingargc=323 将程序prog.c编译后运行:prog–nlahelloworld则*(*(argv+2))是______。A、'p'B、'-'C、'h'D、'w'对于如下程序test.c,编译后运行testhelloworld将输出_________:#includemain(intagrc,char*argv[]){printf("%d%s",argc,argv[1]+1);}答案:3ello答案:C24 §10.4指针和函数10.4.1指针作为函数的返回值函数返回值可以是数值、字符同样也可以返回地址值(指针)1.返回指针的函数的定义格式类型标识符*函数名(参数表)参数说明;{return(指针);}与一般函数定义区别(1)在函数名前多了*(2)在return语句中要求地址值例如int*a(x,y)intx,y;{int*p;…return(p);}2.返回指针的函数调用形式同一般函数调用函数名(实参表)25 例10-18输入一个字符串和一个字符,如果该字符在字符串中,就从该字符首次出现的位置开始输出字符串中的字符。例如,输入字符r和字符串program后,输出rogram。要求定义函数match(s,ch)在字符串,中查找字符ch,如果找到,返回第一次找到的该字符在字符串中的位置(地址);否则,返回空指针NULL。分析:match(s,ch)返回一个地址,所以函数返回值的类型是指针。char*match(char*s,charch){while(*s!='')if(*s==ch)returns;elses++;return(NULL);}main(){charch,str[80],*p=NULL;scanf("%s",str);ch=getchar();if((p=match(str,ch))!=NULL)printf("%s ",p);elseprintf("Notfound ");}programstrs输入:programr输出:rogram26 例10-19定义函数mystrcpy(char*s,char*t),将t复制到s,并返回s的值。分析:要求返回s的值,即返回字符串的起始地址。例10-8voidstrcpy(char*to,char*from)/*第2.2版*/{while(*to++=*from++)}char*mystrcpy(char*s,char*t){char*ss=s;while(*s++=*t++)returnss;}注:由于在函数中改变了指针s的值,又定义了一个指针ss保存s的初值27 10.4.2函数指针和指向函数的指针变量函数指针函数在编译时分配内存给一个入口地址,这个入口地址以函数名表示,称为函数指针。所谓入口地址函数编译后成为若干条指令依次存储在内存,第一条指令存储的单元地址称为入口地址指向函数的指针变量指针变量的值是函数的入口地址1.用指向函数的指针变量调用函数例求a和b的大值max(x,y)intx,y;{intz;if(x>y)z=x;elsez=y;return(z);}main(){inta,b,c;scanf("%d,%d",&a,&b);c=max(a,b);printf("%d ",c);}max28 若使用指向函数指针变量调用函数max(x,y)intx,y;{intz;if(x>y)z=x;elsez=y;return(z);}main(){inta,b,c,(*p)();scanf("%d,%d",&a,&b);p=max;c=p(a,b);printf("%d ",c);}maxp2.指向函数的指针变量定义格式类型标识符(*指针变量名)();其中(1)类型标识符为指向函数的返回值的类型如int(*p)();返回值为整型(2)(*指针变量名)()表示定义一个指向函数的指针变量,专门用来存放函数的入口地址29 3.指向函数的指针变量调用函数注函数的指针变量只能用于调用函数,而不能进行指针变量的个各种运算。如p++,p+i,*p+i是不允许(1)将函数的入口地址赋于指针变量格式指针变量名=函数名;如上例中p=max;(2)调用形式格式(*指向函数的指针变量名)(函数实参表)或指向函数的指针变量名(函数实参表)如上例中c=p(a,b);或c=(*p)(a,b);30 例10-20函数指针示例#includeintodd(intx){returnx%2!=0;}inteven(intx){returnx%2==0;}voidmain(){intr1,r2,r3,r4;int(*fp)();/*定义函数指针*/fp=odd;/*将函数odd的入口地址赋给函数指针*/rl=odd(5);/*通过函数名调用函数odd*/r2=(*fp)(5);/*通过函数指针调用函数odd*/printf("%d,%d ",r1,12);fp=even;/*将函数even的入口地址赋给函数指针*/r3=even(5);/*通过函数名调用函数even*/r4=(*fp)(5);/*通过函数指针调用函数even*/printf("%d,%d ",r3,r4);}运行1,10,031 4.函数指针作为函数参数指向函数的指针变量作为函数参数给模块编程带来较大的灵活性形参为指向函数的指针变量(函数指针)实参可为函数名或已赋值的函数指针虚实结合:形参指向实参所代表函数的入口地址。例10-21编一个求任意函数的定积分,用梯形公式积分然后计算分析:先编一个任意函数的定积分函数模块然后调用函数实现定积分。32 分析对编函数,按积分的几何意义采取数值积分abha+ha+2h12in等分n个小梯形则梯形积分公式函数的参数决定:已知a,b,n和f(x)求积分值a+(i-1)ha+i*hf(a+(i-1)h)f(a+i*h)f(x)x0小梯形宽:小梯形面积:33 doublecalc(f,a,b,n)double(*f)(),a,b;intn;{inti;doubleh,s;s=((*f)(a)+(*f)(b))/2;h=(b-a)/n;for(i=1;i

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
关闭