【教学课件】第7章间接访问-指针.ppt
《【教学课件】第7章间接访问-指针.ppt》由会员分享,可在线阅读,更多相关《【教学课件】第7章间接访问-指针.ppt(109页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、程序设计 cs.sjtu 2011.9程序设计-1第第7章章 间接访问间接访问指针指针v指针的概念指针的概念v指针运算与数组指针运算与数组v动态内存分配动态内存分配v字符串再讨论字符串再讨论v指针作为函数参数和返回值指针作为函数参数和返回值v指针数组与多级指针指针数组与多级指针v指向多维数组的指针指向多维数组的指针v指向函数的指针指向函数的指针程序设计 cs.sjtu 2011.9程序设计-2指针介绍 本章将介绍本章将介绍C+C+语言的一个重要的特性:指针,为了语言的一个重要的特性:指针,为了成为一个优秀的成为一个优秀的C+C+语言程序员,你必须掌握指针并语言程序员,你必须掌握指针并熟练地使用
2、它们。熟练地使用它们。指针指针是内存的是内存的地址地址并可作为数据并可作为数据是一个灵活和危险的机制是一个灵活和危险的机制允许允许共享共享处理数据处理数据允许内存允许内存动态动态分配(只要需要,而非预先定义)分配(只要需要,而非预先定义)程序设计 cs.sjtu 2011.9程序设计-3指针的概念指针的概念v指针就是把地址作为数据处理指针就是把地址作为数据处理v指针变量:存储地址的变量指针变量:存储地址的变量v变量的指针:当一个变量存储另一个变量的变量的指针:当一个变量存储另一个变量的地址时,那我们说它就是那个变量的指针地址时,那我们说它就是那个变量的指针v使用指针的目的:提供间接访问使用指针
3、的目的:提供间接访问程序设计 cs.sjtu 2011.9程序设计-4指针的概念指针的概念 续续续续v如在某一程序中定义了如在某一程序中定义了 int x=2;v如系统给如系统给x分配的空间是分配的空间是1000号单号单元,则指向元,则指向x的指针是另一个变量的指针是另一个变量p,p中存放的数据为中存放的数据为1000v1000号单元的内容有两种访问方号单元的内容有两种访问方式:式:访问变量访问变量x(直接访问)(直接访问)访问变量访问变量p指向的单元的内容(间接指向的单元的内容(间接访问)访问)1000 21000 xp程序设计 cs.sjtu 2011.9程序设计-5定义指针变量定义指针变
4、量v定义指针变量要告诉编译器该变量中存放的是一定义指针变量要告诉编译器该变量中存放的是一个地址。个地址。v指针变量的主要用途是提供间接访问,因此也需指针变量的主要用途是提供间接访问,因此也需要知道指针指向的单元的数据类型要知道指针指向的单元的数据类型v指针变量的定义指针变量的定义 类型标识符类型标识符 *指针变量;指针变量;如:如:int int *intp;intp;double double*doublep;doublep;int*p,x,*q;int*p,x,*q;程序设计 cs.sjtu 2011.9程序设计-6指针变量的操作指针变量的操作v如何让指针指向某一变量?因为我们不知道系统分
5、如何让指针指向某一变量?因为我们不知道系统分配给变量的真正地址是什么。配给变量的真正地址是什么。用地址运算符用地址运算符 “&”解决。如表达式解决。如表达式 “&x”返回的是返回的是变量变量 x 的地址。如:的地址。如:intp=&x;&运算符后面不能跟常量或表达式。如运算符后面不能跟常量或表达式。如&2 是没有意义的,是没有意义的,&(m*n+p)。也是没有意义的。也是没有意义的v如何通过指针变量处理和改变它所指向的单元的值如何通过指针变量处理和改变它所指向的单元的值?用引用运算符用引用运算符 “*”解决。如解决。如 *intp 表示的是表示的是 intp 指指向的这个单元的内容。如:向的这
6、个单元的内容。如:*intp=5 intp=5 等价于等价于 x=5x=5在对在对 intp 使用引用运算之前,必须先对使用引用运算之前,必须先对 intp 赋值赋值程序设计 cs.sjtu 2011.9程序设计-7指针实例指针实例如有:如有:int X,*intp,Y;X=3;Y=4;intp=&X;1000intp10044Y10003X如执行:如执行:*intp=Y+4;1000intp10044Y10008X注意:不能用注意:不能用 intp=100;intp=100;因为我们永远不知道变量存储的因为我们永远不知道变量存储的 真实地址,而且真实地址,而且程序每次运行变量地址可能都不同。
7、程序每次运行变量地址可能都不同。程序设计 cs.sjtu 2011.9程序设计-8指针使用指针使用v指针变量可以指向不同的变量。如上例中指针变量可以指向不同的变量。如上例中intp指向指向x,我们可以通过对,我们可以通过对intp的重新赋值改变指针的指向。的重新赋值改变指针的指向。如果想让如果想让intp指向指向y,只要执行,只要执行intp=&y就可以了。就可以了。这时,这时,intp与与x无任何关系。无任何关系。v同类的指针同类的指针变量之间可相互赋值,表示二个指针指变量之间可相互赋值,表示二个指针指向同一内存空间。向同一内存空间。v空指针空指针指针没有指向任何空间指针没有指向任何空间空指
8、针用常量空指针用常量NULLNULL表示,表示,NULLNULL的值一般赋为的值一般赋为0 0不能引用空指针指向的值不能引用空指针指向的值程序设计 cs.sjtu 2011.9程序设计-9指针变量的使用指针变量的使用设有定义设有定义 int x,y;int*p1,*p2;1000 x1004y1008p11012p2执行语句:执行语句:x=23;y=234;1000 23x1004 234y1008p11012p2执行语句:执行语句:p1=&x;p2=&y;1000 23x1004 234y1008 1000p11012 1004p2执行语句:执行语句:*p1=34;p2=p1;1000 34
9、x1004 234y1008 1000p11012 1000p2程序设计 cs.sjtu 2011.9程序设计-10指针实例指针实例有以下结构有以下结构 Ap1aBp2b比较执行比较执行 p1=p2和和*p1=*p2后的不同结果。后的不同结果。解:解:Ap1aBp2bBp1aBp2b程序设计 cs.sjtu 2011.9程序设计-11指针的初始化指针的初始化v指针在使用前必须初始化。指针在使用前必须初始化。v和别的变量一样,定义指针不初始化是一个比和别的变量一样,定义指针不初始化是一个比较普通的错误。较普通的错误。v没有初始化的指针可能指向任意地址,对这些没有初始化的指针可能指向任意地址,对这
10、些指针作操作可能会导致程序错误。指针作操作可能会导致程序错误。vNULLNULL是一个特殊指针值,称为空指针。它的值是一个特殊指针值,称为空指针。它的值为为0 0。它可被用来初始化一个指针,表示不指。它可被用来初始化一个指针,表示不指向任何地址。向任何地址。v思考:思考:int*p;*p=5;int*p;*p=5;有什么问题?有什么问题?程序设计 cs.sjtu 2011.9程序设计-12第第7章章 间接访问间接访问指针指针v指针的概念指针的概念v指针运算与数组指针运算与数组v动态内存分配动态内存分配v字符串再讨论字符串再讨论v指针作为函数参数和返回值指针作为函数参数和返回值v指针数组与多级指
11、针指针数组与多级指针v指向多维数组的指针指向多维数组的指针v指向函数的指针指向函数的指针程序设计 cs.sjtu 2011.9程序设计-13指针运算和数组指针运算和数组v指向数组元素的指针指向数组元素的指针数组元素是一个独立的变量,因此可以有指针数组元素是一个独立的变量,因此可以有指针指向它。如:指向它。如:p=&a1,p=&ai数组元素的地址是通过数组首地址计算的。如数组元素的地址是通过数组首地址计算的。如数组的首地址是数组的首地址是 1000,则第,则第i 个元素的地址是个元素的地址是1000+i*每个数组元素所占的空间长度每个数组元素所占的空间长度程序设计 cs.sjtu 2011.9程
12、序设计-14指针与数组指针与数组v在在C+C+中,指针和数组关系密切,几乎可以互中,指针和数组关系密切,几乎可以互换使用换使用v数组名可以看成是常量指针,对一维数组来说,数组名可以看成是常量指针,对一维数组来说,数组名是数组的起始地址,也就是第数组名是数组的起始地址,也就是第0 0个元素个元素的地址的地址v如执行了如执行了p=arrayp=array,则,则p p与与arrayarray是等价的,对是等价的,对该指针可以进行任何有关数组下标的操作该指针可以进行任何有关数组下标的操作程序设计 cs.sjtu 2011.9程序设计-15例如:有定义例如:有定义 int a10,*pint a10,
13、*p 并且执行了并且执行了 p=ap=a,那么可用下列语句访问数组那么可用下列语句访问数组a a的元素的元素for (i=0;i10;+i)for (i=0;i10;+i)cout pi;cout pi;程序设计 cs.sjtu 2011.9程序设计-16指针运算指针运算v指针指针+1表示数组中指针指向元素的下一元素表示数组中指针指向元素的下一元素地址;地址;v指针指针-1表示数组中指针指向元素的上一元素地表示数组中指针指向元素的上一元素地址;址;v合法的指针操作:合法的指针操作:p+k,p-k,p1-p2指针保存的是一个地址,地址是一个整型数,因此可指针保存的是一个地址,地址是一个整型数,因
14、此可以进行各种算术运算,但仅有加减运算是有意义的。以进行各种算术运算,但仅有加减运算是有意义的。指针运算与数组有密切的关系指针运算与数组有密切的关系程序设计 cs.sjtu 2011.9程序设计-17数组元素的指针表示数组元素的指针表示v当把数组名,如当把数组名,如 intarray,赋给了一个同类指针,赋给了一个同类指针intp 后,后,intarray 的元素可以通过的元素可以通过intp访问。第访问。第i个元素的地址可表示为个元素的地址可表示为 intp+i,第,第i个元素的值个元素的值可表示为可表示为*(intp+i)。v通过指针访问数组时,下标有效范围由程序员自通过指针访问数组时,下
15、标有效范围由程序员自己检查。己检查。v如输出数组如输出数组 a 的十个元素的十个元素程序设计 cs.sjtu 2011.9程序设计-18方法方法3:for (p=a;pa+10;+p)cout *p;方法方法2:for (i=0;i10;+i)cout *(a+i);方法方法1:for (i=0;i10;+i)cout ai;方法方法4:for (p=a,i=0;i10;+i)cout *(p+i);方法方法5:for (p=a,i=0;i10;+i)cout pi;下列程序段下列程序段 有无问题?有无问题?for (i=0;i10;+i)cout *a;+a;程序设计 cs.sjtu 201
16、1.9程序设计-19指针和数组的区别指针和数组的区别v虽然通过指针可以访问数组,但两者本质是不同的。虽然通过指针可以访问数组,但两者本质是不同的。v在定义数组时为数组的各个元素分配了全部的存储区,在定义数组时为数组的各个元素分配了全部的存储区,而在定义指针时,仅仅分配四个字节的存储区存放指而在定义指针时,仅仅分配四个字节的存储区存放指针地址。只有把一个数组名付给了对应的指针后,指针地址。只有把一个数组名付给了对应的指针后,指针才能当作数组使用针才能当作数组使用v如有:如有:int array5,*intp;int array5,*intp;arrayintp当执行了当执行了 intp=arra
17、yintp=array后后程序设计 cs.sjtu 2011.9程序设计-20第第7章章 间接访问间接访问指针指针v指针的概念指针的概念v指针运算与数组指针运算与数组v动态内存分配动态内存分配v字符串再讨论字符串再讨论v指针作为函数参数和返回值指针作为函数参数和返回值v指针数组与多级指针指针数组与多级指针v指向多维数组的指针指向多维数组的指针v指向函数的指针指向函数的指针程序设计 cs.sjtu 2011.9程序设计-21动态分配动态分配v在在C+C+语言中,每个程序需要用到几个变量,语言中,每个程序需要用到几个变量,在写程序前就应该知道。每个数组有几个元素在写程序前就应该知道。每个数组有几个
18、元素也必须在写程序时就决定。也必须在写程序时就决定。v有时我们并不知道我们需要多大的数组元素直有时我们并不知道我们需要多大的数组元素直到程序开始运行。因此希望能在程序中根据某到程序开始运行。因此希望能在程序中根据某一个当前运行值来决定数组的大小。如设计一一个当前运行值来决定数组的大小。如设计一个打印魔阵的程序,我们希望先输入魔阵的阶个打印魔阵的程序,我们希望先输入魔阵的阶数,然后根据阶数定义一个矩阵数,然后根据阶数定义一个矩阵程序设计 cs.sjtu 2011.9程序设计-22动态分配方法动态分配方法v这些问题的解决方案就是内存的动态分这些问题的解决方案就是内存的动态分配。我们定义一个指针,并
19、让它指向一配。我们定义一个指针,并让它指向一个合适的内存。如:个合适的内存。如:int*scores;int*scores;scores=scores=内存的起始地址;内存的起始地址;程序设计 cs.sjtu 2011.9程序设计-23动态内存分配与回收动态内存分配与回收v中由中由new new 和和 deletedelete两个运算符替代两个运算符替代-运算符运算符newnew用于进行内存分配:用于进行内存分配:申请动态变量:申请动态变量:p=new type;p=new type;申请动态数组:申请动态数组:p=new typesize;p=new typesize;申请动态变量并初始化:
20、申请动态变量并初始化:p=new type(p=new type(初值初值);-运算符运算符delete delete 释放释放 newnew分配的内存:分配的内存:释放动态变量:释放动态变量:delete p;delete p;释放动态数组:释放动态数组:delete p;delete p;程序设计 cs.sjtu 2011.9程序设计-24动态内存分配与回收动态内存分配与回收/为简单变量动态分配内存,并作初始化为简单变量动态分配内存,并作初始化int main()int main()int*p;int*p;p=new int(99);p=new int(99);/动态分配内存,并将动态分配
21、内存,并将9999作为初始化值赋给它作为初始化值赋给它 cout*p;cout*p;delete p;delete p;return 0;return 0;程序设计 cs.sjtu 2011.9程序设计-25动态内存分配与回收动态内存分配与回收/动态字符串的使用动态字符串的使用int main()int*p;char*q;p=new int(5);q=new char10;strcpy(q,abcde);cout *p endl;cout q endl;delete p;delete q;return 0;输出结果:输出结果:5abcde程序设计 cs.sjtu 2011.9程序设计-26动态
22、分配的检查动态分配的检查vnew操作的结果是申请到的空间的地址操作的结果是申请到的空间的地址v当系统空间用完时,当系统空间用完时,new操作可能失败操作可能失败vnew操作失败时,返回空指针操作失败时,返回空指针程序设计 cs.sjtu 2011.9程序设计-27动态内存分配与回收动态内存分配与回收/动态分配检查动态分配检查int main()int main()int*p;int*p;p=new int;p=new int;if(!p)if(!p)cout allocation failuren;cout allocation failuren;return 1;return 1;*p=20
23、;cout *p;*p=20;cout *p;delete p;return 0;delete p;return 0;程序设计 cs.sjtu 2011.9程序设计-28assert宏宏 vassert()宏在标准头文件()宏在标准头文件cassert中中 vassert()有一个参数,表示断言为真的表有一个参数,表示断言为真的表达式,预处理器产生测试该断言的代码。达式,预处理器产生测试该断言的代码。如果断言不是真,则在发出一个错误消如果断言不是真,则在发出一个错误消息后程序会终止。息后程序会终止。程序设计 cs.sjtu 2011.9程序设计-29#include#include /包含包含
24、assert宏的头文件宏的头文件using namespace std;int main()int*p;p=new int;assert(p!=0);/p等于等于0,则退出程序,则退出程序 *p=20;cout *p;delete p;return 0;程序设计 cs.sjtu 2011.9程序设计-30内存分配的进一步介绍内存分配的进一步介绍v静态分配:对全局变量和静态变量,编静态分配:对全局变量和静态变量,编译器为它们分配空间,这些空间在整个译器为它们分配空间,这些空间在整个程序运行期间都存在程序运行期间都存在v自动分配:函数内的局部变量空间是分自动分配:函数内的局部变量空间是分配在系统的
25、栈工作区。当函数被调用时,配在系统的栈工作区。当函数被调用时,空间被分配;当函数执行结束后,空间空间被分配;当函数执行结束后,空间被释放被释放v动态分配:在程序执行过程中需要新的动态分配:在程序执行过程中需要新的存储空间时,可用动态分配的方法向系存储空间时,可用动态分配的方法向系统申请新的空间,当不再使用时用显式统申请新的空间,当不再使用时用显式的方法还给系统。这部分空间是从被称的方法还给系统。这部分空间是从被称为堆的内存区域分配。为堆的内存区域分配。OSProgramHeap动态分配动态分配Stack自动分配自动分配Globe variables静态分配静态分配程序设计 cs.sjtu 20
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 教学课件 教学 课件 间接 访问 指针
限制150内