C++语言-南开大学第 6章 指针引用与动态内存分配 1

上传人:努力****83 文档编号:184846671 上传时间:2023-02-02 格式:PPT 页数:77 大小:1.14MB
返回 下载 相关 举报
C++语言-南开大学第 6章 指针引用与动态内存分配 1_第1页
第1页 / 共77页
C++语言-南开大学第 6章 指针引用与动态内存分配 1_第2页
第2页 / 共77页
C++语言-南开大学第 6章 指针引用与动态内存分配 1_第3页
第3页 / 共77页
点击查看更多>>
资源描述
1 第第 6 6章章 指针,引用与动态内存分配指针,引用与动态内存分配 6.1 6.1 选择排序算法选择排序算法6.2 6.2 指针类型指针类型6.3 6.3 指针与动态内存分配指针与动态内存分配6.4 6.4 引用类型引用类型6.5 6.5 程序实例程序实例2 6.1 6.1 选择排序算法选择排序算法 C+C+语言也为用户对于变量所占空间的地址提供了进语言也为用户对于变量所占空间的地址提供了进行操作的机制行操作的机制,这就是指针类型和引用类型。指针和这就是指针类型和引用类型。指针和引用不是一种独立的数据类型,而是一种导出数据类引用不是一种独立的数据类型,而是一种导出数据类型。指针类型也是型。指针类型也是C C语言和语言和PascalPascal语言的重要类型,语言的重要类型,而引用类型是而引用类型是C+C+语言中新的重要类型,在语言中新的重要类型,在JavaJava语言语言和和C#C#语言等一些新的语言中,引用类型取代了指针类语言等一些新的语言中,引用类型取代了指针类型型 排序的任务是把已经存在一个数组里的排序的任务是把已经存在一个数组里的n n 个数按从个数按从大到小的顺序排列,可以采用多种不同的方法实现,大到小的顺序排列,可以采用多种不同的方法实现,选择排序算法的思路简单,容易理解,每次总是从无选择排序算法的思路简单,容易理解,每次总是从无序的序列中选出最大者,交换到序列的左端,于是,序的序列中选出最大者,交换到序列的左端,于是,无序的序列越来越短,经过无序的序列越来越短,经过n-1n-1步,达到排序的目的。步,达到排序的目的。3 6.1 6.1 选择排序算法选择排序算法 void ssort(float*,int);/原型说明原型说明 void main(void)int i,seed,n=20;coutendlseed;coutendl;srand(seed);float list20,*pf;for(i=0;in;i+)listi=rand();coutsetw(8)listi;if(i+1)%8=0)coutendl;i=0;coutendl;pf=&list0;ssort(pf,n);while(in)coutsetw(8)listi;i+;if(i%8=0)coutendl;coutendl;void swap1(float*a,float*b)float temp;temp=*a;*a=*b;*b=temp;void ssort(float*a,int m)int i,j,index;float elem;for(i=0;im-1;i+)elem=*(a+i);index=i;for(j=i+1;jelem)elem=*(a+j);index=j;swap1(a+i,a+index);4 6.1 6.1 选择排序算法选择排序算法n运行结果:运行结果:seed=6523 21339 28822 26220 8712 18120 1280 27491 8647 7137 2030 24101 20505 4452 26942 10989 29919 27130 20996 17227 13559 29919 28822 27491 27130 26942 26220 24101 21339 20996 20505 18120 17227 13559 10989 8712 8647 7137 4452 2030 1280 5 6.1 6.1 选择排序算法选择排序算法 这个程序重点是介绍函数这个程序重点是介绍函数ssortssort()()和和swap1()swap1()的设计,的设计,主函数做了三件事:主函数做了三件事:1 1)为长度为)为长度为n n的数组的数组listnlistn 输入输入n n个随机数,作为个随机数,作为排序算法处理的对象排序算法处理的对象 2 2)调用函数)调用函数ssortssort()()进行排序。进行排序。3 3)把经过排序的数组)把经过排序的数组list20list20的值输出。的值输出。函数函数swap1()swap1()的定义中使用了指针类型的参数。的定义中使用了指针类型的参数。参数参数a,ba,b 是是float float 型的指针变量,即它们的值应型的指针变量,即它们的值应是浮点型变量的地址。是浮点型变量的地址。6 6.1 6.1 选择排序算法选择排序算法 在函数在函数swap1()swap1()中使用了中使用了*a a 和和*b b,这里符号,这里符号*不是乘不是乘法运算符,而是表示指针变量(法运算符,而是表示指针变量(a a 或或b b)所指向的那个变)所指向的那个变量。量。n例如:例如:intint n=4,n=4,*p;p;p=&n;p=&n;*p+;p+;表示有整型变量表示有整型变量n,n,和整型指针变量和整型指针变量p,p,用用&n&n 表示变量表示变量n n 的的地址,地址,p=&n p=&n 使指针使指针p p 指向变量指向变量n,n,而这时而这时*p p 正是表示变量正是表示变量n,n,*p+p+相当于相当于n+n+&和*是一对用于指针操作的互逆的单目运算符,(在这里&不是“引用”的意思)。&n 表示变量n 的地址,而*p 表示指针p 指向的变量或该变量的值。7 6.1 6.1 选择排序算法选择排序算法 函数函数swap1(float swap1(float*a,floata,float *b)b),与与5.2.55.2.5中介绍的中介绍的swap(intswap(int&a,&a,intint&b)&b)函数作一函数作一比较,虽然它们都达到交换两个变量内容的目的,比较,虽然它们都达到交换两个变量内容的目的,但采用的方式却是不同的。但采用的方式却是不同的。在在swap1()swap1()中有两个指针型参数,属于赋值形中有两个指针型参数,属于赋值形参,在调用时创建两个新的指针变量参,在调用时创建两个新的指针变量a a 和和b b,把,把实参表达式计算的结果地址赋给实参表达式计算的结果地址赋给a a 和和b b,从而使,从而使指针指针a a 和和b b 指向相应的变量。而在指向相应的变量。而在swap()swap()中形中形参参a,ba,b 为引用型,它是在调用时直接由实参的变为引用型,它是在调用时直接由实参的变量代替量代替a,ba,b 参加参加swap()swap()函数的函数体操作。函数的函数体操作。8 6.1 6.1 选择排序算法选择排序算法 函数函数ssortssort()()是一个用于对是一个用于对m m 个浮点数组进行排个浮点数组进行排序的函数,其参数为序的函数,其参数为 float float 型指针和型指针和intint 型整型整数。前者指明数组的首地址,后者为数组中元素数。前者指明数组的首地址,后者为数组中元素的个数,执行结果是把这个数组中的浮点数按从的个数,执行结果是把这个数组中的浮点数按从大到小的顺序排列好。大到小的顺序排列好。把把n n个数排好次序可以有许多种不同的算法,这个数排好次序可以有许多种不同的算法,这个函数是每次把尚未排好的元素中的最大元素选个函数是每次把尚未排好的元素中的最大元素选出,移到左端,最终形成从大到小的排列,故被出,移到左端,最终形成从大到小的排列,故被称为选择排序算法。称为选择排序算法。9 6.6.2 2 指针类型指针类型 -指针类型的变量说明格式为:指针类型的变量说明格式为:*,1,*,.;2,.;例如例如:intint i=3;i=3;intint *pi;pi;/pi/pi为为intint*型变量,其取值为一个型变量,其取值为一个intint型变量的地址,型变量的地址,/也称也称pipi为指向为指向intint型数据的指针变量(简称指针)型数据的指针变量(简称指针)10 pi=&i;/&pi=&i;/&作单目算符时为作单目算符时为“取变量地址取变量地址”,/此处将变量此处将变量i i的地址赋给指针变量的地址赋给指针变量pipicoutcout*pi;pi;/输出:输出:*pipi之值即之值即3 3/“/“*”作单目算符时为作单目算符时为“取内容取内容”/(取指针所指向的那一变量的内容)(取指针所指向的那一变量的内容)*pi=123;/pi=123;/给给pipi所指向的那一变量,既所指向的那一变量,既i i,/赋值赋值123123(等同于(等同于:i=123;i=123;)float float*pnpn=NULL;/=NULL;/NULL NULL 的指针变量,规则规定的指针变量,规则规定NULL NULL 与与整数整数0 0 通用,它是唯一可以赋给任一类型指针变量的值,表通用,它是唯一可以赋给任一类型指针变量的值,表示当前该指针未指向任一变量。因此,一个指针变量,可有示当前该指针未指向任一变量。因此,一个指针变量,可有三种状态:三种状态:n未赋任何值,未赋任何值,“悬空悬空”状态。状态。nNULLNULL值。未指向任一变量。值。未指向任一变量。n指向某一变量指向某一变量 11 读如下程序,看执行后会显示出什么结果读如下程序,看执行后会显示出什么结果?#include include void main()void main()intint i,j;i,j;intint *pi,pi,*pjpj;i=3;i=3;j=6;j=6;pi=&i;pi=&i;pjpj=&j;=&j;coutcouti,j=i,ji,j=i,jendlendl;coutcout*pi,pi,*pjpj=*pi,pi,*pjpjendlendl;*pi=123;pi=123;*pjpj=*pi+2;pi+2;coutcout*pi,pi,*pjpj=*pi,pi,*pjpjendlendl;coutcouti,j=i,ji,j=i,jendlendl;12 程序执行后的显示结果如下:程序执行后的显示结果如下:i,j=3,6i,j=3,6*pi,pi,*pjpj=3,6=3,6*pi,pi,*pjpj=123,125=123,125i,j=123,125i,j=123,12513 6.2 6.2 指针变量的操作指针变量的操作(运算运算)-1.1.取地址运算取地址运算&和取内容运算和取内容运算*注意如下注意如下3 3处出现的处出现的*pipi,它们的含义不相同:它们的含义不相同:intint i=23,i=23,*pi=&i;pi=&i;coutcout*pi;pi;*pi=56;pi=56;14 第一行第一行的的“*pi”pi”处于变量说明处,是说明处于变量说明处,是说明pipi为为“intint*”型变量,并同时将该指针变量初始化为型变量,并同时将该指针变量初始化为i i的地址。不可将此处的地址。不可将此处的的“*”理解为理解为“取内容取内容”运算,它与前面的运算,它与前面的intint联合起来以说联合起来以说明明pipi为为“intint*”型变量。型变量。第二行第二行的的“*pi”pi”表示指针变量表示指针变量pipi所指向的那一变量(即所指向的那一变量(即i i)的内容(的内容(*理解为理解为“取内容取内容”运算,使用其值)。运算,使用其值)。第三行第三行的的“*pi”pi”为左值(存储空间概念),表示要改变为左值(存储空间概念),表示要改变指针变量指针变量pipi所指向的那一变量(即所指向的那一变量(即i i)空间中的内容(使用其空间中的内容(使用其存储空间)。存储空间)。15例:例:int a=5;定义整型变量定义整型变量 a 有两个值:有两个值:1、该变量内容、该变量内容 5;2、该变量在内存中的地址;它被表示为、该变量在内存中的地址;它被表示为&a。int*pa=&a;用用*定义的整型定义的整型指针指针变量变量 pa 也有两个值:也有两个值:1、内容为变量、内容为变量a在内存中的地址,即在内存中的地址,即&a;2、变量、变量pa在内存中的地址;它被表示为在内存中的地址;它被表示为&pa。3、pa 是一个指向变量是一个指向变量a 的指针。的指针。变量变量a 与指针与指针pa 的关系图的关系图内容内容 地址地址a 5 1000Hpa 1000 2000H162.2.数组指针的算术运算数组指针的算术运算1)1)若若p p为指针,已指向数组的某一元素,则为指针,已指向数组的某一元素,则p+i(p+i(或或p-i,p-i,其中其中i i为正整数为正整数)也为一指针,它指向当也为一指针,它指向当前前p p已指元素的后面已指元素的后面(或前面或前面)第第i i个元素。个元素。例例1 1:intint a10;a10;/任一数组名字任一数组名字a a都是一个常量指针都是一个常量指针,/代表数组的首地址代表数组的首地址,也即也即,a a总等同于总等同于&a0a017 则,无论何时则,无论何时,下述两种表示数组元素下述两种表示数组元素aiai的方式总是相同的:的方式总是相同的:a0 a0 *a a a1 a1 *(a+1)(a+1).a9 a9 *(a+9)(a+9)另,下述两种表示数组元素另,下述两种表示数组元素aiai之地址的方式之地址的方式也总是相同的:也总是相同的:&a0 a a0 a&a1 a+1&a1 a+1.&a9 a+9&a9 a+9 18 例例2 2:intint a10;a10;intint*pa=a;pa=a;/pa /pa为变量指针,此时为变量指针,此时papa与与a a /均指向数组均指向数组a a的首元素的首元素 则,下述三种表示数组元素则,下述三种表示数组元素aiai的方式是等的方式是等同的:同的:a0 a0 *a a *papaa1 a1 *(a+1)(a+1)*(pa+1)(pa+1).a9 a9 *(a+9)(a+9)*(pa+9)(pa+9)19 另,下述三种表示数组元素另,下述三种表示数组元素aiai之地址的方式之地址的方式也是等同的:也是等同的:&a0 a paa0 a pa&a1 a+1 pa+1&a1 a+1 pa+1.&a9 a+9 pa+9&a9 a+9 pa+9 而而 pa+=3;pa+=3;及及 pa-;pa-;也都为正确的句子也都为正确的句子(但,但,a+=3;a+=3;及及 a-;a-;却都是不正确的句子却都是不正确的句子!为什么为什么?)?)。20 2)2)若若p,qp,q都为同类型的指针都为同类型的指针,则则p-qp-q为为p p与与q q之间之间的数据项数的数据项数(当当p,qp,q指向同一数组时指向同一数组时,结果有意义结果有意义)。3.3.数组指针的关系运算数组指针的关系运算 若若p,qp,q都为同类型的指针都为同类型的指针,则则p p与与q q间可进行间可进行6 6种种比较运算比较运算(通常用于通常用于p,qp,q指向同一数组的情况,靠指向同一数组的情况,靠前者其指针值小前者其指针值小)。21 指针运算实例指针运算实例 编程序,首先输入编程序,首先输入5 5个整数放入数组个整数放入数组a a,而后按而后按输入的相反顺序输出这输入的相反顺序输出这5 5个数。个数。1.1.常量指针使用方式常量指针使用方式 解法一解法一(通过数组名通过数组名a a,一个常量指针来实现一个常量指针来实现)#include include void main()void main()intint i,a5;i,a5;coutcoutinput 5 integers:input 5 integers:endlendl;22 for(i=0;i5;i+)for(i=0;i*(a+i);(a+i);/*(a+i)(a+i)全同于全同于aiai,/a/a为数组首地址为数组首地址(一个常量指针一个常量指针)coutcout=Reverse output:=Reverse output:=0;i-)for(i=4;i=0;i-)coutcout*(a+i);(a+i);coutcoutendlendl;23 2 2变量指针使用方式变量指针使用方式 解法二解法二(通过指针变量通过指针变量p p值的变化,使其指向数值的变化,使其指向数组各元素并依次使用它们组各元素并依次使用它们)#include include void main()void main()intint i,a5,i,a5,*p;p;/指针变量指针变量p p coutcoutinput 5 integers:input 5 integers:endlendl;24 for(i=0;i5;i+)for(i=0;i*(a+i);(a+i);coutcout=Reverse output:=Reverse output:=a;p-)for(p=a+4;p=a;p-)coutcout*p ;p ;/*p p指向各不同指向各不同aiai coutcout=ap=a为指针比较运算为指针比较运算256.6.2.3 2.3 指针与数组指针与数组 -1.1.指向数组元素的指针指向数组元素的指针 intint n10;n10;intint *pnpn=n;=n;等价于等价于 pnpn=n;=n;pnpn=&n0;=&n0;当然指针也可以指向数组的任意元素当然指针也可以指向数组的任意元素 pnpn=&n4;=&n4;262.2.指向数组的指针指向数组的指针 -把数组作为整体,指向这样一个整体把数组作为整体,指向这样一个整体的指针被称为指向数组的指针。其说明格的指针被称为指向数组的指针。其说明格式如下:式如下:(*)27 例例:intint(*pa)4;pa)4;/pa/pa为指针,指向一维数组,数组含为指针,指向一维数组,数组含4 4个个intint型分量。型分量。/可理解为可理解为*papa为具有为具有4 4个个intint型分量的一维数组名型分量的一维数组名 intint A34=11,12,13,14,21,22,23,24,A34=11,12,13,14,21,22,23,24,31,32,33,34 ;31,32,33,34 ;pa=A;pa=A;/pa/pa指向指向A A数组的第一行数组的第一行 28 coutcout(*pa)0 (pa)0 (*pa)1 (pa)1 (*pa)2pa)2 (*pa)3pa)3endlendl;/输出第一行输出第一行4 4元素元素pa+;pa+;/一步向后一步向后“迈过迈过”papa所指向的那一个一维数组所指向的那一个一维数组/的整体大小,使的整体大小,使papa指向指向A A数组的第二行数组的第二行coutcout(*pa)0 (pa)0 (*pa)1 (pa)1 (*pa)2pa)2 (*pa)3pa)3endlendl;/输出第二行输出第二行4 4元素元素 29-3.3.指针数组(分量为指针的数组)指针数组(分量为指针的数组)其说明格式为其说明格式为(一维数组时一维数组时):*(多维时多维时,将指定多个方括号括起的将指定多个方括号括起的)30例例1 1:intint w,x,y,z,A210;w,x,y,z,A210;intint *p14=&w,&x,&y,&z;p14=&w,&x,&y,&z;/p1 /p1数组的数组的4 4个分量均为个分量均为intint*型指针型指针(变量变量)intint *p22=A0,A1;p22=A0,A1;/A0/A0表示表示A A数组的第一行,为含有数组的第一行,为含有1010个元素的个元素的/一维数组一维数组(的数组名的数组名),表示一个常量地址。,表示一个常量地址。31例例2 2:char char*name5=name5=ZhaolinZhaolin,MazhigangMazhigang,Liguoping,Sunyingmin,MazilanLiguoping,Sunyingmin,Mazilan;/每一分量每一分量nameinamei均为均为“charchar*”类型的类型的 /指针指针(变量变量),从而均可被赋予一个字符串值。,从而均可被赋予一个字符串值。32 4.4.指向指针的指针指向指针的指针 (多重指针,间接再间接多重指针,间接再间接)例例:intint x,x,*p,p,*q;q;/q/q为指向指针的指针为指向指针的指针x=123;x=123;p=&x;p=&x;q=&p;q=&p;coutcoutx=xx=xendlendl;coutcout*p=p=*ppendlendl;coutcout*q=q=*qqendlendl;/x,/x,*p,p,*q q之值均为之值均为12312333 intint*a;a;a=new a=new intint*3;3;/a /a为指针,指向具有为指针,指向具有3 3个个“intint*”数据数据/的数组的数组(即元素均为指针的数组即元素均为指针的数组)for(i=0;i3;i+)for(i=0;i3;i+)*(a+i)=new int4;(a+i)=new int4;/*分配分配3 3批动态空间批动态空间(每批为每批为4 4个个intint大小大小),并使上述数,并使上述数组元素指针指向它们。此时的组元素指针指向它们。此时的a a实际上是一个实际上是一个3 3行行4 4列的数列的数组,也可通过组,也可通过aijaij的形式访问各元素。的形式访问各元素。*/34 指针与数组使用示例指针与数组使用示例 读下面的程序,给出它执行后所显示的结果读下面的程序,给出它执行后所显示的结果(利用指针利用指针实现动态数组功能实现动态数组功能)。#include#include void main()void main()intint lin,col,i,jlin,col,i,j;coutcoutlinlincolcol;/任意输入行数任意输入行数linlin及列数及列数colcolintint*b;b;b=new b=new intint*linlin;/linlin(行数行数)个个“intint*”指针指针for(i=0;ifor(i=0;ilin;ilin;i+)+)bi=new bi=new intcolintcol;/每行有每行有colcol(列数列数)个个intint数数 /此时的此时的b b成为动态成为动态(大小大小)的二维数组的二维数组35 for(ifor(i=0;i=0;ilin;ilin;i+)+)for(j=0;j for(j=0;jcol;jcol;j+)+)bij=i+j;bij=i+j;/可按下标方式使用各数组元素,给可按下标方式使用各数组元素,给b b数组赋值数组赋值for(i=0;ifor(i=0;ilin;ilin;i+)+)/按按linlin行行colcol列格式显示出列格式显示出b b数组各元素数组各元素 for(j=0;jfor(j=0;jcol;jcol;j+)+)coutcoutbij ;bij ;coutcoutendlendl;cout*(*b+2)endl;cout*b+2endl;cout*(b+2)endl;366.2.4 6.2.4 字符串指针字符串指针 -说明与初始化说明与初始化 字符串指针没有自己独立的形式,其说明语句的格式与字符类字符串指针没有自己独立的形式,其说明语句的格式与字符类型指针相同,例如:型指针相同,例如:char char chch=a=a;/chch 是字符型变量,被赋初值字符是字符型变量,被赋初值字符aa。char char*pc1=&pc1=&chch;/clcl 是字符指针,它被赋初值为字符变量是字符指针,它被赋初值为字符变量的地址。的地址。pc1pc1是一个字符型指针是一个字符型指针 char char*pc2=worldpc2=world;/pc2/pc2为字符指针,初值为字符串常量为字符指针,初值为字符串常量“world”world”,于是于是pc2 pc2 就成为一个字符串指针。它的内容是就成为一个字符串指针。它的内容是字符串第一个字符字符串第一个字符ww的存储地址。的存储地址。char as10=Chinesechar as10=Chinese;/as/as 是一个长度为是一个长度为10 10 的字符数的字符数组。为组。为as as 所赋的初值为字符串常量所赋的初值为字符串常量“Chinese”Chinese”,这个常量,这个常量在数组中占八个分量的位置,七个字母和一个串尾符在数组中占八个分量的位置,七个字母和一个串尾符00。char char*pc3=aspc3=as;/pc3/pc3 说明为字符指针,并令其指向字符数说明为字符指针,并令其指向字符数组组asas的首元,这时,的首元,这时,pc3 pc3 也是一个字符串指针也是一个字符串指针 376.2.4 6.2.4 字符串指针字符串指针 -2 2 字符串的整体输入输出字符串的整体输入输出 把字符串作为字符数组,然后按字符依次进行输入把字符串作为字符数组,然后按字符依次进行输入输出是可行的,但比较麻烦。例如输出是可行的,但比较麻烦。例如 whilewhile(*pc3!=0pc3!=0)coutcout*pc3+pc3+;执行的结果是显示执行的结果是显示ChineseChinese。因此提供整体输入输出的方法因此提供整体输入输出的方法 386.2.4 6.2.4 字符串指针字符串指针 -cincin字符串字符串;coutcout字符串字符串;char as 10=worldchar as 10=world;char char*pc2pc2worldworld;char char*pc3=aspc3=as;coutcoutasas;coutcoutpc2pc2;coutcoutpc3pc3;coutcout“world”“world”;后四个输出语句产生相同效果,都是输出了字符串后四个输出语句产生相同效果,都是输出了字符串worldworld。396.2.4 6.2.4 字符串指针字符串指针 -cincin字符串字符串;char char strstr 20 20;cincinstrstr;/允许输入长度不超过允许输入长度不超过20 20 的的字符串,忽略前导空格,以字符串,忽略前导空格,以00作为串尾。作为串尾。或者使用或者使用cin.getline(str,20);cin.getline(str,20);/课本课本p431 p431 cin.getlinecin.getline的最后一个参数是可以缺省的,缺的最后一个参数是可以缺省的,缺省情况下表示用回车作为输入结束标志。省情况下表示用回车作为输入结束标志。406.2.4 6.2.4 字符串指针字符串指针 -字符串指针数组字符串指针数组以字符串指针组成的数组使用起来比较方便,以字符串指针组成的数组使用起来比较方便,例如:例如:char char*menumenu FileFile,EditEdit,SearchSearch,HelpHelp;是一个字符串指针数组,它的每个元素指向一个字符是一个字符串指针数组,它的每个元素指向一个字符串常量。串常量。menu0 menu0,menu1menu1,menu2menu2,menu3menu3将分别表示将分别表示“File”File”,“Edit”Edit”,“Search”Search”,“He1p”He1p”。414.4.字符串指针的标准函数字符串指针的标准函数 -使用这些函数时要在程序中包含头文件使用这些函数时要在程序中包含头文件string.hstring.h。(1)(1)求字符串长度函数求字符串长度函数strlenstrlen(长度不包括串尾符)(长度不包括串尾符)unsinged strlen(const char*string);(2)(2)字符串拷贝函数字符串拷贝函数strcpystrcpychar*strcpy(char*strDestination,const char*strSource);(3)(3)字符串连接函数字符串连接函数strcatstrcatchar*strcat(char*strDestination,const char*strSource);(4)(4)字符串比较函数字符串比较函数strcmpstrcmpint strcmp(const char*string1,const char*string2);421 1 指针(或数组)作为函数参数指针(或数组)作为函数参数指针(或数组)作为函数参数指针(或数组)作为函数参数指针作为函数参数例指针作为函数参数例1 1指针作为函数参数例指针作为函数参数例2 2 6.2.5 6.2.5 指针与函数指针与函数 -43指针(或数组)指针(或数组)作为函数参数作为函数参数 通过指针通过指针(如数组名,或其它指针如数组名,或其它指针)作为函数参作为函数参数,可起到如同引用参数那样的能数,可起到如同引用参数那样的能“双向传递双向传递”数数据的功能。据的功能。用法一:数组作形参,且在被调函数内使用或用法一:数组作形参,且在被调函数内使用或改变数组元素的值改变数组元素的值(已在第已在第5 5章介绍过,系统处理方章介绍过,系统处理方法法-对形参数组元素的使用与改变,就是对实参对形参数组元素的使用与改变,就是对实参数组元素的直接使用与改变数组元素的直接使用与改变)。读如下程序,看执行后会显示出什么结果读如下程序,看执行后会显示出什么结果?44#include include void void myFunc(intmyFunc(int b,b,intint num);num);void main()void main()intint a6=1,2,3,4,5,6;a6=1,2,3,4,5,6;coutcoutbefore calling before calling muFuncmuFunc ai=ai=endlendl;for(intfor(int i=0;i6;i+)i=0;i6;i+)coutcoutai ;ai ;coutcoutendlendl;myFunc(a,6);/myFunc(a,6);/数组名数组名a(a(一个常量指针一个常量指针)作实参作实参coutcoutendlendlafter calling after calling muFuncmuFunc ai=ai=endlendl;45for(i=0;i6;i+)for(i=0;i6;i+)coutcoutai ;ai ;/输出被输出被myFuncmyFunc改变后的改变后的a a数组各元素值数组各元素值(每一数都加了每一数都加了100)100)coutcoutendlendl;/main /main 结束结束void void myFunc(intmyFunc(int b,b,intint num)num)intint sum=0;sum=0;for(intfor(int i=0;inum;i+)i=0;inum;i+)sum+=bi;sum+=bi;coutcoutendlendlin in myFuncmyFunc,sum of bi=sum,sum of bi=sumendlendl;for(i=0;inum;i+)for(i=0;inum;i+)bi+=100;bi+=100;46程序执行后的显示结果如下:程序执行后的显示结果如下:before calling before calling muFuncmuFunc ai=ai=1 2 3 4 5 61 2 3 4 5 6in in myFuncmyFunc,sum of bi=21,sum of bi=21after calling after calling muFuncmuFunc ai=ai=101 102 103 104 105 106101 102 103 104 105 10647指针作为函数参数例指针作为函数参数例1 1 -通过指针通过指针(如数组名,或其它指针如数组名,或其它指针)作为函数参数,可作为函数参数,可起到如同引用参数那样的能起到如同引用参数那样的能“双向传递双向传递”数据的功能。数据的功能。用法二:指针作形参,且在被调函数内使用或改变指用法二:指针作形参,且在被调函数内使用或改变指针所指变量的值针所指变量的值(系统处理方法系统处理方法-对对形参指针所指变量形参指针所指变量值值的使用与改变,就是对的使用与改变,就是对实参指针所指变量实参指针所指变量值的直接使用与值的直接使用与改变改变)读如下程序,看执行后会显示出什么结果读如下程序,看执行后会显示出什么结果?48#include#include void void myFunc(intmyFunc(int *p,p,intint num);num);void main()void main()intint a6=1,2,3,4,5,6;a6=1,2,3,4,5,6;intint*pa=a;pa=a;coutcoutbefore calling before calling muFuncmuFunc *(pa+i)=(pa+i)=endlendl;for(intfor(int i=0;i6;i+)i=0;i6;i+)coutcout*(pa+i);(pa+i);coutcoutendlendl;myFunc(pa,6);myFunc(pa,6);/指针指针papa作为实参去调用自定义函数作为实参去调用自定义函数muFuncmuFunccoutcoutendlendlafter calling after calling muFuncmuFunc *(pa+i)=(pa+i)=endlendl;49 for(i=0;i6;i+)for(i=0;i6;i+)coutcout*(pa+i);(pa+i);/输出被输出被myFuncmyFunc改变后以改变后以papa为首地址的为首地址的/各元素值各元素值(每一数都加了每一数都加了100)100)coutcoutendlendl;void void myFunc(intmyFunc(int *p,p,intint num)num)intint sum=0;sum=0;for(intfor(int i=0;inum;i+)i=0;inum;i+)sum+=sum+=*(p+i);(p+i);coutcoutendlendlin in myFuncmyFunc,sum of,sum of*(p+i)=sum(p+i)=sumendlendl;for(i=0;inum;i+)for(i=0;inum;i+)*(p+i)+=100;(p+i)+=100;50程序执行后的显示结果如下:程序执行后的显示结果如下:before calling before calling muFuncmuFunc ai=ai=1 2 3 4 5 61 2 3 4 5 6in in myFuncmyFunc,sum of bi=21,sum of bi=21after calling after calling muFuncmuFunc ai=ai=101 102 103 104 105 106101 102 103 104 105 10651 指针作为函数参数例指针作为函数参数例2 2-读下面的程序,给出它执行后所显示的结果。读下面的程序,给出它执行后所显示的结果。52#include void swap1(int*p1,int*p2);/指针参数指针参数void swap12(int*p1,int*p2);/指针参数指针参数void swap2(int&a,int&b);/引用参数引用参数void swap3(int x,int y);/赋值参数赋值参数 void main()int b1=11,b2=22;cout b1,b2=b1 b2endl;swap1(&b1,&b2);cout b1,b2=b1 b2nn;53 b1=11,b2=22;cout b1,b2=b1 b2endl;swap12(&b1,&b2);cout b1,b2=b1 b2nn;int c1=33,c2=44;cout c1,c2=c1 c2endl;swap2(c1,c2);cout c1,c2=c1 c2nn;54 int d1=55,d2=66;cout d1,d2=d1 d2endl;swap3(d1,d2);cout d1,d2=d1 d2 b1,b2=11 22 swap1=b1,b2=11 22after swap1=b1,b2=22 11after swap1=b1,b2=22 11beforbefor swap12=b1,b2=11 22 swap12=b1,b2=11 22after swap12=b1,b2=11 22after swap12=b1,b2=11 22beforbefor swap2=c1,c2=33 44 swap2=c1,c2=33 44after swap2=c1,c2=44 33after swap2=c1,c2=44 33beforbefor swap3=d1,d2=55 66 swap3=d1,d2=55 66after swap3=d1,d2=55 66after swap3=d1,d2=55 6658 返回值为指针的函数称为指针型函数,其返回类型的说明返回值为指针的函数称为指针型函数,其返回类型的说明应指明指针的对象类型后加应指明指针的对象类型后加“*”符号。符号。例如:例如:char char*menu menu Error!Error!,FileFile,EditEdit,SearchSearch,Help;Help;char char*menuitemmenuitem(intint m m)return return(m m1|m1|m4 4)?)?menu0menu0:menummenum;这个函数这个函数menuitemmenuitem()()返回的是字符串指针,可直接调用函数返回的是字符串指针,可直接调用函数menuitemmenuitem()()来进行字符串的输入输出。来进行字符串的输入输出。n指针型函数的设计,应注意返回的指针在该函数被调用的指针型函数的设计,应注意返回的指针在该函数被调用的域内是有确切的对象变量的。切不可返回指向函数内说明域内是有确切的对象变量的。切不可返回指向函数内说明的局部变量或参数变量的指针,或无指向的指针。的局部变量或参数变量的指针,或无指向的指针。2 2 函数返回指针函数返回指针-59 说明格式说明格式:*(););例:例:intint *f();f();/f /f为无参函数,其返回值类型为无参函数,其返回值类型 /为为intint*,即指针类型。即指针类型。char char*match(char c,char match(char c,char*strstr););/match /match为具有两个参数的函数,为具有两个参数的函数,/其返回值类型为其返回值类型为charchar*,即指针类型。即指针类型。60 下述示例性程序使用了返回指针值的自定义函下述示例性程序使用了返回指针值的自定义函数,实现如下功能:数,实现如下功能:提示用户输入任意一个字符串,而后找到输入提示用户输入任意一个字符串,而后找到输入串中第一个串中第一个 aa字符出现的位置字符出现的位置(若有的话若有的话),并输出,并输出从从 aa字符开始的子串字符开始的子串;若输入串中不出现若输入串中不出现 aa字符字符的话的话,输出输出“No match found”No match found”。程序执行后的显示结果如下:程序执行后的显示结果如下:Input a string:Input a string:I am a student.I am a student.Sub_strSub_str from first a=am a student.from first a=am a student.61 程序如下:程序如下:#include#include /use getschar*match(char c,char*str);/返回返回str中第一个中第一个c字符出现的位置字符出现的位置(地址值,即指向字符的指针地址值,即指向字符的指针)void main()char s80,*p;coutInput a string:endl;gets(s);p=match(a,s);/调用调用match,返回串返回串s中第一个中第一个a字符出现的位置字符出现的位置if(p)/s中含有中含有a字符时,返回的结果字符时,返回的结果p指针值为非指针值为非0 coutpendl;else /s中不含有中不含有a字符字符 coutNo match foundendl;62 char*match(char c,char*s)/找找str中第一个中第一个c字符出现的位置并返回字符出现的位置并返回int i=0;while(si!=c&si!=0)i+;/此时,或者此时,或者si=c,或者或者si=0if(si=c)return(&si);/若找到,返回在若找到,返回在s串的地址串的地址else return(NULL);/没找到时返没找到时返NULL 63 函数不是数据,但它与变量还是有两点相通之函数不是数据,但它与变量还是有两点相通之处:一个是它有类型(返回类型),另一个是处:一个是它有类型(返回类型),另一个是它也有地址,称为人口地址它也有地址,称为人口地址 函数的地址也可作指针的值,这就是函数指针。函数的地址也可作指针的值,这就是函数指针。函数指针的说明格式与函数的原型相似,主要函数指针的说明格式与函数的原型相似,主要区别是:原来的区别是:原来的函数名函数名,用,用*函数指针函数指针名名所代替,所代替,3 3 函数指针函数指针-64 按照如下的说明格式定义出的按照如下的说明格式定义出的pfpf变量,为指向函数的指变量,为指向函数的指针变量。针变量。说明格式说明格式:(*pf)();pf)();例:例:intint(*pf)();pf)();pf pf为指向函数的指针为指向函数的指针(即即*pfpf为函数名为函数名),该函数无参,且,该函数无参,且返回值类型为返回值类型为intint。下述示例性程序通过使用指向函数的指针变量来调用自下述示例性程序通过使用指向函数的指针变量来调用自定义函数定义函数maxmax及及minmin。程序执行后的显示结果如下:程序执行后的显示结果如下:max?/min?-input 1/0:max?/min?-input 1/0:1 1For MAX:input 2 integer numbers=a,b:For MAX:input 2 integer numbers=a,b:22-322-3max(a,b)=22max(a,b)=2265#include#include intint max(intmax(int x,x,intint y)/y)/自定义的自定义的maxmax函数函数return(xy?x:y);return(xy?x:y);intint min(intmin(int x,x,intint y)/y)/自定义的自定义的minmin函数函数return(xy?x:y);return(xy?x:y);void main()void main()intint(*p)(int,intp)(int,int););/p /p为指向函数的指针为指向函数的指针(即即*p p为函数名为函数名),该函数,该函数/有两个有两个intint型参数型参数,且返回值类型也为且返回值类型也为intintintint a,b,c;a,b,c;char char tmptmp;coutcoutmax?/min?-input 1/0:;tmptmp;66 if(tmp=1)/求求maxp=max;/类似数组名,函数名也为常量指针类似数组名,函数名也为常量指针/(表示函数的入口地址表示函数的入口地址),赋给函数指针,赋给函数指针pcout a,b:;cinab;c=(*p)(a,b);/*p即即max,以实参以实参a、b对对max进行调用进行调用coutcendl;else /求求min p=min;/使使p指向指向min函数函数cout a,b:;cinab;c=(*p)(a,b);/*p即即min,以实参以实参a、b对对min进行调用进行调用coutcendl;67 intint f1 f1(floatfloat););intint f2 f2(charchar););intint f3 f3(floatfloat););intint f4 f4(floatfloat););设设f1,f2,f3,f4 f1,f2,f3,f4 是是4 4 个已说明的函数,这时,下面的说个已说明的函数,这时,下面的说明和赋值,就有合法明和赋值,就有合法 与不合法的区别:与不合法的区别:intint(*pfpf)()(floatfloat)=&f1=&f1;/合法合法 intint(*pf1pf1)()(charchar)=&f1;/=&f1;/不合法不合法 pf=&f4 pf=&f4;/合法合法 pf=&f2 pf=&f2;/不合法不合法 pf=&f3 pf=&f3;/合法合法 示例示例-68 C C语言本身不允许把函数作为参数,有了函数指针,语言本身不允许把函数作为参数,有了函数指针,就可以通过函数指针,把函数作为参数使用。就可以通过函数指针,把函数作为参数使用。例如:用来计算函数定积分的函数例如:用来计算函数定积分的函数simpsonsimpson(),对(),对于不同的函数计算其定积分值,应有一个函数参数,于不同的函数计算其定积分值,应有一个函数参数,在在C C程序中用函数指针可以方便地解决这个问题:程序中用函数指针可以方便地解决这个问题:float float simpsonsimpson(float afloat a,float bfloat b,floatfloat(*pfpf)(floatfloat););参数参数a,ba,b 给出定积分的上下限,函数指针给出定积分的上下限,函数指针pf pf 则指向被则指向被积函数(其函数体从略)。在使用时可以对不同的浮积函数(其函数体从略)。在使用时可以对不同的浮点函数和上下限,调用点函数和上下限,调用simpsonsimpson ()计算其定积分()计算其定积分 说明说明 -69 注意区分:注意区分:按照如下按照如下9 9种方式所定义种方式所定义 出的具有不同含义的出的具有不同含义的a a。(1)(1)intint a;a;(2)(2)intint*a;a;(3)(3)intint*a;a;(4)(4)intint a10;a10;(5)(5)intint*a10;a10;(6)(6)intint(*a)10;a)10;(7)(7)intint a();a();(8)(8)intint*a();a();(9)(9)intint(*a)();a)();706.6.3 3 指针与内存动态分配指针与内存动态分配-通过使用通过使用newnew与与deletedelete单目运算符来实现动态变量的分配单目运算符来实现动态变量的分配与撤消。与撤消。1)1)newnew 使用格式使用格式:new new /动态变量动态变量 new new ()new new /动态数组动态数组 功能功能:生成一个生成一个(或一批或一批)所给类型的无名动态变量所给类型的无名动态变量,返回所生成返回所生成变量的一个指针值变量的一个指针值(首地址首地址)。71 例:例:intint *pi,pi,*pjpj,a=10;,a=10;char char*pc;pc;pi=new pi=new intint;*pi=api=a*a;a;pc=new char(A);pc=new char(A);pjpj=new int10;=new int10;722)delete2)delete 使用格式使用格式:delete delete delete delete 功能功能:释放通过释放通过newnew生成的动态
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


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


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

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


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