第5章 指针和引用.ppt_第1页
第5章 指针和引用.ppt_第2页
第5章 指针和引用.ppt_第3页
第5章 指针和引用.ppt_第4页
第5章 指针和引用.ppt_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

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

文档简介

1、C+语言拥有在运行时获得变量地址和操纵地址的能力,这种可用来操纵地址的变量类型就是指针。指针可以用于数组、内存的访问,还可作为函数的参数(放在第6 章介绍)。,第5章 指针和引用,引用是对变量或对象起的别名,引用可以传递数据,引用可以起到指针的一些作用。,5.1 指针的概念,5.2 数组与指针,5.3 引用的概念,小结与习题,下课,5.1 指针的概念,5.1.1 什么是指针,5.1.2 如何定义指针,5.1.3 指针的赋值,5.1.4 指针的运算,返回,5.1.1 什么是指针,指针是变量,是用来专门存放内存地址的变量。 为了说清楚指针变量,先讨论对变量的访问(存取)方式。 按变量的地址直接存取

2、变量的方法称为“直接访问”方式。存贮变量的内存空间的首地址称为该变量的地址。 如果将一个变量的地址放在另一个变量中,则存放地址的变量称为指针(pointer)型变量。这样存取变量,也可以间接的由指针变量取得该变量的地址进行,称为“间接访问”方式。 由于指针变量中的值是另一个变量的地址,我们习惯上形象地称指针变量指向该变量。指针变量中的值也简称为指针,所以指针就是地址。 设a是整型变量,其值为5,其分配的内存地址为1000H(H是16进制后缀,汇编语言表示方式);又设pa是整型指针变量,其值为1000H,可以说指针pa指向变量a。,返 回,5.1.2 如何定义指针,指针类型变量定义格式如下: 存

3、贮类型 指向类型 *变量名,*变量名; 这里*是一个定义变量为指针的说明符,而不是指针变量的一部分,更不是乘号。 例如: int a=5,*pa; /a定义为整型变量,pa定义为整型变量指针 double *p; / p定义为双精度实型变量指针 char *p3; / p3定义为字符型变量指针 int (*p4)5; p4定义为一维数组的指针,指向的数组有5个元素 int *p6; p6定义为一个整型变量指针的指针,即p6的值是一个 指针型变量的地址,那个指针变量指向一个整型变量,换句话说,p6是一个二级指针变量。,返 回,5.1.3 指针的赋值,为了给指针赋值,C+中提供了一个取变量地址运算

4、符: /赋给p3的值为数组b的首地址,实际上p2、p3的值一样,指针变量必须先赋值再使用。对指针变量决不可任意赋一个非负整数。指针变量中存放的是在内存中可寻址的变量或对象的首地址,而变量或对象的内存地址是由系统分配的。程序员不能代替系统给变量分配内存,系统不允许给指针变量随意赋一个地址值,只能取系统分配的变量地址赋给指针变量。,5.1.3 指针的赋值,指针赋值注意事项: 指针值是地址 指针只能指向定义时规定的类型 如有定义: int *p; double x; 则赋值语句:p= /p1的值是a的地址,p1的值又赋给p2 暂时不用的指针可赋值为0,表示空指针。这表示当前该指针并不指向该类型的任何

5、一个变量(对象),并不是指向地址为0的内存空间。,返 回,5.1.4 指针的运算,使用指针变量可以间接访问指针指向的单元, 如有定义:int a,*p= 其中运算符*称为间接引用(dereference)运算符,作用于一个指针类型的变量,访问该指针所指向的内存数据。实际上例中的a与*p完全是一回事。,指针的运算共有4类: 赋值运算(包括一个指针赋给另一个指针、同类型表达式的值赋给指针指向的变量) 指针加减整数(实际加减的是指向类型长度的整数倍) 同类型指针相减 同类型指针比较 用下面的例5.1、例5.2理解上述运算,【例5.1】逆序输出字符串,#include int strlen1(char

6、); void main() char s=abcdefg;char *p; int n=strlen1(s); /声明调用后面定义的函数 for(p=s+n-1;p+1!=s;p-) cout*p; coutendl; int strlen1(char a) /计算给定字符串的字符个数(字符串长度) char *p=a; int i=0; while(ai+!=0)p+;/移动指针,使其指到串结束标志 return p-a; /两个地址相减,结果为串长度 ,带领同学阅读程序,注意几个知识点:数组、指针、循环、函数。,【例5.2】指针运算例子,#include void main() int

7、i=6,*pi1= ,先在VC+下执行该程序,与同学共同思考为什么是这样的结果?,返 回,5.2 数组与指针,5.2.1 数组名是一个常量指针,5.2.3 指向数组的指针,5.2.2 用指针表示数组元素,5.2.4 指针数组,5.2.5 字符指针与字符串处理函数,返回,5.2.1 数组名是一个常量指针,数组是由同一类型元素组成的一个有序集合,如: int a5=5,8,13,21,34;,该数组在系统编译时分配连续的存储空间,数组名a就是这连续空间的首地址,因此可以将数组名当作地址值(指针)看待。即 数组名是常量,是一个指针值。,如再定义:int *p; 则下述有关指针的运算是合法的: p=a

8、;p+;-p;p+=3;p=a+2;,下述有关指针的运算是非法的: a+;-a;a+=3;a=p+2; 原因在于p是变量,a是常量!,返 回,1. 一维数组元素的指针表示 假设已有定义:int a5,*p=a; 则ai(数组中的第i+1个元素)有以下4种表示方法: ai、p2、*(a+i)、*(p+i) 前两种称为数组表示法,后两种称为指针表示法。C+中指针表示比数组表示效率高。需要提高运行效率时,仅可能使用指针表示方法。 上述表示中,数组名与指针名在使用方式上没有区别,但要注意,指针的值可以改变,数组名代表的值是不可以改变的。,5.2.2 用指针表示数组元素,【例5.3】分析程序,预测输出结

9、果,指针表示数组元素,#include void main() static int a=9,7,5,3,1; int *p=a; for(int i(0);p+i=a+4;p+,i+) cout*(p+i),; coutendl; for(p=a+4,i=0;i5;i+)coutp-i,; /p-i相当于*(p-i) coutendl; ,与学生一起阅读程序,估计输出结果.在阅读循环程序段时列出表格:,2. 二维数组元素的指针表示,二维数组元素在内存中实际上是按照行优先的规定以一维(线性)的形式存储的。如:int b35; 在内存中存储顺序为:b00,b01,b02,b03,b04,b10,

10、b11,b12,b13,b14,b20,b21,b22,b23,b24等15个元素是线性排列的。 二维数组b呈现在用户面前的是3行5列的矩阵,是二维形式.因此对二维数组元素的指针表示有两种方式:一级指针表示和二级指针表示。 上述数组元素bij(i=0,1,2 j=0,1,2,3,4)的 一级指针表示为:*( void main() couta,*a,*aendl; couta0, 先阅读上述程序,再上机运行该程序,结合机器输出结果理解。,3. 三维数组元素的指针表示 三维数组可以看作是元素是一维数组的二维数组或元素是二维数组的一维数组,故其指针表示可参照二维数组元素的指针表示方法分一级、二级、

11、三级等,不再详述。,返 回,5.2.3 指向数组的指针,指针可以指向数组元素,也可以指向数组。 1.指向数组元素的指针 指向数组元素的指针是一级指针,如定义数组、指针: int a10,b35;int *p1,*p2,*p3; 则下述赋值是正确的: p1=是错误的,因为b是二维数组名,相当于二级指针,而p2是一级指针,因此是错误的。,【例 5.5】阅读程序,#include int m3=12,10,8,6,4,2; void main() int *p= p为一级指针,m为二维数组,但m在内存中实际是一维存储的,可用一级指针表示,指针p初始化为指向数组的最后一个元素(m12)。 由于-的级别

12、高于*,故*p-相当于*(p-),而不是(*p)-, *(p-)表示先取出指针p指向变量的值,再将指针的值加1。 将程序中的*p-改为(*p)-,运行程序试一试!,2. 指向一维数组的指针,指向一维数组的指针实际上是二级指针,指向二维数组的指针实际上是三级指针等等。 一维数组指针的定义格式为: 数组元素类型名 (*数组指针名)数组元素个数 注意,定义时的()不可少,因为的级别高于*,【例5.6】阅读程序。 #include int a34=1,2,3,4,5,6,7,8,9,10,11,12 void main() int (*p)4; p=a+1; coutp00,*(*(p+1)+2),*

13、(*(p-1)+3),p-12endl; 阅读程序时,将二级指针p当作二维数组名a看待, 但要注意p的初始位置,返 回,5.2.4 指针数组,前述的数组指针是指针,他指向一个数组;而指针数组是数组,其元素是指针。一维一级指针数组定义方式为: 指针指向类型 *数组名元素个数 其中的元素个数也是数组中的指针个数 例,int *a5就定义了一个5个元素的数组,其中每个元素都是一个整型指针。 注意,int (*a)5定义的是一个指针(二级),指向一个5个整数构成的一个一维数组。,【5.7】求数组元素平均值,并分别求前后半段的最大值.,#include int a=32,65,67,89,21,35,8

14、1,93,60,45; void main() int *pa2;double ave(0); pa0= 带领同学阅读程序,注意发现第二个for循环中的错误!将数据21改为121、45改为145后,运行上述程序,即可发现错误!,改进的【例5.7】,#include int a=32,65,67,89,121,35,81,93,60,145; void main() int *pa2;double ave(0); for(int i=0;i10;i+) ave+=ai; coutave/10endl; pa0= 阅读时注意,第一个循环、第二个循环与课本程序的区别!,返 回,5.2.5 字符指针与

15、字符串处理函数,1. 字符数组与字符指针 字符串用字符型数组存储,要求其尾部以0作为结束标志。 如:char string =C+ programming language; 实际占用内存为25个字节,而字符串本身长度(含空格)为24个字节,多出来的一个就是串结束符0。,字符串可以用字符数组、字符指针两种方式定义: char *pstr= C+ programming language ; 这里是用指针形式定义了一个字符串pstr,与上面用数组形式定义的字符串作用一样,编译器将字符串常量” C+ programming language”的第一个字符的存储地址赋给字符指针作初值。 用指针或数组

16、定义字符串后,字符串的名字就是数组名或指针名。 用数组定义时,内存地址已经分配;用指针定义时如未初始化,则字符串占用的地址需要动态分配。,【5.8】文本加密解密,#include void main() char *p1,a16,b16; p1=I am a teacher.; for(int i(0);i15;i+) ai=p1+1; ai=0;/此句可以改为:ai=0; coutaendl; for(i=0;i15;i+) bi=*(a+i)-1;/此句可改为:bi=ai-1; bi=0; /此句可以改为:bi=0; coutbendl; 字符串p1为原始文本,字符串a为加密结果,b为解密

17、还原。 注意字符串末尾的标志0,可直接写成0.,2.字符指针数组,字符指针数组中的每一个元素都是一个字符指针,指向一个字符串。定义格式为: char *数组名指针个数=若干个初始化字符串 格式中的灰色部分是可选的。 例,char *s3=abc, efg,mnp; 就定义了3个字符指针:s0,s1,s2,分别指向3个字符串,3.字符串处理函数 C+系统设计了一批字符串处理函数,存放在string.h中,使用时应在增加包含文件:#include 求串长函数strlen(字符串) 值为整数 串比较函数strcmp(串1,串2) 值为整数 串中检索字符函数index(字符串,字符) 值为字符指针 串

18、连接函数strcat(串1,串2) 值为字符指针 串复制函数strcpy(字符串名,字符串) 值为字符指针,【例5.9】求最大字符串及其中的最大字符。,#include #include char *s=case,switch,return,double,float,char; void main( ) char *pmax; pmax=s0; for(int i=1;i6;i+) if(strcmp(pmax,si)0) pamx=si; coutpmaxendl; char cmax=*pmax; for(i=1;i6;i+) if(cmax*+pmax) cmax=*pmax; coutcmaxendl; 带领同学阅读上述程序。,【例5.10】求最小字符串,#incl

温馨提示

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

评论

0/150

提交评论