c++標準庫類型

1.

#include <vector>

using std::vector;

使用vector來定義數據類型時,如果沒有初始化,它默認爲空,並且此時不能引用它的元素。如vector<int> ivec; cout<<ivec[0];會產生運行時錯誤,因爲此時ivec[0]並不存在。所以使用下表來引用vector中的元素時,此元素必須存在,可以使用push_back()來添加。附vector的四種定義方式:

vector<T> v1;

vector<T> v2(v1);

vector<T> v3(n,i);

vector<T> v4(n);//元素值默認調用相應的構造函數來初始化。沒有構造函數的,像int初始化爲0


2.迭代器:在使用 vector輸出裏面的元素時,通常使用數組下標來訪問,這和普通的數組訪問的方式類似。這裏我們介紹一種訪問容器元素的方法,稱爲迭代器。對於每一個容器,其內部都集成了一個迭代器類型,比如vector<int>::iterator和vector<int>::const_iterator類型,後者只用於讀取容器內的元素。每種容器都定義了begin和end兩個函數,begin返回值指向容器的第一個元素(如果容器不爲空的話),end返回值指向容器“末端元素的下一個”,即指向一個不存在的位置,只起到一個哨兵的作用。當vector爲空時,begin和end返回的迭代器相同。引用迭代器類似於c中的指針,使用*iter來引用,可以對其賦值或者讀取,可以執行自增自減操作或者算術運算,本人理解爲就迭代器就是一個內置指針而已。

vector<T>::iterator iter=ivec.begin();

vector<T>::const_interator=ivec.begin();

*iter=0;

iter++;

iter+=n;

iter1-iter2;

注意:iter1-iter2的類型是defference_type類型(實際上是一個signed類型),也是vector內置的類型,並且iter1和iter2必須都指向同一個vector中的元素或者執行vector末端之後的下一個元素。但是iter1+iter2沒有定義,使用會出現編譯錯誤;

3.bitset類型:

#include <bitset>

using std::bitset;

bieset也是一個模板,與vector的區別僅在於其長度而不在於其類型,定義時,必須明確bitset含有多少位。如bitset<32> bitvec;//32bits,all zero,初始化時可以使用unsigned來初始化,也可以使用string來初始化,使用string來初始化時需注意,string對象的最右邊字符來初始化bitset的低階位,就是把字符串和bieset反過來就行。

4.數組:數組的維數必須是大於1的常量表達式,此常量表達式只能包含整形字面值常量、枚舉常量或者用常量表達式初始化的整形const對象。非const變量以及要到運行階段才知道其值的const變量都不能用於定義數組的維數。

如int staff_size=27;char input[staff_size];//錯誤  

const unsigned sz=get_size();//雖然是const變量,但是需到運行時才能知道其值

int test[get_size()];//錯誤,不是const變量

int vals[sz];//錯誤,雖然是const,但是需到運行時才知道其值

此外,需要注意的是,一個數組不能用另外一個數組初始化,也不能將一個數組賦值給另一個數組,這些操作都是非法的。但是vector可以直接賦值,如:

vector<int> test1,test2;

test1.push_back(a);

test2=test1;//此時test2也包含了a這個元素。

如,int a[3]={0,1,2};

int b[3];

b=a;//錯誤

5.指針:聲明指針時,好的習慣是初始化,一個未經初始化的指針是危險的。

int *pi=0;//此時pi指向地址0x00000000

上式把0值賦給了pi,但是不允許把int型的變量賦給指針,這是非法的

int ival=0;

int *ppp=ival;//錯誤

但是允許把數值0或者在編譯時可獲得0值的const量賦給指針:

int *p;//未經初始化的,其值未定,在我的機器上,vc環境下,其值爲0xCCCCCCCC,指向了系統領空。

指針是有類型的,一個指針只能指向同類型的變量。除此之外,void*指針可以指向任何指針。

與引用的差別:區別1在於引用總是指向某個對象:定義引用時沒有初始化是錯誤的;第二個重要區別是賦值的差異。給引用賦值修改的是該引用所關聯的對象的值,而不是使引用與另一個對象關聯。引用一經初始化,就始終指向同一個特定對象(這也就是引用爲什麼必須在定義時初始化的原因)。比如:

int ival=1024,ival2=2048;

int *pi=&ival,&pi2=&ival2;

pi=pi2;//賦值的結果是,pi所指向的ival對象值保持不變,賦值操作修改了pi指針的值,使其指向另一個不同的對象。現在考慮另一段相似的程序,使用兩個引用賦值:

int &ri=ival,&ri2=ival2;

ri=ri2;//這個賦值操作修改了ri引用的值ival對象,而非引用本身。賦值後,這兩個引用還是分別指向原來關聯的對象,此時這兩個對象的值相等。

對於const的變量,必須定義const的指針與之對應。但是對於const的指針,可以指向非const的變量,但是不能通過此指針改變此變量的值。

不能使用void*指針保存const對象的地址,而必須使用const void *類型的指針保存const對象的地址。允許把非const對象的地址賦給指向const對象的指針,此非const對象可以通過其他方法來改變其值,但是不能使用const來改變。就是說:不能保證指向const的指針所指對象的值一定不可修改。

注意區分:

指向const對象的指針——const int *p;//不能通過他來改變指向對象的值

const指針——int *const p;//指針本身不能再指向其他對象,但是指向的對象的值可以改變。

指向const對象的const指針——const int *const p;//指針本身和所指向的對象都不能改變

6.指針和typedef:

typedef string *pstring;

const pstring cstr;

很容易把這個理解爲const string *cstr;此時表示的是指向const string對象的指針。但這樣理解是不對的,const是修飾pstring的,而pstring是一個string的指針,所以是修飾指針本身不能修改,就是把cstr定義爲指向string類型對象的const指針,這個定義等價於:

string *const cstr;

此外:

const pstring cstr;

pstring const cstr;

string *const cstr;

上述三種定義具有同一種類型,即指向string對象的const指針。

7.複雜的const類型聲明:(注意:定義const對象和const指針時都要初始化,否則會發生編譯錯誤)

string const s1;

const string s2;

s1和s2都是const類型的string對象。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章