C++基础 – 容器 – vector
vector
动态连续数组, 头文件 <vector>
定义:
template<
class T,
class Allocator = std::allocator<T>
> class vector;
参数解释:
1. T 元素类型
T必须满足可拷贝复制(CopyAssignable)和可拷贝构造(CopyConstructible)的要求
2. Allocator 用于获取/释放内存及构造/析构内存中元素的分配器
常用函数
operator[]
refrence operator[](size_type pos);
const_refrence operator[](size_type pos) const;
返回给定pos位置的元素引用,不检查边界
at()
refrence at(size_type pos);
const_refrence at(size_type pos) const;
返回给定pos位置的元素引用,会进行边界检查。如果给定pos超出边界,会报异常 std::out_of_range
示例:(演示operator[] 和 at() 使用上面的差别)
#include <vector>
#include <iostream>
int main(int argc, char** argv) {
std::vector<int> int_vecs = {2, 3, 4, 5}; //c++ 11
std::cout << int_vecs[3] << std::endl; // 输出:5
int_vecs[3] = 6;
std::cout << int_vecs[3] << std::endl; // 输出:6
std::cout << int_vecs.at(2) << std::endl; // 输出:4
int_vecs.at(2) = 8;
std::cout << int_vecs.at(2) << std::endl; // 输出:8
try {
std::cout << int_vecs.at(4) << std::endl; // 跑出越界异常 std::out_of_range
} catch (std::exception& e) {
std::cout << e.what() << std::endl; //打印异常信息
}
//遍历
for(size_t i = 0; i < int_vecs.size(); ++i) {
std::cout << int_vecs[i] << std::endl;
std::cout << int_vecs.at(i) << std::endl;
}
std::cout << int_vecs[4] << std::endl; //程序崩溃
return 0;
}
//编译 & 运行
//g++ -std=c++11 main.cc -o test & ./test
front()
refrence front();
const_refrence front() const;
返回容器中第一个元素的引用。如果容器为空,调用可能会出现coredump
back()
refrence back();
const_refrence back() const;
返回容器中最后一个元素的引用。如果容器为空,调用可能会出现coredump
empty()
bool empty() const;
检查容器是否为空
size()
size_type size() const;
返回容器中元素的个数
capacity
size_type capacity() const;
返回容器当前已分配的元素数
reserve()
void reserve(size_type new_cap);
- 增加容器的容量到大于或者等于new_cap的值。如果new_cap大于当前的capacity(),则分配新存储,否则该方法不做任何事。reserve不会更改容器的size
- 如果new_cap大于capacity(),则所有迭代器,包括尾迭代器(end,cend)都失效
resize()
void resize(size_type count, T value = T());
- 重新设置容器大小为count
- 当前大小大于count,则减少容器元素个数
- 当前大小小于count,则往后添加额外的元素,并以value的副本初始化
- 当前capacity()小于count,则重新分配内存capacity()发生变化
push_back()
void push_back(const T& value);
void push_back(T&& vlaue); //(c++11)
把元素添加到容器的末尾,如果新的size()大于capacity(),则所有迭代器(包括尾迭代器)失效
pop_back()
void pop_back();
移除容器的末尾元素,在空容器上调用,会产生未定义行为。
emplace_back()
template<class... Args>
iterator emplace_back(Args&& args); //(C++11)
添加新元素到容器末尾,在容器所提供的位置原位构造元素。可以避免push_back时额外复制或移动操作
insert()
iterator insert(iterator pos, const T& value);
iterator insert(iterator pos, size_type count, const T& value);
template<class InputIt>
iterator insert(iterator pos, InputIt first, InputIt last)
1) 在pos前插入value,并返回iterator指向value
2) 在pos前插入value的count个副本,并返回指向插入的第一个value的iterator,如果count = 0,返回pos
3) 在pos前插入来自范围[first, last)的元素,并返回指向插入的第一个元素的iterator,如果范围为空,则返回pos
erase()
iterator erase(iterator pos);
iterator erase(iterator first, iterator last);
1) 移除位于pos的元素, pos需要能合法,可解引用
2) 移除范围[first, last)中的元素
使删除点之后的元素的迭代器失效
基础使用示例
#include <iostream>
#include <vector>
template<class T>
void print(const std::vector<T>& vec) {
for(auto it = vec.begin(); it != vec.end(); ++it) {
if(it != vec.begin()) {
std::cout << " ";
}
std::cout << *it;
}
std::cout << std::endl;
}
template<class T>
void print_size(const std::vector<T>& vec) {
std::cout << "size=" << vec.size() << " capacity=" << vec.capacity() << std::endl;
}
int main(int argc, char** argv) {
std::vector<int> int_vec;
int_vec.resize(3);
print_size(int_vec); //输出: size=3 capacity=3
int_vec.push_back(10);
print_size(int_vec); //输出: size=4 capacity=6
print(int_vec); //输出: 0 0 0 10
int_vec.resize(3);
print_size(int_vec); //输出: size=3 capacity=6
print(int_vec); //输出: 0 0 0
int_vec.reserve(3);
print_size(int_vec); //输出: size=3 capacity=6
auto it = int_vec.insert(int_vec.begin(), 10);
print_size(int_vec); //输出: size=4 capacity=6
print(int_vec); //输出: 10 0 0 0
std::cout << *it << " " << (it == int_vec.begin()) << std::endl; //输出: 10 1
std::cout << int_vec.back() << " " << int_vec.front() << std::endl; //输出: 0 10
int_vec.push_back(11);
print_size(int_vec); //输出: size=5 capacity=6
print(int_vec); //输出: 10 0 0 0 11
int_vec.emplace_back(12);
print_size(int_vec); //输出: size=6 capacity=6
print(int_vec); //输出: 10 0 0 0 11 12
int_vec.emplace_back(13);
print_size(int_vec); //输出: size=7 capacity=12
print(int_vec); //输出: 10 0 0 0 11 12 13
std::cout << (it == int_vec.begin()) << std::endl; //输出: 0
//循环删除偶数
for(auto it = int_vec.begin(); it != int_vec.end();) {
if(*it % 2 == 0) {
it = int_vec.erase(it);
} else {
++it;
}
}
print_size(int_vec); //输出: size=2 capacity=12
print(int_vec); //输出: 11 13
return true;
}