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

上传人:本田雅阁 文档编号:3479277 上传时间:2019-09-01 格式:PPT 页数:94 大小:532.52KB
返回 下载 相关 举报
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页
点击查看更多>>
资源描述

《c指针和动态内存分配.ppt》由会员分享,可在线阅读,更多相关《c指针和动态内存分配.ppt(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

5、pointer 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;

6、,9,Pointer 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 vari

8、able, whose 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 con

9、tains 0012FF88 *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 determ

10、ines which 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= 错,2

12、1,例 指向常量的指针做形参,#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

13、 arrays are directly 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 &a0 a+1&a1 As the

14、 name of an array is 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 1

15、0=1,2,3,4,5,6,7,8,9,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+

16、先得到p指向的变量的值,然后再使P得值加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 13 Element 2 i

17、s 15 Element 3 is 11 Element 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-dimensi

18、onal arrays,30,You can 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 variable a+ ; / 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 :

19、point to element 1 of the array 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 po

20、inter. allowing access to different 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.(通过将指针变量加上或减去一个常量,可以使它指向不同的存储单元。但是,并非所有的算术运算符都可以应用于指针。例如,两个指针相乘是

21、非法的,因为相乘的结果可能不是一个有效的内存地址。),Pointers 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

22、;i+) cout“*(p+“i“)=“*(p+i) ; cout“nNOs(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 arra

23、y ,the name of a two dimensional array is 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 na

24、mespace std; int main() int a34=1,3,5,7,9,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 d

25、efined by struct of classs. struct tag_name* variable_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

26、 namespace std; int main() struct student int num; string 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 namesp

27、ace std; struct student int num; string name; float score3; 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,指向类

28、类型对象的指针,声明形式 类名 *对象指针名; 例 Point A(5,10); Piont *ptr; ptr= 通过指针访问对象成员 对象指针名-成员名,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

29、p1所指向的对象中的hour成员,t1.hour (*p1).get_time 调用p1所指向的对象中的get_time 函数,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 a

30、c ; / ac is a bank_account object. bank_account* ac_ptr ; / ac_ptr 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

31、swap_vals( float* val1, float* val2 ) ; main() float num1 , num2 ; cout 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 memo

32、ry allocation,C+ has the ability to allocate memory while a program is 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;/开辟一个存

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

34、delete 指针P 功能:释放指针P所指向的内存。P必须是new操作的返回值。 delete p; new char10;如果把 new返回的指针付给指针变量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; coutnam

35、enum sexendl; delete p; return 0; ,54,例 动态存储分配举例,#include struct date int 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); de

36、lete float_point2; delete float_point1;,57,date *date_point; date_point = new date; /动态分配结构体 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 char

37、sizeof(date) + 133; /动态分配数组 delete c_point; /释放数组 return 0; 运行结果: The values are 77 77 173 The values are 77 999 999 10/18/1938,59,对象的动态建立和释放,如果已经定义了一个box类,可以用下面的方法动态的建立一个对象: new box; 定义一个指向本类的对象的指针变量来存放地址 box *pt; pt=new box;,60,在程序中就可以通过pt访问这个新建的对象, coutheighr; coutvolume(); c+还允许在执行new时,对新建的对象进行初

38、始化。 可以使用delete运算符对新建的对象所占有的空间进行套释放。 delete pt;在执行运算符时,自动调用析构函数。,61,例 动态创建对象举例,#include class 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;

39、 void Move(int x,int y) X=x; Y=y; private: int X,Y; ;,62,void main( ) cout“Step One:“endl; Point *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,例

40、动态创建对象数组举例,#include class Point /类的声明同例6-15,略 ; void main( ) Point *Ptr=new Point2; /创建对象数组 Ptr0.Move(5,10); /通过指针访问数组元素的成员 Ptr1.Move(15,20); /通过指针访问数组元素的成员 cout“Deleting.“endl; delete Ptr; /删除整个对象数组 ,运行结果: Default Constructor called. Default Constructor called. Deleting. Destructor called. Destruct

41、or called.,64,访问对象的数据成员,#include using namespace std; class Human public: int get()constreturn i; void set(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()constre

42、turn *i; void set(int x)*i=x; Human(); Human(); private: int *i; ; Human:Human() cout“构造函数执行中.n“; i=new int(999); ,int 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 dynamicall

43、y for an array,The new memory allocation operator can be used to allocate a contiguous block of memory for an array of any 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 int1

44、0; / Allocate memory for 5 bank_account objects. ac_ptr = new bank_account5; When allocating memory for an array of class objects, there must be a default constructor for the class so that the elements of the array get initialised.(当为一个类对象数组动态分配内存时,这个类必须有自己的默认构造函数来初始化类对象数组元素。),67,/dynamic memory all

45、ocation for an array of integers. #include using namespace std; main() int* int_array; int no_els, i; cout no_els; int_array = new 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:

46、 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 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

47、the square brackets when freeing memory for a previously allocated array. Without the square brackets, only the first element of the array will be deleted.(可以使用delete运算符释放已分配的内存。当为一个数组释放先前动态分配的内存时,必须用方括号。如果不加释放的仅是数组的第一个元素的内存。),69,9.10.2 Initialisation with new,When allocating memory for an array of

48、class objects, the default constructor for the class initialises the elements of the array.(当为一个类对象的数组动态分配内存时,会自动调用类的默认构造函数对数组元素进行初始化。) 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 e

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

当前位置:首页 > 其他


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