c语言程序设计(第五章12-22).ppt

上传人:tia****nde 文档编号:12805524 上传时间:2020-05-25 格式:PPT 页数:80 大小:284KB
返回 下载 相关 举报
c语言程序设计(第五章12-22).ppt_第1页
第1页 / 共80页
c语言程序设计(第五章12-22).ppt_第2页
第2页 / 共80页
c语言程序设计(第五章12-22).ppt_第3页
第3页 / 共80页
点击查看更多>>
资源描述
第五章指针,重点:1、指针的概念2、指针与数组的应用3、指针与字符串4、指向指针的指针,指针是在C语言中广泛使用的一种数据类型。指针能够模拟引用调用;能够建立和操作动态数据结构(如链表、队列、堆栈和树);能很方便的使用数组和字符串;并能处理内存地址,从而编出精炼高效的程序。,5.1指针的基本概念,计算机中的所有数据是存放在存储器里的。一般将存储器中的一个字节称为一个内存单元。我们为每个内存单元编上号,使之能正确的访问这些内存单元。内存单元的编号也称为地址。指针变量则是将内存地址作为其值的变量。,指针变量的值不仅可以是变量的地址,还可以是其他数据结构的地址,比如说数组、函数的首地址。,一个指针是一个地址,是一个常量,而一个指针变量却可以被赋予不同的指针值,即取值为不同地址的变量。定义它的目的是为了通过指针变量去访问内存单元。变量的指针就是变量的地址,存放变量地址的变量是指针变量。,i=3;*i_point=3;,i,2000H,5.2指针变量的定义和初始化,5.2.1指针变量的定义,格式:类型说明符*变量名例:int*p1;/p1是一个指向整型变量的指针变量float*p2;char*p3;注意:一个指针变量只能指向同类型的变量。,5.2.2指针变量的初始化,指针变量可以用定义语句或赋值语句进行初始化。例:intx,y;int*ipx=在使用指针之前一定要将指针指向一个确定的地址。未被初始化的指针称为“无向指针”,使用该指针非常危险。可以将指针初始化为0、NULL或某个地址。具有值NULL的指针不指向任何值。NULL是在头文件中定义的符号常量。把一个指针初始化为0等价于把它初始化为NULL,但使用NULL更好。值0是唯一能够直接赋值给指针变量的整型数。,5.3指针运算符,5.3.1取地址运算符ip=,*和,5.4指针变量的运算,5.4.1赋值运算,指针变量的赋值运算有以下的几种形式:指针变量初始化赋值。把一个变量的地址赋予指向相同数据类型的指针变量。把一个指针变量的值赋予指向相同类型变量的另一个指针变量。例:inti,*ip=把数组的首地址赋予指向数组的指针变量。,例:inta5,*pa;pa=a;或pa=,inti;int*p=,int*p=,main()inti=10;int*p;*p=i;printf(“%d”,*p);,程序的输出结果?main()inta=10,b;int*ipa=,main()inta=10,b;int*ipa;b=*ipa;printf(“%d”,b);,main()inta=10,b;int*ipa;*ipa=a;b=*ipa;printf(“%d”,b);a=100;b=*ipa;printf(“%d”,b);,通过指针变量实现两变量值的交换,法1:main()inta=10,b=20,t=0;printf(“na=%d,b=%d”,a,b);t=a;a=b;b=t;printf(“na=%d,b=%d”,a,b);getch();,法2:main()inta=10,b=20,t=0,*pa=,5.4.2加减算术运算,指针可进行的算术运算有:自增运算(+)、自减运算(-)、加上一个整数(+或+=)、减去一个整数(-或-=)、减去一个指针。1、指针变量加或减一个整数ip+,ip-,ip+n,ip-n,ip+=n,ip-=n当一个指针变量加或减一个整数时,并不是指针变量加(减)一个整数n,它的实质意义是加上或减去该整数与指针指向对象的大小的乘积。对象的大小(即字节数)取决于对象的数据类型。即将指针由当前位置向前(向后)移动n个数据位置。,.,2000H,2002H,2004H,3000H,3004H,a0,a1,a2,x0,x1,指针变量ipa,inta=10,20,30;floatx=15.5,25.5;int*ipa=a;float*fpx=,指针变量fpx,2、两指针变量相减两指针变量相减所得之差是两个指针所指数组元素之间相差的元素个数。实质上是两个指针值(地址)相减之差再除以该数组元素的长度(字节数)。注:两个指针变量不能进行加法运算。,main()inta=1,2,3,4,5,6,7,8,9,10;int*ip1=a,*ip2=,3、指针变量的使用指针变量可出现在表达式中例:intx,y,*px=,5.4.3两指针变量进行关系运算,指向同一数组的两指针变量可以进行关系运算,pa;若两个指针指向同一个数组的元素,则指向前面元素的指针变量小于指向后面元素的指针变量。,程序的运行结果:main()inta=1,2,3,4,5,6,7,8,9,10;int*ip1=,5.5指针和数组,5.5.1指向数组的指针变量,例intarray10;int*p;p=P是变量,array,for(i=0;i5;i+)ai=i+1;pa=a;for(i=0;i5;i+)printf(*(pa+%d):%dn,i,*(pa+i);for(i=0;i5;i+)printf(*(a+%d):%dn,i,*(a+i);for(i=0;i5;i+)printf(pa%d:%dn,i,pai);for(i=0;i5;i+)printf(a%d:%dn,i,ai);,数组元素的四种引用方法,5.5.3通过指针引用数组元素时应注意的几个问题,1)指针变量可以实现本身的值的改变,例inta=1,2,3,4,5,6,7,8,9,10,*p=a,i;数组元素地址的正确表示:(A)p=a;for(i=0;i7;i+)scanf(%d,p+);printf(n);p=a;for(i=0;i7;i+,p+)printf(%d,*p);,指针变量可以指到数组后的内存单元,3)注意运算符+、-、inty,*p=,输出:56,*p+*(p+)(*p)+*(p-)*(+p)*(-p),通过指针引用数组元素来输出一个一维数组。,#defineN5main()intaN;int*p=a;printf(“npleaseinput%dnumber:”,N);for(;pa+N;p+)scanf(“%d”,p);printf(“n”);for(p=a;pa+N;p+)printf(“%d”,*p);,通过指针引用数组元素实现一位数组的反序输出,#defineN5main()intxN,*p=x,*q=x+N-1,j,t;clrscr();for(j=0;jN;j+)scanf(“%d”,p+j);for(;pq;p+,q-)t=*p;*p=*q;*q=t;for(j=0,p=x;jN;j+)printf(“%d”,*(p+j);,01234567891011,inta340,1,2,3,4,5,6,7,8,9,10,11,5.5.4指向二维数组的指针,1、二维数组和数组元素的地址,1000,1008,1016,a0,a1,a2,(1)从2维数组角度看,数组名a代表整个二维数组的起始地址,是一个以行为单位进行控制的行指针:a+i:行指针值,指向2维数组的第i行,代表第i行的首地址。,a,a+1,a+2,(2)从1维数组角度看,数组名a和第1维下标的每一个值,共同构成一组新的1维数组名a0、a1、a2,它们均由4个元素组成。语言规定:数组名代表数组的地址,所以ai是第i行1维数组的地址,它指向该行的第0列元素,是一个以数组元素为单位进行控制的列指针:ai+j:(列)指针值,指向数组元素aij。*(ai+j):表示数组元素aij的值。如果有“inta34,*p=a0;”,则p+1指向下一个元素用p作指针访问数组元素aij的格式:*(p+(*每行列数+j),*(a+i):(列)指针值,指向第i行第列(控制由行转为列,但仍为指针),表示一维数组第0列的元素地址。*(*(a+i):表示数组元素ai0的值。用a作指针访问数组元素aij的格式:*(*(a+i)j),例:通过指向数组元素的指针输出二维数组的各元素。,main()inta32=1,2,3,4,5,6,*pa;clrscr();for(pa=,用不同的表示方法输出二维数组a每行的起始地址和每行的起始单元的值。,#includevoidmain()inta34=0,1,2,3,4,5,6,7,8,9,10,11;printf(“,printf(“a00-%dn”,a00);printf(“*(a0+0)-%dn”,*(a0+0);printf(“*(*(a+0)+0)-%dn”,*(*(a+0)+0);printf(“,2、指针数组的概念,定义:数组中的元素值为指针。它是一组有序的指针的集合。格式:类型说明符*数组名数组长度,指针值所指向的变量的类型,int*pa3;,指针数组赋值和初始化,初始化:main()intb23,*pb=b0,b1;.,通常可用一个指针数组来指向一个二维数组。指针数组中的每个元素被赋予二维数组每一行的首地址,因此也可理解为指向一个一维数组。,#includevoidmain()inta33=1,2,3,4,5,6,7,8,9;int*pa3;int*p=a0,i,j;for(i=0;i3;i+)pai=ai;for(i=0;i3;i+)printf(“%p-%dn”,pai,*pai);,for(i=0;i3;i+)for(j=0;j3;j+)printf(“%p-%d”,p,*p);p=p+1;printf(“n”);,指针可以指向整型、实型及任何类型,也可以指向一个数组类型,成为数组指针变量。格式:类型说明符(*指针变量)长度;类型说明符:为所指数组的数据类型*:表示其后的变量是指针类型长度:表示二维数组分解为多个一维数组时,一维数组的长度,即二维数组的列数。,3、指向数组的指针变量,设p为一个指向数组的指针变量,可定义为:int(*p)4;它表示p是一个数组指针变量,它可以指向包含4个元素的一维数组。当p指向一个二维数组时,p+i表示指向一维数组ai,即二维数组的第i行*(p+i)+j表示二维数组i行j列的元素的地址*(*(p+i)+j)表示二维数组i行j列的元素的值,通过指向整型变量的指针变量输出二维数组任意一行、任意一列的元素值。,#includevoidmain()inta34;int(*p)4;inti,j;printf(“pointerofarray:n”);p=a;for(i=0;i3;i+)for(j=0;j4;j+)scanf(“%2d”,*(p+i)+j);,printf(“n”);printf(“pleaseinputij:n”);scanf(“%d%d”,指针数组和二维数组指针变量的区别:指向二维数组的指针变量是单个的变量,其形式为“(*指针变量名)”.指针数组类型表示的是多个指针(一组有序指针),一般在指针数组名的两边不能有括号。例:int(*p)3;表示p是一个指向二维数组的指针变量,该二维数组的列数为3或分解为一维数组的长度为3。int*p3表示p是一个指针数组,有三个下标变量p0、p1、p2,均为指针变量。,二维数组与指针数组区别:,charname59=“gain”,“much”,“stronger”,“point”,“bye”;,char*name5=“gain”,“much”,“stronger”,“point”,“bye”;,指针数组元素的作用相当于二维数组的行名但指针数组中的元素值是地址值。二维数组存储空间固定字符指针数组相当于可变列长的二维数组,5.6指向字符串的指针变量,5.6.1字符串表示形式,1)用字符数组存放一个字符串例:main()charstring=“IloveChina!”;printf(“%sn”,string);printf(“%sn”,string+7);,2)用字符串指针指向一个字符串,字符指针初始化:把字符串首地址赋给stringchar*string;string=“IloveChina!”;例main()char*string=“IloveChina!”;printf(“%sn”,string);string+=7;while(*string)putchar(string0);string+;,*string!=0,5.6.2使用字符串指针变量与字符数组的区别,(1)字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一片连续的内存空间中并以“0”作为串的结束,这片空间是无名的。字符数组是由若干个数组元素组成的,它在内存中也占有一片连续的空间,但是它是有名的、有固定的空间,也可用来存放整个字符串。(2)字符串的赋值方式,字符串与数组关系字符串用一维字符数组存放字符数组具有一维数组的所有特点数组名是指向数组首地址的地址常量数组元素的引用方法可用指针法和下标法数组名作函数参数是地址传递等区别存储格式:字符串结束标志赋值方式与初始化输入输出方式:%s%c,charstr=“Hello!”;()charstr=“Hello!”;()charstr=H,e,l,l,o,!;()char*cp=“Hello”;()inta=1,2,3,4,5;()int*p=1,2,3,4,5;(),charstr10,*cp;inta10,*p;str=“Hello”;()cp=“Hello!”;()a=1,2,3,4,5;()p=1,2,3,4,5;(),赋值方式:,字符指针变量与字符数组char*cp;与charstr20;str由若干元素组成,每个元素放一个字符;而cp中存放字符串首地址charstr20;str=“IloveChina!”;()char*cp;cp=“IloveChina!”;()str是地址常量;cp是地址变量cp接受键入字符串时,必须先开辟存储空间,例charstr10;scanf(“%s”,str);()而char*cp;scanf(“%s”,cp);(),改为:char*cp,str10;cp=str;scanf(“%s”,cp);(),例:使用指向字符串常量的指针来处理不同长度的字符串。,main()char*p=“Iamastudent”;printf(“n%s”,p);p=“Youareateacher.”);printf(“n%s”,p);getch();,例:从键盘输入两个字符串s1,s2,然后将s2的内容合并到s1的后面。,#defineN40#defineM20main()inti,j;chars1N,s2M,*p1,*p2;p1=s1;p2=s2;printf(“ninputs1:”);gets(s1);printf(“ninputs2:”);,gets(s2);while(*p1)p1+;while(*p2)*p1+=*p2+;*p1=0;printf(“resultis:%s”,s1);,从键盘输入一个字符串,删除其中与字符变量c相同的字符。,#include“stdio.h”#include“string.h”main()charstr20,*s=str,c;inti,n;clrscr();printf(“nenters:”);gets(s);printf(“nenterc:”);c=getchar();,n=strlen(s);for(i=0;in;i+)if(*s=c)strcpy(s,s+1);elses+;s=str;puts(s);getch();,从键盘中输入两个字符串s1,s2,然后从s1中删除任何在s2中出现的字符。,#defineN40main()inti;chars1N,s2N,*p1,*p2;printf(“ninputs1:”);gets(s1);printf(“ninputs2:”);gets(s2);p1=s1;,for(i=0;*(p1+i)!=0;i+)for(p2=s2;*p2!=0;p2+)while(*(p1+i)=*p2)strcpy(,5.7指向指针的指针变量,一级指针:指针变量中存放目标变量的地址,例int*p;inti=3;p=,int*p2;inti=3;p2=,二级指针,一级指针,目标变量,二级间接寻址,定义形式:存储类型数据类型*指针名;如char*p;,最终目标变量的数据类型,*p是p间接指向对象的地址*p是p间接指向对象的值,例inti=3;int*p1;int*p2;p1=,例inti,*p;p=()/p是二级指针,不能用变量地址为其赋值,指向指针的指针通常用于操作指针数组,读程,写结果main()inti,j;char*p;char*str=“monitor”,”landscape”,”paddle”,”partition”,”current”;p=str;,for(i=0;i5;i+)printf(“n%s”,pi);for(i=0;i5;i+)printf(“n%d”,(*p)+);,stri*(p+i),5.8用于动态内存分配的函数ANSIC标准为动态分配系统定义了四个函数:malloc、calloc、free、realloc。它们必须包含在文件stdlib.h或malloc.h中。库函数malloc、calloc是在内存中申请存储单元,并把存储单元的开始地址赋值给指针变量。库函数free是将指针变量所指向的存储空间释放。,1、malloc()函数格式:void*malloc(unsignedsize)功能:在内存中分配一个指定长度(以字节为单位)的存储空间,函数返回指向分配的存储区起始地址的指针。由于函数的返回值为无值型的指针,因此在把返回值赋予具有一定数据类型的指针变量时,应该对返回值实行强制类型转换。例:int*p;float*q;p=(int*)malloc(2);q=(float*)malloc(4);,2、free()函数格式:voidfree(void*prt)功能:释放由prt所指向的内存空间,以便这些空间可再次分配使用。,3、calloc()函数格式:void*calloc(unsignednum,unsignedsize)功能:在内存中分配一块连续的容量为num*size的存储空间,num为需要分配的元素个数,size为每个元素所占的内存空间。函数返回一个指向被分配内存的指针。,4、realloc()函数格式:void*realloc(void*p,unsignedsize)功能:将指针p所指向的已分配的内存区的大小改为size,size可比原来分配的空间大或小。返回指向该内存区的指针。,例:要求键盘上输入要逆序的数据个数n和n个数据,根据输入的n值用动态存储分配临时申请存储单元。,#include“stdio.h”#include“stdlib.h”main()inti,n,w,nn,*a;while(1)printf(nentern:”);scanf(“%d”,a=(int*)malloc(n*sizeof(int);if(!a)printf(“allocationerror_aborting”);exit(1);printf(“nentera0a1a%d:”,n);for(i=0;in;i+)scanf(“%d”,a+);a=a-n;nn=n/2;,for(i=0;inn;i+)w=ai;ai=an-i-1;an-i-1=w;printf(“thearrayhanbeeninverted:n”);for(i=0;in;i+)if(i%5=0)printf(“n”);printf(“%5d”,*(a+i);getch();,例58将已知的5个字符串按字典顺序将其重新排列。,#defineN5#include#includemain()inti,j;char*t;char*str=monitor,landscape,paddle,partition,current;,for(i=1;i0)t=strj;strj=strj+1;strj+1=t;for(i=0;iN;i+)printf(ns,stri);,二维数组的方式:#defineN5#include#includemain()inti,j;char*t;charstr20=monitor,landscape,paddle,partition,current;,for(i=0;i0)t=strj;strj=stri;stri=t;for(i=0;iN;i+)printf(ns,stri);,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!