C语言教程 第10章1

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

第10章指针第10章指针第10章指针每一个学习和使用C语言的人,都应当深入地学习和掌握指针。可以说,不掌握指针就是没有掌握C的精华。这一章是这本书中的重点与难点,是重中之重。第10章指针10.1地址和指针的概念…359…ijk2000200220042006pt200020022004问:可以定义出存放整型数的变量i、j、k,那么,能否定义出用于存放地址的变量呢?第10章指针pt就是一个存放地址的变量,是一个指针变量。指针是地址的一种较为形象的叫法。其实,指针就是地址,地址就是指针。当pt中存放的是2004时,pt叫作指针变量,指针变量中的值是一个地址,即2004。注意,区分“指针”和“指针变量”,指针是一个地址,而指针变量是存放地址的变量第10章指针10.2变量的指针和指向变量的指针变量10.2.1定义一个指针变量一般形式:基类型*指针变量名;如,int*pt;int*pt;int*pt;int*pt1,*pt2;(不能写为int*pt1,pt2;或int*pt1,pt2;)第10章指针…359…ijk2000200220042006pt2004问:如图所示,若没有定义变量k,能否将2004单元中的9改为20呢?*pt=20;20*pt表示指针pt所指向单元的内容。10.2.2指针变量的引用第10章指针例10.1main(){inta=100,b=10;int*pt1,*pt2;pt1=&a;pt2=&b;printf(“%d,%d\n”,a,b);printf(“%d,%d\n”,*pt1,*pt2);}ab10010pt1pt2&a&b取地址符第10章指针main(){inta=100,b=10;int*pt1=&a,*pt2=&b;*pt1=15;*pt2=30;printf(“%d,%d\n”,a,b);printf(“%d,%d\n”,*pt1,*pt2);}ab10010pt1pt2&a&b1530int*pt1=&a,*pt2=&b;*pt1=15;*pt2=30;pt1指向a,pt2指向b。第10章指针int*pt1=&a,*pt2=&b;*pt1=15;*pt2=30;注意,这两处*的意义是不同的。上面的*处于定义位置,它的作用是表明pt1与pt2为指针。而下面的*则表示引用pt1与pt2所指向单元的内容。即一个表示定义指针,一个表示引用内容。第10章指针答:错,因为它相当于&(*a),而*a是不对的。在混合使用&和*时,要注意分清它们各自的运算对象和运算时的结合性。如,inta,*p;p=&a;*&a*(&a)*pa&*p&(*p)&ap问:&*a对吗?对于*&p,知道就是P即可。至于原因,学完第10章就清楚了。第10章指针10.2.3指针变量作为函数参数例10.3对输入的两个整数按大小顺序输出。main(){voidswap(int*p1,int*p2);inta,b,*pt1,*pt2;scanf(“%d,%d”,&a,&b);pt1=&a;pt2=&b;if(ab)swap(pt1,pt2);printf(“\n%d,%d\n”,a,b);}第10章指针voidswap(int*p1,int*p2){intt;t=*p1;*p1=*p2;*p2=t;}ab59pt1pt2p1p2第10章指针voidswap(int*p1,int*p2){int*t;*t=*p1;*p1=*p2;*p2=*t;}ab59pt1pt2p1p2t595第10章指针这个程序是危险的。是因为指针t没有明确指向,所以有可能指向系统区,从而将系统区中的数据修改。若要消除危险,只需给t一个明确指向。如,intd,*t=&d;(因为d为局部变量,存储在动态数据区,也即存放在用户区,从而不会在系统区。这样t就指向了用户区)。第10章指针voidswap(int*p1,int*p2){int*t;t=p1;p1=p2;p2=t;}ab59pt1pt2p1p2交换前交换后由图可知,p1、p2交换前后没有任何变化,故,此程序没有任何用处。第10章指针main(){voidswap(intp1,int*p2);inta,b,pt1,*pt2;scanf(“%d,%d”,&a,&b);pt1=a;pt2=&b;if(ab)swap(pt1,pt2);printf(“\n%d,%d\n”,a,b);}第10章指针p1voidswap(intp1,int*p2){intt;t=p1;p1=*p2;*p2=t;}ab59pt2p2pt155第10章指针10.3数组与指针10.3.1指向数组元素的指针由于数组元素就是一个普通的变量,所以指向数组元素的指针就是指向普通变量的指针。第10章指针10.3.2通过指针引用数组元素共同回忆:数组名是一个地址,是一个指针,是一个指针常量,它指向数组在内存的起始位置。第10章指针59-6813a[0]a[1]a[2]a[3]a[4]aa+1a+2a+3a+4inta[5]={5,9,-6,8,13};数组元素a[i]可表示为*(a+i)由于a为一个整型指针,所以a+1中加的1为一个整型数所占内存空间,即2字节第10章指针main(){inti,a[5]={5,9,-6,8,13};for(i=0;i5;i++)printf(“%d”,a[i]);}main(){inti,a[5]={5,9,-6,8,13};for(i=0;i5;i++)printf(“%d”,*(a+i));}第10章指针59-6813a[0]a[1]a[2]a[3]a[4]pp+1p+2p+3p+4int*p=a;a由于p为一个整型指针,所以p+1中加的1为一个整型数所占内存空间,即2字节数组元素a[i]可表示为*(p+i)第10章指针main(){inti,a[5]={5,9,-6,8,13};int*p=a;for(i=0;i5;i++)printf(“%d”,*(p+i));}问:a[i]等价于*(a+i),那么*(p+i)能否等价于p[i]呢?答:完全可以。第10章指针main(){inti,a[5]={5,9,-6,8,13};int*p=a;for(i=0;i5;i++)printf(“%d”,p[i]);}问:p[i]是否就永远等于a[i]呢?答:不是。因为p为一个指针变量,是否与a[i]相等,主要看p的初值。第10章指针main(){inti,a[5]={5,9,-6,8,13};int*p=a+2;for(i=0;i3;i++){printf(“%d”,*(p+i));printf(“%d”,p[i]);}}59-6813a[0]a[1]a[2]a[3]a[4]pp+1p+2a+2第10章指针由于p是一个指针变量,所以还可以这样写:main(){inti,a[5]={5,9,-6,8,13};int*p;for(p=a;pa+5;p++)printf(“%d”,*p);}59-6813a[0]a[1]a[2]a[3]a[4]a+5appppp第10章指针main(){inti,a[5]={5,9,-6,8,13};int*p=a;for(;ap+5;a++)printf(“%d”,*a);}问:程序能否改为如下形式呢?答:绝对不能!因为a为数组名,是一个指针常量。第10章指针10.3.3用数组名作函数参数(2)用数组名作函数实参时,不是把数组的值传递给形参,而是把实参数组的起始地址传递给形参数组,两个数组共占同一段内存单元。回忆:例8.11(P179)当时讲到:(1)数组名是一个地址,是一个指针,是一个指针常量,它指向数组在内存的起始位置。第10章指针数组名作形参,其实质是一个指针变量。f(intarr[],intn)与以下方式是等价的,并且即使写为以上形式,系统在编译时也会将它转换为以下方式:f(int*arr,intn)注意,数组名原本是一个指针常量,但惟独作形参时,是一个指针变量。第10章指针问:以下形式是否合法voidf(intarr[],intn){…arr=arr+3;…}答:合法。因为数组名作形参是一个指针变量,而非常量。第10章指针10.3.4多维数组与指针第10章指针10.4字符串与指针10.4.1字符串的表示形式(1)用数组存放一个字符串main(){charstring[]=“China”;printf(“%s”,string);}第10章指针(2)用字符型指针指向一个字符串。main(){char*string=“China”;printf(“%s”,string);}字符型指针string实际上指向了字符串“China“在内存中的首位置,即string中存放的是字符‘C’的地址。以后在使用过程中,便可将字符型指针当作字符串来用。返回第10章指针10.4.3对使用字符指针变量和字符数组的讨论(1)存放内容不同字符数组由若干个元素组成,每个元素中存放一个字符;而字符指针变量中存放的是一个地址,决不是将字符串放到字符指针变量中了。第10章指针(2)使用赋值号赋值不同对于数组:charstr[8]=“China”;正确charstr[8];str=“China”;错误对于字符指针:char*str=“China”;正确char*str;str=“China”;正确指针变量指针常量第10章指针(3)使用scanf赋值不同对于数组:charstr[8];scanf(“%s”,str);正确对于字符指针:char*str;scanf(“%s”,str);错误这是危险的。str没有明确指向,有可能指向系统区,从而将系统区数据修改。第10章指针(4)指针变量可替代printf中的格式字符串。如,inta=3;floatb=5.9;char*format;format=“a=%d,b=%f\n”;printf(format,a,b);相当于printf(“a=%d,b=%f\n”,a,b);输出为:a=3,b=5.900000第10章指针问:以下的程序段的输出是什么?inta=3;floatb=5.9;char*format;format=“a=%d,b=%f\n”;format=format+5;printf(format,a,b);a=%d,b=%f\n\0format第10章指针此时的format为“b=%f\n”,则printf等价于:printf(“b=%f\n”,a,b);回忆第4章相关内容输出结果为:b=3.000000第10章指针问:以下的程序段的输出是什么?inta=3;floatb=5.9;char*format;format=“a=%d,b=%f\n”;format=format+3;printf(format,a,b);a=%d,b=%f\n\0format第10章指针此时的format为“d,b=%f\n”,则printf等价于:printf(“d,b=%f\n”,a,b);输出结果为:d,b=3.000000第10章指针10.5指向函数的指针函数名是一个地址,是一个指针,是一个指针常量,它指向函数的起始地址。指向函数的指针也称为函数指针,是一个指针变量,它可以指向某一类函数。第10章指针例如:intadd(intx,inty){returnx+y;}intsub(intx,inty){returnx-y;}第10章指针main(){inta,b,c,d;scanf(“%d,%d”,&a,&b);int(*pf)(int,int);pf=add;c=(*pf)(a,b);pf=sub;d=(*pf)(a,b);printf(“%d,%d”,c,d);}定义一个函数指针pfc=add(a,b);d=sub(a,b);第10章指针说明:(1)函数指针的一般定义形式为:数据类型(*指针变量名)(参数类型表列)如,int(*pf)(int,int)第10章指针(2)函数指针变量不是固定指向哪个函数的,而是指向某一类函数。将哪一个函数的地址赋值给它,它就指向哪个函数,

1 / 70
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功