一、定义
虽然,前边我们讲过的用new给基本类型和对象在运行时分配内存,但它们的尺寸在编译时就已经确定下来---因为我们为之申请内存的数据类型在程序里有明确的定义,有明确的长度。
可是,总有些时候,必须要等到程序运行时才能确定需要申请多少内存,甚至还需要根据程序的运行情况追加申请更多的内存。
从某种意义上讲,这样的内存管理才是真正的动态。
这一讲中,我们将带大家编写一个程序为一个整数型数组分配内存,实现动态数组。
二、例子
实现一个程序,能够在程序运行时让用户输入一个值自行定义数组的长度。
2.1 复习 数组和指针的关系
在即将编写的例子程序里有一个数组,它的长度在编写这个程序时是未知的,这意味着无法在定义这个数组时在方括号里给出一个准确的数字。
------ int a[???];
如何解决这个问题呢???
不知道大家在脑海里会将数组跟什么挂钩呢??
指针,指针。
数组名和下标操作符[]的组合可以被替换成一个指向该数组的基地址的指针和对应的指针运算:
a[2] 是第三个元素。数组名a存放的是数组的地址,而后面的操作符中括号代表的是地址的偏移 表示 a + (2 * sizeof(数组类型))地址偏移
如下
int a[20];
int *x = a;
指针变量x指向数组a的地址,a[0]和*x都代表数组的第一个元素。
于是,根据指针运算原则,a[1]等价于*(x+1),a[2]等价于*(x+2),以此类推。
大家想想,我们把这个逻辑倒过来,会怎样?
嗯,反过来也成立,并且帮助了我们一个大忙:
---把一个数组声明传递给new语句将使它返回一个改数组基类型的指针。
---把数组下标操作符和该指针变量的名字搭配使用就可以像对待一个数组那样使用new语句为这个数组分配的内存块了。
2.2、创建一个动态数组
例如:
int *x = new int[10]
可以像对待一个数组那样使用指针变量x:
--- x[1] = 4;
---x[2] = 45;
当然,也可以用一个变量来保存该数组的元素个数:
---int count = 10;
---int *x = new int[count];
2.3、删除一个动态数组
---删除一个动态数组要比删除其他动态数据类型稍微复杂一点。
----因为用来保存数组地址的变量只是一个简单的指针,所以需要明确地告诉编译器它应该删除一个数组!
----具体做法是在delete保留字的后面加上一对方括号: delete []x
-----这样的语法可能大家觉得很奇怪,但确实很管用,例子如下
#include <iostream>
#include <string>
using namespace std;
int main()
{
unsigned int count = 0;
cout << "请输入数组的元素个数: \n";
cin >> count;
int *x = new int[count];
for(int i=0; i<count; i++)
{
x[i] = i;
}
for(int j=0; j<count; j++)
{
cout << "x[" << j
<< "]的值是:" << x[j] << "\n";
}
delete [] x;
return 0;
}