std::vector
是 C++ 标准库中的一个动态数组容器,提供了灵活的存储和访问功能。
1. 创建和初始化 std::vector
#include <iostream>
#include <vector>
int main() {
// 创建一个空的 vector
std::vector<int> v1;
// 使用初始值创建 vector
std::vector<int> v2 = {1, 2, 3, 4, 5};
// 创建一个指定大小的 vector,所有元素初始化为 0
std::vector<int> v3(5); // v3 中有 5 个元素,初始值为 0
// 创建一个指定大小的 vector,并用特定值初始化所有元素
std::vector<int> v4(5, 10); // v4 中有 5 个元素,所有元素的值为 10
// 输出 vector 的内容
std::cout << "v2: ";
for (int num : v2) {
std::cout << num << " ";
}
std::cout << std::endl;
std::cout << "v3: ";
for (int num : v3) {
std::cout << num << " ";
}
std::cout << std::endl;
std::cout << "v4: ";
for (int num : v4) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
// 使用初始值创建 vector
std::vector<int> v2 = {1, 2, 3, 4, 5};
// 输出 vector 的内容
std::cout << "v2: ";
for (int num : v2) {
std::cout << num << " ";
}
std::cout << std::endl;
- 创建
vector
std::vector<int> v2 = {1, 2, 3, 4, 5};
-
步骤:
- 这里使用了
std::vector
,它是一个动态数组,可以存储多个同类型的数据。 v2
被初始化为一个包含五个整数(1, 2, 3, 4, 5)的vector
。
- 这里使用了
-
调用过程:
- C++ 的标准库中
std::vector
构造函数被调用,传入一个初始化列表{1, 2, 3, 4, 5}
v2
现在拥有五个元素,分别是 1, 2, 3, 4, 5。
- C++ 的标准库中
- 输出
vector
的内容
2.1 输出头部信息
std::cout << "v2: ";
-
步骤:
std::cout
是标准输出流,用于将信息输出到控制台。"v2: "
是一个字符串,表示要输出的内容。
-
调用过程:
- 调用
std::cout
的operator<<
函数,传递字符串"v2: "
- 字符串被输出到控制台。
- 调用
2.2 遍历 vector
并输出元素
for (int num : v2) {
std::cout << num << " ";
}
-
步骤:
for (int num : v2)
是范围-based 循环,遍历v2
中的每个元素。num
是循环变量,代表当前遍历到的元素。
-
调用过程:
- 编译器生成隐式的迭代器来遍历
v2
的元素。 - 对于
v2
中的每一个元素,执行std::cout << num << " ";
:num
被赋值为当前的元素值(例如第一次循环时是 1,第二次是 2,以此类推)。- 调用
std::cout
的operator<<
函数,将num
的值输出到控制台。 - 再次调用
std::cout
的operator<<
函数,将一个空格" "
输出到控制台。
- 编译器生成隐式的迭代器来遍历
-
执行的顺序:
- 第一次循环:
num
= 1,输出1
(后面有个空格)。 - 第二次循环:
num
= 2,输出2
(后面有个空格)。 - 第三次循环:
num
= 3,输出3
(后面有个空格)。 - 第四次循环:
num
= 4,输出4
(后面有个空格)。 - 第五次循环:
num
= 5,输出5
(后面有个空格)。
- 第一次循环:
- 输出换行
std::cout << std::endl;
-
步骤:
std::endl
是一个操控符,表示输出一个换行符并刷新输出流。
-
调用过程:
- 调用
std::cout
的operator<<
函数,传递std::endl
。 std::endl
将换行符插入到输出流中,并调用flush
方法,确保所有输出立即显示在控制台。
- 调用
总结
- 创建
vector
:初始化v2
为一个包含 1, 2, 3, 4, 5 的动态数组。 - 输出内容:
- 输出字符串
"v2: "
。 - 遍历
v2
中的每个元素,依次输出每个元素及其后面一个空格。
- 输出字符串
- 换行:最后输出一个换行符。
最终,控制台将显示如下内容:
v2: 1 2 3 4 5
2. 添加和删除元素
#include <iostream>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3};
// 在末尾添加元素
v.push_back(4);
v.push_back(5);
// 删除末尾元素
v.pop_back();
// 在指定位置插入元素
v.insert(v.begin() + 1, 10); // 在索引 1 的位置插入 10
// 删除指定位置的元素
v.erase(v.begin() + 2); // 删除索引 2 位置的元素
// 输出 vector 的内容
std::cout << "v: ";
for (int num : v) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
#include <iostream>
- 含义:包含输入输出流库,以便使用
std::cout
进行输出。 - 执行过程:预处理器指令,将
iostream
头文件的内容插入到当前文件中,以提供输入输出功能。
#include <vector>
- 含义:包含
std::vector
容器的定义,以便使用vector
类。 - 执行过程:预处理器指令,将
vector
头文件的内容插入到当前文件中,以提供动态数组功能。
int main() {
- 含义:程序的入口点,主函数的定义。
- 执行过程:程序开始执行从
main
函数开始的代码。
std::vector<int> v = {1, 2, 3};
- 含义:创建一个名为
v
的std::vector<int>
对象,并初始化为包含元素 1, 2, 3 的vector
。 - 执行过程:
- 调用
std::vector<int>
的构造函数,传入初始化列表{1, 2, 3}
。 v
现在包含三个整数元素:1, 2, 3。
- 调用
v.push_back(4);
- 含义:在
vector
的末尾添加一个新元素 4。 - 执行过程:
- 调用
std::vector<int>
的push_back
方法,传入整数 4。 4
被添加到v
的末尾,v
现在包含元素:1, 2, 3, 4。
- 调用
v.push_back(5);
- 含义:在
vector
的末尾添加一个新元素 5。 - 执行过程:
- 调用
std::vector<int>
的push_back
方法,传入整数 5。 5
被添加到v
的末尾,v
现在包含元素:1, 2, 3, 4, 5。
- 调用
v.pop_back();
- 含义:删除
vector
末尾的一个元素。 - 执行过程:
- 调用
std::vector<int>
的pop_back
方法。 - 删除
v
末尾的元素 5,v
现在包含元素:1, 2, 3, 4。
- 调用
8. v.insert(v.begin() + 1, 10);
起到中间添加元素的作用
- 含义:在
vector
的指定位置(索引 1)插入新元素 10。 - 执行过程:
- 调用
std::vector<int>
的insert
方法。 v.begin()
返回一个指向v
第一个元素的迭代器。v.begin() + 1
表示第二个位置的迭代器。- 插入元素 10 到索引 1 位置,
v
现在包含元素:1, 10, 2, 3, 4。
- 调用
9. v.erase(v.begin() + 2);
中间删除元素的作用
- 含义:删除
vector
中指定位置(索引 2)的元素。 - 执行过程:
- 调用
std::vector<int>
的erase
方法。 v.begin() + 2
表示第三个位置的迭代器。- 删除元素 2,
v
现在包含元素:1, 10, 3, 4。
- 调用
std::cout << "v: ";
- 含义:输出字符串
"v: "
到控制台。 - 执行过程:
- 调用
std::cout
的operator<<
函数,传递字符串"v: "
。 - 字符串被输出到控制台。
- 调用
for (int num : v) { std::cout << num << " "; }
- 含义:遍历
vector
中的每个元素,并将其输出到控制台。 - 执行过程:
for (int num : v)
是一个范围-based 循环,遍历v
中的每个元素。- 对于每个元素,
num
被赋值为当前元素值。 - 调用
std::cout
的operator<<
函数,将num
输出到控制台,再输出一个空格" "
。 - 遍历
v
中的所有元素,依次输出 1, 10, 3, 4。
std::cout << std::endl;
- 含义:输出一个换行符,并刷新输出流。
- 执行过程:
- 调用
std::cout
的operator<<
函数,传递std::endl
。 std::endl
输出换行符,并调用flush
方法,确保所有输出立即显示在控制台。
- 调用
return 0;
- 含义:结束
main
函数,返回 0 表示程序成功执行。 - 执行过程:
- 返回 0 给操作系统,表示程序正常结束。
总结
- 初始化
vector
:创建并初始化v
为{1, 2, 3}
。 - 修改
vector
:- 添加元素 4 和 5。
- 删除末尾的元素 5。
- 在索引 1 插入元素 10。
- 删除索引 2 位置的元素 2。
- 输出
vector
内容:打印v
中的每个元素,输出1 10 3 4
。
最终,控制台将显示如下内容:
v: 1 10 3 4
3. 访问和遍历元素
#include <iostream>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
// 使用索引访问元素
std::cout << "Element at index 2: " << v[2] << std::endl;
// 使用 at() 方法访问元素
std::cout << "Element at index 3: " << v.at(3) << std::endl;
// 使用迭代器遍历元素
std::cout << "v elements: ";
for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 使用范围-based for 循环遍历元素
std::cout << "v elements (range-based): ";
for (int num : v) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
- 包含头文件
#include <iostream>
#include <vector>
- 含义:引入标准输入输出流和向量容器的头文件,以便在程序中使用相应的类和函数。
- 创建并初始化
vector
std::vector<int> v = {1, 2, 3, 4, 5};
- 含义:创建一个
vector
容器v
,并初始化为包含 1, 2, 3, 4, 5 这几个整数元素。
- 使用索引和 at() 访问元素
std::cout << "Element at index 2: " << v[2] << std::endl;
std::cout << "Element at index 3: " << v.at(3) << std::endl;
- 含义:分别使用索引和
at()
方法访问vector
中的元素。 - 执行过程:
v[2]
返回索引为 2 的元素,即第三个元素。v.at(3)
返回索引为 3 的元素,即第四个元素。
- 注意:
at()
方法会进行边界检查,当访问越界时会抛出std::out_of_range
异常。
- 使用迭代器遍历元素
std::cout << "v elements: ";
for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
- 含义:使用迭代器遍历
vector
容器中的元素。 - 执行过程:
v.begin()
返回指向容器起始位置的迭代器。v.end()
返回指向容器末尾位置的迭代器。- 在循环中,通过
*it
访问迭代器指向的元素。
在使用迭代器遍历元素时,通过 *it
访问迭代器指向的元素,本质上是通过指针来进行访问的。
具体来说:
-
迭代器本质上是一个指针,指向容器中的某个元素。
-
当我们使用
v.begin()
和v.end()
获取迭代器时,实际上得到的是指向容器第一个元素和最后一个元素后面的位置的指针。 -
在遍历过程中,通过
++it
来移动迭代器,实际上是在移动指针,让它指向下一个元素。 -
当我们使用
*it
访问迭代器指向的元素时,实际上是通过解引用指针来获取该元素的值。
所以,使用迭代器遍历元素的本质就是通过指针来访问容器中的元素。迭代器提供了一种更加安全和易用的方式来遍历容器,但其底层实现确实是基于指针的访问机制。
- 使用范围-based for 循环遍历元素
std::cout << "v elements (range-based): ";
for (int num : v) {
std::cout << num << " ";
}
std::cout << std::endl;
- 含义:使用范围-based for 循环遍历
vector
容器中的元素。 - 执行过程:对于容器
v
中的每个元素,将其值赋给num
,然后输出到控制台。
- 总结
这段代码展示了如何使用向量容器(vector
)存储整数元素,并演示了如何通过索引、at()
方法、迭代器和范围-based for 循环访问和遍历向量的元素。
4. std::vector
的其他常用操作
下面是对你提供的 C++ 代码逐行解释,并附上每一行的输出结果:
#include <iostream> // 包含输入输出流库
#include <vector> // 包含向量库
int main() {
std::vector<int> v = {1, 2, 3, 4, 5}; // 创建一个整数向量 v,初始值为 1, 2, 3, 4, 5
// 获取 vector 的大小
std::cout << "Size of v: " << v.size() << std::endl;
// 输出结果: Size of v: 5
// 解释: v.size() 返回向量 v 的当前大小,即其中元素的个数。此时,v 包含 5 个元素。
// 获取 vector 的容量
std::cout << "Capacity of v: " << v.capacity() << std::endl;
// 输出结果: Capacity of v: 5
// 解释: v.capacity() 返回向量 v 的当前容量,即 v 能够容纳的元素的最大个数而不需要重新分配内存。初始时,它的容量等于大小。
// 重新调整 vector 的大小
v.resize(7, 100); // 将 vector 调整为 7 个元素,新增的元素初始化为 100
// 清空 vector
v.clear(); // 清空 v 中的所有元素
std::cout << "Size of v after clear: " << v.size() << std::endl;
// 输出结果: Size of v after clear: 0
// 解释: v.clear() 会移除向量中的所有元素,v.size() 返回清空后的大小,即 0。
return 0;
}
逐行解释
-
#include <iostream>
- 含义: 包含输入输出流库,以便使用
std::cout
和std::endl
- 含义: 包含输入输出流库,以便使用
-
#include <vector>
- 含义: 包含
std::vector
类的定义,以便使用std::vector
容器。 - 效果: 使得程序可以使用
std::vector
类型来管理动态数组。
- 含义: 包含
-
int main()
- 含义:
main
函数是程序的入口点。所有 C++ 程序都从main
函数开始执行。 - 效果: 程序从这里开始运行。
- 含义:
-
std::vector<int> v = {1, 2, 3, 4, 5};
- 含义: 创建一个
std::vector<int>
类型的变量v
,并初始化为{1, 2, 3, 4, 5}
。 - 效果:
v
是一个包含 5 个整数的向量,元素依次是 1, 2, 3, 4, 5。
- 含义: 创建一个
-
std::cout << "Size of v: " << v.size() << std::endl;
- 含义: 输出向量
v
的大小。v.size()
返回向量的元素个数。 - 输出结果:
Size of v: 5
- 解释: 向量
v
目前包含 5 个元素,所以大小为 5。
- 含义: 输出向量
-
std::cout << "Capacity of v: " << v.capacity() << std::endl;
- 含义: 输出向量
v
的容量。v.capacity()
返回向量可以容纳的最大元素个数而不需要重新分配内存 - 输出结果:
Capacity of v: 5
- 解释: 向量的初始容量与其大小相等,即 5。容量可能会根据实现和分配策略有所不同,但在这里,大小和容量相同。
- 含义: 输出向量
-
v.resize(7, 100);
- 含义: 调整向量
v
的大小为 7。如果新的大小大于当前大小,则用100
初始化新增的元素。 - 效果: 向量
v
的大小变为 7,原有的元素保持不变,新增的元素值为 100。 - 解释: 向量的内容变为
{1, 2, 3, 4, 5, 100, 100}
。
- 含义: 调整向量
-
v.clear();
- 含义: 清空向量
v
中的所有元素。 - 效果: 向量
v
的所有元素被移除,大小变为 0。 - 解释: 向量被清空,所有元素都被删除,但容量 (
capacity
) 可能不变。
- 含义: 清空向量
-
std::cout << "Size of v after clear: " << v.size() << std::endl;
- 含义: 输出向量
v
在清空后的大小。 - 输出结果:
Size of v after clear: 0
- 解释: 清空后,向量
v
不再包含任何元素,所以大小为 0。
- 含义: 输出向量
总结
v.size()
: 返回向量的当前大小,即元素个数。v.capacity()
: 返回向量的容量,即能容纳的最大元素个数而无需重新分配内存。v.resize(new_size, value)
: 调整向量的大小至new_size
。如果新大小大于当前大小,新增元素会初始化为value
。v.clear()
: 移除向量中的所有元素,清空向量,但容量可能保持不变。