【C++】学习笔记十三——数组的替代品
2016-12-01 14:30
190 查看
数组的替代品
数组的替代品有模板类vector和array。1. 模板类vector
模板类vector类似于string类,也是一种动态数组。可以在运行阶段设置vector对象的长度,可在末尾附加新数据,还可在中间插入新数据。
vector是使用new创建动态数组的替代品。实际上,vector类确实使用new和delete来管理内存,不过这些工作是自动完成的。
要使用vector对象,必须包含头文件vector。
vector包含在名称空间std中,因此可以使用using编译指令、using声明或std::vector。
模板使用不同的语法来指出它存储的数据类型。
vector类使用不同的语法来指定元素数。
#include<vector> ... using namespace std; vector<int> vi; //生成一个长度为0的int数组 int n; cin >> n; vector<double> vd(n); //生成一个长度为n的double数组
其中,vi是一个vector< int> 对象,vd是一个vector< double>对象。
由于vector对象在插入或添加值时自动调整长度,因此可以将vi的初始长度设置为0。但要调整长度,需要使用vector包中的各种方法。
一般而言,下面的声明创建一个名为vt的vector对象,它可存储n_elem个类型为typeName的元素:
vector<typeName> vt(n_elem); //n_elem可以是整型常量,也可以是整型变量
2. 模板类array(C++11)
vector类的功能比数组强大,但效率较低。如果需要的是固定长度的数组,直接使用数组是更好的选择,但数组不那么方便和安全。C++11新增了模板类array,它也位于名称空间std中。
与数组一样,array对象的长度也是固定的,也是用栈(静态内存分配),而不是自由存储区,因此其效率与数组相同,但更方便安全。
要创建array类,需要包含头文件array。
array对象的创建语法与vector稍有不同:
#include<array> ... using namespace std; array<int, 5> ai; //创建一个包含5个int的array对象 array<double, 4> ad = {1.2, 2.1, 3.43, 4.3};
一般地,下面的声明创建一个名为arr的array对象,它包含n_elem个类型为typeName的元素:
array<typeName, n_elem> arr; //与vector不同的是,n_elem不能是变量
在C++11中,还可将列表初始化用于vector和array对象。
3. 比较数组、vector对象和array对象
程序4.24#include<iostream> #include<vector> #include<array> int main() { using namespace std; //C,传统C++: double a1[4] = { 1.2, 2.4, 3.6, 4.8 }; //C++98 STL: vector<double> a2(4); //创建一个含有4个元素的vector对象 //在C98中没有简单的初始化方法: a2[0] = 1.0 / 3.0; a2[1] = 1.0 / 5.0; a2[2] = 1.0 / 7.0; a2[3] = 1.0 / 9.0; //C++11--创建和初始化array对象: array<double, 4> a3 = { 3.14, 2.72, 1.62, 1.41 }; array<double, 4> a4; a4 = a3; //对相同长度的array对象进行赋值是有效的 //使用数组记法: cout << "a1[2]: " << a1[2] << " at " << &a1[2] << endl; cout << "a2[2]: " << a2[2] << " at " << &a2[2] << endl; cout << "a3[2]: " << a3[2] << " at " << &a3[2] << endl; cout << "a4[2]: " << a4[2] << " at " << &a4[2] << endl; //错误行为: a1[-6] = 20.2; cout << "a1[-6]: " << a1[-6] << " at " << &a1[-6] << endl; cout << "a3[2]: " << a3[2] << " at " << &a3[2] << endl; cout << "a4[2]: " << a4[2] << " at " << &a4[2] << endl; cin.get(); return 0; }
运行结果:
程序说明
无论是数组、vector对象还是array对象,都可使用标准数组表示法来访问各个元素。
从地址可知,array对象和数组存储在相同的内存区域(即栈)中,而vector对象存储在另一个区域(自由存储区或堆)中。
可以将一个array对象赋给另一个array对象;而对于数组,必须逐元素复制数据。
a1[-6] = 20.2;
这行代码将被转换为
*(a1-2) = 20.2;
其含义为:找到a1指向的地方,向前移6个double元素,并将20.2存储到目的地。也就是说,将信息存储到数组的外面。
与C语言一样,C++也不检查这种越界错误。在这个示例中,这个位置位于array对象a3中。这表明数组的行为是不安全的。
对于vector对象和array对象,仍可以编写这种不安全的代码:
a2[-2] = .5; a3[200] = 1.4; //仍然允许
然而,还有其他选择。可以使用成员函数at():
a2.at(1) = 2.3; //将2.3赋给a2[1]
使用at()时,将在运行期间捕获非法索引,而程序默认将中断。这种额外检查的代价是运行时间更长。
相关文章推荐
- C++学习笔记之八 复合类型---数组的替代品vector和array
- C++基础学习笔记:自定义数组模板类
- C++学习笔记(三)——对象数组的指针和对象指针的数组
- C++学习笔记 | 第三章 字符串、向量和数组 | (1)
- C++学习笔记--数组
- c++ 模板学习笔记:用数组和类模板模拟通用栈(权哥)
- c++ 模板学习笔记:函数模板实现数组通用排序和遍历打印(权哥)
- C++学习笔记二 C++标准库 数组及指针
- C++学习笔记:数组的操作符重载(包括[]和=运算符)
- C++学习笔记十三 - C++宏替换认识大小写区分
- C/C++学习笔记(二)数组、字符
- C++学习笔记9——数组
- C++学习笔记六之函数如何使用指针来处理数组?
- C++基础教程 学习笔记(二) 数组、字符串和指针
- 【C++】学习笔记十一——指针、数组和指针算术
- C++学习笔记--数组操作符重载
- C/C++学习笔记18:指针数组和数组指针
- C++学习笔记十三-复制控制
- C++学习笔记21 多态遇上对象数组
- c++学习笔记(六):数组指针