在c++11中,STL中我们提供了三种类型的数组,一种是std::array,一种是std::vector以及可变数组,这和传统的c语言相比多了很多功能,下面逐一介绍他们的功能以及使用方法。
1. array的使用
array静态数组大小在定义时固定,位于栈上。std::array是在C++11中才引入的,与内置数组相比,array是一种更安全、更容易使用的数组类型。与内置数组类似,array对象的大小是固定的。因此,array不支持添加和删除元素以及改变容器大小的操作。与内置数组一样,标准库array的大小也是类型的一部分。当定义一个array时,除了指定元素类型,还要指定容器大小。为了使用array类型,我们必须同时指定元素类型和大小。array仅仅是为普通数组添加了一些成员或全局函数,这使得数组能够被当成标准容器来使用。array不能被动态地扩展或压缩。
1.1 定义:
// TEMPLATE CLASS array
template<class _Ty,
size_t _Size>
class array
{ // fixed size array of values
std::array 是封装固定大小数组的容器。
比如我们想要的定义一个具有5个元素的int类型,然后取名为array1:
std::array<int, 5> array1
更为详细的定义可以参考如下文档,std::array。同时这里也推荐一个写的比较好的博客,C++11中std::array的使用。
例子1:定义一个固定的std::array
#include<iostream>
#include<stdlib.h>
#include<array>
int main()
{
double db[5] = { 1.2, 1.3, 1.5, 1.6, 1.56 };
std::array<double, 5> dbnew1 = { 1.2, 1.3, 1.5, 1.6, 1.56 }; // 这是C++的新的语法规则
std::array<double, 5> dbnew2 = dbnew1; //新版的C++是可以实现数组的总体直接赋值操作的
for (int i = 0; i < 5; i++)
{
std::cout << db[i] << " " << dbnew1[i] << " " << dbnew2[i] << std::endl;
}
std::cin.get();
return 0;
}
输出:
例子2:定义一个二维的array
#include<iostream>
#include<array>
#include<vector>
int main()
{
array<int, 5> array1 = { 1, 2, 3, 4, 5 }; //定义一个一维的array
array<int, 5> array2 = { 6, 7, 8, 9, 10 };
array<int, 5> array3 = { 11, 12, 13, 14, 15 };
array < array<int, 5>, 3 >array_t = {array1, array2, array3}; //定义一个二维数组
for (int i = 0; i < array_t.size(); i++) // 这里我们在实现数组的遍历的时候,可以使用array.size()求出数组的大小了
{
for (int j = 0; j < array1.size(); j++)
{
cout << array_t[i][j] << " ";
}
cout << endl;
}
cin.get();
return 0;
}
输出:
2. vector的使用
和array不同的是,vector是变长数组,他是可以处理数组长度是不固定的。当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间的目的。
2.1 一些函数说明
vector有一系列的函数操作,非常方便使用.
和vector
不同,数组不提供 push_back()
或者其他的操作在数组中添加新元素,数组一经定义就不允许添加新元素;若需要则要充许分配新的内存空间,再将员数组的元素赋值到新的内存空间。同时我们也是有pop_back()
可以删除一个元素的。另外一些方法可以见下表:
序号 | 函数 | 函数说明 |
---|---|---|
1 | push_back | 在数组的最后添加一个数据 |
2 | pop_back | 去掉数组的最后一个数据 |
3 | at | 得到编号位置的数据 |
4 | begin | 得到数组头的指针 |
5 | end | 得到数组的最后一个单元+1的指针 |
6 | front | 得到数组头的引用 |
7 | back | 得到数组的最后一个单元的引用 |
8 | max_size | 得到vector最大可以是多大 |
9 | capacity | 当前vector分配的大小 |
10 | size | 当前使用数据的大小 |
11 | resize | 改变当前使用数据的大小,如果它比当前使用的大,者填充默认值 |
12 | reserve | 改变当前vecotr所分配空间的大小 |
13 | erase | 删除指针指向的数据项 |
14 | clear | 清空当前的vector |
15 | rbegin | 将vector反转后的开始指针返回(其实就是原来的end-1) |
16 | rend | 将vector反转构的结束指针返回(其实就是原来的begin-1) |
17 | empty | 判断vector是否为空 |
18 | swap | 与另一个vector交换数据 |
19 | insert | 在指定位置插入一个元素 |
2.2 函数举例:
比如我们定义一个int
类型的vector
我们可以使用以下方法:
std::vectot<int> myvector; // 我们定义一个vector的变量,里面的元素是int类型,注意vector和array不同,他是没有长度的。
std::vector<std::vector<int>>allvector; //定义一个动态不规则数组,二维的。
例子1:vector的简单使用
#include<iostream>
#include<vector>
#include<stdlib.h>
int main()
{
vector<string> string1;
string1.push_back("calc");
string1.push_back("mspaint"); //可以增加一个vector元素
string1.push_back("ipconfig");
string1.pop_back(); //我们可以删除一个vector元素
for (int i = 0; i < string1.size(); i++) //使用默认的方式进行遍历vector
{
//cout << string1[i] << endl; 这里的string[i]是std::string而不是普通的字符串
cout << string1[i].c_str() << endl; //我们可以使用std::string.c_str()转换成普通字符串
}
cin.get();
return 0;
}
例子2: 使用迭代器输出vector元素
#include<iostream>
#include<vector>
#include<stdlib.h>
int main()
{
vector<string> string1;
string1.push_back("calc");
string1.push_back("mspaint"); //可以增加一个vector元素
vector<string>::iterator ibegin, iend; //定义一个正向的迭代器
ibegin = string1.begin(); //定义一个头指针
iend = string1.end(); //定义一个尾指针
for (; ibegin < iend; ibegin++) //这里我们是不可以使用等号的
{
cout << (*ibegin).c_str() << endl;
}
cin.get();
return 0;
}
输出效果和上面的是一样的。这里我们可以使用正向迭代器,我们还有反向迭代器,双向迭代器,更加详细的介绍可以参考迭代器(流迭代器,正向,反向迭代器,分配器,存储迭代器)
3.turple的使用
相比较的array和vector里面的元素,turple可以达到数组的里面的元素种类是不一样的。但是我们可以定义一个turpel是可以达到数组里面的元素种类的是不同的。
例子: 可变数组
#include<iostream>
#include<map>
int main()
{
int int1 = 10;
double double1 = 12.2;
char ch1 = 'a';
char * str1 = "china";
std::tuple<int, double, char, char *> all(int1, double1, ch1, str1); //定义一个多元数组,里面的元素可以是不同的类型
auto data1 = std::get<0>(all); // 通过std::get<>我们可以获取类型
auto data2 = std::get<1>(all); // 通过std::get<>我们可以获取类型
auto data3 = std::get<2>(all); // 通过std::get<>我们可以获取类型
auto data4 = std::get<3>(all); // 通过std::get<>我们可以获取类型
std::cout << typeid (data1).name() << std::endl; // 使用typeid我们可以获取类型名称
decltype(data1) data11; // 使用decltype获取指定的类型名称
std::cout << data1 << std::endl;
std::cin.get();
return 0;
}