第八章指针和引用ppt课件_第1页
第八章指针和引用ppt课件_第2页
第八章指针和引用ppt课件_第3页
第八章指针和引用ppt课件_第4页
第八章指针和引用ppt课件_第5页
已阅读5页,还剩63页未读 继续免费阅读

下载本文档

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

文档简介

1、教学内容:教学内容:8.1 指针的概念及其运算指针的概念及其运算8.2 void指针和指针和const指针指针8.3 指针与数组指针与数组8.4 指针与字符串指针与字符串8.5 指针与函数指针与函数8.6 动态内存分配动态内存分配8.7 援用援用熟练掌握指针的概念、定义、初始化及指针运算熟练掌握指针的概念、定义、初始化及指针运算掌握指针与数组、函数、字符串等的联系;掌握指针与数组、函数、字符串等的联系; 掌握动态空间操作;掌握动态空间操作;掌握引用的定义格式及其使用规则掌握引用的定义格式及其使用规则教学目的:教学目的:a1012 1013b1015 1016x1201 1202 1203 12

2、04例如:语句例如:语句 printf(“%d”, a+b); 的执行是这样的:的执行是这样的: 依变量名与地址的对应关系此对应关系是依变量名与地址的对应关系此对应关系是 在编译是确定的找到变量在编译是确定的找到变量a的地址的地址1012和变和变 量量b的地址的地址1015 从从1012开始的两个字节中取出开始的两个字节中取出a的值的值(1);再;再 从从1015开始的两个字节中取出开始的两个字节中取出b的值的值(2) 将将a的值的值(1)与与b的值的值(2)相加后,按相加后,按“%d格式格式 输出输出a1012 10131012p2019l指针变量和它所指向的变量之间的关系的表示:指针变量和

3、它所指向的变量之间的关系的表示:l在程序中用在程序中用“* *”号表示号表示“指向指向“,如:,如:p p代表指针变代表指针变量,而量,而* *p p是是p p所指向的变量,见下图所指向的变量,见下图1012p2019a1012 1* *p p可以看到可以看到p p也代表一个变量,它和变量也代表一个变量,它和变量a a是同一是同一回事。因此语句回事。因此语句 a=1;a=1;和和 * *p=1;p=1;的作用相同的作用相同&P变量的指针:即变量的地址变量的指针:即变量的地址指针变量:存放变量地址的变量是指针变量,用指针变量:存放变量地址的变量是指针变量,用 来指向另一个变量。来指向另一个变量。

4、数据类型数据类型 * *指针变量名;指针变量名; float float * *p1, p1, * *p2; (p1p2; (p1和和p2p2是指向实型变量的指针是指向实型变量的指针变量变量) )char char * *p; (pp; (p是指向字符型变量的指针变量是指向字符型变量的指针变量) )例:例:数据类型:指该指针变量所指的变量的类型。数据类型:指该指针变量所指的变量的类型。:是一个说明符,用来说明该变量是指针变量:是一个说明符,用来说明该变量是指针变量指针变量名:是用户自定义的任意合法的标识符。指针变量名:是用户自定义的任意合法的标识符。数据类型数据类型 * *指针名初始地址;指针

5、名初始地址;留意:留意: 所有指针变量在使用之前都要有确定的指向,如果所有指针变量在使用之前都要有确定的指向,如果暂时不知暂时不知 道给指针变量赋什么值,就赋道给指针变量赋什么值,就赋NULLNULL它是它是iostream.hiostream.h头文件头文件 中的预定义符),值为中的预定义符),值为“NULLNULL的指的指针称为空指针。针称为空指针。 指针变量占指针变量占4 4个存储单元,不能将一个整型数据赋个存储单元,不能将一个整型数据赋给指针变量给指针变量 float xfloat x;float float * *p=&xp=&x;等价:等价:float float * *p p,x

6、 x;p=&xp=&x;/p/p只能指向只能指向floatfloat型变量型变量n&:它是取地址运算符,即取运算符右侧的对象的:它是取地址运算符,即取运算符右侧的对象的地址地址 n* * :它是指针运算符,它有两个含义:它是指针运算符,它有两个含义:n在定义时在定义时* 指后面的变量是指针变量:指后面的变量是指针变量: char *cp;n除定义之外除定义之外* 指取指针所指向的变量的值。指取指针所指向的变量的值。 n 如:如:char *cp&a; /*cp指指a的值的值n *cp=2; /将将2的值赋给的值赋给a若若int *p,a1; 则下列语句的含义是:则下列语句的含义是:p=&a;a

7、= *p;p = &(*p);a = *(&a);/ 将将a的地址赋给的地址赋给p/将将p所指向的值赋给所指向的值赋给a/将将p所指向的值的地址赋给所指向的值的地址赋给p/将将a的值赋给的值赋给a“& &“和和“* *“运算符运算符: :优先级相同,结合性为自右向左优先级相同,结合性为自右向左/&/&* *p1p1代表代表a a的地址(的地址(&a&a或或p1p1). . /它的作用是使它的作用是使p2p2指向指向a a例例: : 若若int int * *p1, p1, * *p2 ,a=5,b,c;p2 ,a=5,b,c; 则下列语句的含义是:则下列语句的含义是: p1=&a;p1=&a;

8、 b=( b=(* *p1)+;p1)+; p2=& p2=&* *p1; p1; c= c=* *&a&a;/* *&a&a与与a a等价等价/相当于相当于a+a+ 若写成若写成* *p1+p1+作用就不一样了,由于作用就不一样了,由于+和和* *为为同一优先级,且都为右结合性,因此它相当于同一优先级,且都为右结合性,因此它相当于* *(p1+),(p1+),因此先对因此先对p1p1的原值进行的原值进行* *运算,得到运算,得到a a的的值,然后使值,然后使p1p1的值改变,这样的值改变,这样p1p1不再指向不再指向a a了了 例:指针变量的引用例:指针变量的引用 #include void

9、 main() int i1=600,i2=800; int *p1,*p2; p1=&i1,p2=&i2; /使使p1指向指向i1,p2指向指向i2 couti1=*p1 i2=*p2endl; *p1=300,*p2=400; /作用相当于作用相当于i1=300,i2=400 couti1=*p1 i2=*p2endl; *p1=*p1+1; /相当于相当于i1=i11; couti1=*p1 i2=*p2endl; p1=p2; /使使p1指向指向p2所指向的目标所指向的目标i2 couti1=*p1 i2=*p2endl; 运行该程序将得到如下结果:运行该程序将得到如下结果:i1=60

10、0 i2=800 i1=300 i2=400i1=301 i2=400 i1=400 i2=400 例:通过指针变量访问整型变量例:通过指针变量访问整型变量 运行结果为:运行结果为:100, 10100, 10#include void main( ) int a=100, b=10; int *p1, *p2; /* 定义指针变量定义指针变量p1和和p2 */ p1=&a; p2=&b; /* 使使p1指向指向a,p2指向指向b */ printf(“%d, %dn”,a,b); printf(“%d, %dn”,*p1,*p2); /*输出输出a、b的值的值*/ 例:输入例:输入a a和和

11、b b两个整数,按先大后小的顺序输出两个整数,按先大后小的顺序输出a a和和b b#include void main( )int *p1, *p2, *p, a, b; scanf(“%d,%d”,&a, &b); p1=&a; p2=&b; /* 先使先使p1指向指向a, p2指向指向b */ if(ab) p=p1;p1=p2;p2=p; /使使p1和和p2改变指向改变指向,使使p1指向指向b,p2指向指向a printf(“na=%d,b=%dnn”,a,b); printf(“max=%d,min=%dn”,*p1,*p2);运行结果:运行结果:80 60 8080 60 指针与整数

12、的加减运算:其结果仍然是一个地址,它是以指针与整数的加减运算:其结果仍然是一个地址,它是以 该指针为基点的前方或后方第该指针为基点的前方或后方第n 个数据的地址个数据的地址 指针自加,自减指针自加,自减p+,p-):自加是指向下一个数据,:自加是指向下一个数据, 自减是指向上一个数据自减是指向上一个数据同类型的指针相减:得出它们所指向的地址之间包含同类型的指针相减:得出它们所指向的地址之间包含的的 数据的个数数据的个数 例:例:int *p,a=1,2,3,4;p=&a0;p+=3;printf(“%d”,*p);运行的结果:运行的结果:假设假设&a0 =1022,则最后则最后p的值:的值:p

13、n sizeof(所指向变量的类型)所指向变量的类型)p=1022+32=10284例:例:#include void main() double a10; double *iptr=&a0; for(int i=0;i5;i+) ai=i*2.5; for(int j=0;j5;j+) coutaj iptr *iptrendl; iptr+; 程序运行结果如下程序运行结果如下:a0 0 x0012FF30 0 a1 0 x0012FF38 2.5 a2 0 x0012FF40 5 a3 0 x0012FF48 7.5a4 0 x0012FF50 10 例:例:char c,*p; p=&c

14、; 把变量的地址赋给相同目标类型的指针把变量的地址赋给相同目标类型的指针 把一个指针的值赋给相同目标类型的另一指针把一个指针的值赋给相同目标类型的另一指针例:例:char *p1,*p2&b; p1=p2; 把数组地址赋给相同目标类型的另一指针把数组地址赋给相同目标类型的另一指针例:例:char a10,*p; p= a; 假设:假设:int a4=1,2,34,5,*q=a;那么:那么:* *q+q+:等价于等价于* *(q+)(q+)。它先得到。它先得到* *q q,然后再使,然后再使q q自增自增1 1,( (* *q)+q)+:表示表示q q所指向的元素值加所指向的元素值加1 1* *

15、(p+)(p+)或或* *p+p+相当于相当于ai+ai+,先对,先对p p进行进行* *运算,再使运算,再使p p自增自增1 1* *(+p)(+p)或或* *+p+p相当于相当于a+ia+i,先使,先使p p自增自增1 1,再对,再对p p进行进行* *运算运算* *(p- -)(p- -)或或* *p- -p- -相当于相当于ai- -ai- -,p p先进行先进行* *运算,运算,p p再自减再自减1 1* *(- -p)(- -p)或或* *- -p- -p相当于相当于a- -ia- -i,p p先自减先自减1 1,p p再进行再进行* *运算运算 假设:假设:p当前指向当前指向a数

16、组的第数组的第i个元素,那么:个元素,那么:void空指针:空指针:是一种不确定类型的指针,它可以指向任是一种不确定类型的指针,它可以指向任何类型的变量。其语法格式为:何类型的变量。其语法格式为: void *指针变量指针变量;指针变量:不指向任何具体的数据类型,任何地址都指针变量:不指向任何具体的数据类型,任何地址都可可 以赋给指针变量以赋给指针变量例:例: int a=9; void *p1=&a; int b=*(int *)p1; int *p2=(int *)p1; 留意:留意:如果需要将如果需要将voidvoid指针的值赋给其他类型的指针,则需要指针的值赋给其他类型的指针,则需要

17、进行强制类型转换。进行强制类型转换。voidvoid型指针型指针p p指向了整型变量指向了整型变量i i,则应用,则应用* *(int(int * *)p)p才能访才能访 问问i i。const指针:指针:关键字关键字constconst放在不同的位置表示的意义也不相放在不同的位置表示的意义也不相同,它有以下三种形式:同,它有以下三种形式: 指向常量的指针:指针指向的内存数据不能修改,但指针本指向常量的指针:指针指向的内存数据不能修改,但指针本 身是变量身是变量, ,可允许这种可允许这种指针变量指向另外一指针变量指向另外一 个同类型的别的变量。个同类型的别的变量。其定义的格式为:其定义的格式为

18、: const int const int * *指针变量名;指针变量名;const int *pci; const int a=1; pci=&a;const char *pc=“Point”; 例:例:指针常量指针常量( (常指针常指针) ) :int a=1; int b=2; int *const cpi=&a; /定义指针常量定义指针常量cpi *cpi=5; /ok! 可以改变变量可以改变变量a的值的值 cpi=&b; /error! 不能改变指针不能改变指针例:例:在指针定义语句的指针名前加在指针定义语句的指针名前加const,表示指针本身是常表示指针本身是常 量,所以在定义指量

19、,所以在定义指针时必须初始化,此后不能再赋其他针时必须初始化,此后不能再赋其他 地址,但指针指向的变量是可变的地址,但指针指向的变量是可变的指向常量的指针常量指向常量的指针常量: :例:例:综上所述,可知道综上所述,可知道: :指向常量的指针变量可以被初始化为变量的地址值,但不指向常量的指针变量可以被初始化为变量的地址值,但不 能通过指针修改该变量的值。能通过指针修改该变量的值。不能将常量的地址赋给不指向常量的指针变量。不能将常量的地址赋给不指向常量的指针变量。 例如:例如: const int a=100; int *p; p=&a; /error! 指针变量既然可以指向变量,当然也可以指向

20、数组或指针变量既然可以指向变量,当然也可以指向数组或 数组元素将数组起始地址或某一元素的地数组元素将数组起始地址或某一元素的地 址放到一个变量中)。址放到一个变量中)。数组的指针:指数组的起始地址。数组的指针:指数组的起始地址。数组元素的指针:指数组元素的地址。数组元素的指针:指数组元素的地址。指向数组的指针变量:指存放数组首地址的指针变量指向数组的指针变量:指存放数组首地址的指针变量指向数组元素的指针变量:指存放数组元素的指针变量指向数组元素的指针变量:指存放数组元素的指针变量例例1: int a10; int *p=a; /等价与等价与int *p; p=a;那么:那么:该数组的第该数组的

21、第i个元素可表示为:个元素可表示为:ai 或或pi或或*(p+i)或或*(a+i)数组数组ap(p+i)p+1, a+1p+i, a+ip+9, a+9该数组的第该数组的第i个元素的地址可表示为:个元素的地址可表示为:&ai 或或&pi 或或a+i 或或p+i 或或留意:留意:a是地址常量,不允许对其赋值,是地址常量,不允许对其赋值, 诸如:诸如:a+、a=&x等都是非法的等都是非法的例:利用指针变量访问数组元素例:利用指针变量访问数组元素 #include void main() int size; double array =5.5,6.7,3.6,6.8,1.2; double *p_a

22、rray; p_array=array; size=sizeof(array)/sizeof(*array); for (int i=0;isize;i+) cout*(p_array+i)endl; 运行结果是:运行结果是: 5.5 6.7 3.6 6.8 1.2 cout*p_arrayendl; p_array+; 对二维数组的理解对二维数组的理解 数组名是数组的首地址。数组名是数组的首地址。 例:例: int a34; /a int a34; /a是数组的首地址。是数组的首地址。 那么,那么,a0a0、a1a1、a2 a2 是什么呢?是什么呢? 也是地址量。也是地址量。 把二维数组,理

23、解成下面的图的形式:把二维数组,理解成下面的图的形式:a00a00a10a10a20a20a01a01a11a11a21a21a02a02a12a12a22a22a03a03a13a13a23a23a aa00a00a10a10a20a20a01a01a11a11a21a21a02a02a12a12a22a22a03a03a13a13a23a23a0a0a1a1a2a2a a?a a 、 a0 a0 是是 a00 a00的地址,是第一行的首地址。的地址,是第一行的首地址。a00a00a10a10a20a20a01a01a11a11a21a21a02a02a12a12a22a22a03a03a1

24、3a13a23a23a0a0a1a1a2a2a aa+1a+1 、a1a1是是 a10a10的地址,是第二行的首地址。的地址,是第二行的首地址。* * a a 是是a0a0的内容,的内容,* * * * a a 是是 a00 a00。 a a 是二维数组,经过两次是二维数组,经过两次* * 操作,才能访问到数组元操作,才能访问到数组元素:素: * * a a是是 a0a0的内容,的内容,* * * * a a 才是才是 a00a00。 a0a0是是a00a00的地址的地址, ,* *a0a0是是a00a00的内容。的内容。 综上所述,对于一般的二维数组综上所述,对于一般的二维数组a a,有以下

25、关系:,有以下关系: * *(a+i)+j=&aij aij=(a+i)+j=&aij aij=* *( (* *(a+i)+j) (a+i)+j) 例:例: int a32=11,12,13,14,15,16,i,j; int *p=a0;那么:那么:内存内存1615141312113000Ha03004Ha13000Hp3000Ha3004H a1a=3000Ha+1=3004H*a=3000H*a=11a0a00a1=&a103004Ha1+1=&a113006Hp=&a003000Hp+1=&a013002H*(p+2)= 13*p+8= 19*p+= 11总之若:总之若: int a

26、22=1,2,3,4,i,j; int *p=a0;aij=(*(a+i)j*(ai+j)=*(*(a+i)+j)=*(&a00+2*i+j) &aij=ai+j=*(a+i)+j=&a00+2*i+j =a0 +2*i+j =*(p+2*i+j) = p+2*i+j那么:那么:例:通过数组元素的地址来引用二维数组元素例:通过数组元素的地址来引用二维数组元素 #include #include void main() int a3 4=1,3,5,7,9,11,13,15,17,19,21,23; for(int i=0;i3;i+) for (int j=0; j4; j+) coutset

27、w(8)*(*(a+i)+j)“ ”; /也可写成也可写成*(ai+j)或或(*(a+i)j coutendl; 运行结果是:运行结果是: 1 3 5 7 9 11 13 15 17 19 21 23 是一个存放二维数组行地址的指针变量,常用于处理二是一个存放二维数组行地址的指针变量,常用于处理二维数组,数组指针的定义格式为:维数组,数组指针的定义格式为:数据类型数据类型 (*变量名)变量名)常量表达式常量表达式; 数据类型:表示一维数组元素的数据类型数据类型:表示一维数组元素的数据类型* *:表示变量是指针:表示变量是指针 :表示是数组:表示是数组常量表达式:表示二维数组的每行元数的个数常量

28、表达式:表示二维数组的每行元数的个数留意:因为运算符留意:因为运算符 的优先级高于的优先级高于*,所以必需用圆括号(),所以必需用圆括号() 将将*与指针变量名括起来与指针变量名括起来例:例: int b22=12,36,62,14; int (*p)2=b; /表示表示p是指向数组是指向数组b的行的指针变量的行的指针变量 int *p5; /表示数组表示数组p含含5个元素,每个元素均是一个指针变量个元素,每个元素均是一个指针变量例:通过数组元素的地址来引用二维数组元素例:通过数组元素的地址来引用二维数组元素 #include void main()int a34=1,3,5,7,9,11,1

29、3,15,17,19,21,23; int (*p)4; p=a; printf(%d,*(*(p+2)+3); 运行结果是:运行结果是: 23由上可得:&ai0=ai=pi=*(p+i)=p+i&aij=&pij=*(p+i)+j=pi+jaij=pij=*(*(p+i)+j)=*(pi+j)指针数组:就是其元素为指针的数组。它是指针的集合,它的指针数组:就是其元素为指针的数组。它是指针的集合,它的 每一个元素都是指针变量,并且它们具有相同的存每一个元素都是指针变量,并且它们具有相同的存 储类型和指向相同的数据类型。主要用于字符串的储类型和指向相同的数据类型。主要用于字符串的 操作,其定义格

30、式为:操作,其定义格式为:数据类型数据类型 *指针数组名指针数组名 常量表达式常量表达式;数据类型:指数组中各元素指针所指向的类型,数据类型:指数组中各元素指针所指向的类型,指针数组名:也即数组的首地址,是一个标识符;指针数组名:也即数组的首地址,是一个标识符;常量表达式:指出这个数组中的元素个数。常量表达式:指出这个数组中的元素个数。例:例:int *p16; float *p234; static char *name3= “Tom”, ”John”, ”Mary”;例:输入月份例:输入月份112),输出该月份所在季节的英文名称。),输出该月份所在季节的英文名称。#include void

31、 main() char *pseason4=Spring,Summer,Autumn,Winter; int month; cinmonth; switch(month) case 12:case 1:case 2: coutpseason0endl; break; case 3:case 4:case 5: coutpseason1endl; break; case 6:case 7:case 8: coutpseason2endl; break; case 9:case 10:case 11: coutpseason3endl; break; default: coutinput dat

32、a error!; 指向指针的指针变量:指该针变量中存放的是另一个指针的地指向指针的指针变量:指该针变量中存放的是另一个指针的地 址。其也称为二级指针。多用于访问二址。其也称为二级指针。多用于访问二 维数组。维数组。 其语法格式为:其语法格式为: 数据类型数据类型 *变量名变量名 例:例:int x=32; int *p=&x; int *pp=&p;则则x、p和和pp三者之间的关系:三者之间的关系: 3000Hpp3004Hp32xp是一级指针;是一级指针;pp是二级指针。是二级指针。*ppp&x*pp*p=x。例:阅读下列程序,写出运行结果。例:阅读下列程序,写出运行结果。 #includ

33、e void main() int b34=12,36,62,56,98,63,56,99,88,32,66,22; int *p3=b0,b1,b2,*pp=p,i,j; cout输出输出b数组每行的首地址数组每行的首地址:n; for(i=0;i3;i+) cout*pp+ ; coutendl; pp=&p0; cout输出输出b数组每个元素的地址数组每个元素的地址:n; for(i=0;i3;i+) for(j=0;j4;j+) cout*(pp+i)+j ; coutendl; coutendl; pp=&p0; cout输出输出b数组每个元素的值数组每个元素的值:n; for(i=

34、0;i3;i+) for(j=0;j4;j+) cout*(*(pp+i)+j) ; coutendl; pi pijpi+j程序运行的结果为:程序运行的结果为: 输出输出b数组每行的首地址数组每行的首地址: 0 x0065FDC8 0 x0065FDD8 0 x0065FDE8 输出输出b数组每个元素的地址数组每个元素的地址: 0 x0065FDC8 0 x0065FDCC 0 x0065FDD0 0 x0065FDD4 0 x0065FDD8 0 x0065FDDC 0 x0065FDE0 0 x0065FDE4 0 x0065FDE8 0 x0065FDEC 0 x0065FDF0 0

35、x0065FDF4 输出输出b数组每个元素的值数组每个元素的值: 12 36 62 56 98 63 56 99 88 32 66 22 在在C+语言中,可以定义一个字符数组,将字符串存放在语言中,可以定义一个字符数组,将字符串存放在该数组中,通过数组下标来访问所需的字符;也可以定义一个该数组中,通过数组下标来访问所需的字符;也可以定义一个字符指针,通过指针的指向来访问所需的字符。字符指针,通过指针的指向来访问所需的字符。如果要通过指针访问一个字符串,可以将这个指针指向此字符串,并利用指针的加1、减1操作实现对各个字符的访问。例:利用字符指针访问字符串。例:利用字符指针访问字符串。 #incl

36、ude void main() char *str=hello; coutstrendl; 例:阅读下列程序,写出运行结果。例:阅读下列程序,写出运行结果。#include void main()char s=C+ program; char *ps1=computer; char *ps2,*ps3=s; ps2=mouse;/使指针变量使指针变量ps2指向字符串指向字符串mouse的首地址的首地址 couts ps1 ps2 ps3endl; ps1+;ps2+=2;ps3+=4;/移动指针移动指针 couts+4 ps1 ps2 ps3endl; cout*s *ps1 *ps2 *ps

37、3endl; ps1=s; 程序的运行结果为:程序的运行结果为: C+ program computer mouse C+ program program omputer use program C o u p 在在C C中,指针和函数可以配合使用,指针可以作函数的中,指针和函数可以配合使用,指针可以作函数的参数,函数的返回值可以是指针类型,还可以有指向函数的指针参数,函数的返回值可以是指针类型,还可以有指向函数的指针及其指针数组。及其指针数组。 指针作函数的参数,能将一个对象的地址传送到被调函数指针作函数的参数,能将一个对象的地址传送到被调函数中,在该被调函数中可以通过指针参数操作主调函数中

38、的对象。中,在该被调函数中可以通过指针参数操作主调函数中的对象。例:输入两个整数,将它们按由大到小的顺序输出,连续进行上例:输入两个整数,将它们按由大到小的顺序输出,连续进行上 述操作述操作3次,即对次,即对3对整数重复操作。对整数重复操作。#include void swap(int *,int *); void main( ) int a,b,*pa,*pb; pa=&a; pb=&b; for (int i=0;i3;i+) coutab; if(ab) swap (pa,pb); cout Output: a bendl; void swap(int *p1,int *p2) int

39、temp; temp=*p1; *p1=*p2;*p2=temp; 程序运行结果是:程序运行结果是: Input: 5 7 Output: 7 5 Input: 8 6 Output: 8 6 Input: 5 5 Output: 5 5 除除void型的函数之外,函数在调用结束后都会有返回型的函数之外,函数在调用结束后都会有返回值,指针同样也可以作为函数的返回值。当一个函数的返回值,指针同样也可以作为函数的返回值。当一个函数的返回值是指针类型时,这个函数就是指针型函数。指针型函数定值是指针类型时,这个函数就是指针型函数。指针型函数定义方式为:义方式为:类型类型* *函数名称函数名称( (变量

40、类型变量类型 变量名称变量名称) ) int *functionA( ) int var=100; int *ptr=&var; cout*ptrendl; return ptr; 例:定义一个返回例:定义一个返回intint型指针值的函数型指针值的函数functionA functionA stadic int var=100;函数指针:就是指向函数的指针。其定义格式为:函数指针:就是指向函数的指针。其定义格式为:类型类型 (*指针名)(参数表);指针名)(参数表);类型:是指函数指针所指向函数的返回值的类型类型:是指函数指针所指向函数的返回值的类型参数表:指明了该函数指针所指向函数的形参类

41、型和参数表:指明了该函数指针所指向函数的形参类型和个数个数例:例: int (*p)(int,int); 就定义了一个函数指针就定义了一个函数指针p,它指向一个返回值为整型,它指向一个返回值为整型且有两个整型参数的函数。用函数指针前,必须先赋值,且有两个整型参数的函数。用函数指针前,必须先赋值,使它指向一个函数的入口地址使它指向一个函数的入口地址(函数名函数名)。函数指针的初始化格式为:函数指针的初始化格式为:类型类型 (*指针名指针名) (参数表参数表)函数名;函数名;或为:或为:类型类型 (*指针名指针名) (参数表参数表); 指针名函数名;指针名函数名; 函数指针作用:函数指针作用: 调

42、用被指向的函数:调用被指向的函数: 其调用的格式是:其调用的格式是: (*指针变量名指针变量名) (实参表);实参表); 等价于:函数名等价于:函数名(实参表实参表) 作参数:函数不能直接作参数,所以当需要用函数作参作参数:函数不能直接作参数,所以当需要用函数作参 数时必须借助数时必须借助 于指向函数的指针来完成。于指向函数的指针来完成。例:通过函数指针作函数参数求三角函数的值。例:通过函数指针作函数参数求三角函数的值。#include #include double func(double (*)(double),double ); void main() double x,a,s1,s2;

43、 coutx; a=3.14159/180.0*x; s1=func(sin,a); s2=func(cos,a); coutx的正弦值:的正弦值:s1endl; coutx的余弦值:的余弦值:s2endl; double func(double (*fp)(double),double y) return (*fp)(y); 程序运行结果是:程序运行结果是: 请输入一个角度值:请输入一个角度值:60 x的正弦值:的正弦值:0.866025 x的余弦值:的余弦值:0.500001函数指针数组:函数指针数组: 与定义变量指针数组一样,C+中也可以定义具有特定返回类型和特定参数类型的函数指针数组。

44、函数指针数组也可以是多维的,但常用到的是一维函数指针数组。其定义格式为:数据类型数据类型 (*函数指针名函数指针名常量表达式常量表达式)(参数表);)(参数表);例:例:int (*p5)(int,int);函数指针数组p含有5个元素,其每个元素都是一个指向函数的指针,且指向的函数都是返回值类型为整型,带两个整型参数的函数。动态内存分配:是指在程序运行期间根据实际需要随时申请内动态内存分配:是指在程序运行期间根据实际需要随时申请内 存存(new),并在不需要时释放,并在不需要时释放(delete)。应用程序数据所占内存可以分为应用程序数据所占内存可以分为4类:类:1全局数据区:存放程序的全局数

45、据和静态数据。2代码区:存放程序的代码,即程序中各个函数代码块。3堆区:也称为自由存储单元。存放程序中的动态数据。new与delete运算符一起使用,就可进行动态内存的申请和释放也称为创建和删除)。4栈区:保存每个函数的局部数据函数的形参及局部变量)。申请分配内存的方法有两种:申请分配内存的方法有两种:利用malloc函数留意:该函数如分配内存成功,则返回其起始地址,留意:该函数如分配内存成功,则返回其起始地址, 否则返回否则返回NULLNULL。 要在程序用该函数时,应写出其所在的文件:要在程序用该函数时,应写出其所在的文件: #include #include或或 #include #in

46、clude 格式是:格式是:void void * * malloc( malloc(字节数字节数) )#include #include void main() int *ip; ip=(int *)malloc(sizeof(int); scanf(%d,ip); printf(*ip=%dn,*ip); 例:用例:用C语言提供的库函数语言提供的库函数 malloc( ) 、free( )来动态分配释放内存来动态分配释放内存:free (ip);内存申请的字节数,内存申请的字节数,这里只申请一个这里只申请一个int返回的指针强制转换为返回的指针强制转换为int*类型才能与类型才能与ip相容

47、相容利用new运算符:留意:格式留意:格式1 1和格式和格式2 2都是给单个对象申请分配内存空间;而都是给单个对象申请分配内存空间;而 格式格式3 3和格式和格式4 4可同时给多个对象数组申请分配内存可同时给多个对象数组申请分配内存格式格式1 1:指针变量名:指针变量名=new =new 类型标识符;类型标识符;格式格式2 2:指针变量名:指针变量名=new =new 类型标识符初始值);类型标识符初始值);格式格式3 3:指针变量名:指针变量名=new =new 类型标识符类型标识符 内存单元个数内存单元个数 ;格式格式4 4:指针:指针=new =new 数据类型数据类型 常量表达式常量表

48、达式11常量表达式常量表达式22;功能:如果分配内存成功,则返回其起始地址,否则返回功能:如果分配内存成功,则返回其起始地址,否则返回0 0例如:例如: int *ip,*p,*q; ip=new int; /ip指向指向1个未初始化的个未初始化的int型对象型对象 p=new int(68); /ip指向指向1个表示为个表示为68的的int型对象型对象 q=new int 5; /ip指向指向5个未初始化个未初始化int型对象首地址型对象首地址 int (*p1)3; p1=new int23; /p1将指向系统分配二维数组的第一行。将指向系统分配二维数组的第一行。mallocmalloc函

49、数和函数和newnew的区别:使用的区别:使用mallocmalloc函数分配内存时,其返函数分配内存时,其返 回值要经过类型转换后才可赋给一回值要经过类型转换后才可赋给一 个指针变量,而利用个指针变量,而利用newnew分配内存分配内存 时则不需要类型转换。时则不需要类型转换。释放内存的方式:释放内存的方式:利用free函数留意:使用时应嵌入相应的头文件:留意:使用时应嵌入相应的头文件:#include #include 或或 #include #include 格式是:格式是:free(free(起始内存地址起始内存地址) );利用delete运算符:阐明:格式阐明:格式1 1可释放某一个

50、内存单元;而格式可释放某一个内存单元;而格式2 2可释放若干可释放若干 个内存单元的空间个内存单元的空间格式格式1 1:delete delete 指针变量名;指针变量名;格式格式2 2:delete delete 指针变量名;指针变量名;#include #include void main() int *number,*p,*q; number=new int100; /申请分配申请分配100个个int类型所占内存空间类型所占内存空间 p=new int; /申请分配一个申请分配一个int类型所占内存空间类型所占内存空间2个字节)个字节) q=(int *)malloc(10*sizeof

51、(int); /申请分配申请分配10个个int类型所占内类型所占内存空间存空间 if (number=NULL | p=NULL | q=NULL) cout内存分配失败内存分配失败endl; else cout内存分配成功内存分配成功endl ; /程序的其它部分程序的其它部分 delete number; /释放释放number所指向的所有内存空间所指向的所有内存空间 delete p; /释放释放p所指向的所有内存空间所指向的所有内存空间 free (q); /释放释放q所指向的所有内存空间所指向的所有内存空间 援用:就是某个变量或对象的另一个名字,所以又被称援用:就是某个变量或对象的另

52、一个名字,所以又被称“别别 名名”。它的值和地址都与被引用的变量或对象的值和。它的值和地址都与被引用的变量或对象的值和 地址值相同。当声明一个引用型变量时,需要用另一地址值相同。当声明一个引用型变量时,需要用另一 个变量对其初始化。其典型用法是用作函数的形参和个变量对其初始化。其典型用法是用作函数的形参和 返回值。返回值。声明一个引用型变量的语法格式为:声明一个引用型变量的语法格式为: 类型类型 &引用变量名引用变量名=变量名变量名; 其中:类型:是被引用变量的的类型,其中:类型:是被引用变量的的类型, &:是引用运算符。:是引用运算符。例:例:int x; int &refx=x; /定义引

53、用定义引用refx,它是变量它是变量x的引用,即别名的引用,即别名阐明:阐明:(1) refx就称为对就称为对x的引用,的引用,x称为称为refx的引用对象。的引用对象。(2)&在此不是求地址运算,而是起标识作用。在此不是求地址运算,而是起标识作用。(3类型标识符是指目标变量的类型。类型标识符是指目标变量的类型。(4声明引用时,必须同时对其进行初始化。声明引用时,必须同时对其进行初始化。(5引用声明完毕后,相当于目标变量名有两个名称,即该引用声明完毕后,相当于目标变量名有两个名称,即该 目标原名称和引用名。目标原名称和引用名。(6声明一个引用,不是新定义了一个变量,它只表示该引声明一个引用,不

54、是新定义了一个变量,它只表示该引 用名是目标变量名的一个别名,所以系统并不给引用分用名是目标变量名的一个别名,所以系统并不给引用分 配存储单元。配存储单元。例:引用的使用例:引用的使用运行的结果为:x=12 refx=12y=36 refy=36x=36 refx=36从该例可以看出:从该例可以看出:引用是被引用变量的另一个名字;引用是被引用变量的另一个名字; 引用一旦初始化后,它就与初始化它的变量绑定在一起了。引用一旦初始化后,它就与初始化它的变量绑定在一起了。即使在即使在 程序中修改了它,也不会绑定到另一个变量上。程序中修改了它,也不会绑定到另一个变量上。 引用与指针不同。指针变量可不进行

55、初始化,并且在程序中引用与指针不同。指针变量可不进行初始化,并且在程序中可以指可以指 向不同的变量。引用必须在声明的同时用一个已经声明的向不同的变量。引用必须在声明的同时用一个已经声明的变量初变量初 始化,并且一旦初始化后就不会再绑定到其他变量上了。始化,并且一旦初始化后就不会再绑定到其他变量上了。 引用的作用:作为另一个变量变量名很长的别名。引用的作用:作为另一个变量变量名很长的别名。 引用可以作为函数的参数,建立函数参数的引用传递方式。引用传递实际上传递的是变量的地址,而不是变量本身。这种传递方式避免了传递大量数据带来的额外空间开销,从而节省大量存储空间,减少了程序运行的时间。引用作为函数

56、的参数引用作为函数的参数引用作为函数的参数引用作为函数的参数引用作为函数的返回值引用作为函数的返回值例:例: 使用引用参数,实现两个数据的交换。使用引用参数,实现两个数据的交换。#include void swap(int &refx,int &refy) int temp; temp=refx; refx=refy; refy=temp; void main() int x=63,y=36; coutfront swap:nx=x y=yendl; swap(x,y); coutback swap:nx=x y=yendl; 运行的结果为:front swap: x=63 y=36 back

57、 swap: x=36 y=63引用作为函数参数具有两个优点:引用作为函数参数具有两个优点: 参数传递方式类似于指针,但可读性却比指针传递参数传递方式类似于指针,但可读性却比指针传递强;强; 调用函数语法简单,与简单传值调用一样,但其功调用函数语法简单,与简单传值调用一样,但其功能却比传能却比传 值方式强。值方式强。 引用作为函数的返回值引用作为函数的返回值 引用既可以作为函数的参数,也可以作为函数的返回值。一般函数可以用return返回一个值,当函数返回值时要生成一个值的副本并保存在临时变量中。用引用返回值时,不生成值的副本。例:例: 阅读程序,给出运行结果。阅读程序,给出运行结果。 #in

58、clude int sum1(int a,int n); int &sum2(int a,int n); void main() int a10=1,2,3,4,5,6,7,8,9,10; int total1,total2; total1=sum1(a,10); total2=sum2(a,10); int &total3=sum2(a,10); couttotal1=total1endl; couttotal2=total2endl; couttotal3=total3endl; int sum1(int a,int n) int sum=0; for(int i=0;in;i+) sum

59、+=ai; return sum; int &sum2(int a,int n) int sum=0; for(int i=0;in;i+) sum+=ai; return sum;运行的结果为:total1=55 total2=55 total3=-858993460 阐明:阐明: 语句语句total1=sum1(a,10);在在sum1函数在返回函数在返回sum值时产生一个值时产生一个sum值的值的 副本,并保存在临时变量中,副本,并保存在临时变量中,total1再从临时变量中再从临时变量中 取得返回值;取得返回值; 语句语句total2=sum2(a,10);是引用调用,是引用调用,su

60、m2函数在返回函数在返回sum值时不产生值时不产生 sum值的副本,值的副本,total2直接从变量直接从变量sum中取得返回值;中取得返回值; 与与total2=sum2(a,10);语句类似语句类似total3=sum2(a,10);也是引用调用,但也是引用调用,但total3 本身也是一个引用,即本身也是一个引用,即total3是是sum2函数的返回值函数的返回值sum的别名。局部变的别名。局部变 量量sum的作用域为的作用域为sum2函数,当函数,当sum2结束后结束后sum也不复存在,因此,也不复存在,因此, total3的值不确定。的值不确定。 引用总结:引用总结:引用的目的主要用

温馨提示

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

评论

0/150

提交评论