C++ STL標準庫與泛型程式設計(一)
泛型程式設計,就是使用模板為主要工具來編寫程式。其中沒有太多的面向物件的觀念,不涉及虛擬函式的使用。
使用C++標準庫
C++標準庫:以程式碼形式給出,放於各種標頭檔案( header files )內,經過編譯後才能使用。
所有新式的 headers 內的元件封裝於 namespace “std” 。
一、STL體系結構
STL標準庫約佔C++標準庫的85%,其中含有六大部件。 容器、演算法、迭代器、仿函式、配接器、配置器。以及一些小的部分。
allocator 一般有預設值,顯示化時,其引數型別要與容器型別匹配,否則編譯出錯。
count_if 演算法 計數給定條件下的元素個數。
not1 函式介面卡 表示條件反轉,括號內的小於40語意變成大於等於40。
bind2nd 函式介面卡 繫結第2引數,表示通過演算法 less 將容器內所有元素與常量40繫結比較。
less 函式物件 比較小於40。
前閉後開區間 [ ),例如 物件都有c.begin() 和 c.end()連個函式, c.end()指向最後一個元素地址的下一個地址。 *c.end() ×
for(begin:end)基於範圍的 for 迴圈
auto 省略型別定義,可由編譯器自動判斷型別
容器 — 結構與分類
1.Sequence Containers 序列式容器
Array 陣列類 —— 連續的固定大小的空間,不能自動擴充
Vector 陣列 —— 可由尾端擴充,由容器分配器自動完成
Deque 雙佇列 —— 雙向擴充
List —— 雙向連結串列 Forward List —— 單鏈表
2.Association Containers 關聯式容器 —— 有 key 和 value ,適合做查詢
Set / Multiset 集合 —— 底層記憶體由紅黑樹(高度平衡二分樹)實現,key 值就是 value
Map / Multimap 圖 —— 有 key 與 value,Multi 表示 key 值可重複
3.Unordered Containers —— C++11不定序容器 之前也歸於關聯式容器
基於 雜湊表雜湊連結串列 (Hash Table Separate Chaining)實現
Unordered Set / Multiset 無序集合 Unordered Map / Multimap 無序圖
容器的測試—限制與效率
無需將所有的 include 操作放在所有程式的最前面,以 namespace 將每段程式分隔開,每段測試用例所需的標頭檔案會更明瞭。而且 include 標頭檔案重複時有保護機制,所以不用擔心。
變數的宣告可不用全部寫在程式開始處,放在使用出利用凸排一目瞭然。
1.測試 array
array提供的操作函式:
size() 返回陣列大小 front() 返回第一個元素值
back() 返回陣列尾元素值 data() 返回陣列存放的首地址
其他:
clock() 記錄當前系統時間,返回毫秒數 ms clock() - timeStart 可得到執行時 間
qsort() 快速排序法 引數為起始地址,元素個數,元素佔用空間大小,元 素比較函式
bsearch() 二分查詢法,查詢前陣列必須有序,存放於cstdlib
2.測試 vector
Vector 提供的操作函式:
push_back() 元素放入Vector 尾端 vector容量增長的本質:每次空間不夠時,容器介面卡會在另一個記憶體空間將待用空間多次的兩倍擴張(1.2.4.8........),安排好擴張記憶體後將所有值複製過去。
size() 目前容器中真正元素的個數 capacity() 擴充後真正的容器容量 2的n次冪
::find() STL模板函式(全域性函式)循序查詢,返回值為迭代器 ::sort() STL模板函式(全域性函式)排序
在全隨機排列的情況下,sort 加 bsearch 的查詢方法所耗費的時間不如直接 find 循序查詢快,雖然二分查詢本身效率較高。
3.測試 List 、Forward_list
.sort() List容器的類方法,當容器自己提供 了 .sort() 函式時,其執行效率一定比全域性 ::sort() 要快。
forward_list只有 push_front() ,沒有 .back()取表尾 與 .size() 取表長函式。
4.測試 Deque
push_front() pop_front() push_back() pop_back()
記憶體中是分段連續的buffer,每次擴充時,擴充一個固定的 buffer 大小。
在佇列前後入隊出隊時,會自動修正++與--所指向的地址,以保證表面上看是連續的。
沒有 sort() 類方法,直接使用 ::sort() STL模板函式
queue 和 stack 都是基於 deque 實現,技術上本質為容器介面卡,因為只能先進先出或者先進後出,所以不提供迭代器。
關聯式容器的查詢速度非常快(結構為紅黑樹),快於所有的序列式容器。
5.測試 Multiset / Set
在set 中 insert 相同資料時,不會報錯,不會有異常返回。所以插入次數可能比元素個數少。
初始化後會自動排序,set 所具有的 insert 方法插入位置由排序自動決定。
6.測試 Multimap / Map
multimap<long,string> c;
c.insert(pair<long,string>(i,buf));
定義時要指定兩個引數 key 和 value。insert 時要將資料組合(pair)放入。
Multimap 不可使用 [ ] 做 insertion,map 可以 : c[ i ] = string (buf),i 預設為key,string 為 value。
取 value 時用 (*pItem).second
7.使用 Unordered Set / Multiset
.bucket_count() 籃子的個數,即雜湊表的大小。可能有的 bucket 存放多個元素,有的 bucket 不存放元素。
bucket 個數一定多餘元素個數,實現時如果元素個數大於等於籃子個數時,bucket 就會以大約兩倍擴充,散列表會重新打散放置。
8.分配器 — 使用
Windows中 Dev-C++ 、Code::Block 等整合開發環境下使用 GCC 編譯器編譯。
這些 allocator 後存放在 <ext\...> 中作為 GCC 擴充套件庫,並非 C++ 標準規定的,存放在__gnu_cxx::名稱空間中。
一般通過 allocator 呼叫容器的類方法來管理記憶體,一般沒有必要使用 allocate() 和 deallocate() 方法直接申請與銷燬記憶體(需指出所指定的記憶體大小)。