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对象。


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