1. 程式人生 > >C++ STL標準庫與泛型程式設計(一)

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 編譯器編譯。

https://blog.izgq.net/archives/841/

這些 allocator 後存放在 <ext\...> 中作為 GCC 擴充套件庫,並非 C++ 標準規定的,存放在__gnu_cxx::名稱空間中。

一般通過 allocator 呼叫容器的類方法來管理記憶體,一般沒有必要使用 allocate() 和 deallocate() 方法直接申請與銷燬記憶體(需指出所指定的記憶體大小)。