1. 程式人生 > >C++語言學習(九)——C++標準庫簡介

C++語言學習(九)——C++標準庫簡介

模塊使用 sse libstdc++ 約定 ngs 列表 oss 雜項 pri

C++語言學習(九)——C++標準庫簡介

一、C++標準庫簡介

1、C++標準庫簡介

C++標準庫(C++ Standard Library),是類庫和函數的集合。?
C++編譯器廠商根據C++標準委員會官方的ISO規範並將其轉化為代碼。C++編譯器廠商在實現C++標準庫過程中必須依賴其不同操作系統所提供的系統調用接口,因此每個平臺都有其自己的C++標準庫實現。
C++標準庫的特點如下:
A、C++標準庫不是C++語言標準的一部分,由類庫和函數庫組成。
B、C++標準庫中定義的類和對象都位於std命名空間中。
C、C++標準庫的頭文件都不帶.h後綴。
D、C++標準庫涵蓋了C庫的功能。

2、C++編譯環境

C++編譯環境組成如下:
技術分享圖片
C++編譯環境的組成如下:
A、不同的C++編譯器有自己不同的C++擴展語法模塊
B、不同的C++編譯器有相同的C++標準語法模塊
C、不同的C++編譯器有自己的編譯器擴展庫
D、為了便於軟件開發,不同的C++編譯器附帶提供C語言兼容庫,C語言兼容庫頭文件帶.h後綴,如#include <stdio.h>,#include <math.h>等
E、C++標準庫中包含一個涵蓋C庫功能的子庫,通常頭文件以c開頭,如#include <cmath>,#include <cstring>等。
F、不同的C++編譯器都有C++編譯器廠商實現的遵循C++標準的C++標準庫,C++標準庫有相同的功能接口,但內部實現不同。

二、C++標準庫實現

1、C++標準庫實現簡介

C++標準庫是一組C++模板類,提供了通用的編程數據結構和函數,如鏈表、堆、數組、算法、叠代器等C++組件。C ++標準庫包含了C標準庫,並在C++標準中進行了定義。
C++編譯器開發廠商根據C++標準委員會官方發布的C++ ISO規範並將其轉化為代碼。C++編譯器廠商在編譯器實現過程中必須依賴其操作系統所提供的功能(讀/寫文件,分配內存,創建線程等系統調用),因此每個平臺都有其自己的標準庫實現。

2、GNU/Linux版實現

在GNU/Linux上,C++標準庫通常由libstdc++或GNU標準C++庫項目實現。通常,所有常規的Linux發行版都默認使用libstdc++。

3、Mac和iOS版實現

在OS X Mavericks(V10.9)前的Mac OS上,libstdc++是默認C++標準庫實現。自OS X Mavericks開始,Apple切換到使用libc++作為C++標準庫實現。

4、Windows版實現

在Windows上,C++標準庫的實現一直嚴格限定在微軟官方的編譯器Visual Studio中。Windows上的C++標準庫通常稱為C/C++運行時庫(CRT),涵蓋了C/C++二者的實現。
Windows最開始的C++標準庫實現為CRTDLL.DLL庫。Windows 95開始,Microsoft開始將其遷移到MSVCRT [版本號]?.DLL(MSVCR20.DLL,MSVCR70.DLL等)上。?
Visual Studio 2015引入了深度的CRT重構。C/C ++標準庫的實現遷移到一個新庫,Universal C運行時庫 (Universal CRT或UCRT),編譯為UCRTBASE.DLL。 UCRT從Windows 10開始作為操作系統的一部分提供。

5、Android版實現

Bionic是Google為其Android操作系統所編寫的C標準庫實現,直接在底層使用。第三方開發者可以通過Android原生開發工具包(NDK)訪問Bionic,NDK可以使用C和C++代碼編寫Android應用程序。
NDK提供了很多C++標準庫版本的實現:
A、libc++,從Lollipop開始的官方安卓系統和現代Mac操作系統都將其作為C++標準庫使用。從NDK發布17版本開始,成為NDK中唯一可用的C++標準庫實現。
B、gnustl,libstdc++的別名,在NDK發布18中刪除。
C、STLport,由STLport項目編寫的C++標準庫的第三方實現,自2008年以來一直處於不活躍狀態。STLport在NDK發布18中移除。

6、其它實現版本

C++標準庫也有不同的實現版本:Apache版C++標準庫,uSTL以及EASTL等等。Apache版本C++標準庫註重可移植性。

三、C++標準庫組成

1、?語言支持功能

<cstddef>:定義宏NULL和offsetof以及其它標準類型size_t和ptrdiff_t。與對應的標準C頭文件的區別是,NULL是C++空指針常量的補充定義(C++11中已有關鍵字nullptr),宏offsetof接受結構或者聯合類型參數,只要沒有成員指針類型的非靜態成員即可。
<limits>:提供與基本數據類型相關的定義。例如,對於每個數值數據類型,它定義了可以表示出來的最大值和最小值以及二進制數字的位數。
<climits>:提供與基本整數數據類型相關的C樣式定義,C++樣式定義在<limits>中。
<cfloat>:提供與基本浮點型數據類型相關的C樣式定義,C++樣式定義在<limits>中。
<cstdlib>:提供支持程序啟動和終止的宏和函數,還聲明了許多其他雜項函數,例如搜索和排序函數,從字符串轉換為數值等函數。<cstdlib>與對應的標準C頭文件stdlib.h不同,定義了abort(void)。abort()函數還有額外的功能,它不為靜態或自動對象調用析構函數,也不調用傳給atexit()函數的函數。它還定義了exit()函數的額外功能,可以釋放靜態對象,以註冊的逆序調用用atexit()註冊的函數。清除並關閉所有打開的C流,把控制權返回給主機環境。
<new>:支持動態內存分配。
<typeinfo>:支持變量在運行期間的類型標識。
<exception>:支持異常處理,是處理程序中可能發生的錯誤的一種方式。
<cstdarg>:支持接受數量可變的參數的函數。即在調用函數時,可以給函數傳送數量不等的數據項。定義了宏va_arg、va_end、va_start以及va_list類型。
<csetjmp>:為C樣式的非本地跳躍提供函數,在C++中不常用。
<csignal>:為中斷處理提供C樣式支持。

2、流輸入/輸出

<iostream>:支持標準流cin、cout、cerr和clog的輸入和輸出,還支持多字節字符標準流wcin、wcout、wcerr和wclog。
<iomanip>:提供操縱程序,允許改變流的狀態,從而改變輸出的格式。
<ios>:定義iostream的基類。
<istream>:為管理輸出流緩存區的輸入定義模板類。
<ostream>:為管理輸出流緩存區的輸出定義模板類。
<sstream>:支持字符串的流輸入輸出。
<fstream>:支持文件的流輸入輸出。
<iosfwd>:為輸入輸出對象提供向前的聲明。
<streambuf>:支持流輸入和輸出的緩存。
<cstdio>:為標準流提供C樣式的輸入和輸出。
<cwchar>:支持多字節字符的C樣式輸入輸出。

3、?診斷功能

<stdexcept>:定義標準異常。
<cassert>:定義斷言宏,用於運行時檢查。
<cerrno>:支持C樣式的錯誤信息。

4、工具函數

<utility>:定義重載的關系運算符,簡化關系運算符的寫入,還定義了pair類型,pair類型是一種模板類型,可以存儲一對值。
<functional>:定義了許多函數對象類型和支持函數對象的功能,函數對象是支持operator()()函數調用運算符的任意對象。
<memory>:給容器、管理內存的函數和auto_ptr模板類定義標準內存分配器。
<ctime>:支持系統時鐘函數。

5、字符串處理

<string>:為字符串類型提供支持和定義,包括單字節字符串(由char組成)的string和多字節字符串(由wchar_t組成)。
<cctype>:單字節字符類別。
<cwctype>:多字節字符類別。
<cstring>:為處理非空字節序列和內存塊提供函數。不同於對應的標準C庫頭文件,C樣式字符串的一般C庫函數被返回值為const和非const的函數對替代。
<cwchar>:為處理、執行I/O和轉換多字節字符序列提供函數,不同於對應的標準C庫頭文件,幾個多字節C樣式字符串操作的一般C庫函數被返回值為const和非const的函數對替代。
<cstdlib>:為把單字節字符串轉換為數值、在多字節字符和多字節字符串之間轉換提供函數。

6、容器類模板

<vector>:定義vector序列模板,是一個大小可以重新設置的數組類型,比普通數組更安全、更靈活。
<list>:定義list序列模板,是一個序列的鏈表,常常在任意位置插入和刪除元素。
<deque>:定義deque序列模板,支持在開始和結尾的高效插入和刪除操作。
<queue>:為隊列(先進先出)數據結構定義序列適配器queue和priority_queue。
<stack>:為堆棧(後進先出)數據結構定義序列適配器stack。
<map>:map是一個關聯容器類型,允許根據鍵值是唯一的,且按照升序存儲。multimap類似於map,但鍵不是唯一的。
<set>:set是一個關聯容器類型,用於以升序方式存儲唯一值。multiset類似於set,但是值不必是唯一的。
<bitset>:為固定長度的位序列定義bitset模板,它可以看作固定長度的緊湊型bool數組。
<array>:(TR1)固定大小數組,支持復制。
<forward_list>:(c++11)單向列表,支持快速隨機訪問。
<unordered_set>:(TR1)無序容器set,其元素隨機存放。multiset類似於set,但是值不必是唯一的。
<unordered_map>:(TR1)無序容器map,其鍵值隨機存放。multimap類似於map,但鍵不是唯一的。

7、叠代器

<iterator>:給叠代器提供定義和支持。

8、算法

<algorithm>:提供一組基於算法的函數,包括置換、排序、合並和搜索。
<cstdlib>:聲明C標準庫函數bsearch()和qsort(),進行搜索和排序。
<ciso646>:允許在代碼中使用and代替&&。

9、數值操作

<complex>:支持復雜數值的定義和操作。
<valarray>:支持數值矢量的操作。
<numeric>:在數值序列上定義一組一般數學操作,例如accumulate和inner_product。
<cmath>:這是C數學庫,其中還附加了重載函數,以支持C++約定。
<cstdlib>:提供的函數可以提取整數的絕對值,對整數進行取余數操作。

10、本地化

<locale>:提供的本地化包括字符類別、排序序列以及貨幣和日期表示。
<clocale>:對本地化提供C樣式支持。

四、C++標準庫使用示例

1、C++標準庫使用示例

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
    string s = "Hello, C++ Library.";
    cout << s <<endl;
    return 0;
}

上述代碼中,使用了C++標準庫中的string類和iostream流類。

2、C++標準庫的C庫子模塊使用示例

#include <iostream>
#include <cmath>

using namespace std;

int main(int argc, char *argv[])
{
    string s = "Hello, C module of C++ Library.";
    cout << s <<endl;
    double d = sqrt(4.0);
    cout << d << endl;
    return 0;
}

上述代碼中,使用了C++標準庫中的string類、iostream流類,以及C++標準庫中C庫的cmath庫。

3、C語言兼容庫使用示例

#include <stdio.h>
#include <math.h>

int main(int argc, char *argv[])
{
    const char* s = "Hello, C Compatible Library.";
    printf("%s\n", s);

    double d = sqrt(4);
    printf("%lf\n", d);
    return 0;
}

上述代碼中,使用了C兼容庫的stdio庫和math庫。

五、C++字符串類

1、C語言的字符串

C語言不支持真正意義上的字符串,但可以使用字符數組和一組函數實現字符串操作。C語言不支持自定義類型,因此也不能定義字符串類型。

2、C++語言的字符串

C++語言可以自定義類型,可以通過類完成字符串類型的定義,但C++語言也沒有原生的字符串類型。
C++語言通過C++標準庫提供的string類型實現對字符串類型的支持。
string類的特性如下:
A、string直接支持字符串連接
B、string直接支持字符串的大小比較
C、string直接支持子串查找和提取
D、string直接支持字符串的插入和替換

3、C++字符串與數字的轉換

C++標準庫提供了相關類對字符串和數字進行轉換。
字符串流類sstream用於string的轉換。
使用字符串流類需要包含#include <sstream>頭文件。
istringstream表示字符串輸入流,ostringstream表示字符串輸出流。

#include <iostream>
#include <sstream>

using namespace std;

int main(int argc, char *argv[])
{
    //字符串轉換為數字
    istringstream iss("3.14");
    double pi;
    if(iss >> pi)
    {
        cout << "PI = " << pi<< endl;
    }
    //數字轉換為字符串
    ostringstream oss;
    if(oss << pi)
    {
        string PI = oss.str();
        cout << "PI = " << PI << endl;
    }

    return 0;
}

4、字符串循環右移示例

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

string operator >> (const string& s, int n)
{
    string ret;
    unsigned int pos = 0;
    //右移位數計算
    n = n % s.length();
    //右移的開始位置
    pos = s.length() - n;
    //右移部分的子串作為起始
    ret = s.substr(pos);
    //連接未移動子串
    ret += s.substr(0,pos);
    return ret;
}

int main(int argc, char *argv[])
{
    string s = "abcdef";
    cout << (s >> 3) << endl;//"defabc"
    return 0;
}

5、string類操作註意事項

string類內部通過一個數據空間保存字符數據,通過一個成員變量保存當前字符串的長度。因此,C++開發中不能使用C語言的方式對string的存儲空間進行直接操作,而應該使用string提供的接口函數進行字符串操作。

#include <iostream>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
    string s = "12345";
    s.reserve(20);
    //直接對string對象的存儲空間進行操作
    for(int i = 0; i < 5; i++)
    {
        s[5+i] = ‘a‘+i;
    }
    cout << s << endl;//12345
    //string對象的存儲空間修改結果如下:
    for(int i = 0; i < 5; i++)
    {
        cout << s[5+i] << endl;
    }
    //通過string類接口進行字符串操作
    s.append("ABCD");
    cout << s <<endl;//12345ABCD
    return 0;
}

上述代碼中,直接對string對象的底層數據進行字符串操作後,使用string類的接口可能不能訪問到對string對象底層數據的修改。

C++語言學習(九)——C++標準庫簡介