90设计手机站,东营网站推广,北京网站制作很好 乐云践新,长安公司网站制作文章目录 前言一、vector的介绍二、vector的常用接口介绍1.vector类对象的常见构造2.vector iterator 的使用3.vector类对象的容量操作3.1 size、capacity 和 empty的使用3.2 reserve的使用3.3 resize的使用 4.vector类对象的访问#xff08;包含data#xff1a;返回底层数组… 文章目录 前言一、vector的介绍二、vector的常用接口介绍1.vector类对象的常见构造2.vector iterator 的使用3.vector类对象的容量操作3.1 size、capacity 和 empty的使用3.2 reserve的使用3.3 resize的使用 4.vector类对象的访问包含data返回底层数组的指针5.vector类对象的修改操作5.1 push_back、insert插入数据5.2 pop_back、erase 和 clear删除数据5.3 成员函数swap 6.vector类非成员函数6.1 relational operators系列函数6.2 非成员函数swap 前言 一、vector的介绍包含vector类中typedef的部分类型别名介绍 二、vector类的常用接口说明vector类对象的 常见构造重点、容量操作、遍历操作 和 修改操作等接口以及一些vector类非成员函数的接口 一、vector的介绍
C标准模板库中的容器vector是一个动态数组能够自动管理内存支持快速随机访问。 它的接口包括构造函数、大小和容量相关的操作、元素访问方法、修改容器的操作还有迭代器相关的函数。 在C标准库的 std::vector 中allocator内存分配器是模板的第二个参数通常可以忽略使用默认的即可。但在需要特殊内存管理时可以自定义allocator不过这种情况相对少见。 默认内存分配器已足够高效自定义内存分配器应仅在性能分析表明有必要时才会使用所以后续介绍vector接口时只会考虑大多数情况忽略allocator直接使用默认的这个参数简化vector的使用。 vector 类中typedef了很多类型别名以下代码展示了一些常用的类型别名
typedef T value_type;// 其中 T 是 vector 的第一个模板参数
typedef size_t size_type;
// size_t 是 C 标准库中定义的一个类型别名它通常是一个无符号整数类型。其可能的定义方式如下:
// 64 位系统下: typedef unsigned long long size_t;
// 32 位系统下: typedef unsigned int size_t;
typedef T reference;
typedef const T const_reference;
typedef Allocator allocator_type;二、vector的常用接口介绍
1.vector类对象的常见构造 忽略allocator相关参数后的简化接口
(constructor)构造函数声明接口说明vector()无参构造,默认构造空容器vector size_type n, const value_type val value_type() 构造并初始化n个valtemplate class InputIterator vector ( InputIterator first, InputIterator last )使用迭代器进行初始化构造vector (const vector x)拷贝构造vector ( initializer_listvalue_type il 初始化列表构造C11新增了解用法
示例一无参构造,默认构造空容器 vector( )
#include vector
using namespace std;int main()
{vectorint app;// size和capacity均为0return 0;
}示例二构造并初始化n个val vector size_t n, const T val T( )
#include vector
#include string
using namespace std;int main()
{vectorint a1(5); // vector(size_t n, const int val int())vectorint* a2(5); // vector(size_t n, const int* val int*())vectorint a3(5, 10);vectorstring a4(5); // vector(size_t n, const string val string())vectorstring a5(5,abcd);return 0;
}补充: 1规定 int()、char() 等内置类型创建的匿名对象不传参数时默认为 0 int * ()、char * () 等默认为 nullptr 2string() 等自定义类型创建的匿名对象不传参数时会去调用对应的默认构造函数 示例三使用迭代器进行初始化构造 template class InputIterator vector ( InputIterator first, InputIterator last )
#include vector
#include list
using namespace std;int main()
{listint lst { 1, 2, 3, 4, 5 }; // 初始化列表的构造方式vectorint vec1(lst.begin(), lst.end()); // list的迭代器是双向迭代器int arr[] { 4, 5, 6, 7, 8, 9 };vectorint vec2(arr 2, arr 5); // 指针作为随机访问迭代器vectorint vec { 10, 11, 12, 13, 14, 15 };vectorint vec3(vec.begin() 1, vec.end() - 2); // vector的迭代器是随机访问迭代器return 0;
}补充知识迭代器的种类 在 C 中迭代器Iterator是用于遍历容器如 vector、list、map等中元素的对象类似于指针的行为。根据功能强弱迭代器分为以下 5 种类别支持不同的操作 1. 输入迭代器Input Iterator 功能只能单向移动向前且只能读取元素不可修改。支持的操作前置/后置递增、*解引用、/!比较。典型应用一次性遍历如从文件流读取数据。示例istream_iterator用于输入流。 2. 输出迭代器Output Iterator 功能只能单向移动向前且只能写入元素不可读取。支持的操作前置/后置递增、*解引用赋值。典型应用向容器或流中写入数据。示例ostream_iterator用于输出流。 3. 前向迭代器Forward Iterator 功能继承自输入迭代器支持多次读写和重复遍历。支持的操作所有输入迭代器的操作且可以多次递增。典型容器单链表如 forward_list、哈希表如 unordered_set。 4. 双向迭代器Bidirectional Iterator 功能继承自前向迭代器支持双向移动向前和向后。支持的操作所有前向迭代器的操作新增 --前置/后置递减。典型容器双链表如 list、关联容器如 set、map。 5. 随机访问迭代器Random Access Iterator 功能功能最强支持直接跳跃访问任意位置。支持的操作所有双向迭代器的操作新增 /-、/-跳跃多个位置。[]下标访问、比较大小如 , 。 典型容器连续内存容器如string、vector、deque、数组。 迭代器关系图示 输入迭代器 → 前向迭代器 → 双向迭代器 → 随机访问迭代器功能由低到高 输出迭代器独立分支 关键区别 随机访问迭代器效率最高如 vector 的迭代器。输入迭代器是等级最低的迭代器所有更高级的迭代器如前向、双向、随机访问迭代器都兼容输入迭代器的功能。双向迭代器仅支持逐步移动如 list。算法需根据迭代器类型选择实现如 算法库中的sort 需要随机访问而list的双向迭代器不能满足sort随机访问的要求所以list 需用自己的 sort 方法。 示例四拷贝构造 vector (const vector x)
#include vector
using namespace std;int main()
{vectorint vec { 10, 11, 12, 13, 14, 15 }; vectorint vec1(vec); // 用vec拷贝构造vec1return 0;
}示例五初始化列表构造 vector ( initializer_list T il )
#include vector
#include string
using namespace std;int main()
{vectorint vec1{ 1, 2, 3 }; // 调用初始化列表构造vector对象时要使用花括号vectorstring vec2{ hello, world };vectorint vec3 { 5, 6, 7 };return 0;
}2.vector iterator 的使用 接口功能begin获取第一个数据位置的iterator/const_iteratorend获取最后一个数据的下一个位置的iterator/const_iterator
#include vector
#include iostream
using namespace std;int main()
{vectorint s1 { 1,3,5,7,9 };vectorint::iterator it1 s1.begin();// 普通vector对象调用 iterator begin();// 返回指向vector对象中第一个元素的普通迭代器,允许修改vector对象中的元素while (it1 ! s1.end()){(*it1);cout *it1 ;it1;}cout endl;const vectorint s2 { 1,3,5,7,9 };vectorint::const_iterator it2 s2.begin();// const vector对象调用 const_iterator begin() const;// 返回指向const vector对象第一个元素的const迭代器,只允许读取const vector对象中的元素不能修改while (it2 ! s2.end()){cout *it2 ;it2;}cout endl;return 0;
}3.vector类对象的容量操作 3.1 size、capacity 和 empty的使用
接口功能size获取数据个数capacity获取容量大小empty判断是否为空
1size 和 capacity
#include vector
#include iostream
using namespace std;int main()
{vectorint vec1{ 1,2,3,4,5 };cout vec1的有效数据个数: vec1.size() endl;cout vec1的容量: vec1.capacity() endl;vectorint vec2{ 6,6,6,6,6,6,6,6,6,6,6};cout vec2的有效数据个数: vec2.size() endl;cout vec2的容量: vec2.capacity() endl;return 0;
}2empty
#include vector
#include iostream
using namespace std;int main()
{vectorint vec1{ 1,2,3,4,5 };cout vec1是否为空: vec1.empty() endl;vectorint vec2;cout vec2是否为空: vec2.empty() endl;return 0;
}3.2 reserve的使用 std::vector 类提供的 reserve() 成员函数用于请求vector对象的容量调整。 注这个函数不会改变vector对象的有效数据个数也不会修改vector对象有效数据中的内容。
#include vector
#include iostream
using namespace std;int main()
{vectorint v1{ 1,2,3,4,5,6,7,8,9 };cout v1的有效数据个数: v1.size() endl;cout v1的容量: v1.capacity() endl;v1.reserve(50);cout v1的有效数据个数: v1.size() endl;cout v1的容量: v1.capacity() endl;return 0;
}我们一般只用reserve函数进行扩容使用场景如下在你预先知道vector对象将增长到某个大小时可以使用reserve函数提前分配足够的空间避免频繁扩容。
3.3 resize的使用 std::vector类提供的 resize() 成员函数用于改变有效数据个数。 如果新的个数大于当前个数会新增有效数据个数新增元素初始化为 val如果新的个数小于当前个数减少有效数据个数。
示例一新的个数大于当前个数会新增有效数据个数新增元素初始化为 val
#include vector
#include iostream
using namespace std;int main()
{vectorint v1{ 1,2,3 };cout v1的有效字符长度: v1.size() endl;cout v1的容量: v1.capacity() endl;v1.resize(5, 10);cout v1的有效字符长度: v1.size() endl;cout v1的容量: v1.capacity() endl;v1.resize(10, 100);cout v1的有效字符长度: v1.size() endl;cout v1的容量: v1.capacity() endl;return 0;
}示例二新的个数小于当前个数减少有效数据个数
#include vector
#include iostream
using namespace std;int main()
{vectorint v1{ 1,2,3,4,5,6,7,8,9 };cout v1的有效字符长度: v1.size() endl;cout v1的容量: v1.capacity() endl;v1.resize(5);cout \n v1的有效字符长度: v1.size() endl;cout v1的容量: v1.capacity() endl;return 0;
}4.vector类对象的访问包含data返回底层数组的指针 接口功能operator[]返回n位置的数据越界访问的情况是不确定的at()返回n位置的数据越界访问会抛异常data()返回底层数组的指针C11
1operator[]
#include vector
#include iostream
using namespace std;int main()
{vectorint v1{1,2,3,4,5,6,7,8,9};for (size_t i 0; i v1.size(); i){v1[i] 1;cout v1[i] ;// 普通对象调用 int operator[](size_t n); // 返回vector对象中指定位置数据的引用int// 这意味着你可以通过返回的引用修改数据的内容。}cout endl;const vectorint v2{ 1,2,3,4,5,6,7,8,9 };for (size_t i 0; i v2.size(); i){cout v2[i] ;// const对象调用 const int operator[](size_t n) const; // 返回vector对象中指定位置数据的常引用const int// 这意味着你只能读取vector对象中的数据而无法进行修改。}cout endl;return 0;
}2at( )
#include vector
#include iostream
using namespace std;int main()
{vectorint v1{1,2,3,4,5,6,7,8,9};for (size_t i 0; i v1.size(); i){v1.at(i) 1;cout v1.at(i) ;// 普通对象调用 int at(size_t n); // 返回vector对象中指定位置数据的引用int// 这意味着你可以通过返回的引用修改数据的内容。}cout endl;const vectorint v2{ 1,2,3,4,5,6,7,8,9 };for (size_t i 0; i v2.size(); i){cout v2.at(i) ;// const对象调用 const int at(size_t n) const; // 返回vector对象中指定位置数据的常引用const int// 这意味着你只能读取vector对象中的数据而无法进行修改。}cout endl;return 0;
}3data( )
#include vector
#include iostream
using namespace std;int main()
{std::vectorint myvector(5, 10);cout myvector contains:;for (unsigned i 0; i myvector.size(); i){cout myvector[i];}cout \n;int* p myvector.data();*p 20;p;*p 20;p[2] 100;cout myvector contains:;for (unsigned i 0; i myvector.size(); i){ cout myvector[i];}cout \n;return 0;
}5.vector类对象的修改操作 5.1 push_back、insert插入数据
接口功能push_back在末尾插入一个元素insert在迭代器 position 位置插入元素
1push_back
#include vector
#include iostream
using namespace std;int main()
{vectorint v1{ 1,1,1,1,1,1,1,1 };for (unsigned i 0; i v1.size(); i){cout v1[i];}cout \n;v1.push_back(100); // 尾插一个元素for (unsigned i 0; i v1.size(); i){cout v1[i];}cout \n;return 0;
}2insert 示例一插入多个相同元素 iterator insert(const_iterator pos, size_t count, const T val);
#include vector
#include iostream
using namespace std;int main()
{vectorint v1{ 1,1,1,1,1,1,1,1 };for (unsigned i 0; i v1.size(); i){cout v1[i];}cout \n;v1.insert(v1.begin() 5, 3, 10);for (unsigned i 0; i v1.size(); i){cout v1[i];}cout \n;return 0;
}示例二插入范围元素: template class InputIterator iterator insert(const_iterator pos, InputIterator first, InputIterator last);
#include vector
#include list
#include iostream
using namespace std;int main()
{vectorint v1{ 1,1,1,1,1,1,1,1 };for (unsigned i 0; i v1.size(); i){cout v1[i];}cout \n;listint lst{ 10,11,12,13,14,15 };v1.insert(v1.begin() 5, lst.begin(), lst.end()); // list的迭代器是双向迭代器for (unsigned i 0; i v1.size(); i){cout v1[i];}cout \n;return 0;
}示例三插入初始化列表 iterator insert(const_iterator pos, initializer_list T il);
#include vector
#include iostream
using namespace std;int main()
{vectorint v1{ 1,1,1,1,1,1,1,1 };for (unsigned i 0; i v1.size(); i){cout v1[i];}cout \n;v1.insert(v1.begin() 5, { 9,5,2,7 }); // 插入初始化列表for (unsigned i 0; i v1.size(); i){cout v1[i];}cout \n;return 0;
}5.2 pop_back、erase 和 clear删除数据
接口功能pop_back删除末尾元素erase删除迭代器 pos 指向的元素clear清空所有有效元素不释放内存
1pop_back
#include vector
#include iostream
using namespace std;int main()
{vectorint v1{ 1,2,3,4,5,6,7,8,9 };for (unsigned i 0; i v1.size(); i){cout v1[i];}cout \n;v1.pop_back();for (unsigned i 0; i v1.size(); i){cout v1[i];}cout \n;return 0;
}2erase 示例一删除单个元素
#include vector
#include iostream
using namespace std;int main()
{vectorint v1{ 1,2,3,4,5,6,7,8,9 };for (unsigned i 0; i v1.size(); i){cout v1[i];}cout \n;v1.erase(v1.begin() 5); // 删除第6个元素for (unsigned i 0; i v1.size(); i){cout v1[i];}cout \n;return 0;
}示例二删除范围元素
#include vector
#include iostream
using namespace std;int main()
{vectorint v1{ 1,2,3,4,5,6,7,8,9 };for (unsigned i 0; i v1.size(); i){cout v1[i];}cout \n;v1.erase(v1.begin() 5, v1.end() - 1); //删除第6~8的元素for (unsigned i 0; i v1.size(); i){cout v1[i];}cout \n;return 0;
}3clear
#include vector
using namespace std;int main()
{vectorint v1{ 1,2,3,4,5,6,7,8,9 };v1.clear();return 0;
}5.3 成员函数swap
swap成员函数是用于高效交换两个vector对象的内容的函数
#include vector
using namespace std;int main()
{vectorint v1{ 1,2,3};vectorint v2{ 10,20,30,40 };v1.swap(v2);return 0;
}6.vector类非成员函数 6.1 relational operators系列函数 #include vector
using namespace std;int main()
{vectorint v1{ 1,2,3 };vectorint v2{ 1,2,3,4 };vectorint v3{ 1,3,2 };// 运算符:元素数量相同且对应元素相等bool b1 (v1 v2); // false元素数量不同// ! 运算符:存在至少一个不相等元素bool b2 (v1 ! v3); // true在第二个元素 2 ! 3// 运算符字典序比较遇到第一个不同元素时判断bool b3 (v1 v2); // truev1是v2的前缀bool b4 (v1 v3); // true在第二个元素 2 3// 运算符字典序更大bool b5 (v2 v3); // false在第二个元素 2 3)return 0;
}核心原理 字典序比较 逐个元素对比直到发现不相等的元素若一个vector是另一个的前缀较短的vector更小元素必须支持operator自定义类型需重载 类型一致性 只能比较相同类型的vectorvectorint不能与vectordouble比较 6.2 非成员函数swap
std::vector的非成员函数swap专门用于交换两个同类型std::vector对象。它底层实际上调用了std::string的swap成员函数。 它在功能上与std::vector的swap成员函数完全一致但其提供了更为通用的接口。
#include vector
using namespace std;int main()
{vectorint v1{ 1,2,3};vectorint v2{ 10,20,30,40 };swap(v1, v2); // 功能上与std::vector的swap成员函数完全一致但其提供了更为通用的接口return 0;
}