




已阅读5页,还剩69页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第十章指针,10.1地址与指针的概念10.2变量的指针和指向变量的指针变量10.3数组与指针10.4字符串与指针10.5指向函数的指针10.6返回指针值的函数10.7指针数组和指向指针的指针10.8有关指针的数据类型和指针运算的小结,引言,A、B、C三人欲住旅馆。A先到达旅馆,在服务台登记了房间,房间号是301。然后,A电话通知了B,但没有通知C.,B和C该怎样找到A呢?,B可以直接到301找到A。,C可以从旅馆的服务台查询到A的房间号301,再找到A。,10.1地址与指针的概念,一、变量的地址,计算机中,数据存储在内存中。,内存可划分若干个存储单元,每个单元可以存放8位二进制数,即1个字节。,内存单元采用线性地址编码,每个单元具有唯一一个地址编码,1、变量的地址:系统为变量分配的内存单元的地址。,一个无符号整型数,shortinta;floatb;a=3;b=5;,3,5,2、变量的有关概念:,存储内容:空间大小:空间位置:生存周期:,数据值,数据类型,地址,存储类别,10.1地址与指针的概念,二、变量的访问方式,1、直接访问,按变量地址存取变量值的方式称为“直接访问”方式,2、间接访问,定义一个变量p,存放a的地址,通过p访问a,这种方式称为“间接访问”方式,如何定义p?如何获取变量a的地址?如何通过p访问a?,10.1地址与指针的概念,指针变量是存放的地址的变量。,三、指针变量,P为指针变量,它存放整型变量a的首地址。,我们称,指针变量p指向整型变量a。,2004,四、指针,一个变量的地址称为该变量的指针。,指针变量的值(即指针变量中存放的值)是地址(即指针)。请区分“指针”和“指针变量”这两个概念。,10.变量的指针和指向变量的指针变量,1、定义指针变量的一般形式基类型*指针变量名,int*p1,*p2;char*p3;,10.1定义一个指针变量,所指向的变量的类型,2、指针变量的赋值,指针说明符,用变量的地址给指针变量赋值(求地址运算符p1=p2;,注:变量的类型必须和指针变量的基类型相同。,指针变量的值为地址。是个无符号整数。但不能直接将整型常量赋给指针变量,inta,b;int*p;p=,floata;int*pointer_1;pointer_1=,10.变量的指针和指向变量的指针变量,10.1定义一个指针变量,注意:,定义指针变量时的前面“*”,表示该变量的类型为指针型变量。,(2)在定义指针变量时必须指定基类型。,例:float*pointer_1;指针变量名是pointer_1,而不是*pointer_1。,(3)对指针变量不赋值,则它的值是随机的。,(4)赋空值,,pointer_1NULL;pointer_1=0;,3、指针变量的初始化方法,(1)赋空值,(2)赋已定义的变量的地址,10.变量的指针和指向变量的指针变量,1、两个有关的运算符:p=,访问所指变量,取内容:b=*p;printf(“dn”,*p);,存内容:,例10-1通过指针变量访问整型变量。main()inta,b;int*p1,*p2;a=100;b=10;p1=,*p100;,10.变量的指针和指向变量的指针变量,2、运算规则,10.2.2指针变量的引用,scanf(“%d,%d”,10.变量的指针和指向变量的指针变量,例10-3读程序,写出结果#includevoidmain()inta=3,b=5;int*p=,运行结果:a=3b=5a=4,b=6,#includevoidswap(intx,inty)intt;t=x;x=y;y=t;voidmain()inta=3,b=5;swap(a,b);printf(%d,%dn,a,b);,#includevoidswap(int*x,int*y)intt;t=*x;*x=*y;*y=t;voidmain()inta=3,b=5;swap(,int*t;t=x;x=y;y=t;,int*t;*t=*x;*x=*y;*y=*t;,例10-4编写一个函数实现两个数的交换,10.3指针变量作为函数参数,i,*t;t=,例10-5输入a、b、c3个整数,按大小顺序输出。,#includevoidswap(int*x,int*y)intt;t=*x;*x=*y;*y=t;voidmain()inta,b,c;scanf(%d,%d,%d,10.3数组与指针,指针变量既然可以指向变量,也可以指向数组元素。,数组的指针:,数组元素的指针:,就是数组元素的地址。,是指数组的起始地址。,定义一个指向数组元素的指针变量,10.3数组与指针,inta10;int*p;p=,在定义指针变量时可以赋给初值:int*p=,10.3.1指向数组元素的指针,数组名就是数组的首地址,10.3数组与指针,某一元素的地址:p=则,10.3数组与指针,数组指针、指针变量与数组元素之间的关系:,10.3.2通过指针引用数组元素,地址关系,内容关系,10.3数组与指针,例10-6输出数组中的全部元素,10.3.2通过指针引用数组元素,#includevoidmain()inta10,*p=a;inti;for(i=0;i10;i+)scanf(%d,scanf(%d,a+i);,printf(%d,*(a+i);,scanf(%d,p+i);,printf(%d,*(p+i);,10.3数组与指针,指针的运算,10.3.2通过指针引用数组元素,1、赋值运算如:p=p=a;for(i=0;i10;i+)scanf(%d,p+);printf(n);for(i=0;i10;i+,p+)printf(%d,*p);printf(n);,运行情况;123456789022153234003003625202116318259823728483,10.3数组与指针,改进方法如下,10.3.2通过指针引用数组元素,#includevoidmain()int*p,i,a10;p=a;for(i=0;i10;i+)scanf(%d,p+);printf(n);p=a;for(i=0;i10;i+,p+)printf(%d,*p);printf(n);,10.3数组与指针,例10-7将数组a的数据复制到数组b中并输出结果,10.3.2通过指针引用数组元素,#include#defineM7voidmain()inti,aM=4,24,12,56,32,9,62;intbM;for(i=0;iM;i+)bi=ai;printf(输出b数组的数据:n);for(i=0;iM;i+)printf(%d,bi);printf(n);,#include#defineM7voidmain()inti,aM=4,24,12,56,32,9,62;intbM;int*p=a,*q=b;for(i=0;iM;i+)*q=*p;p+;q+;printf(输出b数组的数据:n);for(i=0;iM;i+)printf(%d,bi);printf(n);,*q+=*p+;,10.3数组与指针,介绍过可以用数组名作函数的参数,10.3.3用数组名作函数参数,如:voidmain()f(intarr,intn);intarray10;f(array,10);voidf(intarr,intn),形参应该是一个指针变量。,实际上,C编译都是将形参数组名作为指针变量来处理的。,f(intarr,intn)但在编译时是将arr按指针变量处理的,相当于将函数f的首部写成f(int*arr,intn)以上两种写法是等价的。,10.3数组与指针,需要说明的是:C语言调用函数时虚实结合的方法都是采用“值传递”方式,当用变量名作为函数参数时传递的是变量的值,当用数组名作为函数参数时,由于数组名代表的是数组首元素地址,因此传递的值是地址,所以要求形参为指针变量。,10.3.3用数组名作函数参数,在用数组名作为函数实参时,既然实际上相应的形参是指针变量,为什么还允许使用形参数组形式呢?,P236,算法:1、令p指向数组的开始,q指向结束2、交换两单元的内容;3、两指针向中间靠拢;4、重复上述2、3、直到pq。,10.3数组与指针,例10-8将数组中个整数按相反顺序存放,10.3.3用数组名作函数参数,#includevoidinverse(int*p,intn);voidmain()inta=12,56,32,9,62;intk,*p=a;for(k=0;k5;k+)printf(%4d,*p+);puts();inverse(a,5);for(p=a,k=0;k5;k+)printf(%4d,*p+);puts();voidinverse(int*p,intn)int*q,t;q=p+n-1;while(pq)t=*p;*p=*q;*q=t;p+;q-;,10.3数组与指针,归纳起来,如果有一个实参数组,想在函数中改变此数组中的元素的值,实参与形参的对应关系有以下种情况:,10.3.3用数组名作函数参数,(1)形参和实参都用数组名,如:voidmain()void(intx,intn)inta10;(a,10);,10.3数组与指针,(2)实参用数组名,形参用指针变量。如:voidmain()voidf(int*x,intn)inta10;f(a,10);,10.3.3用数组名作函数参数,(3)实参形参都用指针变量。例如:voidmain()voidf(int*x,intn)inta10,*p=a;f(p,10);,10.3数组与指针,(4)实参为指针变量,形参为数组名。如:voidmain()voidf(intx,intn)inta10,*p=a;f(p,10);,10.3.3用数组名作函数参数,以上4种方法,实质上都是地址的传递。,10.3数组与指针,例10-9用选择法对10个整数按由大到小顺序排序,10.3.3用数组名作函数参数,#includevoidsort(intx,intn)/*形参为数组名*/inti,j,k,t;for(i=0;ixk)k=j;t=xi;xi=xk;xk=t;,10.3数组与指针,voidmain()int*p,i,a10;p=a;for(i=0;i10;i+)scanf(%d,p+);p=a;sort(p,10);/*实参为指针变量*/for(p=a,i=0;iy)z=x;elsez=y;returnz;main()int(*p)(int,int);inta,b,c;p=max;scanf(%d,%d,10.5.用函数指针变量调用函数,用函数指针调用函数max(),函数max的入口地址赋给指针变量p。,函数名代表该函数的入口地址。,定义一个指向函数的指针,10.6返回指针值的函数,所谓函数类型是指函数返回值的类型。,一般定义形式为类型名*函数名(参数表列);,如:int*a(intx,inty)声明一个函数,函数名为a,其返回值类型是“指向整型的指针”,函数形式参数为intx和inty。,a的两侧分别为*运算符和()运算符。,在语言中允许一个函数的返回值是一个指针(即地址),,这种返回指针值的函数称为指针型函数。,()运算符的优先级高于*运算符,因此a先与()结合。这是函数形式。然后函数前面有一个*号,表示此函数是指针型函数。,10.6返回指针值的函数,例10-17有若干学生的成绩(每个学生四门课程),要求用户在输入学生序号(从开始)后,能输出该学生的全部成绩。,分析:设计一个指针pointer指向一个学生的四门成绩float(*pointer)4,pointer是一个指向一维数组的指针。数组元素个数为4(四门课程)pointer+1指向下一个学生的成绩。输入学生序号后,使pointer指向该学生的成绩,然后返回pointer指针.,10.6返回指针值的函数,#includefloat*search(float(*pointer)4,intn);voidmain()staticfloatscore4=60,70,80,90,56,89,67,88,34,78,90,66;float*p;inti,m;printf(enterthenumberofstudent:);scanf(%d,/*在score数组中查询m号学生的成绩*/*查询结果为指向成绩的指针*/,/*pt是指向实数的指针,pointer是指向数组的指针*/*pt=(float*)(pointer+n)*/,10.6返回指针值的函数,分析:上例中,search函数返回学生成绩的首地址。本例,用返回地址区分学生成绩中有无不及格课程,若有不及格课程时,仍返回学生成绩的首地址;若无不及格课程,则返回学生成绩的末地址(等于下一个学生的首地址)。,例10-18对上例中的学生,找出有不及格成绩的学生及其学号。,float*search(float(*pointer)4);main()staticfloatscore4=60,70,80,90,56,89,67,88,34,78,90,66;float*p;inti,j;for(i=0;i3;i+)p=search(score+i);if(p=*(score+i)printf(“No.%dscores:t”,i);for(j=0;j4;j+)printf(“%5.2t”,*(p+j);printf(“n”);float*search(float(*pointer)4)inti;float*pt;pt=*(pointer+1);for(i=0;i4;i+)if(*(*pointer+i)60)pt=*pointer;returnpt;,/*p指向i号学生成绩首地址,该生有不及格课程*/*显示该生的四门课程成绩*/,/*先设pt指向成绩末地址(等于下一个学生成绩首地址),即先假设无不及格成绩*/*查四门课程中有无不及格成绩*/,/*有不及格课程,pt指向成绩首地址*/,10.7指针数组和指向指针的指针,10.7.1指针数组的概念,指针数组是一个数组,该数组中的每一个元素是指针变量。,概念:形式:例子:区分:用途:,int*p4;定义一个指针数组,数组名p,有4个元素,每一个元素是指向整型变量的指针。,类型标识符*数组名数组元素个数,int(*p)4(指向数组的指针)定义一个指针变量,它指向有4个元素的一维数组,处理多个字符串。字符串本身是一维数组,多个字符串可以用二维数组来处理,但会浪费许多内存。用指针数组处理多个字符串,不会浪费内存。,10.7指针数组和指向指针的指针,10.7.1指针数组的概念,二维数组charname16,浪费许多内存,指针数组char*name,不浪费内存,10.7指针数组和指向指针的指针,10.7.1指针数组的概念,#include#includevoidmain()voidsort(char*name,intn);voidprint(char*name,intn);char*name=Followme,BASIC,GreatWall,FORTRAN,Computerdesign;intn=5;sort(name,n);print(name,n);,例10-19将若干字符串按字母顺序(由小到大)输出。,10.7指针数组和指向指针的指针,占用静态存储区,用static说明。,voidsort(char*name,intn)/*冒泡法排序*/char*temp;inti,j,k;for(i=0;i0)k=j;/*比较namek与namej的大小,较小字符串的序号保留在k中*/if(k!=i)temp=namei;/*交换namei与namek的指向*/namei=namek;namek=temp;voidprint(char*name,intn)inti;for(i=0;in;i+)printf(%sn,namei);,10.7指针数组和指向指针的指针,10.7.2指向指针的指针,定义举例:char*p;p是一个
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025至2030中国AM和和FM收音机行业发展趋势分析与未来投资战略咨询研究报告
- 冷库主管工作总结
- 2025至2030中国心耳封堵器行业产业运行态势及投资规划深度研究报告
- 铁路隧道消防培训
- 2025年智能可穿戴设备个性化健康服务技术创新报告
- 欺诈性债务抵消:虚构合同解除与补偿协议
- 蒙氏混龄班老师工作总结
- 高铁站空调采购、安装及旅客舒适度提升合同
- 离婚协议书中财产分割、子女抚养及共同财产清算协议
- 离婚协议违约金及财产分配纠纷解决合同
- GA/T 1661-2019法医学关节活动度检验规范
- 小学生(成语故事100个)讲解
- 楷书毛笔课件
- 急危重症患者的抢救应急处理预案及流程
- 班主任基本功大赛评分标准
- 额窦手术课件
- 流感疫苗项目市场营销策略方案
- 财务代理记账报税合同模板
- HY_T 0330-2022 海滩养护与修复工程验收技术方法
- 十四条经络养生课件
- 清洁生产的实施途径
评论
0/150
提交评论