C++标准库vector的基础用法总结
vector简介
vector
是C++标准模板库(STL)中的一个动态数组模板类,它可以随着元素的添加而自动增长。vector
使用连续的内存空间来存储元素,这意味着可以使用下标运算符([]
)来访问元素,就像使用数组一样高效。然而,与数组不同的是,vector
的大小是动态的,可以自动调整以适应添加的元素。
当新元素被添加到vector
中时,如果当前容量不足以容纳新元素,vector
会自动重新分配内存,通常是分配更大的内存块,并将所有原始元素复制到新的内存块中。这个过程可能会导致一些性能开销,因为需要复制元素和重新分配内存。但是,由于这个自动增长的能力,使用vector
可以避免手动管理内存和数组大小的复杂性。
vector
还提供了许多有用的成员函数,例如push_back()
(添加元素到末尾)、pop_back()
(删除末尾元素)、push_front()
(添加元素到开头)、pop_front()
(删除开头元素)、insert()
(在指定位置插入元素)和erase()
(删除指定位置的元素)等。
需要注意的是,由于vector
使用动态内存分配,因此在处理大量数据或频繁调整大小的情况下,使用vector
可能会导致内存碎片化或性能下降。在这种情况下,可以考虑使用其他容器,如deque
、list
或array
等。
简单应用
以下是一个使用vector
的简单例子:
#include <iostream>
#include <vector>
int main() {
// 创建一个空的vector
std::vector<int> vec;
// 使用push_back()添加元素
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
// 遍历vector并输出元素
for (int i : vec) {
std::cout << i << " ";
}
std::cout << std::endl;
// 使用front()和back()获取第一个和最后一个元素
std::cout << "第一个元素是: " << vec.front() << std::endl;
std::cout << "最后一个元素是: " << vec.back() << std::endl;
// 使用pop_back()删除最后一个元素
vec.pop_back();
// 再次遍历vector并输出元素
std::cout << "删除最后一个元素后的向量: ";
for (int i : vec) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
这个例子创建了一个空的vector
,使用push_back()
添加了三个整数,然后使用循环遍历并输出所有元素。接着,使用front()
和back()
获取第一个和最后一个元素,并使用pop_back()
删除最后一个元素。最后,再次遍历并输出修改后的vector
。
push操作
push_back()
函数用于在std::vector
的末尾添加一个元素。如果std::vector
是空的,push_back()
会首先创建一个容量为1的std::vector
,然后添加元素。如果std::vector
已经有元素,push_back()
会增加容量(如果需要的话)并添加新元素到末尾。
pop操作
删除末尾
在C++中,std::vector
提供了一个pop_back()
函数,用于从尾部删除一个元素。这个函数不会返回被删除的元素,但是你可以通过back()
函数来获取它。
下面是一个简单的示例:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 获取最后一个元素
int last_element = vec.back();
std::cout << "最后一个元素是: " << last_element << std::endl;
// 删除最后一个元素
vec.pop_back();
// 再次输出向量,以验证最后一个元素已被删除
std::cout << "向量现在包含: ";
for (int i : vec) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
运行这个程序,你会看到以下输出:
最后一个元素是: 5
向量现在包含: 1 2 3 4
如你所见,pop_back()
函数删除了最后一个元素,而back()
函数则返回被删除的元素。
删除开头
std::vector
也提供了pop_front()
函数,用于从头部删除一个元素。同样,这个函数也不会返回被删除的元素,但你可以使用front()
函数来获取它。
例如:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 获取第一个元素
int first_element = vec.front();
std::cout << "第一个元素是: " << first_element << std::endl;
// 删除第一个元素
vec.pop_front();
// 再次输出向量,以验证第一个元素已被删除
std::cout << "向量现在包含: ";
for (int i : vec) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
运行这个程序,你会看到以下输出:
第一个元素是: 1
向量现在包含: 2 3 4 5
参数传递
在C++中,传递一个std::vector
作为函数参数可以通过以下几种方式:
- 值传递:这是最直接的方式,但会创建一个新的
std::vector
对象。
void func(std::vector<int> vec) {
// 函数体
}
- 引用传递:这种方式可以避免复制,并且可以修改原始的
std::vector
。
void func(std::vector<int>& vec) {
// 函数体
}
- const引用传递:这种方式既可以避免复制,又保证
std::vector
在函数内不会被修改。
void func(const std::vector<int>& vec) {
// 函数体
}
- 指针传递:使用指针传递可以避免复制,但需要小心管理内存,因为如果原始的
std::vector
在函数外部被销毁,指针会变得无效。
void func(std::vector<int>* vec) {
// 函数体
}
- const指针传递:这种方式与第4点类似,只是保证
std::vector
在函数内不会被修改。
void func(const std::vector<int>* vec) {
// 函数体
}
选择哪种方式取决于你的具体需求。如果不需要修改std::vector
,建议使用const引用或const指针传递。如果需要修改,并且希望避免复制,可以使用引用或指针传递。如果你希望避免不必要的内存复制,并且对内存管理有信心,可以选择指针或const指针传递。