收藏 分享(赏)

c++指针和动态内存分配.ppt

上传人:eukav 文档编号:3929357 上传时间:2018-11-29 格式:PPT 页数:94 大小:532.50KB
下载 相关 举报
c++指针和动态内存分配.ppt_第1页
第1页 / 共94页
c++指针和动态内存分配.ppt_第2页
第2页 / 共94页
c++指针和动态内存分配.ppt_第3页
第3页 / 共94页
c++指针和动态内存分配.ppt_第4页
第4页 / 共94页
c++指针和动态内存分配.ppt_第5页
第5页 / 共94页
点击查看更多>>
资源描述

1、Lecture 9: Pointers and Dynamic Memory (指针和动态内存分配),Learn C+ through English and Chinese,2,Chapter Nine: Pointers and Dynamic Memory (指针和动态内存分配),Variable address (变量的地址) Pointer variables (指针变量) The dereference operator *(解引用运算符*) Using const with pointers (使用const修饰指针变量) Pointers and one-dimensional

2、 arrays(指针和一维数组) Pointers and multi-dimensional arrays (指针和多维数组),3,Pointers to structures (指向结构体的指针) Pointers to class objects (指向类对象的指针) Pointers as function arguments(指针变量作为函数实参) Dynamic memory allocation(动态内存分配),Chapter Nine: Pointers and Dynamic Memory (指针和动态内存分配),4,9.1 Variable address(变量地址),Ev

3、ery variable object used in a C+ program is stored in a specific place in memory. Each location in memory has a unique address, in the same way that every house in a street has a unique address.(在C+程序中使用的每个变量和对象,都存储在内存中特定的存储单元中。每个存储单元都有唯一的地址,就像街道旁的每个房子都有唯一的地址一样。),5,Variable address(变量地址),内存空间的访问方式 通

4、过变量名访问 通过地址访问 地址运算符: 则&var 表示变量var在内存中的起始地址,6,#include #include using namespace std ;void main() int var1 = 1 ; float var2 = 2 ;cout “var1 has a value of “ var1 “ and is stored at “ ,7,7.1.1 地址与指针,程序中: int i; float k;,内存中每个字节有一个编号-地址,i,k,为其分配内存单元,变量是对程序中数据 及存储空间的抽象,8,9.2 Pointer variables(指针变量),A po

5、inter variable is a variable that holds the address of another variable.(指针变量是存放另一变量地址的变量) data_type* variable_name;int* int_ptr;float* float_ptr;其中,“*”表示后面声明的变量是指针类型的变量。指针变量一旦被赋值,我们就说该指针变量有了指向。“数据类型”可以是任意类型,指的是指针所指向的对象类型,这说明了指针所指向的内存单元可以用于存放什么类型的数据,我们称之为指针的类型。,区分:int * p1, * p2; 与 int *p1, p2;,9,Po

6、inter variables(指针,声明 例:int i; int *i_pointer=,注意事项用变量地址作为初值时,该变量必须在指针初始化之前已说明过,且变量类型应与指针类型一致。可以用一个已赋初值的指针去初始化另一 个指针变量。,10,说明: 在指针变量定义中,*是一个说明符,它表明其后的变量是指针变量,如在 int * p; 语句中,p是指针变量,而不要认为“*p”是指针变量; 指针变量定义时指定的数据类型不是指针变量本身的数据类型,而是指针变量所指向的对象(或称目标)的数据类型,指针变量只能指向定义时所规定类型的变量; 定义后值不确定,而指针变量一旦被赋值,就有了有效的指向对象;

7、 指针变量并不固定指向一个变量,可指向同类型的不同变量; 指针变量和普通变量的共同点是:它们都能存放数据,而又有自己的地址。不同的是:普通变量中直接存放通常意义下的数据,而指针变量中存放的是地址。,11,2000,指针,指针变量,变量的内容,变量的地址,指针变量和指针所指向的变量的区别: 对于:int i=10, * i_pointer = ,变量的地址,变量的内容,12,9.3 the dereference operator * (解引用运算符*),The dereference operator * is used to access the value of a variable, w

8、hose address is stored in a pointer.(解引用运算符*用于访问指针变量所指向的存储单元的内容。) int i=10, * i_pointer =,i_pointer = &i = &(*i_pointer)i = *i_pointer = *(&i),i_pointer-指针变量,它的内容是地址量 *i_pointer-指针的目标变量,它的内容是数据 &i_pointer-指针变量占用内存的地址,13,#include using namespace std; main() int var =1;int* ptr;ptr= ,prt contains 0012

9、FF88 *ptr contains 1,14,#include using namespace std; int main() int *p1,*p2,*p,a,b; cinab; p1= ,15,9.4 Using const with pointers (使用const修饰指针变量),When defining a pointer, the pointer itself, the value it points to or both can be made constant. The position of const in the definition determines which

10、 of these apply.(定义指针变量时,指针变量本身、指针变量所指向的数据都可以声明为常量。变量定义中的const的位置决定了谁被声明为常量。),16,int i=3,j=4;const int* p= /Illegal: p is a constant.,17,指针与常量 指向常变量的指针,不能通过指针来改变所指对象的值,但指针本身可以改变,可以指向另外的对象。例: const int n2=5; const int *pn= 错,18,定义指向常变量的指针变量形式: const 类型名 * 指针变量名 如:const char *ptr; (1)如果一个变量已经被声明为常变量,只

11、能用指向常变量的指针变量指向它,而不能用一般的指针变量去指向它。 如:const char c=“boy”; const char*p p=c; char *p2=c; /不合语法。,19,(2)指向常变量的指针变量除了可以指向常变量外,还可以指向未被声明为 const型的变量,此时不能通过指针变量改变该变量的值。 char c1=a; const char *p; p=,20,指针与常量 常量指针,若声明指针常量,则指针本身的值不能被改变。 但是它指向的整型变量是可以改变的。 例: int n1=3;const int n2=5; int *const pn= 错,21,例 指向常量的指针做

12、形参,#include const int N=6; void print(const int *p,int n); void main() int arrayN;for(int i=0;iarrayi;print(array,N); ,22,void print(const int *p, int n) cout“*p;for(int i=1;in;i+)cout“.“*(p+i);cout“endl; 1 2 3 4 5 6 1.2.3.4.5.6,23,9.5 Pointers and one-dimensional arrays,Ponters and arrays are direc

13、tly related to one another . In c+ ,the name of an array is equivalent to the address of the first element of the array. The name of an array ,therefore ,is a pointer to the first element of the array . (指针和数组是相互联系的。在C+中,数组名代表数组的首地址。因此,数组名即为指向数组第一个元素的指针。)int a5; a &a0a+1&a1As the name of an array is

14、 a pointer to the first element of the array, the dereference operator * can be used to access the elements of the array.,24,Pointers and one-dimensional arrays,指向数组元素的指针 int a10; int *p; p=,25,Pointers and one-dimensional arrays,如果指针变量p已经指向数组中得一个元素,则P+1指向同一数组中得下一个元素。 int array 10=1,2,3,4,5,6,7,8,9,

15、10,*p; 当p=array时 下面的等价关系成立: p=array=/表示第i个数组元素的地址 *(p+i)=*(array+i)=arrayi/表示第i个数组元素 指向数组的的指针变量也可以带下标,所以p+i和pi是一样的、,26,引用数组元素,可以有三种方法: (1)下标法: 数组名下标 a1 (2)指针变量法:*指针变量 *(P+i) (3)首地址法:*(首地址+位移量 ) *(array+i),27,如果先使指针变量p指向数组a的首地址(p=a) 则: (1)p+ 使p指向下一个元素,即a1,用*p可以得到下一个元素a1的值, (2)*p+ 先得到p指向的变量的值,然后再使P得值加

16、1,使p指向下一个元素, for(p=a;pa+10;) cout*p+; (3)*(p+)和*(+P)不同,后者是先使P加1,在求*P的值。 (4)(*p)+表示P所指向的元素值加1.,28,#include using namespace std ; main() int a5 = 10, 13 , 15 , 11, 6 ; for ( int i = 0; i 5; i+ ) cout “Element “ i “ is “ *( a + i ) endl ; ,Element 0 is 10 Element 1 is 13Element 2 is 15Element 3 is 11 E

17、lement 4 is 6,29,Although the name of an array is a pointer to the first element of the array, you cannot change its value; this is because it is a constant pointer.(虽然数组名是指向数组第一个元素的指针,但是由于它是一个常量指针,因此它的值是不能改变的。) int a10; float numbers100;a+; number+=2;,Pointers and one-dimensional arrays,30,You can

18、assign the name of an array to a pointer variable of the same type.int a5;int * p;p=a; / valid :assiqnment of a constant to a variablea+ ; / Invalia: the value of a costant cannot change.p+; / Valid:p is a variable. p now points to element 1 of the array a .p-; / Valid :point to element 1 of the arr

19、ay a .p +=10 ;/ Valid. But p is outside the range of the array a ./ so *p is underfined . A common error.p=a -1; / Valid , but p is outside the ranger of the array .,Pointers and one-dimensional arrays,31,A constant may be added to or subtancted from the value of a pointer. allowing access to differ

20、ent memory to locations. Hower ,not all arithmeic operations are permissible on poniters .For example ,the multiplication of two pointers is illegal,because the result would not be a valid memory address.(通过将指针变量加上或减去一个常量,可以使它指向不同的存储单元。但是,并非所有的算术运算符都可以应用于指针。例如,两个指针相乘是非法的,因为相乘的结果可能不是一个有效的内存地址。),Point

21、ers and one-dimensional arrays,32,分别用三种方式访问数组中的所有元素 void main( ) int i, array10= 1,2,3,4,5,6,7,8,9,10 , *p;cout“NO1: “;for( i=0; i10; i+) cout“array“i“=“ arrayi ;cout“nNO2:n“;for( i=0; i10; i+) cout“*(array+“i“)=“*(array+i) ;cout“nNO3(1)n“;for( p=array, i=0; i10;i+) cout“*(p+“i“)=“*(p+i) ;cout“nNOs(

22、2)n“;for( p=array; parray+10; p+) cout“*p+=“*p ;cout“n“; ,33,A two-dimensional array is stored as an array of arrays. This means that a is a one-dimensional array whose elements are themselves a one-dimensional arrays of integers . As with one-dimensonal array ,the name of a two dimensional array is

23、 pointer to the first element of the array .Therefore a is equivalent to &a 0 , a 0 is itself an array of two intergers,which means that a 0 is equivalent to &a00 .,Pointers and multi-dimensional arrays,34,int a34;,a13 *(a1+3) *(*(a+1)+3),35,#include using namespace std; int main() int a34=1,3,5,7,9

24、,11,13,15,17,19,21,23;int *p;for(p=a0;pa0+12;p+)cout*p“ “;coutendl;return 0; ,指针与二维数组,36,9.7 Pointers to structures,In addition to defining a pointer to a variable of a built-in data type, it is also possible to define a pointer to a variable of a type defined by struct of classs. struct tag_name* v

25、ariable_name;struct student int number;float score;stu;struct student *prt=,37,9.7 Pointers to structures,而使用结构体指针变量访问被指向的结构体变量有两种形式:( * 结构体指针变量).成员名 或者结构体指针变量-成员名,例: struct stu date, *pstu = 则:pstu -num 等价于 (*pstu).num,38,指向结构体变量的指针,#include using namespace std; int main() struct student int num;st

26、ring name;char sex;float score;,student stu; student*p= ,39,(1)结构体变量名.成员名 (2)(*p).成员名 (3)p-成员名 -指向运算符 P-n得到P指向的结构体变量中的成员n的值。 p-n+得到p指向的结构体变量中成员n的值,用完改值后使它加1. +p-n得到p指向的结构体变量中的成员n的值,并使之加1,然后再使用它。,40,用指向结构体变量的指针作实参 #include #include using namespace std; struct student int num;string name;float score3;

27、 stu=12345,“lifung“,67.5,89,78.5;,int main() void print(student *);student *pt= ,41,9.8 Pointers to class objects,Defining a pointer to a class object is similar to defing a pointer to a structure variable. class-name* variable-name;,42,指向类类型对象的指针,声明形式 类名 *对象指针名; 例 Point A(5,10); Piont *ptr; ptr= 通过

28、指针访问对象成员 对象指针名-成员名,43,Class Time public:int hour;int minute;int sex;void get_time(); ; Void Time:get_time() couthour“:”minute“:”sexendl;,44,在此基础上有以下语句: Time*p1; Time t1; p1= 可以通过对象指针访问对象成员和对象 (*p1).hour p1所指向的对象中的hour成员,t1.hour P1-hour p1所指向的对象中的hour成员,t1.hour (*p1).get_time 调用p1所指向的对象中的get_time 函数,

29、t1.get_time P1-get_time 调用p1所指向的对象中的get_time 函数,t1.get_time,45,例 对象指针应用举例,void main( ) Point A(5,10);Point *ptr;ptr= ,46,Example,#include #include #include “bank_ac.h“ #include “bank_ac.cpp“ using namespace std ; main() bank_account ac ; / ac is a bank_account object.bank_account* ac_ptr ; / ac_ptr

30、is a pointer to a bank_account.ac_ptr = ,ac-ptr - deposit (100) ; ( *ac_ptr) .deopsit(100);,47,9.9 Pointers as funtion arguments,Like any data type, pointers can be used as function arguments.,48,#include using namespace std ; void swap_vals( float* val1, float* val2 ) ; main() float num1 , num2 ;co

31、ut num1 ;cin num2 ; if ( num1 num2 ) swap_vals( ,void swap_vals( float* ptr1, float* ptr2 ) float temp = *ptr1 ; *ptr1=*ptr2; *ptr2=temp; ,Please enter two number:12.1 6.4 The numbers in order are 6.4 and 12.1,49,9.10 Dynamic memory allocation,C+ has the ability to allocate memory while a program is

32、 executing. This is done by using the memory allocation operator new.,50,Dynamic memory allocation,动态申请内存操作符 new new 类型名T(初值列表) 功能:在程序执行期间,申请用于存放T类型对象的内存空间,并依初值列表赋以初值。 结果值:成功:T类型的指针,指向新分配的内存。失败:0(NULL),51,new运算符的例子; new int;/开辟一个存放整数的存储空间,返回一个指向该存储空间的地址(即指针) new int(100);/开辟一个存放整数的存储空间,并指定该整数的初值为100

33、,返回一个指向该存储空间的地址(即指针), new char10;/开辟一个存放字符数组的(包含10个元素)空间,返回首元素的地址。 new int54;/开辟一个存放二维整型数组(大小为5*4)的空间,返回首元素的地址。 float *p =new float(3.14159);/开辟一个存放单精度数的空间,并指定该实数的初值是3.14159,将返回的该空间的地址赋给指针变量p。,52,释放内存操作符delete,delete 运算符使用的一般格式为: delete 指针P 功能:释放指针P所指向的内存。P必须是new操作的返回值。 delete p; new char10;如果把 new返

34、回的指针付给指针变量pt,则用 delete pt;/在指针变量前面加一对方括号,表示是对数组空间的操作。,53,#include #include using namespace std; struct student char * name;int num;char sex; ;,int main() student*p; p=new student; p-name=“wang Fun“; p-num=10123; p-sex=m; coutnamenum sexendl; delete p; return 0; ,54,例 动态存储分配举例,#include struct date in

35、t month;int day;int year; ;,55,void main( ) int index, *point1, *point2;point1 = ,56,float *float_point1, *float_point2 = new float;float_point1 = new float;*float_point2 = 3.14159;*float_point1 = 2.4 * (*float_point2);delete float_point2;delete float_point1;,57,date *date_point;date_point = new dat

36、e; /动态分配结构体date_point-month = 10;date_point-day = 18;date_point-year = 1938;cout month day year “n“;delete date_point; /释放结构体,58,char *c_point;c_point = new char37; /动态分配数组delete c_point; /释放数组c_point = new charsizeof(date) + 133; /动态分配数组delete c_point; /释放数组return 0; 运行结果: The values are 77 77 173

37、The values are 77 999 999 10/18/1938,59,对象的动态建立和释放,如果已经定义了一个box类,可以用下面的方法动态的建立一个对象: new box; 定义一个指向本类的对象的指针变量来存放地址 box *pt; pt=new box;,60,在程序中就可以通过pt访问这个新建的对象, coutheighr; coutvolume(); c+还允许在执行new时,对新建的对象进行初始化。 可以使用delete运算符对新建的对象所占有的空间进行套释放。 delete pt;在执行运算符时,自动调用析构函数。,61,例 动态创建对象举例,#include clas

38、s Point public:Point( ) X=Y=0; cout“Default Constructor called.n“;Point(int xx,int yy) X=xx; Y=yy; cout “Constructor called.n“; Point( ) cout“Destructor called.n“; int GetX( ) return X;int GetY( ) return Y;void Move(int x,int y) X=x; Y=y; private:int X,Y; ;,62,void main( ) cout“Step One:“endl;Point

39、*Ptr1=new Point;delete Ptr1; cout“Step Two:“endl;Ptr1=new Point(1,2);delete Ptr1; ,运行结果: Step One: Default Constructor called. Destructor called. Step Two: Constructor called. Destructor called.,63,例 动态创建对象数组举例,#include class Point /类的声明同例6-15,略 ; void main( ) Point *Ptr=new Point2; /创建对象数组Ptr0.Move

40、(5,10); /通过指针访问数组元素的成员Ptr1.Move(15,20); /通过指针访问数组元素的成员cout“Deleting.“endl;delete Ptr; /删除整个对象数组 ,运行结果: Default Constructor called. Default Constructor called. Deleting. Destructor called. Destructor called.,64,访问对象的数据成员,#include using namespace std; class Human public:int get()constreturn i;void set

41、(int x)i=x; private:int i; ;,int main() Human *p=new Human;p-set(1);coutget()endl;delete p;return 0; ,运行结果:1,65,在构造函数中开辟空间,#include using namespace std; class Human public:int get()constreturn *i;void set(int x)*i=x;Human();Human(); private:int *i; ; Human:Human() cout“构造函数执行中.n“;i=new int(999); ,in

42、t main() Human *p=new Human;coutget()set(1);coutget()endl;delete p;return 0; Human:Human() cout“析构函数执行中.n“;delete i; ,构造函数执行中 999 1 析构函数执行中,66,9.10.1 Allocating memory dynamically for an array,The new memory allocation operator can be used to allocate a contiguous block of memory for an array of any

43、 type, whether the data type is built-in or is a user-defined structure of class. pointer = new data_typesize ; For example: / Allocate memory for 10 integers.int_ptr = new int10;/ Allocate memory for 5 bank_account objects.ac_ptr = new bank_account5; When allocating memory for an array of class obj

44、ects, there must be a default constructor for the class so that the elements of the array get initialised.(当为一个类对象数组动态分配内存时,这个类必须有自己的默认构造函数来初始化类对象数组元素。),67,/dynamic memory allocation for an array of integers. #include using namespace std; main() int* int_array;int no_els, i;cout no_els;int_array = n

45、ew intno_els;for ( i = 0 ; i int_arrayi;for( i = 0;i no_els;i+)cout“Element”i“ is “*(int_array+i)endl;delete int_array; ,Enter the number of elements 2 Enter element 0: 57 Enter element 1: 69 Element 0 is 57 Element 1 is 69,68,The elements of the newly allocated array can be accessed using either a

46、pointer or an index.(可以使用指针或下标方式访问新分配内存的数组元素。)int_array1*(int_array+1) The allocated memory is freed using the delete operator. It is important to remember to include the square brackets when freeing memory for a previously allocated array. Without the square brackets, only the first element of the

47、array will be deleted.(可以使用delete运算符释放已分配的内存。当为一个数组释放先前动态分配的内存时,必须用方括号。如果不加释放的仅是数组的第一个元素的内存。),69,9.10.2 Initialisation with new,When allocating memory for an array of class objects, the default constructor for the class initialises the elements of the array.(当为一个类对象的数组动态分配内存时,会自动调用类的默认构造函数对数组元素进行初始化

48、。)Ac_ptr = new bank_account5; results in the default constructor for the bank account class being called five times. No initialisation is done for dynamically allocated arrays of built-in data types. (对内置数据类型的数组动态分配内存时无需对其初始化。)For example,int_ptr = new int10; results in the ten non-initialised integ

49、er elements.,70,Single instances of any data type(built-in, a user-defined structure or a class) can be initialised using a second form of the new operator.(对任意数据类型的单个实例,可以使用new运算符的另一种形式对其进行初始化。)pointer = new data_type( initial_value); Eg. /allocate memory for an integer, with an initial value of 10

50、0.int_ptr = new int(100);/allocate memory for an integer, with no initial value.int_ptr = new int;/allocate memory for a bank_account object. The default constructor is /called to do the initialisation.ac_ptr = new bank_account;/allocate memory for a bank_account object. A constructor is called to /assign initial values to account number and balance.ac_ptr = new bank_account(1234,100);,

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

当前位置:首页 > 网络科技 > C/C++资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报