指针ppt课件.ppt

上传人:本田雅阁 文档编号:2798624 上传时间:2019-05-18 格式:PPT 页数:48 大小:427.03KB
返回 下载 相关 举报
指针ppt课件.ppt_第1页
第1页 / 共48页
指针ppt课件.ppt_第2页
第2页 / 共48页
指针ppt课件.ppt_第3页
第3页 / 共48页
指针ppt课件.ppt_第4页
第4页 / 共48页
指针ppt课件.ppt_第5页
第5页 / 共48页
点击查看更多>>
资源描述

《指针ppt课件.ppt》由会员分享,可在线阅读,更多相关《指针ppt课件.ppt(48页珍藏版)》请在三一文库上搜索。

1、指针,本部分要点,指针的基本概念 指针型变量 变量的定义 指针的基本操作 指针变量的使用 指针数组 指针与函数 指针与字符串,本部分难点,多级指针 指针与函数的关系,各指针类型作为函数参数,用函数指针变量调用函数,第一节 指针的基本概念,1.内存单元:在计算机中,所有的数据都是存放在存储器中的。一般把存储器中的一个字节称为一个内存单元,不同的数据类型所占用的内存单元数不等,如整型量占2个单元,字符量占1个单元等。,2.地址:为了正确地访问内存单元,必须为每个内存单元编上号。根据一个内存单元的编号即可准确地找到该内存单元。内存单元的编号也叫做地址。既然根据内存单元的编号或地址就可以找到所需的内存

2、单元,可以说地址指向该内存单元,因此通常把地址形象化地称为指针。那么指针的定义:是一种数据类型,指存放数据的存储地址。,3.变量与地址:程序中可以用变量来存放各种数据,因此每个变量都需要分配连续的内存单元。如程序中有如下定义语句:int i=5,j=3;float f;给它分配的内存单元如右下图:,结论 当一个变量只占用一个内存单元时,内存单元的地址就是变量的地址;当变量占用连续的若干个内存单元时,最前面一个单元的地址就是该变量的地址。,4.直接存取与间接存取 对变量操作时不需知道它的地址(变量与地址的联系由编译程序实现),对变量的存取就是对相应存储单元的存取,这就是“直接存取”方式;指针变量

3、的内容是另一个变量的地址,称p指向a。通过指针变量p存取变量a的存取方式叫“间接存取”。,指针变量:指针变量是存放另一个变量的地址的变量。它和普通变量一样占用一定的存储空间。它与普通变量不同之:指针的存储空间里存放的不是普通的数据,而是一个地址。,第二节 指针型变量,指针在程序中使用时,必须预先在数据说明部分说明。在指针说明的同时也可以进行初始化。 2.1 定义(指针的说明) 指针的说明指出了指针的存储类型和数据类型,它的一般形式如下: 存储类型 数据类型 *指针变量名; 例如: int *px; char *name; static int *pa; 上面定义了名字为px,name和pa的三

4、个不同类型的指针。,2.2 指针的基本操作,两个有关的运算符: (1) 将打印相同的结果 ,*与 x=*&x,2.3 初始化和引用 指针在说明的同时,也可以被赋予初值,称为指针的初始化。由于指针是保持地址的变量,所以初始化时赋予它的初值必须是地址量。指针初始化的一般形式是 : 存储类型 数据类型 *指针名=初始地址值; 例如: int *pa= 它把变量a 的地址作为初值赋予了int型指针pa。 需要注意的是,从表面上看,似乎把一个初始地址量赋予给了指针的目标变量*pa。其实不然,初始化形式中*pa=&a不是一个运算表达式,这里是一个说明性语句。所以,读者应该记住,这里的初始地址值是赋给指针变

5、量,而不是赋给目标变量。,当把一个变量的地址作为初值赋给指针时,该变量必须在指针初始化之前已经说明过。其道理很简单,变量只有在说明之后才被分配一定的内存地址。此外,该变量的数据类型必须与指针的数据类型一致。例如: char cc; char *pc= int *px=0;是把一个指针初始化为空指针。,例1: 指针的概念 main() int a; int *pa= ,运行结果: a:10 *pa:10 &a:f86(HEX) pa:f86(HEX) &pa:f88(HEX),2.4 指针的运算,指针的赋值运算 指针的算术运算 是按C语言地址计算规则进行的,这种运算与指针指向的数据类型有密切关系

6、,也就是C语言的地址计算与地址中存放的数据长度有关。设px和py是指向具有相同数据类型的一组若干数据的指针,n是整数,则指针可以进行的算术运算有如下几种: px+n,pxn,px+,+px, px,px,pxpy,(1)、 指针与整数的加减运算 指针作为地址量加上或减去一个整数n,其意义是指针当前指向位置的前方或后方第n个数据的位置。由于指针可以指向不同数据类型,即数据长度不同的数据,所以这种运算的结果值取决于指针指向的数据类型。例如,假设有一单字节字符类型和另一个双字节整数类型:当字符指针加1时,增量为1,而整数指针加1时,增量为2。,(2)、 指针加1、减1运算 指针加1、减1单项运算也是

7、地址计算,指针+运算后就指向了下一个数据的位置,- - 运算后就指向上一个数据的位置。运算后指针地址值的变化量取决于它指向的数据类型。 要注意它们之间的结合规则和运算顺序。例如:,(3)、 指针的相减 设指针p和q是指向同一组数据类型一致的数据,则pq运算的结果值是两指针指向的地址位置之间的数据个数。 例: 统计输入字符串的字符个数 main() char str20; char *p; coutstr; p=str; while(*p!= 0) p+; cout“The string length“p-str; 若输入:UNIXANDC,则运行结果:Enter a string (less

8、than 20 characters): The string length:10,3、指针变量的关系运算 两个指向同一组类型相同的数据的指针之间可以进行各种关系运算,运算结果为逻辑值,满足关系时,结果为(真),否则为(假)。 如int a10,*p,*q; p= 则p&a2 结果为0 指向不同数据类型的指针之间的关系运算是没有意义的。 指针与一般整数变量之间的关系运算也是无意义的。 但是指针可以和零之间进行等于或不等于的关系运算,即:p= =0或p!=0,它们用于判断指针p是否为一个空指针。,3 指针与数组,3.1 指针和数组的关系: 指针和数组有着密切的关系, 任何能由数组下标完成的操作也

9、都可用指针来实现, 但程序中使用指针可使代码更紧凑、更灵活。可以设置指针变量指向数组或数组中的元素。 如:int a10, *p; 可以使整型指针p指向数组中任何一个元素, 假定给出赋值运算 p= 此时, p指向数组中的第0号元素, 即a0, 指针变量p中包含了数组元素a0 的地址, 由于数组元素在内存中是连续存放的, 因此, 我们就可以通过指针变量p及其有关运算间接访问数组中的任何一个元素。根据地址运算规则, a+1为a1的地址, a+i就为ai的地址。,在定义指向数组的指针时,有下列几种表示方式: (1) int a10, *p = 则p2就相当于*(p+2), 由于p指向a5, 所以p2

10、就相当于a7。而p-3就相当于*(p-3), 它表示a2。,3.2 通过指针引用数组元素,程序P199,当数组的元素类型为某种指针类型时,该数组就称为指针数组。 即该数组中每个元素都是指针变量。指针数组的定义形式为: 类型标识 *数组名整型常量表达式; 例如: int *a10; 定义了一个指针数组, 数组中的每个元素都是指向整型量的指针, 该数组由10个元素组成, 即a0, a1, a2, ., a9, 它们均为指针变量。a为该指针数组名, 和数组一样, a是常量, 不能对它进行增量运算。a为指针数组元素a0的 地址, a+i为ai的地址, *a就是a0, *(a+i)就是ai。,3.3 指

11、针数组和多级指针,注意指针数组与数组指针的不同,int *a10; 定义了一个指针数组 int (*a)10; a为指向含10个元素的一维整型数组的指针变量,当指针变量pp所指的变量ip又是一个指针时,pp是一种指向指针的指针,此时称指针变量pp是一种多级指针。定义指向指针变量的指针变量的一般形式为: 类型说明符 * 变量名; 该一般形式说明以下几个方面的内容:首先定义变量为指针变量,其次是该变量能指向一种指针对象,最后是被指向的指针对象能指向的对象的类型。 例如 int *pp, *ip, i; ip = 定义说明pp是指向指针的指针变量;它能指向的是这样一种指针对象,该指针对象是能指向in

12、t型的指针变量。如上述代码让pp指向指针变量ip,ip指向整型变量i。,多级指针,4 指针与字符串,字符串常量是由双引号括起来的字符序列 ,C+语言中操作一个字符串常量的方法有: (1). 把字符串常量存放在一个字符数组之中, 例如: char s=“a string“; 数组s共有9个元素所组成, 其中s8中的内容是0。实际上, 在字符数组定义的过程中, 编译程序直接把字符串复写到数组中, 即对数组s初始化。 (2). 用字符指针指向字符串, 然后通过字符指针来访问字符串存贮区域。当字符串常量在表达式中出现时, 根据数组的类型转换规则, 它被转换成字符指针。因此, 若我们定义了一字符指针cp

13、: char *cp; 于是可用: cp=“a string”; 使cp指向字符串常量中的第0号字符a,以后我们可通过cp来访问这一存贮区域, 如*cp或cp0就是字符a, 而cpi或*(cp+i)就相当于字符串的第i号字符 。,例: 使用字符指针处理字符串 #include main( ) static char str =“program“; char *ps; ps=str; while(*ps !=/0) cout*ps; ps+; coutendl; 运行结果 program,二级指针的应用实例: 输入5个字符串,从中找出最大的字符串并输出。 #include #include ma

14、in() char a580=“abc“,“efg“,“egk“,“nfg“,“waf“,*p5,*max; int i; for(i=0;i5;i+) pi=ai; max= ,返回,5.7 指向对象的指针,对象指针就是用来存放对象地址的变量。 声明形式 类名 *对象指针名; 使用对象指针一样可以方便的访问对象的成员,但是与通过对象名访问对象成员不一样,通过指针访问对象成员要使用“-”操作符。 通过指针访问对象成员 对象指针名-成员名,通过指针对类对象成员的访问,案例名称:类对象成员的访问 # include class Tdate private: int month; public: v

15、oid setMonth(int d) month = d; int getMonth() return month; ; void main() Tdate b ; Tdate *p; p= ,This 指针的使用,Example: class A private: int x; public: A(int x,int y) x=x+y; Getx() return x; ;,A的构造函数没有达到给x赋值的目的。,this指针,隐含于每一个类的成员函数中的特殊指针。 明确地指出了成员函数当前所操作的数据所属的对象。 当通过一个对象调用成员函数时,系统先将该对象的地址赋给this指针,然后调用

16、成员函数,成员函数对对象的数据成员进行操作时,就隐含使用了this指针。,指 针,class A private: int x; public: A(int x,int y) this-x=x+y; A(int z,int y) x=z+y; Getx() return x; ;,X在这个时候隐含有this指针, 也可以把this指针加上。,5.8 动态内存分配,在C语言中使用“malloc()”函数来申请内存,使用“free()”函数来释放内存。在C+语言中依然可以使用这种方法,但是不建议使用该方法。C+语言提供了new表达式和delete表达式来申请和释放内存。 用new表达式创建动态的类

17、对象,它的寿命期由创建开始,释放时结束,定义格式为,“new ();”,其中初始值是可选项,若给出了初始值,系统会自动调用相应的构造函数初始化新创建的类对象,否则调用缺省构造函数进行初始化。,动态内存分配与撤销,例如, int *p; /整数类型指针 float *f; /浮点类型指针 p = new int; /为一个整数类型的数分配内存 f = new float; /为一个浮点类型的数分配内存 如果成功调用了new,则返回一个指向已分配空间的指针,如果此空间不可用或检测到某些错误,则返回零。为对象分配内存使用同样的语法,例如, person *stu_ptr; /指向类型为person

18、对象的指针 stu_ptr = new person(); /指向新的 person 对象 如果不再需要所分配的存储空间,要用delete释放,例如: delete p; delete f;,动态改变数组的大小: int *a=new int40; for(int i=0;i40;i+) ai=i; for(int i=0;i40;i+) coutaiendl;,使用new和delete,案例名称:使用new和delete的方法 class Tdate private: int month; public: void setMonth(int d) month = d; int getMont

19、h() return month; ; void main() Tdate * b = new Tdate(); /定义一个对象 b - setMonth(10); cout getMonth() endl; delete b; /删除一个对象 int * i = new int; * i = 12; cout * i endl; delete i; ,浅拷贝与深拷贝,默认构造函数将作为参数传入的对象的每个成员变量复制到新对象的成员变量中,这被称为成员浅复制。这虽然对大多数成员变量可行,但对于指向自由存储区中对象的指针成员变量不可行,浅拷贝与深拷贝,成员浅复制只是将对象成员变量的值复制到另一个

20、对象中,两个成员变量的指针最后指向同一个内存块,当其中任何一个指针被delete时,将生成一个迷途指针,程序将处于危险之中。如图:,这种情况的解决办法是:创建自己的复制构造函数并根据需要来分配内存。分配内存后,可以将原对象的值复制到新内存中。这称之为深层复制。,对象的深拷贝,#include #include class Point public: Point() X=Y=0; Pname=new char20; strcpy(Pname,“point“); Point(const Point ,浅拷贝与深拷贝,void main(int argc, char *argv) Point P;

21、P.GetX(); / Point B=P; / B.GetX(); ,5 指针与函数,4.1 函数参数的新形式? (1)指针变量作为函数形参,传递的是指针中存放的地址 #include void changeFunction(int *m,int *n) int temp; temp=*m; *m=*n;*n=temp; Void main() int a=5,b=10; changeFunction( ,(2)引用做函数形参 引用:给对象取一个别名,主要用于三个用途 独立引用 作为参数传递 作为函数返回类型 一般形式: 基类型 说明 引用变量不另外分配内存空间 独立引用在声明时必须初始化,

22、引用的基类型必须与建立联系的变量类型一致。引用名一旦被声明成一个变量的别名,则不能与其他变量相联系了 一个引用只能指向一个对象,一个对象则可有多个别名,按引用调用的参数传递:实现双向的参数传递,形参为实参的别名 例子:用一函数交换两个变量的值 (1) 按值参数传递 void swap(int x, int y) int temp ; 程序执行: temp = x ; main( ) 实参i j x = y ; 调用swap( ) 形参x y y = temp; 执行swap swap结束,x、y释放,i、j保 void main() 持原值不变 失败 int i, j; cinij; swap

23、( i, j); coutij; ,(2) 用引用做形参按引用参数传递 void swap(int ,5.2 指针作为函数的返回类型,/有若干个学生的成绩(4门),要求在用户输入学生序号后能输出该学生的全部成绩 #include void main() float score4=60,70,80,80,56,89,67,88,34,78,90,66; float *search(float (*pointer)4,int n); /函数search被定义为指针函数,形参pointer是指向包含4个元素的一维数组的指针变量。 float *p; int i,m; coutm; cout“The

24、scores of No.“m“are:“; p=search(score,m); for(i=0;i4;i+) cout“ “*(p+i); coutendl; ,float *search(float (*pointer)4,int n) float *pt; pt=*(pointer+n); return(pt); 程序1,5.3函数指针 函数指针:函数在编译时被分配的入口地址,用函数名表示,函数指针变量赋值:如p=max;,函数返回值的数据类型,专门存放函数入口地址 可指向返回值类型相同的不同函数,指向函数的指针变量 定义形式: 数据类型 (*指针变量名)(); 如 int (*p)(

25、);,函数指针变量指向的函数必须有函数说明,函数调用形式: c=max(a,b); c=(*p)(a,b); c=p (a,b); 对函数指针变量pn, p+, p-无意义,( )不能省 int (*p)() 与 int *p()不同,例 用函数指针变量调用函数,比较两个数大小,main() int max(int ,int); int a,b,c; cinab; c=max(a,b); couty) z=x; else z=y; return(z); ,main() int max(int ,int), (*p)(); int a,b,c; p=max; cinab; c=(*p)(a,b); couty) z=x; else z=y; return(z); ,

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

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1