C++動(dòng)態(tài)數(shù)組vector的使用小結(jié)
vector的基本概念
vector是C++標(biāo)準(zhǔn)模板庫(STL)中最重要且最常用的容器之一,它本質(zhì)上是一個(gè)封裝了動(dòng)態(tài)數(shù)組的類模板,提供了一系列便捷的方法來操作和管理數(shù)組數(shù)據(jù)。作為序列式容器的一種,vector支持在尾部高效地添加或刪除元素,同時(shí)保持元素的線性存儲順序。
vector的實(shí)現(xiàn)原理是基于動(dòng)態(tài)數(shù)組,它在內(nèi)部使用連續(xù)的內(nèi)存空間來存儲元素。當(dāng)現(xiàn)有容量不足時(shí),vector會(huì)自動(dòng)重新分配更大的內(nèi)存空間(通常是當(dāng)前容量的2倍),并將原有元素復(fù)制到新的內(nèi)存區(qū)域。這個(gè)特性使得vector具有以下特點(diǎn):
- 隨機(jī)訪問效率高:通過下標(biāo)運(yùn)算符[]或at()方法可以在O(1)時(shí)間內(nèi)訪問任意元素
- 尾部操作高效:push_back()和pop_back()操作的時(shí)間復(fù)雜度為O(1)
- 插入刪除效率低:在中間位置插入或刪除元素需要移動(dòng)后續(xù)元素,時(shí)間復(fù)雜度為O(n)
vector的典型使用場景包括:
- 需要頻繁隨機(jī)訪問元素的場合
- 數(shù)據(jù)量變化不大或主要在尾部增刪的場合
- 需要兼容C風(fēng)格數(shù)組的場合
基本操作示例:
#include <vector> using namespace std; vector<int> v; // 創(chuàng)建空vector v.push_back(10); // 尾部添加元素 v.insert(v.begin(), 5); // 在頭部插入元素 int val = v[0]; // 隨機(jī)訪問 v.pop_back(); // 刪除尾部元素
vector還提供了許多有用的成員函數(shù),如size()獲取元素?cái)?shù)量,capacity()獲取當(dāng)前容量,reserve()預(yù)分配內(nèi)存等,這些函數(shù)使得vector比原始數(shù)組更安全、更易于使用。
與傳統(tǒng)靜態(tài)數(shù)組的比較
與傳統(tǒng)的靜態(tài)數(shù)組相比,vector具有以下顯著優(yōu)勢:
動(dòng)態(tài)擴(kuò)容能力:
- 當(dāng)元素?cái)?shù)量超過當(dāng)前容量時(shí),vector會(huì)自動(dòng)分配更大的內(nèi)存空間(通常是當(dāng)前容量的1.5-2倍)并將原有元素拷貝到新空間
- 擴(kuò)容策略可以通過reserve()方法預(yù)先指定,減少頻繁擴(kuò)容帶來的性能開銷
- 示例:
vector<int> v; v.reserve(100);預(yù)先分配100個(gè)元素的空間
自動(dòng)內(nèi)存管理:
- 用戶無需手動(dòng)分配和釋放內(nèi)存,vector會(huì)在析構(gòu)時(shí)自動(dòng)釋放所有內(nèi)存
- 遵循RAII(資源獲取即初始化)原則,避免內(nèi)存泄漏
- 示例:
{ vector<int> temp; /*...*/ }作用域結(jié)束時(shí)自動(dòng)釋放內(nèi)存
豐富的成員函數(shù):
- 提供了push_back()、pop_back()、insert()、erase()等方法來方便地增刪元素
- 支持size()、capacity()、empty()等狀態(tài)查詢方法
- 提供front()、back()快速訪問首尾元素的方法
隨機(jī)訪問支持:
- 通過[]運(yùn)算符或at()方法可以像普通數(shù)組一樣快速訪問任意位置的元素
- 時(shí)間復(fù)雜度為O(1),與靜態(tài)數(shù)組相同
- 示例:
v[10] = 42;或int x = v.at(5);
常用操作示例
#include <vector>
#include <iostream>
int main() {
// 創(chuàng)建vector
std::vector<int> numbers;
// 尾部添加元素
numbers.push_back(10);
numbers.push_back(20);
numbers.push_back(30);
// 訪問元素
std::cout << "第一個(gè)元素: " << numbers[0] << std::endl;
// 遍歷元素
for(int num : numbers) {
std::cout << num << " ";
}
// 刪除尾部元素
numbers.pop_back();
return 0;
}
實(shí)際應(yīng)用場景
在實(shí)際應(yīng)用中,vector常用于以下場景:
需要頻繁在尾部添加/刪除元素的場合:
- 日志記錄系統(tǒng)
- 數(shù)據(jù)采集緩沖
- 動(dòng)態(tài)生成的結(jié)果集存儲
需要隨機(jī)訪問元素的場合:
- 圖像像素處理
- 數(shù)學(xué)向量/矩陣運(yùn)算
- 游戲?qū)ο蠊芾?/li>
無法預(yù)先確定元素?cái)?shù)量的情況:
- 讀取未知長度的用戶輸入
- 解析動(dòng)態(tài)數(shù)據(jù)文件
- 數(shù)據(jù)庫查詢結(jié)果存儲
需要將數(shù)據(jù)作為參數(shù)傳遞給函數(shù)時(shí):
- 避免數(shù)組退化為指針
- 保持完整的容器信息(size/capacity等)
- 示例:
void process(const std::vector<int>& data);
例如:
#include <vector>
#include <iostream>
int main() {
std::vector<int> nums; // 創(chuàng)建一個(gè)空的int型vector
// 添加元素
nums.push_back(10);
nums.push_back(20);
nums.push_back(30);
// 訪問元素
std::cout << "第一個(gè)元素:" << nums[0] << std::endl;
std::cout << "當(dāng)前容量:" << nums.capacity() << std::endl;
// 遍歷元素
for(auto num : nums) {
std::cout << num << " ";
}
return 0;
}
需要注意的是,雖然vector提供了諸多便利,但在中間位置插入/刪除元素時(shí)效率較低(O(n)復(fù)雜度),這種情況下可以考慮使用list等其他容器。此外,頻繁的擴(kuò)容操作也可能帶來性能開銷,可以通過reserve()方法預(yù)先分配足夠空間來優(yōu)化。
基本特性
動(dòng)態(tài)擴(kuò)容機(jī)制
當(dāng)vector的size達(dá)到capacity時(shí),會(huì)自動(dòng)進(jìn)行擴(kuò)容:
- 擴(kuò)容策略:大多數(shù)實(shí)現(xiàn)采用1.5倍或2倍擴(kuò)容策略(如VS通常1.5倍,g++通常2倍)
- 擴(kuò)容過程:分配新內(nèi)存→拷貝元素→釋放舊內(nèi)存
- 時(shí)間復(fù)雜度:均攤O(1),但單次擴(kuò)容可能達(dá)到O(n)
vector<int> v;
for(int i=0; i<100; i++){
v.push_back(i); // 自動(dòng)擴(kuò)容約7-8次(取決于實(shí)現(xiàn))
}
內(nèi)存布局
- 連續(xù)存儲:所有元素在內(nèi)存中連續(xù)排列,與普通數(shù)組一致
- 隨機(jī)訪問:支持通過下標(biāo)直接訪問,效率與數(shù)組相同
- 迭代器:提供隨機(jī)訪問迭代器,支持各種STL算法
類型安全
通過模板實(shí)現(xiàn),可存儲任意類型:
vector<string> names; vector<pair<int,double>> measurements; vector<vector<int>> matrix; // 二維數(shù)組
常用操作詳解
初始化方式
// 1. 默認(rèn)構(gòu)造
vector<int> v1;
// 2. 指定大小和初始值
vector<int> v2(10, 0); // 10個(gè)0
// 3. 通過迭代器范圍初始化
int arr[] = {1,2,3};
vector<int> v3(arr, arr+3);
// 4. 列表初始化(C++11)
vector<int> v4 = {1,2,3};
// 5. 拷貝構(gòu)造
vector<int> v5(v4);
元素添加
vector<int> v; // 尾部添加 v.push_back(10); v.push_back(20); // 高效構(gòu)造(C++11) v.emplace_back(30); // 直接在容器內(nèi)構(gòu)造,避免拷貝 // 任意位置插入 v.insert(v.begin(), 5); // 頭部插入 v.insert(v.begin()+1, 2, 8); // 插入2個(gè)8
元素訪問
// 下標(biāo)訪問(不檢查邊界)
int a = v[0];
// 安全訪問(檢查邊界)
try {
int b = v.at(100); // 拋出out_of_range異常
} catch(out_of_range& e) {
cerr << e.what() << endl;
}
// 迭代器訪問
for(auto it = v.begin(); it != v.end(); ++it) {
cout << *it << " ";
}
// 反向迭代器
for(auto rit = v.rbegin(); rit != v.rend(); ++rit) {
cout << *rit << " ";
}
// C++11范圍for
for(int num : v) {
cout << num << " ";
}
元素刪除
// 刪除末尾元素
v.pop_back();
// 刪除指定位置
v.erase(v.begin());
// 刪除范圍
v.erase(v.begin(), v.begin()+2);
// 條件刪除(C++11)
v.erase(remove_if(v.begin(), v.end(),
[](int x){return x%2==0;}), v.end());
// 清空容器
v.clear();
容量管理
// 當(dāng)前元素?cái)?shù)量
size_t count = v.size();
// 當(dāng)前容量
size_t cap = v.capacity();
// 是否為空
if(v.empty()) {
cout << "Vector is empty" << endl;
}
// 預(yù)分配空間(避免多次擴(kuò)容)
v.reserve(100);
// 釋放多余空間
v.shrink_to_fit();
// 調(diào)整大小
v.resize(50); // 不足補(bǔ)0,多余刪除
v.resize(100, -1); // 不足補(bǔ)-1
性能優(yōu)化建議
預(yù)分配空間:已知元素?cái)?shù)量時(shí)先reserve,避免多次擴(kuò)容
vector<int> v; v.reserve(1000); // 預(yù)先分配 for(int i=0; i<1000; i++) { v.push_back(i); // 不會(huì)觸發(fā)擴(kuò)容 }選擇合適的添加方法:
- 優(yōu)先使用emplace_back而非push_back(避免臨時(shí)對象)
- 批量插入時(shí)使用insert范圍版本
避免不必要的拷貝:
// 返回vector的函數(shù) vector<int> getData() { vector<int> data; // ...填充data return data; // 移動(dòng)語義優(yōu)化,無拷貝 }元素類型選擇:
- 存儲大型對象時(shí)考慮存儲指針
- 頻繁插入刪除時(shí)考慮list或deque
典型應(yīng)用場景
動(dòng)態(tài)數(shù)組需求
// 讀取未知數(shù)量的輸入 vector<int> inputs; int num; while(cin >> num) { inputs.push_back(num); }實(shí)現(xiàn)棧結(jié)構(gòu)
vector<int> stack; stack.push_back(1); // push int top = stack.back(); // top stack.pop_back(); // pop
矩陣運(yùn)算
vector<vector<double>> matrix(m, vector<double>(n)); // 矩陣操作...
算法容器
vector<int> data = {5,3,8,1,9}; sort(data.begin(), data.end()); auto it = find(data.begin(), data.end(), 8);緩存數(shù)據(jù)
vector<CacheEntry> cache; cache.reserve(MAX_CACHE_SIZE);
與其他容器對比
| 特性 | vector | deque | list |
|---|---|---|---|
| 隨機(jī)訪問 | O(1) | O(1) | O(n) |
| 頭部插入 | O(n) | O(1) | O(1) |
| 尾部插入 | O(1) | O(1) | O(1) |
| 中間插入 | O(n) | O(n) | O(1) |
| 內(nèi)存連續(xù)性 | 是 | 部分 | 否 |
vector是C++標(biāo)準(zhǔn)模板庫(STSL)中最基礎(chǔ)也是最重要的序列容器,它通過類模板的方式實(shí)現(xiàn)了一個(gè)動(dòng)態(tài)數(shù)組。與普通數(shù)組相比,vector具有自動(dòng)內(nèi)存管理的特性,能夠根據(jù)元素?cái)?shù)量的變化動(dòng)態(tài)調(diào)整存儲空間。
內(nèi)存管理機(jī)制:
- 初始分配:vector在構(gòu)造時(shí)通常會(huì)分配一個(gè)初始容量(具體實(shí)現(xiàn)可能不同,常見為0或一個(gè)小值)
- 擴(kuò)容策略:當(dāng)元素?cái)?shù)量超過當(dāng)前容量時(shí),vector會(huì)進(jìn)行擴(kuò)容。標(biāo)準(zhǔn)沒有規(guī)定具體擴(kuò)容倍數(shù),但主流實(shí)現(xiàn)(如GCC、MSVC)通常采用2倍擴(kuò)容策略
- 內(nèi)存釋放:除非調(diào)用shrink_to_fit(),否則vector通常不會(huì)自動(dòng)縮小容量
內(nèi)存管理示例:
std::vector<int> v; // 初始容量可能是0
v.reserve(100); // 預(yù)分配100個(gè)元素空間
for(int i=0; i<200; ++i) {
v.push_back(i); // 當(dāng)超過100時(shí)自動(dòng)擴(kuò)容
}
性能特點(diǎn)與優(yōu)化
時(shí)間復(fù)雜度分析:
- 隨機(jī)訪問:O(1) - 通過下標(biāo)直接訪問
- 尾部操作:
- push_back/pop_back:平均O(1)
- emplace_back:平均O(1)
- 中間操作:
- insert/erase:O(n),因?yàn)樾枰苿?dòng)后續(xù)元素
- 查找:O(n)(無序情況下)
性能優(yōu)化技巧:
- 預(yù)分配空間:使用reserve()可避免多次擴(kuò)容
std::vector<Item> items; items.reserve(1000); // 預(yù)分配空間避免多次擴(kuò)容
- 使用emplace_back代替push_back:
items.emplace_back(arg1, arg2); // 直接在容器中構(gòu)造對象
- 避免不必要的拷貝:
std::vector<std::string> getData() {
std::vector<std::string> result;
// ...填充數(shù)據(jù)
return result; // 利用返回值優(yōu)化(RVO)或移動(dòng)語義
}
典型應(yīng)用場景
- 數(shù)據(jù)緩存:需要快速隨機(jī)訪問的臨時(shí)數(shù)據(jù)存儲
- 矩陣運(yùn)算:多維數(shù)組的實(shí)現(xiàn)基礎(chǔ)
- 圖形處理:像素緩沖區(qū)、頂點(diǎn)數(shù)據(jù)存儲
- 網(wǎng)絡(luò)通信:數(shù)據(jù)包緩沖區(qū)的實(shí)現(xiàn)
- 替代原始數(shù)組:更安全、更易用的動(dòng)態(tài)數(shù)組替代方案
與其他容器的對比
| 特性 | vector | list | deque |
|---|---|---|---|
| 內(nèi)存布局 | 連續(xù) | 非連續(xù) | 分段連續(xù) |
| 隨機(jī)訪問 | O(1) | O(n) | O(1) |
| 中間插入/刪除 | O(n) | O(1) | O(n) |
| 迭代器失效 | 擴(kuò)容時(shí)全部失效 | 通常不失效 | 復(fù)雜情況可能失效 |
| 緩存友好度 | 高 | 低 | 中等 |
到此這篇關(guān)于C++動(dòng)態(tài)數(shù)組vector的使用小結(jié)的文章就介紹到這了,更多相關(guān)C++動(dòng)態(tài)數(shù)組vector內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言實(shí)現(xiàn)電子郵件地址驗(yàn)證程序
這篇文章主要介紹了C語言實(shí)現(xiàn)電子郵件地址驗(yàn)證程序,利用的是POSIX正則表達(dá)式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2015-11-11
C語言模擬實(shí)現(xiàn)strstr函數(shù)的示例代碼
strstr是C語言中的函數(shù),作用是返回字符串中首次出現(xiàn)子串的地址。本文將用C語言模擬實(shí)現(xiàn)strstr函數(shù),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-07-07
C++?LeetCode1769移動(dòng)所有球到每個(gè)盒子最小操作數(shù)示例
這篇文章主要為大家介紹了C++?LeetCode1769移動(dòng)所有球到每個(gè)盒子所需最小操作數(shù)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
C語言中調(diào)用Swift函數(shù)實(shí)例詳解
這篇文章主要介紹了C語言中調(diào)用Swift函數(shù)實(shí)例詳解的相關(guān)資料,實(shí)現(xiàn)該功能可以通過定義全局的指向Blocks的對象指針來實(shí)現(xiàn),需要的朋友可以參考下2017-07-07

