复杂数据及运算-指针.ppt

上传人:小飞机 文档编号:6560362 上传时间:2023-11-12 格式:PPT 页数:75 大小:1.17MB
返回 下载 相关 举报
复杂数据及运算-指针.ppt_第1页
第1页 / 共75页
复杂数据及运算-指针.ppt_第2页
第2页 / 共75页
复杂数据及运算-指针.ppt_第3页
第3页 / 共75页
复杂数据及运算-指针.ppt_第4页
第4页 / 共75页
复杂数据及运算-指针.ppt_第5页
第5页 / 共75页
点击查看更多>>
资源描述

《复杂数据及运算-指针.ppt》由会员分享,可在线阅读,更多相关《复杂数据及运算-指针.ppt(75页珍藏版)》请在三一办公上搜索。

1、第四章 复杂数据及运算,清华大学 郑 莉,数组复习问题,1)什么情况下使用数组?2)数组里的元素是顺序存放的吗?3)一维数组如何定义?4)一维数组的初始化5)一维数组元素怎么使用6)一维数组如何输入输出7)二维数组的使用,4.2指针,为了操作地址!,一点忠告!,C/C+可以直接操作内存地址。指针就是为了地址操作而存在的。指针是复杂又容易出错的。在不是必须使用指针的场合,不推荐用指针。我们学习指针不是为了到处用指针,而是在需要用的时候使用。我们自己写程序的时候,在确保程序实现功能的前提下,代码是越简单越好,而不是技巧越多,越复杂越好!,本节的学习,本节除了动态内存分配,其余所有程序例题,其实都可

2、以不需要指针。只所以用指针是为了帮助我们理解指针的用法。本节的学习,一定要了解一点内存的知识。内存单元的地址C+各种基本数据类型的长度(字节),4.2.1 数据在内存中的地址,内存空间的访问方式通过变量名访问通过地址访问,6,程序中:int i;,内存中每个字节有一个编号-地址,.,.,2001,2002,内存,0,i,编译或函数调用时为其分配内存单元,变量是对程序中数据存储空间的抽象,变量与地址,2000,如何获得变量的地址,地址运算取地址运算符:&数组的起始地址数组名字既是数组的起始地址,因此数组名是地址常量。,8,例4-5:观察变量在内存中的地址,#includeusing namesp

3、ace std;int main()int intVal=1;double dVal=2.0;int intarray3=0,1,2;cout,9,4.2 数组4.2.1数据在内存中的地址,运行结果:0013FF7C:10013FF74:20013FF68:0013FF68:0,例4-5(续),4.2 数组4.2.1数据在内存中的地址,对例4_5的分析:如何获得变量的地址,1,intVal,地址:&intVal,2,dVal,地址:&dVal,intArray,intArray是数组名,代表的是数组的起始地址,也就是第一个元素的地址。intArrayi,用下标法访问数组的元素。intArray

4、0是数组的第一个元素,该元素的地址是&intArray0。所以intArray,&intArray0,所存放的地址是一样的。,一旦定义了一个数组,数组名存放的就是数组的起始地址,也就是一个地址类型的数据。在生存期内,整个数组在内存中的所占用的存储空间是不变的,地址是不变的,所以数组名是一个地址类型的常量。,对一维数组的再探讨,一维数组有个关键问题:下标不可以越界。但是如果越界编译器并不能检查出错误。从地址的角度来考虑这个问题。,intArray,&intArray3,超出数组范围,可能对其他数据产生破坏,例4-6:观察一维数组在内存中的存储,#include#include using nam

5、espace std;const int size=5;int main()int arraysize;int i;for(i=0;isize;i+)arrayi=i;for(i=0;isize;i+)coutsetw(10)arrayi;coutendl;for(i=0;isize;i+)coutsetw(10),15,4.2 数组4.2.1数据在内存中的地址,运行结果:0 1 2 3 4 0012FF6C 0012FF70 0012FF74 0012FF78 0012FF7C&array5:0012FF80,例4-6(续),对例4_6的分析,通过本例的输出,可以看出数组元素是顺序存储的。在

6、编译时不会出现错误信息;运行后得到的错误信息,是操作系统发出的。,例4-7:观察多维数组在内存中的存储,#include#include using namespace std;const int nrow=3;const int ncol=2;int main()int arraynrowncol;int i;for(i=0;inrow;i+)for(int j=0;jncol;j+)arrayij=i+j;for(i=0;inrow;i+)for(int j=0;jncol;j+)coutsetw(3)arrayijsetw(10),18,4.2 数组4.2.1数据在内存中的地址,运行结果

7、:0 0012FF68 1 0012FF6C 1 0012FF70 2 0012FF74 2 0012FF78 3 0012FF7C,例4-7(续),4.2 数组4.2.1数据在内存中的地址,对例4_7的分析,通过本例的输出,可以看出多维数组元素是按行存储的。,二维数组在内存中的存储,占据一片连续存储区int a43,a00 a01 a02a10 a11 a12a20 a21 a22a30 a31 a32,按行存放,4.2.1 结束语,这个部分通过3个例子,展示了数据在内存中如何存放,特别强调了数组的存放。普通变量:用取地址运算符&获得地址。数组:数组名就是数组的起始地址。那么,地址取出来做什

8、么?刚学过的3个例子中,地址取出来只是做了输出。问题1:为什么要使用地址?问题2:如何使用地址?,问题1:为什么要使用地址?,在C+中,除了用变量名,还可以直接使用地址来访问内存单元。这样做的原因:1 有些场合更高效2 动态分配内存时必须用地址访问3 有效的表示复杂数据结构。,问题2:如何使用地址?,用于存放地址的变量就是指针类型的变量。,4.2.2 指针及指针运算,定义指针*Name;T为类型,表示指针所指对象的类型;*表示此变量类型为指/针;Name为定义指针的名称。指针变量赋初值1.在声明指针的同时进行初始化赋值;2.在声明之后,使用赋值表达式语句为指针赋值。,25,4.2 数组,程序中

9、:int i;,内存中每个字节有一个编号-地址,.,.,2001,2002,内存,0,i,编译或函数调用时为其分配内存单元,变量是对程序中数据存储空间的抽象,1 变量与地址,2000,.,.,2000,整型变量i,10,变量i_pointer,2004,指针:一个变量的地址。指针变量:专门用来存放地址的变量叫指针变量,它的值也可以是数组或函数的地址。,2000,指针,指针变量,变量的内容,变量的地址,2.指针与指针变量,.,1.指针变量与其所指向的变量之间的关系,注意:1、int*p1,*p2;与 int*p1,p2;不一样。2、指针变量名是p1,p2,不是*p1,*p2。3、指针变量只能指向

10、定义时所规定类型的变量。4、指针变量定义后,变量值不确定,应用前必须先赋值。,3.指针变量的定义,2.指针变量的定义一般形式:数据类型*指针名;,合法标识符,指针的目标变量的数据类型,表示定义指针变量不是乘法运算符*,例 int*p1,*p2;float*q;char*name;,含义:取变量的地址单目运算符结合性:自右向左,含义:从某个地址中获取数据单目运算符结合性:自右向左,两者关系:互为逆运算,4.取地址运算符&与指针运算符*,.,.,2000,2010,整型变量i,10,变量i_pointer,2004,2000,指针变量,i_pointer-指针变量,它的内容是地址量2000*i_p

11、ointer-指针的目标变量i,它的内容是数据10&i_pointer-指针变量占用内存的地址:2010,i_pointer&i&(*i_pointer)i*i_pointer*(&i),指针运算符示例,.,例 main()int i=10;int*p;*p=i;cout*p;,不可以危险!,例 main()int i=10,k;int*p;p=,5.指针变量必须先赋值,再使用!,空指针:定义:指针变量值为零 例如:int*p=0;,p指向地址为0的内存单元;系统保证该单元不作它用;表示指针变量的值没有意义。,P为空指针与未对p赋值不同避免指针变量的非法引用,6.空指针,例4-8:定义指针并通

12、过指针访问变量,#include using namespace std;int main()int num(23);int*P_num=0;P_num=,33,4.2 数组4.2.2指针及指针运算,运行结果:the integer is:23the number that is pointed to is:23the address of the number is:0012FF7C,例4-8(续),4.2 数组4.2.2指针及指针运算,对例4_8的分析,通过本例的,学习定义指针给指针赋值使用指针空指针,指针初始化,int*P_num=0;P_num=定义指针同时初始化,习题,P72:选择题

13、3,4,将地址值赋给指针变量,例 int i;int*p=,变量必须已说明过;并要求两者类型一致。,例 int i;int*p=,用已初始化指针变量作初值,一般形式:数据类型*指针名=初始地址值;,7.指针变量的初始化,例 i=3;-直接访问,指针变量,.,.,2000,2010,整型变量i,10,变量i_pointer,2004,2000,3,例*i_pointer=20;-间接访问,20,直接访问间接访问,8.直接访问与间接访问,.,9.对指针变量的操作,指针变量的算术运算,指针与整数的加减运算指针p加上或减去n,其意义是指针当前指向位置的前方或后方第n个数据的地址。这种运算的结果值取决于

14、指针指向的数据类型。指针加一,减一运算指向下一个或前一个数据。例如:y=*p+相当于 y=*(p+),指 针,p-1,p,p+1,p+2,*(p-1)或者p-1,*p或者p-0,*(p+1)或者p1,*(p+2)或者p2,int*p;,42,注意:,指针做算术运算有意义的场合:访问连续数据序列,例如数组。其他情况不要用,不仅没意义,还容易带来危险操作。,关系运算指向相同类型数据的指针之间可以进行各种关系运算。指向不同数据类型的指针,以及指针与一般整数变量之间的关系运算是无意义的。指针可以和零之间进行等于或不等于的关系运算。例如:p=0或p!=0,判断是否为空指针赋值运算向指针变量赋的值必须是地

15、址常量或变量,不能是普通整数。但可以赋值为整数0,表示空指针。,指针变量的关系运算,例4-9:通过指针访问有序的批量数据,#include#include using namespace std;const int size=6;int main()int arraysize=2,4,13,7,9,21;int*P_array=array;coutthe sequence is:endl;while(P_array array+size)coutsetw(4)*P_array;P_array+;coutendl;P_array=array;coutthe forth number of the

16、 sequence is:endl;cout*(P_array+3)endl;return 0;,45,4.2 数组4.2.2指针及指针运算,运行结果:the sequence is:2 4 13 7 9 21the forth number of the sequence is:7,例4-9(续),4.2 数组4.2.2指针及指针运算,对例4_9的分析,指针可以和整数进行加减运算,运算规则比较特殊。指针加减运算的结果与指针类型密切相关。指针加1的效果是使指针指向下一个完整数据的起始地址。利用指针的这个特性,通过指针的不断增值,依次顺序访问有序的批量数据。,指针的算术运算,一般来讲,指针的算术

17、运算是和数组的使用相联系的,因为只有在使用数组时,才会得到连续分布的可操作内存空间。常用的比较运算:如果两个同类型的指针相等,表示这两个指针是指向同一个地址的。如果一个指针等于0,表示这个指针是空指针。,习题,P71:选择题2,指向数组元素的指针,声明与赋值例:int a10,*pa;pa=通过指针引用数组元素经过上述声明及赋值后:*pa就是a0,*(pa+1)就是a1,.,*(pa+i)就是ai.ai,*(pa+i),*(a+i),pai都是等效的。不能写 a+,因为a是数组首地址是常量。,指 针,为什么用指针处理数组,与后面要学习的动态内存分配数组有关。下面的例子,用了三种方法,对比,大家

18、可以发现:完成了同样的功能,使用指针也并没有更方便。包括例4_9,完全可以不用指针,大家思考如果不用指针,此题怎么写。,设有一个int型数组a,有10个元素。用三种方法输出各元素:使用数组名和下标使用数组名和指针运算使用指针变量,指 针,int main()int a10;int i;for(i=0;iai;coutendl;for(i=0;i10;i+)coutai;,使用数组名和下标,54,int main()int a10;int i;for(i=0;iai;coutendl;for(i=0;i10;i+)cout*(a+i);,使用数组名指针运算,55,使用指针变量,int main(

19、)int a10;int*p,i;for(i=0;iai;coutendl;for(p=a;p(a+10);p+)cout*p;,56,习题,P72:选择题5,复 习,指针复习-问题,1)指针里存的是什么?2)指针的定义,指针变量的定义一般形式:数据类型*指针名;,合法标识符,指针的目标变量的数据类型,表示定义指针变量不是乘法运算符*,例 int*p1,*p2;float*q;char*name;,指针复习-问题,3)指针的赋值,例 main()int i=10,k;int*p;p=,指针复习-问题,4)下面程序段有错误吗?,例 main()int i=10;int*p;*p=i;cout*p

20、;,指针必须先赋值 再使用,指针复习,建议:在定义指针时进行初始化如果暂且没有地址需要赋值给指针,将指针置为空。例如:int*p=0;,含义:取变量的地址单目运算符结合性:自右向左,含义:从某个地址中获取数据单目运算符结合性:自右向左,两者关系:互为逆运算,取地址运算符&与指针运算符*,指针习题1,指针习题2,动态分配与释放内存空间,以静态方式定义的数组,其大小必须定义好,而且不可改变大小。在运行时动态分配内存空间,一旦空间不再被使用,应该在程序中及时释放。但是动态分配的内存空间,不可以命名,也就不能通过变量名来访问了,只能使用地址操作。,4.2.2 指针及指针运算(续),内存的动态分配动态分

21、配单个变量的语法形式为:new T(初值列表);动态分配一维数组的语法形式为:new T元素个数;内存的动态释放释放单个变量空间的语法形式为:delete 指针名;释放动态数组空间的语法形式为:delete 指针名;,67,4.2 数组,运算结果是为新分配空间的起始地址,例4-10:实现一个在运行时确定大小的一维数组,#include#include using namespace std;int main()int size;coutsize;int*p=new intsize;int i;for(i=0;i size;i+)pi=i;coutthe sequence is:endl;for

22、(i=0;isize;i+)coutsetw(4)pi;coutendl;delete p;,68,4.2 数组4.2.2指针及指针运算,运行结果:please ensure the number of the sequence:5the sequence is:0 1 2 3 4,例4-10(续),4.2 数组4.2.2指针及指针运算,对例4_10的思考,动态分配内存解决了运行时确定数组大小的问题。但是这样的数组是没有名字的,只能通过地址访问。int*p=new intsize;*(p+i)与pi,是等价的,用此方法访问动态分配数组里面的元素。不再使用该数组,释放空间Delete p;,例4

23、-11:动态创建多维数组,#include#include#include using namespace std;int main()int(*p)3;/定义指向一维数组的指针p=new int23;int i;for(i=0;i2;i+)for(int j=0;j3;j+)pij=i*j;coutthe matrix is:endl;for(i=0;i2;i+)for(int j=0;j3;j+)coutsetw(3)*(*(p+i)+j);coutendl;,71,4.2 数组4.2.2指针及指针运算,运行结果:the matrix is:0 0 0 0 1 2,例4-11(续),4.2 数组4.2.2指针及指针运算,作 业,1)复习2)预习4.33)课程网站第三单元编程题编程题14:动态空间管理 4)书本P71选择题:2345填空题:13456,THANKS,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号