《C语言综合实验》1数组与指针.ppt_第1页
《C语言综合实验》1数组与指针.ppt_第2页
《C语言综合实验》1数组与指针.ppt_第3页
《C语言综合实验》1数组与指针.ppt_第4页
《C语言综合实验》1数组与指针.ppt_第5页
已阅读5页,还剩60页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1,C语言综合实验,谢颂华whxiesonghua,2,C语言综合实验,指针与数组构造数据类型链表,3,指针与数组基本概念变量的指针和指针变量指针和数组指针和字符串指针函数和函数的指针指针数组例题讲解,4,主要内容指针的引用和运算方法数组、函数和字符串与指针的关系学习难点指针变量的引用指针作为函数参数的运用,5,基本概念,内存:内部存储器,是由存储单元组成的。特点:存储单元是线性连续。存储单元的最小单位是字节。,1.内存的概念,6,地址:为了访问内存中的某个存储单元,我们要为它编号,这种编号称为内存地址。通过地址就能够访问该地址所标识的存储单元。内存单元的地址和内存单元的内容的区别:,2.地址的概念,inti,j,k;i=3,j=5;,i,j,k,7,变量的地址:变量在内存中占用几个连续的字节,开始字节的地址,就是变量的地址。,2007,变量的指针:一个变量的地址称为该变量的指针,指针是内存地址的别名。,指针变量:若一个变量专用于存放另一个变量的地址(指针),则该变量称为指针变量(特殊性,指针变量的存储单元存放的不是普通数据,而是地址),注意区分“指针”和“指针变量”这两个概念。,指针的对象:当把变量的地址存入指针变量后,我们就可以说这个指针指向了该变量。,变量的存取方法:直接存取和间接存取,10,数据所占有的内存单元个数是由其数据类型决定的;,首地址:即第一个内存单元的地址;,表示地址的数与整数的区别;,变量i、j的地址可能相邻,也可能不相邻,是由系统分配的,我们不必关心。,3.说明,程序中定义的每个变量在编译后都占有各自的内存单元,系统是通过内存地址对变量进行存取的;,变量的指针和指向变量的指针变量,一、指针变量的定义,例如:int*ptr1,*ptr2;,指针变量的类型:指明了该指针指向的内存空间所存储的数据的类型,在定义指针变量时要注意以下几个问题:,变量名ptr2前面的*”不能省略,如果写成int*ptr1,ptr2;则ptr2被定义为整型变量,而非整型指针变量。,12,定义中的*”表示所定义的变量是指针变量,但指针变量名是ptr1、ptr2,而非*ptr1、*ptr2。,指针变量只能指向定义时所规定类型的变量。这个规定的类型称为该指针变量的基类型”。,如:上例中ptr1、ptr2只能指向整型变量,不能指向实型或字符型变量。其基类型”相同,都是整型。,定义指针变量后,并未确定该变量指向何处。即该变量的值是不确定的。在引用指针变量前必须首先让它指向一个变量,这一点非常重要。,13,二、指针变量的运算,指针运算符(/等价于i=15,由此可见:通过指针运算符*”可以引用一个变量。如:当ptr已经指向变量i后,*ptr就等同于i。,进一步理解pi=,把指针变量的值赋给另一个指针变量。,如:inti,*pa,*pb;pa=,给指针变量赋值为符号常量NULL。,说明:NULL是一个空指针,表示该指针变量的值没有意义。作用是为了避免对没有被初始化的指针变量的非法引用。NULL的定义在stdio.h”中。,如:int*pi;pi=NULL;,16,说明:,(1)在定义指针变量时,可以立即将一个地址值赋给指针变量,这就是指针变量的初始化。,如:floatflt,*f_ptr=,(2)指针变量间的赋值和引用应保证基类型相同。,若有定义:int*p,i;float*q,x;,则:q=,(3)可以将数组名或函数名赋给某些类型的指针变量;,inta10,*ip;,ip=,ip=a;,(4)不能将一个整型量(或任何其它非地址类型的数据)赋给一个指针变量;,int*ip;,ip=3000;,#includevoidmain()inta1=11,a2=22;int*p1,*p2;p1=,int*p1,*p2,*p;p1=,int*p1,*p2;p1=,ptr1=,x的值是?,3,2指针的+、-、+=、-=运算,+、+=:移动指针到下一个或下几个存储单元,-、-=:移动指针到上一个或上几个存储单元,例如:int*ptr,ary5=2,4,6,8,10;,ptr=ary;,ptr+=3;,ptr-;,23,三、指针变量作为函数参数,指针可以用作函数参数,这在调用函数希望改变参数的值时非常有用。,例如:编写函数,实现两个数的交换,例:输入两个整数a、b,按大小顺序输出。,#includevoidswap(intx,inty)inttemp;temp=x;x=y;y=temp;voidmain()inta,b;printf(nInputa,b:);scanf(%d%d,注意:语言中的函数调用采用“传值”方式,即单向传递方式。,即:主调函数可以将实参的值传递给被调函数的形参,但不能通过改变形参的值而改变实参的值。,输入:a=5,b=8输出:?,max=5,min=8,#includevoidswap(int*px,int*py)inttemp;temp=*px;*px=*py;*py=temp;voidmain()inta,b,*p1,*p2;printf(nInputa,b:);scanf(%d%d,*temp=*px;*px=*py;*py=*temp;voidmain()inta,b,*p1,*p2;printf(nInputa,b:);scanf(%d%d,错误:*temp是指针变量temp所指向的变量,但temp中并无确定的地址值,其值不确定;*temp所指向的单元也不确定。因此,对*temp赋值可能会破坏系统的正常工作状况。,修改:应该将*px的值赋给一个整型变量,用整型变量作为临时存储空间实现*px和*py的交换。,#includevoidswap(int*px,int*py)int*p;p=px;px=py;py=p;voidmain()inta,b,*p1,*p2;printf(nInputa,b:);scanf(%d%d,for(i=1;in;i+),if(*pmaxxi)*pmin=xi;,inta20,max,min;for(i=0;i20;i+)scanf(%d,search(a,20,29,指针和数组,一、数组的指针和指向数组的指针变量的概念,数组的指针:数组在内存中的起始地址。,数组元素的指针:数组元素的起始地址。,当指针变量指向数组或数组元素时,它就是指向数组的指针变量。,C规定:,数组名代表数组的首地址(起始地址),即第一个元素的地址。,当指针变量p指向数组时,p+1指向数组的下一个元素。假设一个整型元素占两个字节,p+1是使p的地址加2个字节。,如:inta10,*p;则:p=a;与p=等价称指针变量p指向数组元素a0,p+i、a+i、b25=200;,2.用指针法引用数组元素,如:inta10,*p,i;p=a;,则:*(p+i)、*(a+i)代表元素ai,*(p+i)也可以写成pi,31,程序举例:输出10个元素数组中的全部元素。,方法2:通过数组名计算数组元素地址,找出元素的值main()inta10=54,65,8,2,3,56,8,21,57,98,i;for(printf(n),i=0;i10;i+)printf(%4d,*(a+i);,方法1:下标法main()inta10=54,65,8,2,3,56,8,21,57,98,i;for(printf(n),i=0;i10;i+)printf(%4d,ai);,方法3:用指针变量指向数组元素main()inta10=54,65,8,2,3,56,8,21,57,98,*p,i;p=a;for(printf(n),i=0;i10;i+)printf(%4d,*p+);,以上三种方法,利用指针变量效率最高!,程序举例:输出10个元素数组中的全部元素。,33,说明:,指针变量是地址变量,数组名是地址常量。即指针变量的内容可以在程序运行过程中被改变;而数组名一旦被定义,它的值就不能被改变了。,例如:inti,*p,a6;则:p=,不能给常量赋值,指针变量与数组名的区别:,利用指针变量编程时特别要注意指针变量的当前值。例如:通过指针变量输入输出a数组元素。,main()int*p,i,a10;p=a;for(i=0;i10;i+)scanf(%d,p+);for(printf(n”),i=0;i10;i+)printf(%6d”,*p+);,应插入语句p=a;,注意:*p+、*(p+)、(*p)+、*(+p)的含义,35,#includevoidmain()int*p,ary5=2,4,6,8,10;p=ary;p+=3;p-;/*p为6printf(%4dn,*p+);/printf(%4dn,*(p+);/printf(%4dn,(*p)+);/printf(%4dn,*(+p);,例如:指针变量的不同表示形式,输出结果是?,/6,/6,/6,/8,36,*ptr+和*(ptr+)是一样的么?,*与+的优先级一样在*和+同时出现的情况下依据从右到左的原则ptr+先取值再加一.所以*ptr+的意思是先取ptr的指针值,然后指针值后移指向下个元素*ptr+的结果还是*ptr,只有到下个循环时*ptr的值才是后个元素,三、数组名作函数的参数,例如:f(intarr,intn)main()intarray10;f(array,10);,解释:实际上,能够接受并存放地址值的只能是指针变量。因此,C编译系统都是将形参数组名作为指针变量来处理的。上例中f(intarr,intn)等价于f(int*arr,intn)。,使用形参数组的概念只是为了与实参数组对应,直观,便于理解而已。,归纳起来,实参与形参的对应关系有:,、形参和实参都用数组名:,f(intx,intn);,f(a,10);,把实参数组首地址传给形参作为形参数组首地址;,、实参用数组名,形参用指针变量:,f(int*x,intn);,f(a,10);,把实参数组首地址传给形参(指针变量),函数中用指针访问实参数组,、形参和实参都用指针变量:,f(int*x,intn);,f(p,10);,函数调用前应先给实参指针变量赋值(如:int*p=a),、实参为指针变量,形参为数组名:,f(intx,intn);,f(p,10);,实参通过指针变量为形参提供数组首地址;,34/55,inta10;,39,例:从10个数中找出其中最大值和最小值。,#includevoidmax_min(inta,intn,int*max,int*min);main()inti,a=2,4,1,6,7,32,45,75,45,90,max,min;for(printf(Theoriginalarray=),i=0;iai)*min=ai;,40,上例中如果形参数组用指针变量,则程序如下:,#includevoidmax_min(int*x,intn,int*max,int*min);main()inti,a=2,4,1,6,7,32,45,75,45,90,max,min;for(printf(Theoriginalarray=),i=0;i*x)*min=*x;,指针和字符串,字符串的指针:字符数组在内存中存放的首地址。,指向字符串的指针变量:专门用来存放字符数组首地址的变量。,字符指针变量定义时可以赋初值。,C程序访问字符串有以下两种方法:,1用字符数组存放一个字符串,例如:chars=Iamastudent.;,字符串输出语句可写成:printf(%sn,s);for(i=0;si;i+)printf(%c,si);for(i=0;si;i+)printf(%c,*(s+i);,也可用si!=0,2用字符指针指向一个字符串,例如:char*ps=Iamastudent.;,字符串输出语句可写成:printf(%sn,ps);for(;*ps;ps+)printf(%c,*ps);,说明:,字符数组由若干个元素组成,每个元素中放一个字符。而字符指针变量中存放的是地址(字符串的首地址),决不是将字符串放到字符指针变量中;,字符数组和字符指针变量都可以在定义时赋初值,但以下方法对字符数组非法,对字符指针变量合法:,44,字符数组名是指针常量,只能表示一个确定的字符串,不能改变。而字符指针变量的值是可以改变的,它可以代表不同的字符串。,若定义了一个指针变量,并使它指向一个字符串,就可以用下标形式引用指针变量所指字符串中的字符。,如:char*a=IloveChina!;printf(%c”,a5);,若把字符指针所指对象当作数组使用,应注意对象的长度,如:charstr110,*ps=str1;ps10=0;,45,程序举例:将字符串a复制为字符串b。,#includemain()chara=Itisadog.,b20;inti=0;do*(b+i)=*(a+i);i+;while(*(a+i)!=0);/*也可写成while(*(a+i);*/puts(b);,46,上例程序还可写成:,#includemain()chara=Itisadog.,b20,*p1=a,*p2=b;inti=0;do*p2=*p1;p2+;p1+;while(*p1!=0);/*也可写成while(*p1);*/puts(b);,指针函数,一、指针函数,返回指针的函数称作指针函数。,含意:函数的返回值是一个指针,它指向所定义类型的数据。,例如:int*a(intx,inty);/*函数原型声明*/含义:a是函数名,调用它以后能得到一个指向整型数据的指针(地址)。,48,例:编写能返回结果串地址的串拷贝函数。,#includechar*strcpy1(char*str1,char*str2);main()char*ps,s180=yhhhj;ps=strcpy1(s1,fdgjdfh);puts(ps);char*strcpy1(char*str1,char*str2)char*s=str1;while(*str2)*str1+=*str2+;*str1=0;returns;,49,函数的指针,1.函数的指针(地址)概念,每一个函数都占用一段内存,在编译时,被分配一个入口地址,这个入口地址就称为函数的指针。,2.指向函数的指针变量,例如:float(*p)();含意:定义了p是指向函数的指针变量,函数的返回值是float类型。,50,(*p)()表示定义一个指向函数的指针变量,它不是固定指向哪个函数。,注意:,对指向函数的指针变量,p+n,p+,p-等运算是无意义的。,注意区别int(*p)()、int*p(),51,3.对指向函数的指针变量赋值,将一个函数的函数名(代表入口地址)赋值给指向函数的指针变量,也称该指针变量指向了这个函数。,如:intmax(intx,inty);/*函数的原型声明*/int(*p)();p=max;,注意:赋值时,只需给出函数名而不必给出参数。,4.函数的调用,例如:若有定义intmax(intx,inty);int(*p)(),a,b,c;p=max;则可有语句c=(*p)(a,b);,53,指针数组,一、指针数组,数组中每个元素是基类型相同指针变量。,例如:int*p2;含意:p是一个一维指针数组,每个元素都是一个指向整型变量的指针变量。可以将整型变量的地址赋值给元素p0或p1。,54,二、指针数组的应用,利用指针数组处理多个串,方法:先用指针数组指向字符数组,再处理。,main()charname80=aaa,bbb,ccc,ddd,eee;char*pname10,i;for(i=0;i5;i+)pnamei=namei;for(i=0;i0)swap(s1,s3);if(strcmp(s2,s3)0)swap(s2,s3);printf(n%10s%10s%10s,s1,s2,s3);voidswap(char*ps1,char*ps2)charps100;strcpy(ps,ps1);strcpy(ps1,ps2);strcpy(ps2,ps);,常用的字符串操作函数,58,例题3:写一函数,实现两个字符串的比较。相等的结果为0,不等时结果为第一个不相等字符的ASCII差值。,#includecmps(char*p,char*q);main()chars1128,s2128;gets(s1);gets(s2);printf(cmps(s1,s2)=%d,cmps(s1,s2);cmps(char*p,char*q)for(;*p!=0,char*gets(char*);参数为从标准输入得到的字符串存储的指针.返回值也是一个指针.如果函数执行失败返回值是一个NULL,59,例题4:写一个函数,求字符串的长度,在main函数中输入字符串,并输出其长度。,#includeintlen(char*ps);main()charstr30;gets(str);printf(nlen=%d,len(str);intlen(char*ps)intn=0;while(*ps+)n+;returnn;,60,例题5:有一字符串包含N个字符,写一个函数,将字符串中从第M个字符开始的全部字符复制成为另一个字符串。,#include#includescopy(char*psn,char*psm,intm);main()charsn100=fasjfkjsdfsdfjsdjkfdfjssdf,sm100;intn=strlen(sn),m=n/2;scopy(sn,sm,m);printf(nsn=%snm=%dnsm=%s,sn,m,sm);scopy(char*psn,char*psm,intm)while(*(psn+m)*psm+=*(m+psn+);*psm=0;,例题6-1:求a和b中的大者-用函数名调用函数m

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论