C语言程序设计第9章指针进阶.ppt
《C语言程序设计第9章指针进阶.ppt》由会员分享,可在线阅读,更多相关《C语言程序设计第9章指针进阶.ppt(61页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、第第9 9章章 指针进阶指针进阶 学习目标1掌握指针数组的定义及其应用,了解二级指针的基本概念;2.理解二维数组的指针和指向二维数组的指针变量;3.了解指向函数的指针,理解指针型函数;4.初步了解内存的动态分配和动态回收;5.初步掌握单向链表的建立与访问、在单向链表中插入、删除结点等算法。9.1 9.1 指针数组指针数组9.1.1 9.1.1 指针数组的概念指针数组的概念 指针数组:一个数组的每个元素均为指针类型 形式:数据类型*数组名数组长度;int*pa3;char*pname5=JiangSu,ShanDong,ZheJiang,GuangXi,AnHui;指针数组pname字符串pna
2、me0pname1pname2pname3pname4JiangSuShanDongZheJiangGuangXiAnHuipname9.1.2 9.1.2 指向指针的指针变量指向指针的指针变量 指向指针的指针变量:一个指针变量中存放的是另一个指针变量的地址形式:数据类型*指针变量名;int*p;intx=5,*q=&x;int*p;p=&q;变量、一级指针、二级地址之间的关系示意变量、一级指针、二级地址之间的关系示意指针变量q变量x指针变量p&x5&q#includevoidmain()inta=10,*b,*c;b=&a;c=&b;printf(%d,%d,%dn,a,*b,*c);*b=
3、20;/*通过b间接访问a*/printf(%d,%d,%dn,a,*b,*c);*c=30;/*通过c间接访问a*/printf(%d,%d,%dn,a,*b,*c);运行结果:10,10,1020,20,2030,30,30&a变量b变量a&b变量c*c*c或*b10(初值)二级指针示意图二级指针示意图9.1.3 指针数组应用举例指针数组应用举例编程将若干字符串按字母顺序由小到大排序后输出。#include#include#defineN5/*字符串个数*/voidsort(char*name,intn);voidprint(char*name,intn);voidmain()char*p
4、nameN=JiangSu,ShanDong,ZheJiang,GuangXi,AnHui;printf(beforesorted:n);print(pname,N);/*排序前输出各字符串*/sort(pname,N);/*排序*/printf(aftersorted:n);print(pname,N);/*排序后输出各字符串*/voidsort(char*name,intn)char*pt;inti,j,k;for(i=0;in-1;i+)/*选择排序算法*/k=i;for(j=i+1;j0)k=j;if(k!=i)pt=namei;namei=namek;namek=pt;voidpri
5、nt(char*name,intn)inti;for(i=0;in;i+)printf(%sn,namei);/*或printf(%sn,*(name+i);*/(b)排序后排序后指针数组pname字符串pname0pname1pname2pname3pname4JiangSuShanDongZheJiangGuangXiAnHui(a)排序前排序前指针数组pname字符串pname0pname1pname2pname3pname4JiangSuShanDongZheJiangGuangXiAnHui9.2 9.2 二维数组的指针和二维数组的指针和 指向二维数组的指针变量指向二维数组的指针变量
6、9.2.1 9.2.1 二维数组的行地址和列地址二维数组的行地址和列地址一、二维数组的行地址一、二维数组的行地址ints34;s数组的逻辑结构图数组的逻辑结构图s00s10s20s01s11s21s02s12s22s03s13s23s0s1s2ss数组的行地址数组的行地址s0s1s2ss+1s+2*s等于*(s+0)为元素s0*(s+1)即为元素s1*(s+2)即为元素s2由于行地址代表某一行(这一行可以看成是一个一维数组)的地址,而不是某一个元素的地址,故行地址是一个二级指针。例如,s是第0行,即s0(s0可看作是s00、s01、s02、s03四个元素组成的一维数组的数组名)的地址,s+1表
7、示下一行的地址,即s1的地址。二、二维数组的列地址二、二维数组的列地址 一维数组名代表数组首元素的地址 s0代表一维数组s0中第0列元素的地址(&s00)s1代表一维数组s1中第0列元素的地址(&s10)s2代表一维数组s2中第0列元素的地址(&s20)s0+0、s0+1、s0+2、s0+3分别是s00、s01、s02、s03的地址,这些地址被称为二维数组s的列地址。列地址是数组元素的地址,可以利用列地址指向某一个实际的二维数组元素。s10s11s12s13二维数组二维数组s的行地址和列地址的行地址和列地址s1+0s1+1s1+2s1+3s2+0s2+1s2+2s2+3s0s1s2ss+1s+
8、2行地址列地址一维数组s0一维数组s1一维数组s2s20s22s23s21s0+0s0+1s0+2s0+3s00s01s02s039.2.2 9.2.2 通过地址引用二维数组的元素通过地址引用二维数组的元素ints34,i,j;s数组中各种表示形式和含义表示形式表示形式含含 义义s二维数组名,指向一维数组s0,即第0行首地址s0,*(s+0),*s第0行的首地址s+1第1行首地址s1+0,*(s+1),*(s+1)+0,&s10第1行第0列元素的地址*(s1+2),*(*(s+1)+2),s12,(*(s+1)2第1行第2列元素的值s129.2.3 9.2.3 指向二维数组的指针变量指向二维数
9、组的指针变量一、指向二维数组元素的指针一、指向二维数组元素的指针 列地址是数组元素的地址,使用该地址对一指针变量进行初始化,那么该指针变量就指向二维数组元素。这种指针被称为指向二维数组元素的指针或者被称为列指针#includevoidmain()inta34=0,2,4,6,1,3,5,7,9,10,11,12;int*p;for(p=a0;pa0+12;p+)if(p-a0)%4=0)printf(n);/*保证每行四个元素*/printf(%4d,*p);/*输出当前p所指向元素的值*/运行结果:024613579101112阅读下列程序,考察lessavg函数调用时实参与形参的结合。#i
10、nclude#defineM3#defineN3voidlessavg(float*,int);voidmain()floataMN=65,67,70,80,89,97,69,76,80;lessavg(&a00,M*N);voidlessavg(float*p,intn)floatsum=0,average;float*p1;inti;p1=p;/*p1指向第一个元素a00*/for(;p1p+n;p1+)sum=sum+(*p1);average=sum/n;/*average存储平均值*/printf(average=%5.2f,average);printf(nthearrayelem
11、ents(less%5.2f):n,average);for(i=0;in;i+)if(piaverage)/*或if(*(p+i)average)*/printf(%5.2fn,pi);/*或printf(%5.2fn,*(p+i);*/二、指向二维数组行的指针二、指向二维数组行的指针行地址代表某一行(一行可以看成是一个一维数组)的地址,使用该地址对一指针变量进行初始化,那么该指针变量便指向二维数组的一行。这种指针变量被称为指向二维数组行的指针变量,简称行指针。n形式:数据类型 (*行指针名)长度;“长度”表示行指针所指向的一维数组的长度(即二维数组的列数)“数据类型”表示行指针所指一维数组
12、的元素类型“*”表示其后定义的标识符是指针。例如,变量声明语句“int(*p)4=s;”表示定义的指针变量p用以指向包含4个整型元素的一维数组,也可理解为p用以指向列数为4的二维数组的行。#includevoidmain()ints34=0,2,4,6,1,3,5,7,9,10,11,12;int(*p)4,i,j;scanf(%d%d,&i,&j);p=s;printf(%dn,*(*(p+i)+j);测试数据及运行结果:输入:13输出:79.2.4 二维数组名作为函数参数二维数组名作为函数参数若主函数中有以下定义及函数调用语句:#include#defineM3#defineN4voidm
13、ain()intaMN;fun(a);则fun函数(设为void类型)定义时的首部可以是以下三种形式之一:(1)voidfun(int(*p)N)(2)voidfun(intpN)(3)voidfun(intpMN)n注意:上述三种方式中,无论是哪一种方式,编译系统都将把p处理成一个行指针。和一维数组相同,数组名传递给形参的是一个地址值,因此,对应的形参也必定是一个类型相同的指针变量,在函数中引用的将是主函数中的数组元素,系统只为形参开辟一个存放地址的存储单元,而不可能在调用函数时为形参开辟一系列存放数组元素的存储单元。#include#defineM3#defineN4intmax_valu
14、e(int(*p)4,intrnum);voidmain()intsMN=1,3,12,7,2,14,6,28,15,47,34,12;printf(maxvalueis%dn,max_value(s,M);intmax_value(int(*p)N,intrnum)/*或intmax_value(intpN,intrnum)*/inti,j,max;max=p00;/*或max=*p;*/for(i=0;irnum;i+)for(j=0;jmax)max=pij;/*或max=*(*(p+i)+j);*/returnmax;运行结果:maxvalueis479.3 9.3 函数的指针与函数的
15、指针与 指向函数的指针变量指向函数的指针变量*9.3.1 指向函数的指针变量的定义指向函数的指针变量的定义形式为:数据类型(*指针变量名)();“数据类型”表示指针变量所指向函数的返回值的类型。最后的空括号表示指针变量所指的是一个函数。例如,int(*pf)();pf被定义为一个可以指向函数的指针变量,该函数的返回值(函数值)是整型。它在没有赋值前不指向一个具体的函数,不能随便使用。9.3.2 9.3.2 用指向函数的指针变量调用函数用指向函数的指针变量调用函数形式:(*指针变量名)(实参表列);#includeintmax(int,int);intmin(int,int);voidmain(
16、)int(*p)();intx,y,l,j;printf(Pleaseinputtwonumbers:n);scanf(%d%d,&x,&y);p=max;/*函数名max表示函数的入口地址(首地址)*/l=(*p)(x,y);/*通过函数指针变量调用max函数,与“z=max(x,y)”等价*/printf(max=%dn,l);p=min;/*函数名min表示min函数的入口地址(首地址)*/j=(*p)(x,y);/*通过函数指针变量调用min函数,与“z=min(x,y)”等价*/printf(min=%dn,j);intmax(inta,intb)if(ab)returna;else
17、returnb;intmin(inta,intb)if(ab)returna;elsereturnb;测试数据及运行结果:输入:610输出:max=10min=69.4 9.4 返回值为指针的函数返回值为指针的函数形式:数据类型*函数名(形参表)函数名前的“*”号表明这是一个指针型函数,即返回值是一个指针。数据类型表示了返回的指针所指向数据的类型。例如:int*ap(intx,inty).表示ap是一个返回指针值的指针型函数,它返回的指针指向一个整型变量。编写一个函数连接两个字符串,并返回连接后字符串的首地址#includechar*catstr(char*str1,char*str2);vo
18、idmain()chars1100=beijing;chars2100=2008;char*result=NULL;result=catstr(s1,s2);printf(ntheresultis:%sn,result);char*catstr(char*str1,char*str2)char*temp=str1;while(*str1!=0)str1+;while(*str2!=0)*str1=*str2;str1+;str2+;*str1=0;returntemp;运行结果:theresultis:beijing20089.5 9.5 链表链表9.5.1 链表的概念链表的概念链表是一种常见
19、的重要的数据结构,它是动态地进行存储分配的一种结构。一、自引用结构体当一个结构体中的一个或多个成员的基类型就是本结构体类型时,称为可以“引用自身的结构体”,简称自引用结构体。例如:structnodecharc;structnode*next;a;next是一个可以指向struct node类型变量的指针成员,因此,“a.next=&a;”就是合法的赋值语句,由此构成的存储结构如图。自引用结构体示意自引用结构体示意B#includestructstudentintid;floatscore;structstudent*next;voidmain()structstudenta,b,c,*hea
20、d,*p;a.id=1000;a.score=90;b.id=1001;b.score=86;c.id=1002;c.score=78;/*对结点的id和score成员赋值*/head=&a;/*将结点a的起始地址赋给头指针head*/a.next=&b;/*将结点b的起始地址赋给a结点的next成员*/b.next=&c;/*将结点c的起始地址赋给b结点的next成员*/c.next=NULL;/*c结点的next成员不存放其他结点地址*/p=head;/*使p指针指向a结点*/while(p!=NULL)/*p的值为NULL,表示链表已经结束*/printf(%d%5.1fn,p-id,p
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言程序设计 指针 进阶
限制150内