C++向量(Vector)类型讲义
一、引言
在C++标准模板库(STL)中,vector
是一个动态数组,它可以随着元素的插入和删除而自动改变大小。与固定大小的数组相比,vector
提供了更多的灵活性和便利性。
二、vector
的基本使用
-
包含头文件 使用
vector
之前,需要包含<vector>
头文件。#include <vector>
-
创建向量 可以创建一个空的
vector
,也可以指定初始大小和初始值。 -
vector<int> v1; // 空的整数向量 vector<int> v2(7);// 创建初始长度为7的整数向量,后面还可以增加长度 vector<int> v3(4, 20); // 包含4个值都是20的整数向量[20, 20, 20, 20]
-
访问元素 使用下标操作符
[]
或at()
函数来访问向量中的元素。int firstElement = v2[0]; // 访问第一个元素 int secondElement = v2.at(1); // 访问第二个元素
注意:使用
[]
访问时,如果下标越界,会导致未定义行为;而at()
在下标越界时会抛出out_of_range
异常。 -
修改元素 可以直接通过下标操作符修改向量中的元素。
v2[0] = 1; // 修改第一个元素为1
-
添加元素 使用
push_back()
函数在向量末尾添加元素。v1.push_back(1); // 在v1末尾添加元素1
-
删除元素 使用
pop_back()
函数删除向量末尾的元素。if (!v1.empty()) { v1.pop_back(); // 删除v1末尾的元素 }
-
遍历向量 可以使用范围基础的for循环、迭代器或传统的for循环来遍历向量。
// 传统的for循环 for (size_t i = 0; i < v2.size(); ++i) { cout << v2[i] << ' '; } // 范围基础的for循环 for (int num : v2) { cout << num << ' '; }
-
大小和容量 使用
size()
函数获取向量中元素的数量,使用capacity()
函数获取向量当前分配的存储空间大小。cout << "Size: " << v2.size() << ", Capacity: " << v2.capacity() << endl;
-
其他常用操作
clear()
:删除向量中的所有元素。resize(n)
:改变向量的大小为n
,如果n
大于当前大小,则添加新元素(默认初始化为0或空值);如果n
小于当前大小,则删除多余的元素。insert(pos, elem)
:在位置pos
插入元素elem
。erase(pos)
或erase(first, last)
:删除位置pos
的元素或删除从first
到last
(不包括last
)的元素。
三、vector
的效率
- 向量在尾部添加和删除元素时,通常具有较高的效率(O(1)复杂度,在大多数情况下)。
- 在其他位置插入或删除元素时,可能需要移动其他元素,因此效率较低(O(n)复杂度)。
- 当向量的大小超过其容量时,可能需要重新分配内存并复制所有元素到新位置,这会导致效率下降。
四、总结
vector
是C++中非常实用的动态数组类型,它提供了灵活且方便的方式来存储和操作元素。通过掌握其基本使用方法和常用操作,可以有效地利用 vector
来解决各种编程问题。
vector和数组的优缺点及应用情境选择
数组(Array)
优点:
- 内存连续:数组在内存中是一段连续的存储空间,这使得元素的访问速度非常快,因为它们可以通过索引和起始地址直接计算得出。
- 简单直观:数组的概念简单直观,易于理解和使用。
- 固定大小:在某些情况下,知道数据的大小是固定的,使用数组可以确保不会浪费额外的空间。
缺点:
- 大小固定:一旦定义,数组的大小就不能改变。如果需要存储更多的数据,可能需要重新分配一个更大的数组,并将旧数组中的数据复制到新数组中,这可能导致效率问题。
- 容易越界:如果访问数组的索引超出了其大小,会导致未定义行为,如内存访问错误。
应用情境:
- 已知数据量固定,并且不需要频繁地进行动态大小调整的场景。
- 需要快速访问元素,且元素在内存中的位置连续的场景。
vector(C++ STL中的动态数组)
优点:
- 动态大小:vector可以根据需要自动增长和缩小,无需手动管理内存。
- 方便操作:提供了丰富的成员函数,如
push_back()
,pop_back()
,insert()
,erase()
等,方便进行元素的添加、删除和查找。 - 自动管理内存:当vector的大小超过其容量时,它会自动重新分配内存,并将旧数据复制到新内存中,无需程序员手动操作。
缺点:
- 可能产生内存碎片:由于vector在重新分配内存时可能会分配比原来更大的内存块,这可能导致内存碎片。
- 访问速度略慢:与数组相比,vector在访问元素时可能稍慢一些,因为它需要通过额外的计算来找到元素的位置。但在大多数情况下,这种差异可以忽略不计。
应用情境:
- 需要动态调整数据大小,且不希望手动管理内存的场景。
- 需要方便地进行元素添加、删除和查找的场景。
- 对内存碎片不敏感,且对访问速度要求不是特别高的场景。
总结
选择使用数组还是vector取决于具体的应用场景和需求。如果数据量固定且不需要频繁地进行动态大小调整,且对访问速度有较高要求,那么数组可能是更好的选择。如果需要动态调整数据大小,且希望避免手动管理内存,那么vector可能是更好的选择。在实际应用中,可以根据具体需求权衡两者的优缺点,选择最适合的数据结构。