指针与动态内存分配.ppt

上传人:本田雅阁 文档编号:2717273 上传时间:2019-05-08 格式:PPT 页数:23 大小:312.01KB
返回 下载 相关 举报
指针与动态内存分配.ppt_第1页
第1页 / 共23页
指针与动态内存分配.ppt_第2页
第2页 / 共23页
指针与动态内存分配.ppt_第3页
第3页 / 共23页
指针与动态内存分配.ppt_第4页
第4页 / 共23页
指针与动态内存分配.ppt_第5页
第5页 / 共23页
点击查看更多>>
资源描述

《指针与动态内存分配.ppt》由会员分享,可在线阅读,更多相关《指针与动态内存分配.ppt(23页珍藏版)》请在三一文库上搜索。

1、指针与动态内存分配,课程内容安排,指针概述 指针的运算 指针与数组 指针与函数 指针与字符串 二级指针 动态内存分配 小结 习题,1 指针概述,1.内存单元:在计算机中,所有的数据都是存放在存储器中的。一般把存储器中的一个字节称为一个内存单元,不同的数据类型所占用的内存单元数不等,如整型量占2个单元,字符量占1个单元等。 为了正确地访问内存单元,必须为每个内存单元编上号。根据一个内存单元的编号即可准确地找到该内存单元。内存单元的编号也叫做地址。 简单来说,指针是一个地址,其指向存储某一个数据的存储地址。 指针变量是一种特殊性质的变量。指针变量是存放另一个变量的地址的变量。它和普通变量一样占用一

2、定的存储空间。它与普通变量不同之处:指针的存储空间里存放的不是普通的数据,而是一个地址。 对于指针我们可以这样理解,比如一个人要到某地去,但不认识路,于是去问交警。然后交警把该地方的地址写在了一张纸上,并且给了该问路人。那么交警写的地址就是指针,指向要去的地址,而那张纸就是指针变量,用于存储指针。,2 定义指针,指针是一个变量,在程序中使用时,必须先声明,后使用。在指针声明的同时也可以进行初始化。指针的定义指出了指针的存储类型和数据类型,定义的语法形式如下: 存储类型名 数据类型 *指针变量名 例如: int *px; char *name; static int *pa; 定义了一个指针后,

3、在使用此指针前,必须首先给它赋一个合法的值。否则,程序中对指针的使用就有可能导致系统崩溃。可以在定义指针的同时通过初始化来给指针赋值,也可以在使用之前给指针赋值。指针初始化的一般形式如下: 存储类型 数据类型 *指针名=初始地址值;,3 指针的运算,两个有关的运算符: (1)&:取地址运算符 (2)*:指针运算符(或称“间接访问”运算符) 例如,&为变量的地址,*为指针变量所指向的变量 使用*p与定义*p不同,定义时,int *p中的“*”不是运算符,而在程序执行语句中,引用“*p”,其中的“*”是一个指针运算符 指针运算是以指针变量所持有的地址值为运算量进行的运算。因此,指针运算的实质是地址

4、的计算。由于指针是持有地址量的变量这一特性,指针的运算与普通变量的运算在种类上和意义上都是不同的。指针运算的种类是有限的,它只能进行取地址和取值运算、算术运算、关系运算和赋值运算。 如果说明了一个指针,并使其值为某个变量的地址,则可以通过这个指针间接地访问在这个地址中存储的值。,4 常指针与指针常量,修饰词 const const是C语言的一种关键字,起受保护,防止以外的变动的作用!可以修饰变量,参数,返回值,甚至函数体。 const 修饰变量,表示该变量不能被修改。 1、const char *p 表示 指向的内容不能改变,叫常量指针。 2、char * const p,就是将p声明为指针常

5、量,它的地址不能改变,是固定的,但是它的内容可以改变。 3、若const指针是前两种的结合,使得指向的内容和地址都不能发生变化. const double pi = 3.14159; const double *const pi_ptr = 教材54到55页,5 多级指针,当指针变量pp所指的变量ip又是一个指针时,pp是一种指向指针的指针,此时称指针变量pp是一种多级指针。定义指向指针变量的指针变量的一般形式为: 类型说明符 * 变量名; 该一般形式说明以下几个方面的内容:首先定义变量为指针变量,其次是该变量能指向一种指针对象,最后是被指向的指针对象能指向的对象的类型。 例如 int *pp

6、, *ip, i; ip = 定义说明pp是指向指针的指针变量;它能指向的是这样一种指针对象,该指针对象是能指向int型的指针变量。如上述代码让pp指向指针变量ip,ip指向整型变量i。,6 指针的算术运算,指针的算术运算是按C语言地址计算规则进行的,这种运算与指针指向的数据类型有密切关系,也就是C语言的地址计算与地址中存放的数据长度有关。设px和py是指向具有相同数据类型的一组若干数据的指针,n是整数,则指针可以进行的算术运算有如下几种: px+n,pxn,px+,+px, px,px,pxpy,指针与整数运算 指针作为地址量加上或减去一个整数n,其意义是指针当前指向位置的前方或后方第n个数

7、据的位置。由于指针可以指向不同数据类型,即数据长度不同的数据,所以这种运算的结果值取决于指针指向的数据类型。例如,假设有一单字节字符类型和另一个双字节整数类型:当字符指针加1时,增量为1,而整数指针加1时,增量为2。 指针相减: 设指针p和q是指向同一组数据类型一致的数据,则pq运算的结果值是两指针指向的地址位置之间的数据个数。,两个指向同一组类型相同的数据的指针之间可以进行各种关系运算,运算结果为逻辑值,满足关系时,结果为(真),否则为(假)。 如int a10,*p,*q; p= 则p&a2 结果为0 指向不同数据类型的指针之间的关系运算是没有意义的。 指针与一般整数变量之间的关系运算也是

8、无意义的。 但是指针可以和零之间进行等于或不等于的关系运算,即:p= =0或p!=0,它们用于判断指针p是否为一个空指针。,7 指针与数组,指针在数组中使用较为频繁,事实上,数组名就是一个地址,表示的是该数组的首地址 。 要访问或使用一个数组元素,可以用三种不同的方法:下标法、地址法,还有一种是指针法。 可以设置指针变量指向数组或数组中的元素。 如:int a10, *p; 可以使整型指针p指向数组中任何一个元素, 假定给出赋值运算 p= 此时, p指向数组中的第0号元素, 即a0, 指针变量p中包含了数组元素a0 的地址, 由于数组元素在内存中是连续存放的, 因此, 我们就可以通过指针变量p

9、及其有关运算间接访问数组中的任何一个元素。根据地址运算规则, a+1为a1的地址, a+i就为ai的地址。,在定义指向数组的指针时,有下列几种表示方式: (1) int a10, *p = 用指针表示数组元素的地址和内容的几种形式: (1). p+i和a+i均表示ai的地址, 或者讲, 它们均指向数组第i号元素, 即指向ai。 (2). *(p+i)和*(a+i)都表示p+i和a+i所指对象的内容, 即为ai。 (3). 指向数组元素的指针, 也可以表示成数组的形式, 也 就是说, 它允许指针变量带下标, 如pi与*(p+i)等 价。 练习教材57页5-5例题 。,8 指针数组,数组中每个元素

10、都是指针变量,该数组就称为指针数组。 指针数组的定义形式为: 类型标识 *数组名整型常量表达式; 例如: int *a10; 定义了一个指针数组, 数组中的每个元素都是指向整型量的指针, 该数组由10个元素组成, 即a0, a1, a2, ., a9, 它们均为指针变量。a为该指针数组名, 和数组一样, a是常量, 不能对它进行增量运算。a为指针数组元素a0的 地址, a+i为ai的地址, *a就是a0, *(a+i)就是ai。,9 指向数组的指针,int *a10; 定义了一个指针数组,本质是一个数组,每个元素都是指针。 int (*p)10; a为指向含10个元素的一维整型数组的指针变量。

11、指向数组的指针是一个二级指针。,10 指向二维数组指针的应用,int main() int twoArray34 = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11; int (*p)4 = twoArray; / 定义一个指向一维数组的指针 for(p = twoArray; p != twoArray + 3; +p) / 第一层循环,每个循环遍历一行元素 for(int *q = *p; q != *p + 4; +q) / 第二层循环,每次循环输出一个元素 cout *q “ “; cout endl; return 0; ,上图表示了二维数组的存储方法,tw

12、oArray0twoArray2表示各一维数组的首地址,二维数组名twoArray表示整个二维数组的首地址,它和twoArray0以及twoArray00是同一个地址。但是他们表示的级别是不同的,因此不能混用。 twoArray1是元素级别的,是int*,而&twoArray1是行级别的,是int(*p)4。也就是说,如果对twoArray1加1,那么指针移动到下一个元素的位置,而如果对&twoArray1加1,指针移动到下一行的位置:,11 指针与字符串,字符串常量是由双引号括起来的字符序列 ,C+语言中操作一个字符串常量的方法有: (1). 把字符串常量存放在一个字符数组之中, 例如: c

13、har s=“a string“; 数组s共有9个元素所组成, 其中s8中的内容是0。实际上, 在字符数组定义的过程中, 编译程序直接把字符串复写到数组中, 即对数组s初始化。 (2). 用字符指针指向字符串, 然后通过字符指针来访问字符串存贮区域。当字符串常量在表达式中出现时, 根据数组的类型转换规则, 它被转换成字符指针。因此, 若我们定义了一字符指针cp: char *cp; 于是可用: cp=“a string”; 使cp指向字符串常量中的第0号字符a,以后我们可通过cp来访问这一存贮区域, 如*cp或cp0就是字符a, 而cpi或*(cp+i)就相当于字符串的第i号字符 。,12 动

14、态内存分配,在C语言中使用“malloc()”函数来申请内存,使用“free()”函数来释放内存。在C+语言中依然可以使用这种方法,但是不建议使用该方法。C+语言提供了new表达式和delete表达式来申请和释放内存。 用new表达式创建动态的类对象,它的寿命期由创建开始,释放时结束,定义格式为,“new ();”,其中初始值是可选项,若给出了初始值,系统会自动调用相应的构造函数初始化新创建的类对象,否则调用缺省构造函数进行初始化。,例如, int *p; /整数类型指针 float *f; /浮点类型指针 p = new int; /为一个整数类型的数分配内存 f = new float;

15、/为一个浮点类型的数分配内存 如果成功调用了new,则返回一个指向已分配空间的指针,如果此空间不可用或检测到某些错误,则返回零。为对象分配内存使用同样的语法,例如, person *stu_ptr; /指向类型为person 对象的指针 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;,本章主要

16、介绍了C+中较为复杂的指针的基本内容。以前接触过C语言的读者应该知道,指针是C语言中最难掌握的,也是最灵活的。本章一开始就通过一个示例介绍了指针的概念和作用,接下来主要介绍了指针的运算,包括通过指针取值(*)、取地址(&)、指针的算术运算和关系运算等。此外,本章重点介绍了指针的应用,主要包括指针在数组中的应用、在字符串中的应用和指向指针的应用。最后,就动态内存分配和引用作了简要介绍。,小结,1写出下列程序的运行结果。 #include void main() int *p; int n = 100; p= 2编写一个C+程序,接收从键盘输入的10个整数,用指针求这10个数中的最大数、最小数和平均值。,习题,习题,3.以下程序的输出结果是?。 #include void main() char s=“ABCD“; char *p; for (p=s;ps+4;p+) coutpendl; ,

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

当前位置:首页 > 其他


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