1.STL的容器类介绍
【1】何为容器
- 顾名思义,容器就是盛放东西的东西,这里被盛放的一般是数据对象,用来盛放的是容器类
- 计算机中一切皆是数据,数据存储只能在内存中,而容器类是用做容器的内存的管理方法
- 容器类的内核就是:数据结构 + 算法
- C语言语法内置的数组和结构体,就是语言源生支持的容器
- C++容器通过类库方式提供,容器类库被模板技术泛化后,就是STL容器了。可见STL的本质其实就是一套模板技术泛化类型的C++基本数据结构和算法类库
【2】STL有哪些容器类
- 顺序容器
- 顺序容器实现能按顺序访问的数据结构。。包括array、vector、deque、list、forward_list等几个。
- 关联容器
- 关联容器实现能快速查找( O(log n) 复杂度)的数据结构。包括set、multiset、map、mutilmap等。
- 无序关联容器
- 无序关联容器提供能快速查找的无序(哈希)数据结构。无序关联容器中的元素是未排序的,元素的位置由哈希函数确定,即遵守一定规则的
<key,value>
对式存储。 - 包括unordered_set、unordered_map、hash_set、hash_multiset、hash_map、hash_multimap等。
2.容器类array的基本使用
【1】array的特性
- array是定长、同类型多元素、内存中连续排布的一种容器
- array其实就是C语言数组的C++的 template封装
- array的参考文档
【2】array的基本信息
C++ 容器库 std::array 定义于头文件 <array>
template<class T, std::size_t N> struct array;
- std::array 是封装固定大小数组的容器。
- 成员函数
- 非成员函数和辅助类
【3】array的构造和初始化
- 和C数组兼容的初始化方式
- 需要C++11或以上标准来支持,编译时:
g++ array.cpp -std=c++11
- 支持默认的拷贝构造
#include <iostream>
#include <array>
using namespace std;
int main(int argc, char const *argv[])
{
array<int,3> a1; //可以,定义未初始化
array<int,3> a2 {1,3,5}; //可以,属于聚合初始化
array<int,3> a3 = {1,3,5}; //可以,初始化赋值,效果等同于a2
//array<int,3> a4 (1,3,5); //不可以,C++无法提供无数个构造函数来匹配
array<int,3> a5 = a3; //可以,拷贝构造
return 0;
}
【4】array的元素访问
- at方法
- operator[]实现的C数组式访问
- front和back方法返回第1个和最后1个元素
#include <iostream>
#include <array>
using namespace std;
int main(int argc, char const *argv[])
{
array<int,3> a {1,3,5};
cout << "a[0] = " << a[0] << endl;
cout << "a.at(1) = " << a.at(1) << endl;
cout << "a.operator[](2) = " << a.operator[](2) << endl;
cout << "a.front() = " << a.front() << endl;
cout << "a.back() = " << a.back() << endl;
return 0;
}
- 如果array的元素访问越界了,那么at方法用编译时没问题,但是运行时会抛出异常;用operator[]实现的C数组式访问不会出现异常
array<int,3> a {1,3,5};
cout << "a.at(3) = " << a.at(3) << endl;
array<int,3> a {1,3,5};
cout << "a[3] = " << a[3] << endl;
cout << "a.operator[](3) = " << a.operator[](3) << endl;
- data返回真实存储内存中首元素首地址的值。
#include <iostream>
#include <array>
using namespace std;
int main(int argc, char const *argv[])
{
array<int,3> a {1,3,5};
int *p = a.data();
cout << "a.data = " << a.data() << ",*p++ = " << *p++ << endl;
cout << "a.data = " << a.data() << ",*p++ = " << *p++ << endl;
cout << "a.data = " << a.data() << ",*p++ = " << *p++ << endl;
return 0;
}
【5】array的容量设置和获取
- 容量设置只能在定义时一次设定,且必须设定,设定后再不能改
- empty:检查容器是否为空
array<int,3> a {1,3,5};
array<int,3> b;
array<int,0> c;
cout << a.empty() << endl; // 0
cout << b.empty() << endl; // 0
cout << c.empty() << endl; // 1
- size:返回容纳的元素数
- max_size:返回可容纳的最大元素数
array<int,3> a {1,3,5};
array<int,3> b;
array<int,0> c;
cout << a.size() << endl; // 3
cout << b.size() << endl; // 3
cout << c.size() << endl; // 0
cout << a.max_size() << endl; // 3
【6】操作
- fill:以指定值填充容器
array<int,3> a {1,3,5};
a.fill(6);
- swap:交换内容
array<int,3> a {1,3,5};
array<int,3> b {2,4,6};
a.swap(b);
cout << a[0] << endl; // 2
cout << a[1] << endl; // 4
cout << a[2] << endl; // 6
cout << b[0] << endl; // 1
cout << b[1] << endl; // 3
cout << b[2] << endl; // 5
【7】非成员函数
- operator重载函数:按照字典顺序比较 array 中的值
- get:访问 array 的一个元素
template< std::size_t I, class T, std::size_t N > T& get( std::array<T,N>& a ) noexcept;
从 array 提取第 I 个元素。I 必须是范围 [0, N) 中的整数值。
array<int,3> a {1,3,5};
cout << get<0,int,3>(a) << endl; //1
cout << get<1,int,3>(a) << endl; //3
cout << get<2,int,3>(a) << endl; //5
- swap:特化 std::swap 算法
template< class T, std::size_t N > void swap( std::array<T,N>& lhs, std::array<T,N>& rhs );
交换 lhs 与 rhs 的内容。调用 lhs.swap(rhs)
- to_array:从内建数组创建 std::array 对象 (C++20)
【8】辅助类
- 辅助类tuple_size:获得 array 的大小
tuple_size - 辅助类tuple_element:获得 array 元素的类型
tuple_element - 被取代的make_array