1. 程式人生 > >C++面試總結(四)標準庫

C++面試總結(四)標準庫

1.什麼是標準庫(STL)?

C++ STL(標準模板庫)是一套功能強大的 C++ 模板類,提供了通用的模板類和函式,這些模板類和函式可以實現多種流行和常用的演算法和資料結構,如向量、連結串列、佇列、棧。

2.C++ 標準模板庫的核心三個元件組成?

3.string

C++ 從 C 繼承的字串概念仍然是以 '\0' 為結束符的 char 陣列。C++ 標準庫中的 string class 可以將 string 作為一個型別,可以實現複製、賦值和比較,不必擔心記憶體大小及佔用記憶體實際長度等具體問題。

STL 中只有一個字串類,即 basic_string。類 basic_string 實現管理以 \0

 結尾的字元陣列,字元型別由模板引數決定。要使用 string 類,必須包含標頭檔案 <string>。在 STL 庫中,basic_string 有兩個預定義型別:包含 char 的 string 型別和包含 wchar 的 wstring 型別。

(1)string 類提供的各種操作函式大致分為八類:構造器和析構器、大小和容量、元素存取、字 符串比較、字串修改、字串接合、I/O 操作以及搜尋和查詢。

                                                                              string 類的所有成員函式

函式名稱 功能
建構函式 產生或複製字串
解構函式 銷燬字串
=,assign 賦以新值
Swap 交換兩個字串的內容
+ =,append( ),push_back() 新增字元
insert () 插入字元
erase() 刪除字元
clear () 移除全部字元
resize () 改變字元數量
replace() 替換字元
+ 串聯字串
==,! =,<,<=,>,>=,compare() 比較字串內容
size(),length() 返回字元數量
max_size () 返回字元的最大可能個數
empty () 判斷字串是否為空
capacity () 返回重新分配之前的字元容量
reserve() 保留記憶體以儲存一定數量的字元
[],at() 存取單一字元
>>,getline() 從 stream 中讀取某值
<< 將值寫入 stream
copy() 將內容複製為一個 C - string
c_str() 將內容以 C - string 形式返回
data() 將內容以字元陣列形式返回
substr() 返回子字串
find() 搜尋某子字串或字元
begin( ),end() 提供正向迭代器支援
rbegin(),rend() 提供逆向迭代器支援
get_allocator() 返回配置器

(2) string建構函式和解構函式詳解

//建構函式
string strs //生成空字串
string s(str) //生成字串str的複製品
string s(str, stridx) //將字串str中始於stridx的部分作為建構函式的初值
string s(str, strbegin, strlen) //將字串str中始於strbegin、長度為strlen的部分作為字串初值
string s(cstr) //以C_string型別cstr作為字串s的初值
string s(cstr,char_len)    //以C_string型別cstr的前char_len個字串作為字串s的初值
strings(num, c) //生成一個字串,包含num個c字元
strings(strs, beg, end)    //以區間[beg, end]內的字元作為字串s的初值
//解構函式
~string() //銷燬所有記憶體,釋放記憶體
//注意,不能使用字元或者整數去初始化字串。
std::string s('x');    //錯誤
std::string s("x");    //正確
std::string s(1, 'x');    //正確

(3)C++獲取字串長度詳解

String 型別物件包括三種求解字串長度的函式:size() 和 length()、 maxsize() 和 capacity():

  • size() 和 length():這兩個函式會返回 string 型別物件中的字元個數,且它們的執行效果相同。
  • max_size():max_size() 函式返回 string 型別物件最多包含的字元數。一旦程式使用長度超過 max_size() 的 string 操作,編譯器會丟擲 length_error 異常。
  • capacity():該函式返回在重新分配記憶體之前,string 型別物件所能包含的最大字元數。

string 型別物件還包括一個 reserve() 函式。呼叫該函式可以為 string 型別物件重新分配記憶體。重新分配的大小由其引數決定。reserve() 的預設引數為 0。

(4)string獲取字串元素:[]和at()

字串中元素的訪問是允許的,一般可使用兩種方法訪問字串中的單一字元:下標操作符[] 和 成員函式at()。兩者均返回指定的下標位置的字元。第 1 個字元索引(下標)為 0,最後的字元索引為 length()-1。

需要注意的是,這兩種訪問方法是有區別的:

  • 下標操作符 [] 在使用時不檢查索引的有效性,如果下標超出字元的長度範圍,會示導致未定義行為。對於常量字串,使用下標操作符時,字串的最後字元(即 '\0')是有效的。對應 string 型別物件(常量型)最後一個字元的下標是有效的,呼叫返回字元 '\0'。
  • 函式 at() 在使用時會檢查下標是否有效。如果給定的下標超出字元的長度範圍,系統會丟擲 out_of_range 異常。

(5)C++ string字串比較方法詳解

Basic_string 類模板既提供了  >、<、==、>=、<=、!= 等比較運算子,還提供了 compare() 函式,其中 compare() 函式支援多引數處理,支援用索引值和長度定位子串進行比較。該函式返回一個整數來表示比較結果。如果相比較的兩個子串相同,compare() 函式返回 0,否則返回非零值。

4.容器

  容器是用來管理某一類物件的集合,包括序列式容器和關聯式容器。

STL 中已經提供的容器主要如下:

  • vector <T>:一種向量。
  • list <T>:一個雙向連結串列容器,完成了標準 C++ 資料結構中連結串列的所有功能。
  • queue <T>:一種佇列容器,完成了標準 C++ 資料結構中佇列的所有功能。
  • stack <T>:一種棧容器,完成了標準 C++ 資料結構中棧的所有功能。
  • deque <T>:雙端佇列容器,完成了標準 C++ 資料結構中棧的所有功能。
  • priority_queue <T>:一種按值排序的佇列容器。
  • set <T>:一種集合容器。
  • multiset <T>:一種允許出現重複元素的集合容器。
  • map <key, val>:一種關聯陣列容器。
  • multimap <key, val>:一種允許出現重複 key 值的關聯陣列容器。

    序列式容器:vector,list,deque,queue,stack,priority_queue
    關聯式容器:map,set

5.序列式容器的種類?

序列容器以線性序列的方式儲存元素。它沒有對元素進行排序,元素的順序和儲存它們的順序相同。以下有5種標準的序列容器,每種容器都具有不同的特性:

  • array<T,N>(陣列容器)是一個長度固定的序列,有 N 個 T 型別的物件,不能增加或刪除元素
  • vector<T>(向量容器)是一個長度可變的序列,用來存放 T 型別的物件。必要時,可以自動增加容量,但只能在序列的末尾高效地增加或刪除元素。
  • deque<T>(雙向佇列容器)是一個長度可變的、可以自動增長的序列,在序列的兩端都不能高效地增加或刪除元素
  • list<T>(連結串列容器)是一個長度可變的、由 T 型別物件組成的序列,它以雙向連結串列的形式組織元素,在這個序列的任何地方都可以高效地增加或刪除元素。訪問容器中任意元素的速度要比前三種容器慢,這是因為 list<T> 必須從第一個元素或最後一個元素開始訪問,需要沿著連結串列移動,直到到達想要的元素。
  • forward list<T>(正向連結串列容器)是一個長度可變的、由 T 型別物件組成的序列,它以單鏈表的形式組織元素,是一類比連結串列容器快、更節省記憶體的容器,但是它內部的元素只能從第一個元素開始訪問
表 1 array、vector 和 deque 容器的函式成員
函式成員 array<T,N> vector<T> deque<T>
begin() - 返回幵始迭代器
end() - 返回結束迭代器
rbegin() - 返回反向'開始迭代器
rend() - 返回反向結束迭代器
cbegin() - 返M const開始迭代器
cend() - 返回const結束迭代器
crbegin() - 返回const反向開始迭代器
crend() - 返回const反向結束迭代器
assign() - 用新元素替換原有內容 -
operator=() - 複製同類型容器的元素,或者用初始化列表替換 現有內容
size() - 返回實際元素個數
max_size() - 返回元素個數的設大值
capacity() - 返回當前容量 - -
empty() - 返回true,如果容器中沒有元素的話
resize() - 改變實際元素的個數 -
shrink _to_fit() - 將記憶體減少到等於當前元素實際所使用的大小 -
front() - 返回第一個元素的引用
back() - 返回鋮後一個元素的引用
operator[]() - 使用索弓丨訪問元素
at() - 使用經過邊界檢査的索引訪問元素
push_back() - 在序列的尾部新增一個元素 -
insert() - 在指定的位置插入一個或多個元素 -
emplace() - 在指定的位置直接生成一個元素 -
emplace_back() - 在序列尾部生成一個元素 -
pop_back() - 移出序列尾部的元素 -
erase() - 移出一個元素或一段元素 -
clear() - 移出所苻的元素,容器大小變為 0 -
swap() - 交換兩個容器的所有元素
data() - 返回包含元素的內部陣列的指標 -
表 2 list 和 forward_list 的函式成員
函式成員 list<T> forward list<T>
begin() - 返回開始迭代器
end() - 返回結束迭代器
rbegin() - 返回反向開始迭代器 -
rend() - 返回反向結束迭代器 -
cbegin() - 返回 const 開始結束迭代器
before_begin() - 返回一個指向第一個元素前一個位置的迭代器 -
cbefore_begin() - 返回一個指向第一個元素前一個位置的const迭代器 -
cend() - 返回 const 結束迭代器
crbegin() - 返回 const 反向開始迭代器 -
crend() - 返回 const 反向結束迭代器 -
assign() - 用新元素替換原有內容
operator=() - 複製同類型容器的元素,或者用初始化列表替換現有內容
size() - 返回實際元素個數 -
max_size() - 返回元素個數的最大值
resize() - 改變實際元素的個數
empty() - 返回 true,如果容器中沒有元素的話
from() - 返回第一個元素的引用
back() - 返回最後一個元素的引用 -
push_back() - 在序列的潘部新增一個元素 -
push_front() - 在序列的起始位置新增一個元素
emplace() - 在指矩位置直接生成一個元素 -
emplace_after() - 在指定位置的後面直接生成一個元素 -
emplace_back() - 在序列尾部生成一個元素 -
cmplacc_front() - 在序列的起始位生成一個元索
insert() - 在指定的位置插入一個或多個元素 -
insert_after() - 在指定位置的後面插入一個或多個元素 -
pop_back() - 移除序列尾部的元素 -
pop_front() - 移除序列頭部的元素
reverse()-反向元素的順序
erase() - 移除指定位置的一個元素或一段元素 -
erase_after() - 移除指定位 1;後面的一個元素或一段元素 -
remove() - 移除所苻和引數匹配的元素
remove_if() - 移除滿足一元函式條件的所有元素
unique() - 移除所有連續重複的元素
clear() - 移除所有的元素,容器大小變為 0
swap() - 交換兩個容器的所有元素
sort() - 對元素進行排序
merge() - 合併兩個有序容器
splice() - 移動指定位置前面的所有元素到另一個同類型的 list 中 -
splice_after() - 移動指定位置後面的所有元素到另一個同類型的 list 中 -

6.常見的容器介面卡? 

容器介面卡是一個封裝了序列容器的類模板,它在一般序列容器的基礎上提供了一些不同的功能。之所以稱作介面卡類,是因為它可以通過適配容器現有的介面來提供不同的功能。
這裡有 3 種容器介面卡:

  1. stack<T>:是一個封裝了 deque<T> 容器的介面卡類模板,預設實現的是一個後入先出(Last-In-First-Out,LIFO)的壓入棧。stack<T> 模板定義在標頭檔案 stack 中。
  2. queue<T>:是一個封裝了 deque<T> 容器的介面卡類模板,預設實現的是一個先入先出(First-In-First-Out,LIFO)的佇列。可以為它指定一個符合確定條件的基礎容器。queue<T> 模板定義在標頭檔案 queue 中。
  3. priority_queue<T>:是一個封裝了 vector<T> 容器的介面卡類模板,預設實現的是一個會對元素排序,從而保證最大元素總在佇列最前面的佇列。priority_queue<T> 模板定義在標頭檔案 queue 中。

 

7.stack堆疊操作

stack<T>容器介面卡中的資料是以 LIFO 的方式組織的,和其他序列容器相比,stack 是一類儲存機制簡單、所提供操作較少的容器。下面是 stack 容器可以提供的一套完整操作:

top():返回一個棧頂元素的引用,型別為 T&。如果棧為空,返回值未定義。

push(const T& obj):可以將物件副本壓入棧頂。這是通過呼叫底層容器的 push_back() 函式完成的。

push(T&& obj):以移動物件的方式將物件壓入棧頂。這是通過呼叫底層容器的有右值引用引數的 push_back() 函式完成的。

pop():彈出棧頂元素。

size():返回棧中元素的個數。

empty():在棧中沒有元素的情況下返回 true。

emplace():用傳入的引數呼叫建構函式,在棧頂生成物件。

swap(stack<T> & other_stack):將當前棧中的元素和引數中的元素交換。引數所包含元素的型別必須和當前棧的相同。對於 stack 物件有一個特例化的全域性函式 swap() 可以使用。

8. queue(STL queue)用法

只能訪問 queue<T> 容器介面卡的第一個和最後一個元素。只能在容器的末尾新增新元素,只能從頭部移除元素。

queue操作:

queue 和 stack 有一些成員函式相似,但在一些情況下,工作方式有些不同:

(1)front():返回 queue 中第一個元素的引用。如果 queue 是常量,就返回一個常引用;如果 queue 為空,返回值是未定義的。

(2)back():返回 queue 中最後一個元素的引用。如果 queue 是常量,就返回一個常引用;如果 queue 為空,返回值是未定義的。

(3)push(const T& obj):在 queue 的尾部新增一個元素的副本。這是通過呼叫底層容器的成員函式 push_back() 來完成的。

(4)push(T&& obj):以移動的方式在 queue 的尾部新增元素。這是通過呼叫底層容器的具有右值引用引數的成員函式 push_back() 來完成的。

(5)pop():刪除 queue 中的第一個元素。

(6)size():返回 queue 中元素的個數。

(7)empty():如果 queue 中沒有元素的話,返回 true。

(8)emplace():用傳給 emplace() 的引數呼叫 T 的建構函式,在 queue 的尾部生成物件。

(9)swap(queue<T> &other_q):將當前 queue 中的元素和引數 queue 中的元素交換。它們需要包含相同型別的元素。也可以呼叫全域性函式模板 swap() 來完成同樣的操作。

9.C++序列容器儲存智慧指標 

通常用容器儲存指標比儲存物件更好,而且大多數時候,儲存智慧指標比原生指標好。下面是一些原因:

在容器中儲存指標需要複製指標而不是它所指向的物件。複製指標通常比複製物件快。

(1)在容器中儲存指標可以得到多型性。存放元素基類指標的容器也可以儲存其派生型別的指標。當要處理有共同基類的任意物件序列時,這種功能是非常有用的。應用這一特性的一個常見示例是展示一個含有直線、曲線和幾何形狀的物件序列。

(2)對指標容器的內容進行排序的速度要比對物件排序快;因為只需要移動指標,不需要移動物件。

(3)儲存智慧指標要比儲存原生指標安全,因為在物件不再被引用時,自由儲存區的物件會被自動刪除。這樣就不會產生記憶體洩漏。不指向任何物件的指標預設為 nullptr。

10.各容器的實現原理

vector 擁有一段連續的記憶體空間

list 就是資料結構中的雙向連結串列

deque 的動態陣列首尾都開放

set 有序的容器,紅黑樹的平衡二叉檢索樹的資料結構

multiset 紅黑樹實現的,set插入的元素不能相同,但是multiset可以相同。

map  鍵不能重複,紅黑樹實現的,

mtltimap 紅黑樹實現的,允許鍵有重複
 

這一章感覺做成了字典,不應該這樣的!所以不再新增內容!這部分主要是各個容器的操作函式和演算法函式較多,感覺用的時候查一查。提供學習的地址:http://c.biancheng.net/stl/algorithms/