跟我學C++中級篇——STL的學習
一、c++標準庫
C++的標準庫主要包含兩大類,首先是包含C的標準庫的,當然,為了適應c++對一些C庫進行了少許的修改和增加。最重要的當然是物件導向的c++庫;而c++庫又可以分成兩大類,即物件導向的c++庫和標準模板庫,也就是題目中的STL。另外在此基礎上,還要提醒同學們的是,除了上面的庫,在各個平臺的開發廠商中,還會針對實際情況,對標準庫進行擴充套件,這些可以歸納為擴充套件庫。
同時,隨著c++標準的不斷迭代,還推出了很多新的庫,同學們需要不斷的學習跟進,目前最新的c++標準為c++20。主流的c++標準庫實現有GNU/Linux上的libstdc++;IOS的libc++;微軟的CRT,android的libc++,當然在NDK有過很多c++的版本,不過後來都被刪除了;其它包括uSTL,Apache等很多大公司也有自己的相關的c++庫(這裡就不能叫標準庫了,雖然實現的目的是一樣的)。下面是相關庫的基本組成部分分類:
c庫主要包括:
1、標準輸入輸出,比如stdin,stdout,stderr。
2、字串處理,比如strcat,strcopy等。
3、記憶體管理,如果malloc等。
4、日期、時間和本地化等如ctime,time,localtime等。
5、數學相關函式,如pow,cos等。
6、系統和管理相關函式,它定義了和OS相關的訊號和函式呼叫規則,如setjmp,va_start等。
7、異常和錯誤,最典型的就是errno。
8、其它輔助如一些巨集定義等。
c++庫主要包括:
1、標準的IO類,如std::cout,std::in,ofstream等。
2、必須要提到的std::string。
3、數值處理相關類,numeric的complex。
4、本地化庫。
5、異常庫。
6、其它。
7、STL(標準模板庫)。
在後面的學習應用中將以STL為主,穿插學習標準庫的其它用法。
二、STL主要分類
STL標準模板庫主要分類:
1、STL容器(Containers),包含順序容器和關聯容器以及無序容器
容器非常好理解,日常的容器可以盛納各種液體和物品。而在STL的容器可以盛納各種資料。它分為順序容器和關聯容器兩大類,順序容器是指讀寫按照容器內的元素位置進行操作。你可以理解成一個箱子裡有好多小格子,你可以根據小格子的順序來取到其中的內容。它主要包括向量(Vector),連結串列(List)和雙端佇列(deque);而關聯容器則是需要通過一個鍵值(KEY)來讀寫容器的元素。在標準庫裡主要就是對映(map)和集合(set)。無序容器主要包括unordered_set和unordered_map。
2、STL迭代器(Iterators)
迭代器其實更好理解,就是一種可以通用在容器中的遍歷訪問的模板指標。就是一個資料訪問的索引。
3、STL分配器(Allocators)
分配器其實就是為了方便對容器等的通用化記憶體管理,提供的一種記憶體分配管理機制,可以理解成一種STL中的記憶體池。
4、STL介面卡(Adapters)
介面卡這個概念有點意思,其實如果有過介面開發經驗的可能更容易明白,兩種不同的介面要想使用同一個資料體系,就需要寫一個小模組來進行介面資料的統一,這個小模組就叫做介面卡。它其實是一種設計模式,而這種思想體現在STL中,就成為了介面卡。
5、STL仿函式(函式物件)(Functors)
仿函式,有的翻譯成函式物件,這個更有意思,其實就是通過前面提到的過載運算子(),實現了類似於函式使用的機制。在c++11後,提供了更安全的std::function。
6、STL演算法(Functors)
模板庫最初其實就是為了實現演算法而設計的,這個在《c++程式設計思想》中的“通用演算法”中有過提及。演算法可能是同學們最容易理解但最不容易掌握的一部分了。比如常見的查詢,排序以及刪除、複製等。
除了上面這些基礎的分類,在c++的新版本中又增加了概念等相關的知識,有興趣可以看看本公眾號中c++20的新功能相關文章。
三、例程
後面會對這些STL的基本容器和演算法逐一進行分析,這裡給出一個綜合例子:
#include <iostream>
#include <vector>
#include <list>
#include <queue>
#include <array>
#include <algorithm>
struct Data
{
int len = 0;
int type = 0;
};
//類似陣列
void TestVector()
{
std::vector<Data> vec;
Data d1;
Data d2;
vec.emplace_back(d1);
vec.push_back(d2);
std::cout << "vector first:" << vec[0].len << std::endl;
std::cout << "vector size:" << vec.size() << std::endl;
}
//連結串列
void TestList()
{
std::list<int> l;
l.push_back(3);
l.push_front(9);
l.emplace_back(6);
std::cout << "list first:" << l.front() << std::endl;
std::cout << "list size:" << l.size() << std::endl;
}
//佇列
void TestQueue()
{
std::queue<int> q;
q.emplace(10);
q.push(20);
q.push(30);
std::cout << "queue first:" << q.front() << std::endl;
q.pop();
std::cout << "queue first:" << q.front() << std::endl;
q.pop();
std::cout << "queue first:" << q.front() << std::endl;
q.pop();
}
int buf[] = { 10,9,21,68,96,11,11,11,88,199,36,96,60,126,19,168 };
void TestSort()
{
std::array<int, 16> arr = { 0,9,21,68,96,11,11,11,88,199,36,96,60,126,19,168 };
std::sort(arr.begin(), arr.end());
std::cout << " ordered reslut:" << std::endl;
for (int num = 0; num < 16; num++)
{
std::cout << arr[num] << " ";
}
std::cout << " " << std::endl;
}
void TestSearch()
{
std::sort(buf,buf+16);
bool result = std::binary_search(buf,buf+16, 199);
std::cout << "search result:" << result << std::endl;
}
void TestCopy()
{
int buf_dst[100] = {0};
std::copy(buf,buf+16,buf_dst);
std::cout << "copy result:" << std::endl;
for (auto& au : buf_dst)
{
std::cout << au << " ";
}
std::cout << " " << std::endl;
}
int main()
{
TestVector();
TestList();
TestQueue();
//排序
TestSort();
TestSearch();
TestCopy();
std::cout << "STL test project!" << std::endl;
}
執行結果是:
vector first:0
vector size:2
list first:9
list size:3
queue first:10
queue first:20
queue first:30
ordered reslut:
0 9 11 11 11 19 21 36 60 68 88 96 96 126 168 199
search result:1
copy result:
9 10 11 11 11 19 21 36 60 68 88 96 96 126 168 199 0 0 0 0
STL test project!
這裡仍然提醒注意的是,新標準在快速迭代,要注意更新標準的知識。
四、注意點
1、c++標準庫不是萬能的,有些庫其實並不多受歡迎,比如標準輸入輸出的流操作。
2、c++標準庫使用不復雜,但內部機制越來越複雜,特別模板機制,本身就是一個複雜而又困難的事情。而新標準中增加的協程等更是提高了內部實現的複雜度。
3、c++標準從c++11迭代的速度明顯加快,要注意新版本的更新和跟進。
五、總結
在STL的學習過程中,會把相關的原始碼解析也會展開一部分,這樣,既可以更好的瞭解庫的內部實現,又容易理解庫的應用情況。STL是學c++的人繞不過去的庫,不想用,不代表不需要。
相關文章
- STL學習
- C++ 學習筆記之——STL 庫 queueC++筆記
- C++學習筆記 — STL標準模板庫C++筆記
- C++ 學習筆記(1):STL、Vector 與 SetC++筆記
- C++學習篇(2)C++
- Java工程師學習指南 中級篇Java工程師
- Java工程師學習指南(中級篇)Java工程師
- C++STL學習第一篇(什麼是STL以及string的各種功能用法)C++
- 跟我學SpringCloud | 第一篇:介紹SpringGCCloud
- 跟我學習javascript的call(),apply(),bind()與回撥JavaScriptAPP
- C++中cbegin迭代器學習C++
- Java工程師學習指南 初級篇Java工程師
- Java工程師學習指南(初級篇)Java工程師
- 談談 C++ STL 中的迭代器C++
- C++遠征離港篇-學習筆記C++筆記
- 跟我學SpringCloud | 第二篇:註冊中心EurekaSpringGCCloud
- 跟我學SpringCloud | 第十二篇:Spring Cloud Gateway初探SpringGCCloudGateway
- 跟我學SpringCloud | 第四篇:熔斷器HystrixSpringGCCloud
- 學習篇:NodeJS中的模板引擎:jadeNodeJS
- c++學習C++
- C++中string字串的基礎操作,學習C++字串
- 跟我學SpringCloud | 第三篇:服務的提供與Feign呼叫SpringGCCloud
- C++學習步驟(C++該如何學)C++
- 【演算法學習】STL庫 大小根堆的用法演算法
- 如何學習C++?C++
- C++ Prime 學習C++
- C++ 自我學習C++
- C++學習四C++
- C++學習五C++
- 演算法中級學習3演算法
- 演算法中級學習1演算法
- 《跟我學Shiro》學習筆記 第四章:編碼/加密筆記加密
- C++ STL -- vectorC++
- C++ STL -- listC++
- C++ STL -- HashTableC++
- C++ STL stackC++
- C++ STL listC++
- 跟我學SpringCloud | 第六篇:Spring Cloud Config Github配置中心SpringGCCloudGithub