指针和自由存储空间
你可能一直有一个疑问,计算在存储数据时如何跟踪这三个属性
- 信息存储在何处
- 存储的值为多少
- 存储的信息是什么类型
下面就来看看一种策略,它以指针为基础,指针是一个变量,其存储的是值的地址,而不是值本身。在讨论指针之前,我们看看如何找到常规变量的地址。只需对变量应用地址运算符(&),就可以获得它的位置。
使用常规变量时,值是指定的量,而地址是派生量。
下面来看看指针策略(c++内存管理编程理念的核心)
指针与C++基本原理
面向对象编程和传统性编程的区别在于,OOP强调的是运行阶段(而不是决策阶段)进行决策:即在程序正在运行时。运行阶段决策好比度假时,参观景点取决于你的心情和天天气,决策阶段决策好比不管在什么条件下,都坚持预先的安排。
运行阶段决策提供了灵活性。例如,在声明数组时如果一开始就将数组长度定为20,但程序有时需要处理200个元素,但是声明200长度的数组又浪费了内存。OOP通过将这样的决策推迟到运行阶段进行,使程序更灵活。在运行后,可以这次告诉它需要20个元素,下次告诉它需要200个元素。
为使用这一种方法,语言必须在运行时创建数组。在C++中使用关键字new请求正确数量的内存以及使用指针来跟踪新分配的内存位置。
一种特殊的变量——指针用于存储值的地址。因此,指针名表示的是地址。*运算符被称为间接值或解除引用运算符,*指针名即为该地址处存储的值
int updates=6;
int * p_updates;
p_updates = &updates;
int变量update和指针变量p_updates只不过是一枚硬币的两面。变量updates表示值,并使用&运算符获得地址;变量p_updates表示地址,并使用*p_updates运算符获得值
指针和数字
int * pt;
pt = 0xB8000000;//不行,因为右边是整数类型
pt = (int *) 0xB8000000;//可以,左右两边都是整数的地址
使用new来分配内存
指针真正的用武之地在于,在运行阶段分配未命名的内存以存储值。在这种情况下,只能通过指针来访问内存。
接下来用new运算符为一个int值分配未命名的内存,并使用指针来访问这个值。程序员要告诉new,需要为哪种数据类型分配内存;new找到一个长度正确的内存块,并返回该地址赋给指针。
int * pn = new int;
int higgens;
int * pt = &higgens;
第一种情况,只能通过该指针进行访问。第二种情况可以通过名称higgens来访问该int
最后用delete来释放内存,会释放指针指向的内存,但不会删除指针本身,可以将指针重新指向一个新分配的内存块。需要与new配对使用。不能用delete释放声明变量所获得的内存
使用new来创建动态数组
int * psome = new int [10];
//delete [] psome;
new返回第一个元素的地址,然后将地址赋给指针
使用动态数组
上述指针psome指向10个int值的内存块中的第一个元素。可以将其看做一根手指。假如int占4字节,将手指沿正确方向移动4个字节,手指会指向第二个元素。而手指的移动范围就是这10个元素。
那么问题来了,如何访问其中的元素呢。第一个元素就是*psome。
另外的元素可以把指针当做数组名用即可,第一个元素psome[0],第二个psome[1]…
但是数组名和指针还是有着根本的差别
double * p3 = new double [2];
p3[0]=0.1;
p3[1]=0.2;
cout<<p3[0]<<endl;
p3 = p3 + 1;
cout<<p3[0]<<endl;
两次输出的分别是0.1和0.2
不能修改数组名的值,但指针是变量,可以修改它的值。