C++面試題:介紹一下STL,具體說明STL如何?vector。
考點:vector的理解與實現細節
出現頻率:★★★★
解析:
前面例題已經介紹過了STL,因此這裡不再贅述,只說明STL如何?vector。
vector的定義如下:
template<class _Ty, class _A = allocator<_Ty> >
class vector {
……
};
這裡省略了中間的成員。其中_Ty類型用於表示vector中儲存的元素類型,_A預設為allocator<_Ty>類型。
這裡需要說明的是allocator類,它是一種“記憶體配置器”,負責提供記憶體管理(可能包含記憶體配置、釋放、自動回收等能力)相關的服務。於是對於程式員來說,就不用關心記憶體管理方面的問題。
vector支援隨機訪問,因此為了效率方面的考慮,它內部使用動態數組的方式實現的。當進行insert或push_back等增加元素的操作時,如果此時動態數組的記憶體不夠用,就要動態重新分配,一般是當前大小的兩倍,然後把原數組的內容拷貝過去。所以,在一般情況下,其訪問速度同一般數組,只有在重新分配發生時,其效能才會下降。例如下面的程式:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v; //初始時無元素,容量為0
cout << v.capacity() << endl;
v.push_back(1) ; //容量不夠,分配1個元素記憶體
cout << v.capacity() << endl;
v.push_back(2); //容量不夠,分配2個元素記憶體
cout << v.capacity() << endl;
v.push_back(3); //容量不夠,分配4個元素記憶體
cout << v.capacity() << endl;
v.push_back(4);
v.push_back(5); //容量不夠,分配8個元素記憶體
cout << v.capacity() << endl;
v.push_back(6);
v.push_back(7);
v.push_back(8);
v.push_back(9); //容量不夠,分配16個元素記憶體
cout << v.capacity() << endl;
return 0;
}
下面是各個執行步驟:
(1)代碼7行,初始化時v無元素(size為0),且容量(capacity)也為0。
(2)代碼9行,在數組末尾添加元素1,由於容量不夠,因此allocator分配1個int大小的記憶體,並把整數1複製到這個記憶體中。
(3)代碼11行,在數組末尾添加元素2。此時容量為1,但元素個數需要變為2,因此容量不夠,於是allocator先分配原來容量的2倍大小的記憶體(即2個int大小的記憶體),然後把原來數組中的1和新加入的2拷貝到新分配的記憶體中,最後釋放原來數組的記憶體。
(4)代碼13行,在數組末尾添加元素3。此時容量為2,而元素個數需要變為3,因此容量也不夠。和(3)相同,allocator分配4個int的記憶體,然後把原來數組中的1、2以及新加入的3拷貝到新分配的記憶體,最後釋放原數組的記憶體。
(5)代碼15行,在數組末尾添加元素3。此時容量為4,而元素個數需要變為3,因此容量足夠,不需要分配記憶體,直接把4拷貝到數組的最後即可。
以後的操作不再贅述。注意vector的size()和capacity()是不同的,前者表示數組中元素的多少,後者表示數組有多大的容量。由上面的分析可以看出,使用vector的時候需要注意記憶體的使用,如果頻繁地進行記憶體的重新分配,會導致效率低下。
答案:
STL(Standard Template Library),即標準模板庫,是一個具有工業強度的,高效的C++程式庫。它被容納於C++標準程式庫中,包括容器、演算法、迭代器組件。
vector內部使用動態數組的方式實現的。如果動態數組的記憶體不夠用,就要動態重新分配,一般是當前大小的兩倍,然後把原數組的內容拷貝過去。所以,在一般情況下,其訪問速度同一般數組,只有在重新分配發生時,其效能才會下降。它的內部使用allocator類進行記憶體管理,程式員不需要自己操作記憶體。
vector <int> array;
array.push_back( 1 );
array.push_back( 2 );
array.push_back( 3 );
for( vector <int>::size_type i=array.size()-1; i>=0; --i ) // 反向遍曆array數組
{
cout < < array[i] < < endl;
}
當我運行代碼的時候,沒有輸出 3 2 1,而是輸出了一大堆很大的數字,為什嗎?
於是我修改了代碼
for(vector <int>::size_type j=array.size();j>0;j--)
{
cout < < "element is " < <array[j-1] < <endl;
}
這樣就輸出了 3 2 1,倒是為什麼呢?
////
答案:size_type 是 unsigned int型的,也就是說, i用於大於0,第一種做法會陷入死迴圈!
當i=0時,再--i,i=0xFFFFFFFF. 引用一個無效的元素,然後程式就崩潰了!
建議用iterator迭代子來操作!
原文連結:http://genwoxuec.blog.51cto.com/1852764/504999
原文連結:http://blog.csdn.net/zdl1016/article/details/2455182
vector <int> array;
array.push_back( 1 );
array.push_back( 2 );
array.push_back( 3 );
for( vector <int>::size_type i=array.size()-1; i>=0; --i ) // 反向遍曆array數組
{
cout < < array[i] < < endl;
}
當我運行代碼的時候,沒有輸出 3 2 1,而是輸出了一大堆很大的數字,為什嗎?
於是我修改了代碼
for(vector <int>::size_type j=array.size();j>0;j--)
{
cout < < "element is " < <array[j-1] < <endl;
}
這樣就輸出了 3 2 1,倒是為什麼呢?
////
答案:size_type 是 unsigned int型的,也就是說, i用於大於0,第一種做法會陷入死迴圈!
當i=0時,再--i,i=0xFFFFFFFF. 引用一個無效的元素,然後程式就崩潰了!
建議用iterator迭代子來操作!