简介
-
标准库相关笔记
C++ std::vector和C风格数据互相转换
在C++中,std::vector
是一个动态数组,而C风格的数据通常是指使用指针和数组来管理数据。在实际开发中,有时需要在 std::vector
和 C 风格数组之间进行互相转换。下面是具体的转换方式:
1. 从 C 风格数组转换为 std::vector
假设有一个C风格的数组:
1
int c_array[] = {1, 2, 3, 4, 5};
要将它转换为 std::vector
:
1
2
3
#include <vector>
std::vector<int> vec(std::begin(c_array), std::end(c_array));
说明:
- 使用
std::begin()
和std::end()
来获取数组的首尾指针(或使用&c_array[0]
和&c_array[size]
)。 - 如果知道数组的长度,你可以直接指定长度:
1 2
int size = 5; std::vector<int> vec(c_array, c_array + size);
2. 从 std::vector
转换为 C 风格数组
假设有一个 std::vector
:
1
std::vector<int> vec = {1, 2, 3, 4, 5};
要将其转换为 C 风格的数组,你可以获取 vector
的内部数据指针:
1
int* c_array = vec.data();
说明:
vec.data()
返回一个指向std::vector
内部存储数据的指针,该数据是连续的,与C风格数组类似。- 注意:不要手动释放这个指针,因为它是由
std::vector
管理的。
3. 完整示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <vector>
int main() {
// 从C风格数组转换为std::vector
int c_array[] = {1, 2, 3, 4, 5};
std::vector<int> vec(std::begin(c_array), std::end(c_array));
// 输出std::vector的内容
std::cout << "Vector: ";
for (const auto& elem : vec) {
std::cout << elem << " ";
}
std::cout << std::endl;
// 从std::vector转换为C风格数组
int* c_array_from_vec = vec.data();
// 输出C风格数组的内容
std::cout << "C array: ";
for (size_t i = 0; i < vec.size(); ++i) {
std::cout << c_array_from_vec[i] << " ";
}
std::cout << std::endl;
return 0;
}
注意事项
- 当从
std::vector
获取到 C 风格的指针时,不要手动释放内存,因为std::vector
会自动管理其内存。 - 从 C 风格数组转换为
std::vector
时,尽量使用std::begin()
和std::end()
来避免出错。
通过这些方法,你可以轻松地在C++的 std::vector
和C风格数据之间进行转换。
vector 内存分配方案
- vector会自动分配内存来保存插入的元素。vector要求必须放在连续的内存中。由于不可能请求在当前的内存块的尾部添加内存,因此每次vector申请更多内存时,都一定要在另一个位置分配一块新的,更大的内存块,然后将所有元素复制/移动到新的内存块。
- 这个过程非常耗时,因此vector的实现在执行重分配时,会分配此次所需内存更多的内存,以尽量避免这个复制转移的过程。通过这种方式,vector可避免在每次插入元素时都重新重新分配内存。
C++ 标准库是什么
<vector>
是 C++ 标准库提供的头文件之一,用于包含 C++ 标准库中的向量(vector
)容器类的定义。向量是一个动态数组,它能够以连续的内存空间存储元素,并提供了灵活的大小调整和高效的随机访问。
std::vector
是一个模板类,可以存储任意类型的元素,并具有以下特性:
- 动态大小: 向量可以根据需要动态增长或缩小其大小,可以通过
push_back
、pop_back
等方法在尾部添加或删除元素。 - 随机访问: 支持通过索引快速访问和修改元素,时间复杂度为 O(1)。
- 连续内存存储: 向量的元素在内存中是连续存储的,这有助于提高数据的访问速度。
- 尾部插入和删除的高效性: 在尾部插入或删除元素的操作通常是高效的,时间复杂度为平摊 O(1)。
以下是一个简单的示例,演示了如何使用 <vector>
头文件中的 std::vector
类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <vector>
int main() {
// 创建一个整数向量
std::vector<int> vec = {1, 2, 3, 4, 5};
// 在向量尾部添加元素
vec.push_back(6);
// 遍历输出向量中的元素
std::cout << "Vector Elements: ";
for (int num : vec) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
<vector>
头文件中的 std::vector
类是 C++ 中常用的标准容器之一,它提供了方便的动态数组功能,并且在许多情况下都是一种方便且高效的数据结构选择。
C++ 标准库 详解
<vector>
是 C++ 标准库提供的头文件之一,包含了 std::vector
类的定义,这是 C++ 中最常用的容器之一。
std::vector
类
std::vector
是一个动态数组,它能够存储一系列同类型的元素,并且可以动态地调整其大小。以下是 std::vector
类的一些重要特性和函数:
-
动态大小: 向量的大小可以根据需要动态增长或缩小。通过
push_back()
在尾部添加元素、pop_back()
删除尾部元素,或者直接使用resize()
调整大小。 -
随机访问: 可以通过索引快速访问和修改向量中的元素,支持使用
operator[]
实现随机访问。 -
连续内存存储: 向量中的元素在内存中是连续存储的,因此支持高效的随机访问,并且迭代器可用于遍历元素。
-
内存管理: 向量会自动处理内存的分配和释放,使得在尾部插入或删除元素的操作通常是高效的。
-
元素访问: 提供了
at()
方法和operator[]
,front()
和back()
方法用于访问首尾元素。 -
迭代器支持: 支持使用迭代器进行遍历,如
begin()
和end()
返回的迭代器用于遍历容器元素。 -
其他方法: 包括
empty()
、size()
、clear()
、erase()
等方法用于检查空、获取大小、清空内容和删除元素等。
下面是一个简单示例,展示了如何使用 <vector>
中的 std::vector
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <vector>
int main() {
// 创建一个整数向量并初始化
std::vector<int> vec = {1, 2, 3, 4, 5};
// 在向量尾部添加元素
vec.push_back(6);
// 使用迭代器遍历输出向量中的元素
std::cout << "Vector Elements: ";
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
return 0;
}
<vector>
头文件提供了 std::vector
类,它是一个常用的容器,能够满足动态数组的需求,支持高效的元素访问、插入和删除操作,是 C++ 中非常实用的数据结构之一。
C++ 标准库中 std::vector模板类详解
std::vector
是 C++ 标准库提供的动态数组容器,属于序列容器的一种。它以连续的内存空间存储元素,并支持动态增长和收缩。以下是 std::vector
的一些重要特性和使用方法:
特性:
-
动态大小:
std::vector
允许在运行时根据需要动态地增加或减少其大小。通过push_back()
在尾部添加元素,pop_back()
删除尾部元素,或者直接使用resize()
调整大小。 -
随机访问: 可以通过索引快速访问和修改向量中的元素。支持使用
operator[]
实现随机访问,其时间复杂度为 O(1)。 -
连续内存存储: 向量的元素在内存中是连续存储的,这有助于提高数据的访问速度,并且迭代器可用于遍历元素。
-
尾部插入和删除的高效性: 在尾部插入或删除元素的操作通常是高效的,时间复杂度为平摊 O(1)。
-
迭代器支持: 提供了迭代器,如
begin()
和end()
返回的迭代器用于遍历容器元素。 -
元素访问: 可以使用
at()
方法、operator[]
、front()
和back()
方法来访问元素。 -
其他方法: 包括
empty()
、size()
、clear()
、erase()
等方法,用于检查空、获取大小、清空内容和删除元素等。
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <vector>
int main() {
// 创建一个整数向量并初始化
std::vector<int> vec = {1, 2, 3, 4, 5};
// 在向量尾部添加元素
vec.push_back(6);
// 使用迭代器遍历输出向量中的元素
std::cout << "Vector Elements: ";
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
return 0;
}
以上代码演示了 std::vector
的一些常见操作,包括初始化、在尾部添加元素、迭代器遍历输出元素等。std::vector
是 C++ 标准库中常用的容器之一,提供了便捷且高效的动态数组功能。
C++ 标准库中 std::vector模板类所有成员函数
std::vector
类是 C++ 标准库中的动态数组容器,提供了许多成员函数用于管理其内部的元素。以下是 std::vector
类的一些主要成员函数:
容量相关操作:
size()
: 返回向量中元素的个数。capacity()
: 返回当前向量的容量(即分配的内存大小)。empty()
: 检查向量是否为空。reserve(size_type new_cap)
: 尝试预分配足够的内存以存储指定数量的元素。
访问元素操作:
operator[]
: 通过索引访问向量中的元素。at(size_type pos)
: 通过索引访问向量中的元素,提供了边界检查。front()
: 返回向量中第一个元素的引用。back()
: 返回向量中最后一个元素的引用。data()
: 返回指向向量内部数组的指针。
修改容器内容操作:
push_back(const T& value)
: 在向量尾部添加一个元素。pop_back()
: 删除向量中最后一个元素。insert(iterator pos, const T& value)
: 在指定位置插入一个元素。erase(iterator pos)
: 删除指定位置的元素。clear()
: 删除向量中的所有元素。
其他操作:
swap(vector& other)
: 交换两个向量的内容。assign(count, value)
: 用新值替换向量的内容。resize(size_type new_size)
: 改变向量的大小。shrink_to_fit()
: 要求释放多余的容量。
此外,std::vector
还具有迭代器相关的成员函数,如 begin()
、end()
用于迭代访问容器的元素。以上列出的成员函数并非全部,但是是 std::vector
常用的一些成员函数,能够对向量的大小、容量、元素访问和修改等进行有效管理。
C++ std::vector::swap() 函数 详解
std::vector::swap()
是 C++ 标准库中 std::vector
类的成员函数,用于交换两个 vector 的内容,即交换它们所包含的元素。
函数签名:
1
void swap(std::vector& x);
参数:
x
:另一个std::vector
对象,其内容将与调用该函数的 vector 对象进行交换。
功能:
std::vector::swap()
函数用于交换两个 vector 对象的元素内容,使得调用该函数的 vector 与参数x
所包含的元素互换。
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec1 = {1, 2, 3};
std::vector<int> vec2 = {4, 5, 6};
std::cout << "Vector 1: ";
for (int num : vec1) {
std::cout << num << " ";
}
std::cout << std::endl;
std::cout << "Vector 2: ";
for (int num : vec2) {
std::cout << num << " ";
}
std::cout << std::endl;
vec1.swap(vec2); // 交换两个 vector 的内容
std::cout << "\nAfter Swap:" << std::endl;
std::cout << "Vector 1: ";
for (int num : vec1) {
std::cout << num << " ";
}
std::cout << std::endl;
std::cout << "Vector 2: ";
for (int num : vec2) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
注意事项:
std::vector::swap()
函数非常高效,因为它只是交换了两个 vector 内部的数据结构指针,而不是复制每个元素。- 交换后,两个 vector 对象的大小和容量可能会发生变化,但其所包含的元素会完全交换。
- 该函数是
std::vector
类的成员函数,所以需要使用一个已经存在的 vector 对象来调用该函数。
std::vector::swap()
是一个很有用的函数,特别是在需要交换两个 vector 的元素内容时,可以避免进行元素的逐个复制。
std::vector::size()
std::vector::size()
是 C++ 标准库中 std::vector
类的一个成员函数,用于返回 std::vector
容器中当前存储元素的数量(大小)。
在 C++ 中,std::vector
是一个动态数组,它能够自动调整大小,可以根据需要动态地增加或减少存储在其中的元素数量。size()
函数返回的是当前 std::vector
中的元素数量,即容器中元素的个数。
下面是一个简单的示例演示了如何使用 std::vector::size()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <vector>
int main() {
// 创建一个空的 std::vector 容器
std::vector<int> vec;
// 向容器中添加一些元素
vec.push_back(10);
vec.push_back(20);
vec.push_back(30);
// 获取容器中元素的数量(大小)
std::cout << "Vector的大小为:" << vec.size() << std::endl;
return 0;
}
在这个示例中:
- 创建了一个空的
std::vector<int>
容器vec
。 - 使用
push_back
方法向容器中添加了三个整数元素。 - 通过
vec.size()
获取了vec
容器中元素的数量,并将结果打印出来。
std::vector::size()
对于获取 std::vector
中元素数量非常方便,它可以帮助你确定容器中元素的个数,从而进行后续的操作或逻辑处理。
std::vector::capacity()
std::vector::capacity()
是 C++ 标准库中 std::vector
类的一个成员函数,用于返回当前 std::vector
容器的容量大小。
在 C++ 中,std::vector
是一个动态数组,它能够自动调整大小,可以根据需要动态地增加或减少存储在其中的元素数量。capacity()
函数返回的是当前 std::vector
内部所分配内存空间的大小,即该容器在不分配新的内存的情况下能够容纳的元素数量。
下面是一个简单的示例演示了如何使用 std::vector::capacity()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <vector>
int main() {
// 创建一个空的 std::vector 容器
std::vector<int> vec;
// 向容器中添加一些元素
for (int i = 0; i < 10; ++i) {
vec.push_back(i);
std::cout << "Size: " << vec.size() << " Capacity: " << vec.capacity() << std::endl;
}
return 0;
}
在这个示例中:
- 创建了一个空的
std::vector<int>
容器vec
。 - 使用
push_back
方法向容器中循环添加了十个整数元素,并在每次添加后打印了当前容器的大小和容量。
std::vector::capacity()
是一个重要的函数,它可以用来观察 std::vector
容器当前的内存分配情况。当 std::vector
中的元素数量超过当前分配的容量时,std::vector
会自动重新分配更大的内存空间以容纳更多的元素,这个过程可能会导致容器大小和容量之间的不同步。
std::vector::empty()
std::vector::empty()
是 C++ 标准库中 std::vector
类的一个成员函数,用于检查 std::vector
容器是否为空。
当 std::vector
容器中不含有任何元素时,即容器的大小为零时,empty()
函数将返回 true
;否则,如果容器中包含至少一个元素,则返回 false
。
以下是一个简单的示例演示了如何使用 std::vector::empty()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <vector>
int main() {
// 创建一个空的 std::vector 容器
std::vector<int> vec;
// 检查容器是否为空
if (vec.empty()) {
std::cout << "容器为空" << std::endl;
} else {
std::cout << "容器不为空" << std::endl;
}
// 向容器中添加一个元素
vec.push_back(10);
// 再次检查容器是否为空
if (vec.empty()) {
std::cout << "容器为空" << std::endl;
} else {
std::cout << "容器不为空" << std::endl;
}
return 0;
}
在这个示例中:
- 创建了一个空的
std::vector<int>
容器vec
。 - 使用
vec.empty()
检查容器是否为空,并根据返回结果打印相应的消息。 - 使用
push_back
方法向容器中添加了一个整数元素。 - 再次使用
vec.empty()
检查容器是否为空,并根据返回结果打印相应的消息。
std::vector::empty()
是一个简单而常用的函数,用于确定 std::vector
容器是否为空,可以在需要检查容器是否含有元素时使用。
std::vector::reserve()
std::vector::reserve()
是 C++ 标准库中 std::vector
类的一个成员函数,用于预留 std::vector
容器的存储空间,但不会改变容器中元素的数量。
当你预先知道 std::vector
将要存储大量元素时,可以使用 reserve()
函数来预留足够的内存空间,避免多次重新分配内存,从而提高程序的性能。
以下是一个简单的示例演示了如何使用 std::vector::reserve()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <vector>
int main() {
// 创建一个空的 std::vector 容器
std::vector<int> vec;
// 打印容器当前的大小和容量
std::cout << "当前大小: " << vec.size() << " 当前容量: " << vec.capacity() << std::endl;
// 预留容器存储空间为 10 个元素
vec.reserve(10);
// 打印预留后的容器当前的大小和容量
std::cout << "预留后大小: " << vec.size() << " 预留后容量: " << vec.capacity() << std::endl;
return 0;
}
在这个示例中:
- 创建了一个空的
std::vector<int>
容器vec
。 - 使用
vec.reserve(10)
预留了容器的存储空间为 10 个元素。 - 打印了预留前后容器的大小和容量。
需要注意的是,reserve()
函数只是预留了足够的存储空间,并没有改变容器的实际大小,容器的大小仍然是 0。容器的大小由实际插入的元素个数决定,而容器的容量则是实际分配的内存大小,reserve()
仅仅是为容器预留了更多的内存空间,以备将来的使用。
这个函数通常在你已经知道将要存储大量元素的情况下使用,以减少因重新分配内存而引起的开销。
std::vector::at()
std::vector::at()
是 C++ 标准库中 std::vector
类的一个成员函数,用于访问 std::vector
容器中指定位置的元素,并提供了边界检查。
与 operator[]
不同,at()
函数在访问容器元素时提供了边界检查,如果指定的位置超出了容器的范围,则会抛出 std::out_of_range
异常。
以下是一个简单的示例演示了如何使用 std::vector::at()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <vector>
#include <stdexcept>
int main() {
// 创建一个 std::vector 容器,并向其中添加一些元素
std::vector<int> vec = {10, 20, 30, 40, 50};
try {
// 使用 at() 访问容器中的元素
std::cout << "元素 at(2): " << vec.at(2) << std::endl; // 访问索引为 2 的元素
std::cout << "元素 at(5): " << vec.at(5) << std::endl; // 尝试访问超出范围的索引
}
catch (const std::out_of_range& ex) {
std::cout << "发生异常: " << ex.what() << std::endl; // 捕获并打印 out_of_range 异常信息
}
return 0;
}
在这个示例中:
- 创建了一个
std::vector<int>
容器vec
,并初始化了一些整数元素。 - 使用
vec.at(2)
获取了索引为 2 的元素值,并正常打印出来。 - 然后尝试使用
vec.at(5)
访问超出容器范围的索引,这会导致std::out_of_range
异常被抛出,并被catch
语句捕获并处理。
总的来说,std::vector::at()
是一个安全的访问元素的方法,可以在需要对访问进行边界检查的情况下使用,以防止意外访问超出容器范围的索引位置。
std::vector::front()
std::vector::front()
是 C++ 标准库中 std::vector
类的一个成员函数,用于返回 std::vector
容器中第一个元素的引用。
它提供了对 std::vector
容器中第一个元素的访问,类似于数组的第一个元素。如果 std::vector
容器为空,则调用 front()
函数将会导致未定义行为。
以下是一个简单的示例演示了如何使用 std::vector::front()
:
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <vector>
int main() {
// 创建一个 std::vector 容器,并向其中添加一些元素
std::vector<int> vec = {10, 20, 30, 40, 50};
// 访问容器中的第一个元素
std::cout << "第一个元素是: " << vec.front() << std::endl;
return 0;
}
在这个示例中:
- 创建了一个
std::vector<int>
容器vec
,并初始化了一些整数元素。 - 使用
vec.front()
获取了容器中的第一个元素值,并将其打印出来。
需要注意的是,调用 std::vector::front()
函数时,应确保 std::vector
容器不为空,否则在空容器上调用 front()
将导致未定义行为。因此,在调用 front()
函数之前,最好先检查 std::vector
是否包含元素,可以通过 empty()
函数进行检查。
std::vector::back()
std::vector::back()
是 C++ 标准库中 std::vector
类的一个成员函数,用于返回 std::vector
容器中最后一个元素的引用。
它提供了对 std::vector
容器中最后一个元素的访问。如果 std::vector
容器为空,则调用 back()
函数将会导致未定义行为。
以下是一个简单的示例演示了如何使用 std::vector::back()
:
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <vector>
int main() {
// 创建一个 std::vector 容器,并向其中添加一些元素
std::vector<int> vec = {10, 20, 30, 40, 50};
// 访问容器中的最后一个元素
std::cout << "最后一个元素是: " << vec.back() << std::endl;
return 0;
}
在这个示例中:
- 创建了一个
std::vector<int>
容器vec
,并初始化了一些整数元素。 - 使用
vec.back()
获取了容器中的最后一个元素值,并将其打印出来。
需要注意的是,调用 std::vector::back()
函数时,应确保 std::vector
容器不为空,否则在空容器上调用 back()
将导致未定义行为。因此,在调用 back()
函数之前,最好先检查 std::vector
是否包含元素,可以通过 empty()
函数进行检查。
std::vector::data()
std::vector::data()
是 C++ 标准库中 std::vector
类的一个成员函数,用于返回指向 std::vector
容器内部存储元素的指针。
这个函数返回一个指向 std::vector
内部数据存储区的指针,该指针可以用于直接访问容器中的元素。如果 std::vector
容器为空,则返回的指针可能为空指针。
以下是一个简单的示例演示了如何使用 std::vector::data()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <vector>
int main() {
// 创建一个 std::vector 容器,并向其中添加一些元素
std::vector<int> vec = {10, 20, 30, 40, 50};
// 获取指向容器数据的指针
int* ptr = vec.data();
// 打印指针指向的元素
std::cout << "第一个元素是: " << *ptr << std::endl;
return 0;
}
在这个示例中:
- 创建了一个
std::vector<int>
容器vec
,并初始化了一些整数元素。 - 使用
vec.data()
获取了指向容器数据存储区的指针,并将其赋值给ptr
。 - 打印了指针所指向的第一个元素的值。
需要注意的是,std::vector::data()
返回的指针可以用于直接访问容器中的元素,但在修改容器中的元素时应格外小心,确保不会越界或者引起其它未定义的行为。此外,如果 std::vector
容器为空,则返回的指针可能为 nullptr
。
std::vector::push_back()
std::vector::push_back()
是 C++ 标准库中 std::vector
类的一个成员函数,用于在 std::vector
容器的末尾添加一个新的元素。
这个函数将新的元素添加到 std::vector
容器的末尾,并使容器的大小增加 1。如果 std::vector
的容量不足以容纳新元素,则会自动重新分配更大的内存空间以适应新的元素。
以下是一个简单的示例演示了如何使用 std::vector::push_back()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <vector>
int main() {
// 创建一个空的 std::vector 容器
std::vector<int> vec;
// 向容器中添加一些元素
vec.push_back(10);
vec.push_back(20);
vec.push_back(30);
// 打印容器中的元素
std::cout << "容器中的元素: ";
for (const auto& element : vec) {
std::cout << element << " ";
}
std::cout << std::endl;
return 0;
}
在这个示例中:
- 创建了一个空的
std::vector<int>
容器vec
。 - 使用
push_back()
方法向容器中分别添加了三个整数元素。 - 使用循环遍历容器中的元素,并将它们打印出来。
std::vector::push_back()
是一个常用的函数,用于向 std::vector
容器的末尾添加新的元素,非常方便实用。
std::vector::pop_back()
std::vector::pop_back()
是 C++ 标准库中 std::vector
类的一个成员函数,用于移除 std::vector
容器中的最后一个元素。
该函数会将 std::vector
容器中最后一个元素移除,并且减少容器的大小(size)1。如果 std::vector
容器为空,则调用 pop_back()
函数将导致未定义行为。
以下是一个简单的示例演示了如何使用 std::vector::pop_back()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <vector>
int main() {
// 创建一个 std::vector 容器,并向其中添加一些元素
std::vector<int> vec = {10, 20, 30, 40, 50};
// 移除容器中的最后一个元素
vec.pop_back();
// 打印容器中的元素
std::cout << "移除后的容器中的元素: ";
for (const auto& element : vec) {
std::cout << element << " ";
}
std::cout << std::endl;
return 0;
}
在这个示例中:
- 创建了一个
std::vector<int>
容器vec
,并初始化了一些整数元素。 - 使用
vec.pop_back()
移除了容器中的最后一个元素。 - 使用循环遍历容器中的元素,并将它们打印出来。
需要注意的是,调用 std::vector::pop_back()
之前最好检查容器是否为空,以避免在空容器上调用该函数而导致的未定义行为。这个函数通常用于从 std::vector
容器的末尾删除元素,可以方便地实现栈(stack)等数据结构的功能。
std::vector::insert()
std::vector::insert()
是 C++ 标准库中 std::vector
类的一个成员函数,用于在指定位置插入一个或多个元素到 std::vector
容器中。
这个函数允许在指定位置插入一个元素或一组元素。插入操作可能会导致所有在指定位置之后的元素被移动,因为 std::vector
是一个连续存储的容器。
下面是 std::vector::insert()
函数的基本语法:
1
2
3
iterator insert (iterator position, const T& val); // 在 position 位置插入 val
iterator insert (iterator position, size_type n, const T& val); // 在 position 位置插入 n 个 val
iterator insert (iterator position, InputIterator first, InputIterator last); // 在 position 位置插入区间 [first, last) 内的元素
这里的 position
参数是一个迭代器,指示了插入元素的位置。val
是要插入的元素值,n
是要插入的元素数量,first
和 last
是表示要插入的元素范围的迭代器。
以下是一个简单的示例演示了如何使用 std::vector::insert()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <vector>
int main() {
// 创建一个 std::vector 容器,并向其中添加一些元素
std::vector<int> vec = {10, 20, 30};
// 在容器的第二个位置插入一个元素 25
auto it = vec.insert(vec.begin() + 1, 25);
// 在容器的末尾插入两个元素,值分别为 40 和 50
vec.insert(vec.end(), {40, 50});
// 打印容器中的元素
std::cout << "容器中的元素: ";
for (const auto& element : vec) {
std::cout << element << " ";
}
std::cout << std::endl;
return 0;
}
在这个示例中:
- 创建了一个
std::vector<int>
容器vec
,并初始化了一些整数元素。 - 使用
vec.insert(vec.begin() + 1, 25)
在容器的第二个位置插入了一个值为 25 的元素。 - 使用
vec.insert(vec.end(), {40, 50})
在容器的末尾插入了两个值为 40 和 50 的元素。 - 使用循环遍历容器中的元素,并将它们打印出来。
std::vector::insert()
函数允许在 std::vector
容器的指定位置插入一个或多个元素,提供了灵活且方便的插入操作。
std::vector::erase()
std::vector::erase()
是 C++ 标准库中 std::vector
类的一个成员函数,用于从 std::vector
容器中移除一个或一段元素。
这个函数有多种用法,它可以删除单个元素,也可以删除一个范围内的元素。删除操作可能会导致被移除元素后面的元素向前移动,因为 std::vector
是一个连续存储的容器。
下面是 std::vector::erase()
函数的基本语法:
1
2
iterator erase (iterator position); // 移除指定位置的元素
iterator erase (iterator first, iterator last); // 移除位于 [first, last) 区间的元素
这里的 position
是要移除的元素的位置的迭代器,first
和 last
表示一个范围,用来移除这个范围内的所有元素。
以下是一个简单的示例演示了如何使用 std::vector::erase()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <vector>
int main() {
// 创建一个 std::vector 容器,并向其中添加一些元素
std::vector<int> vec = {10, 20, 30, 40, 50};
// 移除容器中的第二个元素
vec.erase(vec.begin() + 1);
// 移除容器中的第三个到第四个元素(迭代器范围 [vec.begin() + 2, vec.begin() + 4))
vec.erase(vec.begin() + 2, vec.begin() + 4);
// 打印容器中的元素
std::cout << "容器中的元素: ";
for (const auto& element : vec) {
std::cout << element << " ";
}
std::cout << std::endl;
return 0;
}
在这个示例中:
- 创建了一个
std::vector<int>
容器vec
,并初始化了一些整数元素。 - 使用
vec.erase(vec.begin() + 1)
移除了容器中的第二个元素。 - 使用
vec.erase(vec.begin() + 2, vec.begin() + 4)
移除了容器中的第三个到第四个元素。 - 使用循环遍历容器中的元素,并将它们打印出来。
std::vector::erase()
函数允许从 std::vector
容器中移除指定位置或指定范围内的元素,提供了便捷的删除操作。
std::vector::clear()
std::vector::clear()
是 C++ 标准库中 std::vector
类的一个成员函数,用于清空 std::vector
容器中的所有元素。
当调用 clear()
函数时,std::vector
容器的大小变为零,即移除了容器中的所有元素。容器的内存空间不会被释放,但容器中的元素数量将变为零,即容器会变为空。
以下是一个简单的示例演示了如何使用 std::vector::clear()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <vector>
int main() {
// 创建一个 std::vector 容器,并向其中添加一些元素
std::vector<int> vec = {10, 20, 30, 40, 50};
// 打印清空前容器中的元素数量
std::cout << "清空前容器的大小: " << vec.size() << std::endl;
// 清空容器
vec.clear();
// 打印清空后容器中的元素数量
std::cout << "清空后容器的大小: " << vec.size() << std::endl;
return 0;
}
在这个示例中:
- 创建了一个
std::vector<int>
容器vec
,并初始化了一些整数元素。 - 使用
vec.size()
打印了清空前容器中的元素数量。 - 使用
vec.clear()
清空了容器中的所有元素。 - 再次使用
vec.size()
打印了清空后容器中的元素数量,这时应该为 0。
std::vector::clear()
函数是一种快速清空 std::vector
容器中的元素的方法,但并不释放容器的内存空间,仅将容器的大小设置为零,使得容器变为空。
std::vector::swap()
std::vector::swap()
是 C++ 标准库中 std::vector
类的一个成员函数,用于交换两个 std::vector
容器的内容。
这个函数接受另一个 std::vector
容器作为参数,并将调用它的容器和传入的容器进行内容交换。交换操作将使得两个容器中的元素互相交换,但它们的内存空间不会发生改变。
以下是 std::vector::swap()
函数的基本用法:
1
void swap(vector& other);
这里的 other
是另一个 std::vector
容器,它的内容将与调用函数的容器进行交换。
以下是一个简单的示例演示了如何使用 std::vector::swap()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <vector>
int main() {
// 创建两个 std::vector 容器,并分别向其中添加一些元素
std::vector<int> vec1 = {1, 2, 3};
std::vector<int> vec2 = {4, 5, 6};
// 打印交换前两个容器中的元素
std::cout << "交换前 vec1 中的元素: ";
for (const auto& element : vec1) {
std::cout << element << " ";
}
std::cout << std::endl;
std::cout << "交换前 vec2 中的元素: ";
for (const auto& element : vec2) {
std::cout << element << " ";
}
std::cout << std::endl;
// 使用 swap() 函数交换两个容器的内容
vec1.swap(vec2);
// 打印交换后两个容器中的元素
std::cout << "交换后 vec1 中的元素: ";
for (const auto& element : vec1) {
std::cout << element << " ";
}
std::cout << std::endl;
std::cout << "交换后 vec2 中的元素: ";
for (const auto& element : vec2) {
std::cout << element << " ";
}
std::cout << std::endl;
return 0;
}
在这个示例中:
- 创建了两个
std::vector<int>
容器vec1
和vec2
,并初始化了一些整数元素。 - 使用
vec1.swap(vec2)
对两个容器的内容进行了交换。 - 分别打印了交换前后两个容器中的元素。
std::vector::swap()
函数提供了一种快速交换两个 std::vector
容器内容的方法,不需要复制元素,只需交换指针。这对于需要在两个容器间交换数据时非常有用。
std::vector::assign()
std::vector::assign()
是 C++ 标准库中 std::vector
类的一个成员函数,用于重新分配 std::vector
容器的内容。
这个函数可以使用多种方式重新设置 std::vector
容器的内容:可以用新值替换已有的内容,也可以设置容器中的元素数量,或者使用一个范围内的值替换容器中的元素。
以下是 std::vector::assign()
函数的不同形式及其基本用法:
1
2
3
4
void assign(size_type count, const T& value); // 设置容器中元素的数量为 count,并用 value 值替换所有元素 (1)
template <class InputIterator>
void assign(InputIterator first, InputIterator last); // 使用区间 [first, last) 内的元素替换容器的内容 (2)
void assign(std::initializer_list<T> il); // 使用初始化列表 il 内的元素替换容器的内容 (3)
- 参数
- count - 容器的新大小
- value - 用以初始化容器元素的值
- first, last - 复制来源元素的范围
- ilist - 复制值来源的initializer_list
- 复杂度
- 1 与count呈线性
- 2 与first和last间的距离呈线性
- 3 与il.size()呈线性
这里的 count
表示新的元素数量,value
是要赋给新元素的值。first
和 last
是迭代器,表示一个范围,用来替换容器的内容。il
是一个初始化列表,用来替换容器的内容。
以下是一个简单的示例演示了如何使用 std::vector::assign()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <vector>
#include <iostream>
#include <string>
int main()
{
std::vector<char> characters;
auto print_list = [&]()
{
for (char c : characters)
std::cout << c << ' ';
std::cout << '\n';
};
characters.assign(5, 'a');
print_list();
const std::string extra(6, 'b');
characters.assign(extra.begin(), extra.end());
print_list();
characters.assign({'C', '+', '+', '1', '1'});
print_list();
}
在这个示例中:
- 创建了一个空的
std::vector<int>
容器vec
。 - 使用
vec.assign(5, 10)
设置容器中的元素数量为 5,并用值 10 替换了所有元素。 - 使用循环遍历容器中的元素,并将它们打印出来。
std::vector::assign()
函数提供了多种方式来重新设置 std::vector
容器的内容,使得容器可以被不同类型的数据重新填充。
std::vector::resize()
std::vector::resize()
是 C++ 标准库中 std::vector
类的一个成员函数,用于改变 std::vector
容器中的元素数量。
这个函数允许你改变 std::vector
容器中元素的数量。如果新的大小比当前大小大,将会增加元素数量并用默认构造函数的值初始化新的元素。如果新的大小比当前大小小,将会删除超出新大小的元素。
以下是 std::vector::resize()
函数的基本语法:
1
2
void resize(size_type count); // 设置容器中的元素数量为 count
void resize(size_type count, const value_type& value); // 设置容器中的元素数量为 count,并用 value 值初始化新元素
这里的 count
是指定的新的元素数量,value
是可选的值,用于初始化新添加的元素。
以下是一个简单的示例演示了如何使用 std::vector::resize()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <vector>
int main() {
// 创建一个空的 std::vector 容器
std::vector<int> vec;
// 使用 resize() 设置容器中的元素数量为 5
vec.resize(5);
// 打印容器中的元素
std::cout << "容器中的元素: ";
for (const auto& element : vec) {
std::cout << element << " ";
}
std::cout << std::endl;
// 使用 resize() 设置容器中的元素数量为 8,并用值 100 初始化新添加的元素
vec.resize(8, 100);
// 再次打印容器中的元素
std::cout << "调整大小后的容器中的元素: ";
for (const auto& element : vec) {
std::cout << element << " ";
}
std::cout << std::endl;
return 0;
}
在这个示例中:
- 创建了一个空的
std::vector<int>
容器vec
。 - 使用
vec.resize(5)
设置容器中的元素数量为 5,默认使用默认构造函数进行初始化。 - 使用
vec.resize(8, 100)
将容器中的元素数量增加到 8,并用值 100 初始化新添加的元素。 - 分别使用循环遍历容器中的元素,并将它们打印出来。
std::vector::resize()
函数允许你在运行时动态调整 std::vector
容器的大小,并可以选择性地使用特定的值初始化新添加的元素。
std::vector::shrink_to_fit()
std::vector::shrink_to_fit()
是 C++ 标准库中 std::vector
类的一个成员函数,用于要求 std::vector
容器减小其容量,使其容量和大小相匹配。
std::vector
容器会根据需要分配更多的内存空间以容纳新的元素。然而,当一些元素被删除后,std::vector
容器的实际大小可能小于其容量。shrink_to_fit()
函数就是用来释放容器多余的内存空间,将容器的容量减小到与其大小相匹配。
以下是 std::vector::shrink_to_fit()
函数的基本语法:
1
void shrink_to_fit();
这个函数没有参数,调用它将使 std::vector
容器的容量减小到和当前元素数量相匹配的大小。但并不保证一定会成功减小容器的容量,因为具体实现可能会有所不同。
以下是一个简单的示例演示了如何使用 std::vector::shrink_to_fit()
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <vector>
int main() {
// 创建一个 std::vector 容器,并向其中添加一些元素
std::vector<int> vec = {1, 2, 3, 4, 5};
// 移除容器中的最后两个元素
vec.pop_back();
vec.pop_back();
// 调用 shrink_to_fit() 函数将容器的容量减小到与其大小相匹配
vec.shrink_to_fit();
// 打印容器的大小和容量
std::cout << "容器的大小: " << vec.size() << std::endl;
std::cout << "容器的容量: " << vec.capacity() << std::endl;
return 0;
}
在这个示例中:
- 创建了一个
std::vector<int>
容器vec
,并初始化了一些整数元素。 - 使用
pop_back()
移除了容器中的最后两个元素。 - 使用
shrink_to_fit()
函数将容器的容量减小到与其大小相匹配。 - 使用
size()
和capacity()
分别打印了容器的大小和容量。
std::vector::shrink_to_fit()
函数提供了一种手段来释放 std::vector
容器内多余的内存空间,使得容器的实际容量与其大小相匹配。但并不保证一定会成功减小容器的容量,具体情况取决于实现。
std::vector::emplace_back() 函数 详解
std::vector::emplace_back()
是 C++ 中 std::vector
容器提供的一个函数,用于在容器的末尾直接构造元素,而不是先创建一个临时对象再进行拷贝或移动操作。这个函数允许你在容器中就地构造对象,从而避免额外的拷贝或移动开销。
以下是 std::vector::emplace_back()
的详细解释:
1
2
3
4
5
6
namespace std {
template <class... Args>
void emplace_back(Args&&... args);
} // namespace std
-
emplace_back
函数接受任意数量的参数,并将这些参数传递给容器中元素的构造函数,用于在容器的末尾直接构造一个新元素。 -
参数
Args&&... args
是一个可变参数模板,可以接受任意数量的参数。
使用 emplace_back
的典型用法是,直接在容器末尾构造一个元素,而不需要在代码中创建临时对象。这对于避免额外的拷贝或移动操作特别有用。
以下是一个简单的示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <vector>
struct MyClass {
int value;
MyClass(int v) : value(v) {
std::cout << "Constructing MyClass with value: " << value << std::endl;
}
};
int main() {
std::vector<MyClass> myVector;
// 使用 emplace_back 直接在容器末尾构造元素
myVector.emplace_back(42);
// 使用 emplace_back 可以避免额外的拷贝或移动操作
return 0;
}
在这个例子中,emplace_back
直接在 std::vector
的末尾构造了一个 MyClass
对象,而不需要先创建一个临时对象再进行拷贝操作。这样可以提高效率,特别是对于那些不支持移动语义的类。
C++ std::vector 拷贝构造函数 详解
在 C++ 中,std::vector
是一个动态数组,它提供了在运行时大小可以动态变化的数组容器。拷贝构造函数是一种特殊的构造函数,用于创建一个对象的副本。std::vector
的拷贝构造函数用于创建一个新的 std::vector
对象,其元素与另一个 std::vector
对象完全相同。
以下是 std::vector
的拷贝构造函数的详细解释:
1
2
// 默认构造函数
vector(const vector& other);
拷贝构造函数采用另一个 std::vector
对象作为参数,并创建一个新的 std::vector
对象,其中包含与参数相同的元素。这个构造函数通过复制另一个 std::vector
对象的所有元素来构造新的对象。
拷贝构造函数通常在以下情况下被调用:
- 用一个
std::vector
对象初始化另一个std::vector
对象。 - 作为函数参数传递
std::vector
对象。 - 从函数返回
std::vector
对象时。
下面是一个简单的示例,展示了如何使用拷贝构造函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <vector>
int main() {
// 创建一个原始的 std::vector 对象
std::vector<int> originalVector = {1, 2, 3, 4, 5};
// 使用拷贝构造函数创建一个新的 std::vector 对象
std::vector<int> copiedVector(originalVector);
// 输出新的 std::vector 对象的元素
for (int i : copiedVector) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
在上面的示例中,copiedVector
对象使用了原始向量 originalVector
的拷贝构造函数创建了一个副本。