文章目录
非更易型操作
empty()
在C++中,std::vector是一个动态数组类模板,它提供了许多有用的成员函数来操作数组。其中,empty()是一个成员函数,用于检查vector是否为空。
当vector中没有包含任何元素时,empty()函数将返回true。如果vector至少包含一个元素,则empty()将返回false。
下面是一个简单的示例,展示了如何使用empty()函数:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec1; // 创建一个空的vector
std::vector<int> vec2 = {1, 2, 3, 4, 5}; // 创建一个包含5个元素的vector
// 检查vec1是否为空
if (vec1.empty()) {
std::cout << "vec1 is empty." << std::endl;
} else {
std::cout << "vec1 is not empty." << std::endl;
}
// 检查vec2是否为空
if (vec2.empty()) {
std::cout << "vec2 is empty." << std::endl;
} else {
std::cout << "vec2 is not empty." << std::endl;
}
return 0;
}
在这个示例中,vec1是一个空的vector,所以vec1.empty()将返回true,并输出"vec1 is empty.“。而vec2包含5个元素,所以vec2.empty()将返回false,并输出"vec2 is not empty.”。
empty()函数是一个常量时间操作,这意味着无论vector的大小如何,检查其是否为空的速度都是很快的。
size()
在 C++ 中,std::vector 是一个动态数组,它提供了很多方法来操作数组元素和查询数组的属性。size() 是 std::vector 的一个成员函数,用于返回向量中当前元素的数量。
当你想要知道向量中有多少元素时,你可以使用 size() 函数。这个函数返回一个 std::size_t 类型的值,表示向量中存储的元素的数量。
下面是一个简单的例子,展示了如何使用 size() 函数:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec;
// 向向量中添加元素
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
// 使用 size() 函数获取向量中元素的数量
std::size_t size = vec.size();
// 输出向量的大小
std::cout << "Size of vector: " << size << std::endl;
return 0;
}
在这个例子中,我们创建了一个名为 vec 的 std::vector 对象,并向其中添加了三个整数。然后,我们使用 size() 函数来获取向量中元素的数量,并将结果存储在 size 变量中。最后,我们输出这个数量。
输出将会是:
Size of vector: 3
因为向量 vec 中有三个元素:1、2 和 3。
注意,size() 函数返回的是当前向量中实际存储的元素的数量,而不是向量的容量(capacity)。容量是向量在需要重新分配内存之前可以容纳的元素数量。你可以使用 capacity() 函数来获取向量的容量。
max_size()
在C++中,std::vector的max_size()成员函数返回的是vector容器在特定系统或编译器实现下可能包含的最大元素数量。这通常是一个非常大的值,通常受限于可用内存和系统架构。实际上,对于大多数应用来说,max_size()返回的值大到足以保证在程序的生命周期内不会达到这个限制。
max_size()并不保证是vector可以实际分配的内存量,而是表示在理论上vector可以容纳的最大元素数量。实际上,当vector的大小接近max_size()时,尝试添加更多元素可能会导致内存分配失败,即使还有足够的物理内存可用。
下面是一个使用max_size()的示例:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec;
// 获取vector可能包含的最大元素数量
std::size_t maxSize = vec.max_size();
std::cout << "Maximum possible size of the vector: " << maxSize << std::endl;
// 通常情况下,你不需要担心达到这个限制
// 因为这个值通常非常大,足以满足日常需求
return 0;
}
输出可能类似于:
Maximum possible size of the vector: 18446744073709551615
这个值取决于实现和平台,但通常是一个非常大的数,足以容纳数十亿到数十万亿个元素。在实际编程中,你很少需要关心max_size(),因为当vector的大小接近这个值时,通常意味着你的程序有更深层次的设计问题或者内存使用不当。
capacity()
在C++中,std::vector的capacity()成员函数返回向量当前分配的存储空间能够容纳的元素数量。这个容量是向量在不需要重新分配内存的情况下能够增长到的最大大小。
当你向vector中添加元素时,如果当前的容量不足以容纳新的元素,vector会自动重新分配内存,通常会增加其容量,以便能够容纳更多的元素。这个过程可能会导致额外的性能开销,因为重新分配内存涉及到复制现有元素到新的内存位置,并释放旧的内存。因此,了解vector的容量可以帮助你优化程序,避免不必要的内存重新分配。
capacity()函数返回的是一个size_t类型的值,表示当前分配的存储空间的大小。这个值至少等于vector的大小(可以通过size()函数获得),但通常更大,以便为未来的增长留出空间。
下面是一个使用capacity()函数的例子:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec;
// 输出初始容量
std::cout << "Initial capacity: " << vec.capacity() << std::endl;
// 向vector中添加元素
for (int i = 0; i < 10; ++i) {
vec.push_back(i);
}
// 输出添加元素后的容量
std::cout << "Capacity after adding 10 elements: " << vec.capacity() << std::endl;
// 预留更多的容量
vec.reserve(20);
// 输出预留容量后的容量
std::cout << "Capacity after reserving 20 elements: " << vec.capacity() << std::endl;
return 0;
}
输出可能是这样的:
Initial capacity: 0
Capacity after adding 10 elements: 10
Capacity after reserving 20 elements: 20
在这个例子中,初始时vector的容量是0,因为还没有分配任何内存。添加10个元素后,vector会自动分配足够的内存来容纳这些元素,容量至少为10。然后,我们通过调用reserve(20)来预留足够的空间来容纳20个元素,这可能会导致vector重新分配内存以增加其容量。
请注意,capacity()返回的是至少能够容纳的元素数量,而不是最大可能的数量。在某些实现中,vector可能会预留更多的空间以适应未来的增长,但这并不是C++标准所要求的。因此,不应依赖capacity()返回的具体值来编写依赖于特定实现的代码。
reserve(num)
在C++中,std::vector的reserve()成员函数用于预先分配一定数量的内存空间,以便向量能够容纳至少num个元素而不需要重新分配内存。这可以提高向量的性能,因为频繁的内存重新分配和元素复制会导致额外的开销。
当你预计将要向向量中添加大量元素时,使用reserve()函数可以一次性分配足够的内存空间,从而避免多次的内存分配和复制操作。
这里是如何使用reserve()函数的一个例子:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec;
// 预先分配内存,以便能够容纳至少1000个元素
vec.reserve(1000);
// 现在,向量有足够的空间来容纳至少1000个元素,
// 而不需要重新分配内存,直到达到或超过1000个元素。
// 向向量中添加元素
for (int i = 0; i < 1000; ++i) {
vec.push_back(i);
}
// 在这个循环中,向量不需要重新分配内存,因为我们已经预留了足够的空间。
// 输出向量的大小和容量
std::cout << "Size of vector: " << vec.size() << std::endl;
std::cout << "Capacity of vector: " << vec.capacity() << std::endl;
return 0;
}
在这个例子中,我们创建了一个空的vector对象vec,并使用reserve(1000)预先分配了足够的内存来容纳至少1000个整数。然后,我们向vec中添加了1000个元素,而在这个过程中,vector不需要重新分配内存,因为它已经有了足够的空间。
注意,reserve()函数只改变向量的容量,不改变它的大小。调用vec.size()将返回实际添加到向量中的元素数量,而vec.capacity()将返回已分配的内存空间能够容纳的元素数量。
预留内存并不总是必要的,因为vector在需要时会自动管理内存。但是,在你知道将要添加大量元素的情况下,使用reserve()可以提高性能。
shrink_to_fit()
在C++中,std::vector的shrink_to_fit()成员函数试图减少向量所使用的内存量,使其尽可能接近当前元素数量所需的大小。这意味着如果向量之前因为预留了大量空间而分配了较多的内存,调用shrink_to_fit()可能会释放这些未使用的内存,使得向量的容量(capacity)更接近于它的大小(size)。
需要注意的是,shrink_to_fit()并不保证一定能够减少容量,因为实现可能会决定保留一些额外的空间以优化未来的增长。此外,即使shrink_to_fit()成功减少了容量,也不能保证在之后添加元素时不会发生内存重新分配。
下面是一个使用shrink_to_fit()的例子:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec;
// 预留足够的空间以容纳1000个元素
vec.reserve(1000);
// 向量现在有一个较大的容量,但只包含0个元素
std::cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << std::endl;
// 添加一些元素
for (int i = 0; i < 10; ++i) {
vec.push_back(i);
}
// 现在向量的大小是10,但容量可能仍然是1000
std::cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << std::endl;
// 调用shrink_to_fit()尝试减少容量
vec.shrink_to_fit();
// shrink_to_fit()后,容量应该更接近于大小
std::cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << std::endl;
return 0;
}
输出可能是这样的:
Size: 0, Capacity: 1000
Size: 10, Capacity: 1000
Size: 10, Capacity: 10
在这个例子中,shrink_to_fit()成功地将容量减少到了与大小相同,即10。然而,这并不是shrink_to_fit()的保证行为,具体行为取决于标准库的实现。
使用shrink_to_fit()的一个常见场景是在你知道向量不再需要增长,并且想要释放未使用的内存时。然而,在大多数情况下,频繁地调用shrink_to_fit()并不是一个好的做法,因为它可能导致不必要的内存重新分配和性能开销。通常,你应该只在确实需要减少内存使用时才调用它。
c1 == c2
在C++中,std::vector是一种动态数组,它提供了对序列容器(sequence container)的封装。要比较两个std::vector对象c1和c2是否相等,你可以使用==操作符。这个操作符会逐个比较两个vector中的元素,如果它们的元素数量相同且每个元素都相等,那么这两个vector就被认为是相等的。
下面是一个示例,展示了如何使用==操作符来比较两个std::vector对象:
#include <iostream>
#include <vector>
int main() {
std::vector<int> c1 = {1, 2, 3, 4, 5};
std::vector<int> c2 = {1, 2, 3, 4, 5};
std::vector<int> c3 = {1, 2, 3, 4};
// 比较c1和c2
if (c1 == c2) {
std::cout << "c1 is equal to c2" << std::endl;
} else {
std::cout << "c1 is not equal to c2" << std::endl;
}
// 比较c1和c3
if (c1 == c3) {
std::cout << "c1 is equal to c3" << std::endl;
} else {
std::cout << "c1 is not equal to c3" << std::endl;
}
return 0;
}
在这个例子中,c1和c2是相等的,因为它们的元素数量和每个元素的值都相同。而c1和c3则不相等,因为c3缺少c1中的最后一个元素。
==操作符会比较两个vector的大小(通过size()函数获得),如果大小不同,则它们肯定不相等。如果大小相同,则会逐个比较元素,直到找到一个不相等的元素或比较完所有元素。
需要注意的是,操作符的行为依赖于vector中元素的类型是否定义了操作符。如果vector包含自定义类型的元素,你需要确保这些类型也重载了==操作符,以便能够比较它们是否相等。
c1 != c2
在C++中,std::vector类的!=操作符用于比较两个vector对象是否不相等。当两个vector的大小不同,或者即使大小相同但至少有一个元素不相等时,这两个vector对象就被认为是不相等的。
下面是使用!=操作符来比较两个std::vector对象是否不相等的示例:
#include <iostream>
#include <vector>
int main() {
std::vector<int> c1 = {1, 2, 3, 4, 5};
std::vector<int> c2 = {1, 2, 3, 4, 5};
std::vector<int> c3 = {1, 2, 3, 4};
// 比较c1和c2
if (c1 != c2) {
std::cout << "c1 is not equal to c2" << std::endl;
} else {
std::cout << "c1 is equal to c2" << std::endl;
}
// 比较c1和c3
if (c1 != c3) {
std::cout << "c1 is not equal to c3" << std::endl;
} else {
std::cout << "c1 is equal to c3" << std::endl;
}
return 0;
}
在这个例子中,c1和c2是相等的,因为它们的元素数量和每个元素的值都相同。因此,c1 != c2的结果是false,所以程序会输出"c1 is equal to c2"。
然而,c1和c3不相等,因为c3缺少c1中的一个元素。因此,c1 != c3的结果是true,程序会输出"c1 is not equal to c3"。
!=操作符会比较两个vector的大小,如果大小不同则它们肯定不相等。如果大小相同,它会逐个比较元素,直到找到一个不相等的元素或比较完所有元素。如果所有元素都相等,则两个vector被认为是相等的,!=操作符返回false;否则,返回true。
c1 < c2
返回c1是否小于c2
c1 > c2
返回c1是否大于c2
c1 <= c2
返回c1是否小于等于c2
c1 >= c2
返回c1是否大于等于c2