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