STL實踐指南 一

2021-04-13 00:22:55 字數 4751 閱讀 2743

stl簡介

背景知識

一些基礎概念的定義

hello world程式

stl的煩惱之一——初始化

命名空間(namespace)

一些建議

另一種容器——集合(set)

所有的stl容器

stl簡介 

返回top

stl (標準模版庫,standard template library)是當今每個從事c++程式設計的人需要掌握的一項不錯的技術。我覺得每乙個初學stl的人應該花費一段時間來熟悉它,比如,學習stl時會有急劇公升降的學習曲線,並且有一些命名是不太容易憑直覺就能夠記住的(也許是好記的名字已經被用光了),然而如果一旦你掌握了stl,你就不會覺得頭痛了。和mfc相比,stl更加複雜和強大。

stl有以下的一些優點:

* 可以方便容易地實現搜尋資料或對資料排序等一系列的演算法;

* 除錯程式時更加安全和方便;

* 即使是人們用stl在unix平台下寫的**你也可以很容易地理解(因為stl是跨平台的)。

背景知識

返回top

寫這一部分是讓一些初學計算機的讀者在富有挑戰性的電腦科學領域有乙個良好的開端,而不必費力地了解那無窮無盡的行話術語和沉悶的規則,在這裡僅僅把那些行話和規則當作stler們用於自娛的創造品吧。

使用**

本文使用的**在stl實踐中主要具有指導意義。

一些基礎概念的定義

返回top

模板(template)——類(以及結構等各種資料型別和函式)的巨集(macro)。有時叫做甜餅切割機(cookie cutter),正規的名稱應叫做范型(generic)——乙個類的模板叫做范型類(generic class),而乙個函式的模板也自然而然地被叫做范型函式(generic function)。

stl——標準模板庫,一些聰明人寫的一些模板,現在已成為每個人所使用的標準c++語言中的一部分。

容器(container)——可容納一些資料的模板類。stl中有vector,set,map,multimap和deque等容器。

向量(vector)——基本陣列模板,這是乙個容器。

游標(iterator)——這是乙個奇特的東西,它是乙個指標,用來指向stl容器中的元素,也可以指向其它的元素。

hello world程式

返回top

我願意在我的**時間在這裡寫下我的程式:乙個hello world程式。這個程式將乙個字串傳送到乙個字元向量中,然後每次顯示向量中的乙個字元。向量就像是盛放變長陣列的花園,大約所有stl容器中有一半是基於向量的,如果你掌握了這個程式,你便差不多掌握了整個stl的一半了。

//程式:vector演示一

//目的:理解stl中的向量

// #include "stdafx.h" -如果你使用預編譯的標頭檔案就包含這個標頭檔案

#include // stl向量的標頭檔案。這裡沒有".h"。

#include // 包含cout物件的標頭檔案。

using namespace std;  //保證在程式中可以使用std命名空間中的成員。

char* szhw = "hello world"; 

//這是乙個字元陣列,以」/0」結束。

int main(int argc, char* argv)

// push_back函式將資料放在向量的尾部。

// 將向量中的字元乙個個地顯示在控制台

for (vi=vec.begin(); vi!=vec.end(); vi++)

// 這是stl迴圈的規範化的開始——通常是 "!=" , 而不是 "<"

// 因為"<" 在一些容器中沒有定義。

// begin()返回向量起始元素的游標(iterator),end()返回向量末尾元素的游標(iterator)。

// 使用運算子 「*」 將資料從游標指標中提取出來。

cout << endl;  // 換行

return 0;

} push_back是將資料放入vector(向量)或deque(雙端佇列)的標準函式。insert是乙個與之類似的函式,然而它在所有容器中都可以使用,但是用法更加複雜。end()實際上是取末尾加一(取容器中末尾的前乙個元素),以便讓迴圈正確執行——它返回的指標指向最靠近陣列界限的資料。就像普通迴圈中的陣列,比如for (i=0; i<6; i++) ——ar[6]是不存在的,在迴圈中不會達到這個元素,所以在迴圈中不會出現問題。

stl的煩惱之一——初始化

返回top

stl令人煩惱的地方是在它初始化的時候。stl中容器的初始化比c/c++陣列初始化要麻煩的多。你只能乙個元素乙個元素地來,或者先初始化乙個普通陣列再通過轉化填放到容器中。我認為人們通常可以這樣做:

//程式:初始化演示

//目的:為了說明stl中的向量是怎樣初始化的。

#include // 和相同

#include

using namespace std;

int ar[10] = ;

char* str = "hello world";

int main(int argc, char* argv)

在程式設計中,有很多種方法來完成同樣的工作。另一種填充向量的方法是用更加熟悉的方括號,比如下面的程式:

//程式:vector演示二

//目的:理解帶有陣列下標和方括號的stl向量

#include

#include

#include

using namespace std;

char* szhw = "hello world";

int main(int argc, char* argv)

for (i=0; i這個例子更加清晰,但是對游標(iterator)的操作少了,並且定義了額外的整形數作為下標,而且,你必須清楚地在程式中說明為向量分配多少記憶體空間。

命名空間(namespace)

返回top

1.用using關鍵字使用這個命名空間,在檔案的頂部,但在宣告的標頭檔案下面加入:

using namespace std;

這對單個工程來說是最簡單也是最好的方法,這個方法可以把你的**限定在std命名空間中。

2.使用每乙個模板前對每乙個要使用的物件進行宣告(就像原形化):

using std::cout;

using std::endl;

using std::flush;

using std::set;

using std::inserter;

儘管這樣寫有些冗長,但可以對記憶使用的函式比較有利,並且你可以容易地宣告並使用其他命名空間中的成員。

3.在每一次使用std命名空間中的模版時,使用std域識別符號。比如:

typedef std::vector vec_str;

這種方法雖然寫起來比較冗長,但是是在混合使用多個命名空間時的最好方法。一些stl的狂熱者一直使用這種方法,並且把不使用這種方法的人視為異類。一些人會通過這種方法建立一些巨集來簡化問題。

除此之外,你可以把using namespace std加入到任何域中,比如可以加入到函式的頭部或乙個控制迴圈體中。

一些建議

返回top

為了避免在除錯模式(debug mode)出現惱人的警告,使用下面的編譯器命令:

#pragma warning(disable: 4786)

另一條需要注意的是,你必須確保在兩個尖括號之間或尖括號和名字之間用空格隔開,因為是為了避免同「>>」移位運算子混淆。比如

vector > veclis;

這樣寫會報錯,而這樣寫:

vector > veclis;

就可以避免錯誤。

另一種容器——集合(set)

返回top

這是微軟幫助文件中對集合(set)的解釋:「描述了乙個控制變長元素序列的物件(注:set中的key和value是key型別的,而map中的 key和value是乙個pair結構中的兩個分量)的模板類,每乙個元素包含了乙個排序鍵(sort key)和乙個值(value)。對這個序列可以進行查詢、插入、刪除序列中的任意乙個元素,而完成這些操作的時間同這個序列中元素個數的對數成比例關係,並且當游標指向乙個已刪除的元素時,刪除操作無效。」

而乙個經過更正的和更加實際的定義應該是:乙個集合(set)是乙個容器,它其中所包含的元素的值是唯一的。這在收集乙個資料的具體值的時候是有用的。集合中的元素按一定的順序排列,並被作為集合中的例項。如果你需要乙個鍵/值對(pair)來儲存資料,map是乙個更好的選擇。乙個集合通過乙個鍊錶來組織,在插入操作和刪除操作上比向量(vector)快,但查詢或新增末尾的元素時會有些慢。

下面是乙個例子:

//程式:set演示

//目的:理解stl中的集合(set)

#include

#include

#include

using namespace std;

如果你感興趣的話,你可以將輸出迴圈用下面的**替換:

copy(strset.begin(), strset.end(), ostream_iterator(cout, " "));

.集合(set)雖然更強大,但我個人認為它有些不清晰的地方而且更容易出錯,如果你明白了這一點,你會知道用集合(set)可以做什麼。

所有的stl容器

返回top

容器(container)的概念的出現早於模板(template),它原本是乙個電腦科學領域中的乙個重要概念,但在這裡,它的概念和stl混合在一起了。下面是在stl中出現的7種容器:

STL實踐指南

stl實踐指南 作者 jeff bogan 介紹這是一篇指導您如何在microsoft visual studio下學習stl並進行實踐的文章。這篇文章從stl的基礎知識講起,循序漸進,逐步深入,涉及到了stl編寫 的方法 stl 的編譯和除錯 命名空間 namespace stl中的ansi is...

STL實踐指南上

譯者注 這是一篇指導您如何在microsoft visual studio下學習stl並進行實踐的文章。這篇文章從stl的基礎知識講起,循序漸進,逐步深入,涉及到了stl編寫 的方法 stl 的編譯和除錯 命名空間 namespace stl中的ansi iso字串 各種不同型別的容器 contai...

STL實踐指南(上)

譯者注 這是一篇指導您如何在microsoft visual studio下學習stl並進行實踐的文章。這篇文章從stl的基礎知識講起,循序漸進,逐步深入,涉及到了stl編寫 的方法 stl 的編譯和除錯 命名空間 namespace stl中的ansi iso字串 各種不同型別的容器 contai...