4.7.1. 计算机存储数据时的3种基本属性
- 信息存储在何处
- 存储的值为多少
- 存储的信息是什么类型
4.7.2. 面向对象编程与传统过程性编程的区别:
面向对象编程在运行阶段(更具灵活性)而非编译阶段进行决策(如:使用关键词new在运行阶段才确定数组的长度)
4.7.3. 指针
- 是一个变量,存储的是值的地址(对常规变量应用地址运算符(&),就可以获得其地址,如home是变量,&home是他的地址)
- 运算符*,被称为间接值或解除引用运算符,其应用于指针,可以得到该地址存储的值;
4.7.4. 指针声明
-
必须指定指针指向的数据的类型,例:
int * ptr
i. C语言:
int *ptr
ii. C++:int* ptr //强调int*是一种类型——指向int的指针
-
同时声明多个指针时,每个指针变量名都需要一个*
int* p1, p2 //创建的是一个指针p1和一个int变量p2
-
指针可以指向多种长度不同的数据类型,但指针本身的长度是相同的
4.7.5. 指针初始化
- 可以在声明语句中初始化指针
- c++创建指针时,计算机将分配用来存储地址的内存,但不会分配用来存储指针所指向的数据的内存。因此一定要在对指针应用*运算符前,将指针初始化为一个确定的、适当的地址!
4.7.6. 指针和数字
- 不能简单的将整数赋值给指针,如果要将数字作为地址来使用,应通过强制类型准换,将数字转换为适当的地址类型。
int* pt; pt = (int *)0xB8000000;
4.7.7. 指针&运行阶段&内存空间分配
-
c语言:malloc分配内存
-
c++:new分配内存
i. 需要指定为哪种数据类型分配内存,new将找到一个长度正确的内存块,并返回该内存块的地址
typeName * pointer_name = new typeName;
ii. new分配的内存块与常规变量声明分配的内存块不同:
a. 常规变量声明的值被存储在栈中
b. new从堆或自由存储区的内存区域分配内存 -
delete释放内存
int * ps = new int; … delete ps;
i. 释放ps指向的内存,但不会删除ps本身;
ii. new和delete一定要配对使用,否则将发生内存泄漏
iii. delete只能用于释放new分配的内存(关键在将delete用于new分配的内存,而不是使用new的指针)int * ps = new int; //allocate memory int * pq = ps; //set second pointer to same block delete pq; //delete with second pointer //一般不要创建两个指向同一个内存块的指针,可能会错误的删除同一个内存块两次
iv. 对空指针使用new是安全的
v. delete 指针后,只是释放了指针指向的内存空间。p并不会自动被置为NULL,此时指针还存在,同时还指向了之前的地址。对一个非空指针delete后,最好赋值为NULL,若没有赋NULL,若再次delete的话,可能出现问题
4.7.8. new创建动态数组
-
静态联编与动态联编
i. 静态联编:通过声明来创建数组,编译时给数组分配内存;
ii. 动态联编:运行时创建,还可以在运行时选择数组的长度(动态数组) -
使用new创建动态数组
i. 在类型名后加方括号
type_name * pointer_name = new type_name [num_element]
例:int * psome = new int [10]; //get a block of 10 ints
ii. new返回第一个元素的地址
-
delete释放数组:[]是指释放整个数组,而不仅仅是指针指向的元素。
delete [] psome; //free a dynamic array
-
使用new和delete应遵循以下规则:
i. 不要使用delete来释放不是new分配的内存
ii. 不要使用delete释放同一个内存块两次
iii. 使用new [] 为数组分配内存,则应使用delete []来释放
iv. 使用new为一个实体分配内存,则应使用delete(没有方括号)来释放
v. 对空指针应用delete是安全的
4.7.9. 使用动态数组
- 访问动态数组中的元素:把指针当作数组名,psome[0]访问第一个元素,psome[1]访问第二个元素
- 数组名与指针之间的区别
p3 = p3 + 1; //okay for pointers, wrong for ayyay names
i. 不能修改数组名的值,但可以修改指针变量的值
ii. p3+1后将导致p3[0]指向第2个元素