主要參考: 遍歷的幾種方式及性能對比;
一個非常隱蔽的越界錯誤
vector類稱作向量類, 它實現了動態的數組, 用於元素數量變化的對象數組. 索引下標從0開始, 元素個數可以動態變化.
構造函數與初始化
vector()
空向量vector(int nSize)
聲明元素個數vector(int nSize, const T& t)
聲明元素個數, 且值均爲t。vector<T> a
聲明元素類型爲模板類Tvector(const vector&)
複製構造函數。
vector<int> a;
vector<int> a(5);
vector<int> a(5, 0);
vector<int> b(a);
增加與刪除函數
a.push_back(const T& t))
末尾追加元素a.pop_back()
刪除末尾元素a.clear()
清空所有元素a.inset
插入a.erase
刪除
a.push_back(10);
a.push_back(20);
a.push_back(30); // [10, 20, 30]
a.pop_back(); // [10, 20]
auto index1 = find(a.begin(), a.end(), 20);
a.insert(index1, 0); // [10, 0, 20]
vector<int> ::iterator index2 = find(a.begin(), a.end(), 20);
a.erase(index2); // [10, 0]
a.clear();
索引與遍歷
a.at(int index)
索引index位置(引用)a.front()
首元素的引用a.back()
尾元素的引用a.begin()
指向首元素的指針a.end()
指向末尾的指針, 並不是尾元素a.rbegin()
反向迭代器的起始指針a.rend()
反向迭代器的終止指針
索引
vector<int> a(3, 0); // [0, 0, 0]
a.front() = 10;
a.at(1) = 20;
a.back() = 30; // [10, 20, 30]
迭代器遍歷
- 正向:
auto iter1 = a.begin();
while(iter1 != a.end())
{
*iter1 += 1;
cout << *iter1 << ", "; // [11, 21, 31]
iter1++;
}
cout << endl;
- 反向:
auto iter2 = a.rbegin();
while(iter2 != a.rend())
{
*iter2 += 1;
cout << *iter2 << ", "; // [32, 22, 12]
iter2++;
}
cout << endl;
下標遍歷
for(int i = 0; i < a.size(); i++)
{
a[i] += 1;
cout << a[i] << ", "; // [13, 23, 33]
}
cout << endl;
auto 輸出
for(auto x : a)
{
cout << x << ", "; // [13, 23, 33], 對源數據無影響
}
cout << endl;
注: 三種遍歷方法的Release實時運行差別很小, 同樣高效. 點擊訪問參考博文
其他函數
a.empty()
判斷是否爲空a.size()
返回元素的個數a.capacity()
返回預分配內存中所能容納的最多元素數 點擊訪問參考博文a.max_size()
返回所能容納的最多元素數
vector<int> a(5);
cout << a.size() << endl; // 5
cout << a.capacity() << endl; // 5
cout << a.max_size() << endl; // 1073741823
vector<int> b;
cout << b.size() << endl; // 0
cout << b.capacity() << endl; // 0
cout << b.max_size() << endl; // 1073741823
越界問題
- 下標越界,如本例的
a[5]
, 但程序Debug報錯, Release不報錯, 輸出該地址中存儲值. 點擊訪問參考博文 - 隱蔽型越界, 如以下代碼. 當size=0時, 減一操作是危險的. 因爲
a.size()
是無符號整數,根據C++的規則表達式a.size()-1
也是個無符號整數,而-1轉成無符號數的值是4294967295, 顯然越界, 應該避免使用a.size()-1
. Java等語言沒有無符號類型, 也就避免了這一問題. 點擊訪問參考博文
vector<int> a;
for(int i = 0; i <= a.size() - 1; i++)
{
cout << a[i] << endl;
}
其他問題
- static索引變量問題:
如圖所示, 由於static變量只初始化一次, 有固定內存, 相當於全局變量, 所以並不能按照意圖在每次調用函數時都被賦值爲3, 只會在反覆++, 最後造成越界. 應該改正爲:
static int index;
index = 3;