C++Primer学习笔记(二)标准库类型

3.1 命名空间的using声明

前面看到过std::cin这样的读取数据操作,如果每次读取数据时都这么写代码会感觉非常麻烦和不简洁,现在介绍一种最安全的机制:using声明。

-使用using声明,我们可以直接引用名字,而不需要在引用改名字的命名空间。

如: using std::cin;

-每个名字都需要一个using声明
-对cin,cout和endl进行using声明,就意味着以后可以省去前缀std::,直接使用命名空间中的名字,这样代码可以更易读

3.2 标准库string类型

摘要:

string类型的输入操作符:

Ø 读取并忽略开头所有空白字符

Ø 读取字符直至再次遇到空白字符,读取终止。

 

用getline读取整行文本:

-这个函数接受两个参数:一个输入流对象和一个string对象

-getline 函数从输入流的下一行读取,并保存读取的内容到不包括换行符。

-与输入操作符不一样:不忽略行开头发换行符。

-只要 getline 遇到换行符,即便它是输入的第一个字符,getline 也将停止读入并返回。

-由于 getline 函数返回时丢弃换行符,换行符将不会存储在 string 对象中。

 

标准库vector类型

-vector是同一种类型的对象的集合,每个对象都有一个对应的整数索引值。

-vector被称为容器,是因为它可以包含其他对象,一个容器中的所有对象都必须是同一种类型的。

-vector是一个类模板,使用模板可以编写一个类定义或函数定义,而用于多个不同的数据类型。

-和其他变量一样,定义vector对象要指定和一个变量列表。

具体如下:

vector<int> ivec;  //该类型即是含有若干int类型对象,变量名为ivec

 

- vector对象的定义和初始化

下面介绍几种初始化vector对象的方式

vector<T>v1;            vector 保存类型为 T 对象

                                 默认构造函数,v1为空

vector<T>v2(v1);     v2是v1的一个副本

vector<T>v3(n,i);     v3包含n个值为i的元素

vector<T>v4(n);       v4含有初始化的元素的n个元素

 

vector 对象动态增长

vector 对象(以及其他标准库容器对象)的重要属性就在于可以在运行时高效地添加元素。

因为 vector 增长的效率高,在元素值已知的情况下,最好是动态地添加元素。

虽然可以对给定元素个数的 vector 对象预先分配内存,但更有效的方法是先初始化一个空 vector 对象,然后再动态地增加元素

 

vector对象的操作

-vector标准库提供了许多类似string对象的操作

v.empty()     如果 v 为空,则返回 true,否则返回 false。
v.size()      返回 v 中元素的个数。
v.empty()     如果 v 为空,则返回 true,否则返回 false。
v.push_back(t)    在 v 的末尾增加一个值为 t 的元素。
v[n]         返回 v 中位置为 n 的元素。
v1 = v2        把 v1 的元素替换为 v2 中元素的副本。
v1 == v2      如果 v1 与 v2 相等,则返回 true。
!=, <, <=,
>, and >=    保持这些操作符惯有的含义。

-如对size和empty的操作跟string类型一样的

 

向vector添加元素

用以下代码来说明:

 string word;

vector<string> text;

while(cin >> word){

      text.push_back(word);

}

-上述代码中 text.push_back(word)是vector对象text引用push_bacd()函数,这个操作的作用是为vector添加元素,添加到vector对象的后面。

 

vector的下标操作

跟string类型类似,用size_type类型作为vector下标类型:

for(vector<int>::size_typeix=0;ix!=str.size();++ix)

ivec[ix]=0;

-警告:下标操作不添加元素;仅能对确定存在的元素进行下标操作。

 

C++ 程序员习惯于优先选用 != 而不是 < 来编写循环判断条件。

我们倾向于在每次循环中测试 size的当前值,而不是在进入循环前,存储 size 值的副本。

 

3.4 迭代器简介

-迭代器是一种检查容器内元素并遍历元素的数据类型

-它可以代替下标操作来访问元素,并且比下标操作跟通用,所有标准库容器都定义了相应的迭代器类型,而只有少数的容器支持下标操作。

 

容器的iterator类型

如vector:

vector<int>::iterator iter; //定义名为iter的变量,它的数据类型是由vector<int>定义的iterator类型。

术语:迭代器和迭代器类型

-重要理解:若一种类型支持一组确定的操作(这些操作可用来遍历容器内的元素,并访问这些元素的值),我们就称这种类型为迭代器。

 

begin和end操作

-这两个操作用来返回迭代器

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

-用begin操作返回迭代器指向的第一个元素,end操作来返回迭代器指向的最后一个元素的下一个元素(称为超出末端迭代器)

如果 vector 为空,begin 返回的迭代器与 end 返回的迭代器相同。

由 end 操作返回的迭代器并不指向 vector 中任何实际的元素,相反,它只是起一个哨兵(sentinel)的作用,表示我们已处理完 vector 中所有元素。

由于 end 操作返回的迭代器不指向任何元素,因此不能对它进行解引用或自增操作。

如果两个迭代器对象指向同一个元素,则它们相等,否则就不相等。

 

const_iterator

-每种容器类型还定义const_iterator的类型,该类型只能用于读取容器内的元素,但不能改变其值。

-当对const_iterator类型进行解引用(*),返回的是一个const值,不允许用const_iterator进行赋值。

-使用const_iterator类型时,它自身的值可以改变,但不能用来改变其所指向的元素的值。

-可以对迭代器进行自增以及使用解引用操作符来读值,但不能对该元素值赋值。

-注意:不要把const_iterator对象与const的iterator对象混淆。

-const迭代器几乎没什么作用,因为一旦它初始化,只能用它来改写其指向的元素,而不能使它指向任何元素。

 

 

3.5 标准库bitset类型

-提供bitset类型是用来处理二进制位的有序集的。

-bitset也是一种类模板,但与vector的区别仅在其长度而不在其类型。

-在定义bitset时,要明确bitset含有多少位,须在尖括号内给出长度值:

bitset<32>bitvec;   //bitvec被定义为含有32位的bitset对象

 

初始化bitset对象的方法

bitset<n>b;            //对象b有n为位,每位为0

bitset<n> b(u);       //b是unsignedlong型u的一个副本

bitset<n> b(s);       //b是string对象s中含有位串的副本

bitset<n> b(s,pos,n);//b是s中从位置pos开始的n个位的副本

-当用unsigned long值作为bitset对象的初始值时,该值将转化为二进制的位模式。

十六进制值0xffff表示为二进制位就是十六个1和十六个0

//bitvec1 的长度小于初始化值

bitset<16>bitvec1(0xffff);   //0~15位被设置为1

//bitvec2的长度和unsigned long相同

bitset<32>bitvec2(0xffff);   //0~15位设置为1,16~31位设置为0

//bitset3的长度大于usigned long

bitset<128>bitvec3(0xffff);  //位32到127被初始化为0

当用string对象初始化bitset对象时,string对象直接表示为为模式。从string对象读入位集的顺序是从右向左:

string strval(“1100”);

bitset<32>bitvec4(strval);

//bitvec4的位模式中第2和3位置为1,其余位置都为0.

-注解:string对象和bitset对象之间是反向转化:string对象的最右边字符(即下标最大的那个字符)用来初始化bitset对象的低阶位(即下标为 0 的位)。

 

bitset对象上的操作

-用来测试或设置bitset对象中的单个或多个二进制位。

表 3.7. bitset 操作
b.any()      b 中是否存在置为 1 的二进制位?
b.none()       b 中不存在置为 1 的二进制位吗?
b.count()      b 中置为 1 的二进制位的个数
b.size()        b 中二进制位的个数
b[pos]       访问 b 中在 pos 处二进制位
b.test(pos)      b 中在 pos 处的二进制位置为 1 么?
b.set()       把 b 中所有二进制位都置为 1
b.set(pos)      把 b 中在 pos 处的二进制位置为 1 

b.reset()      把 b 中所有二进制位都置为 0
b.reset(pos)      把 b 中在 pos 处的二进制位置为 0
b.flip()       把 b 中所有二进制位逐位取反
b.flip(pos)      把 b 中在 pos 处的二进制位取反
b.to_ulong()     用 b 中同样的二进制位返回一个 unsigned long 值
os << b       把 b 中的位集输出到 os 流

 

-count操作的返回类型是标准库中命名为size_t的类型

-bitset的size操作返回bitset对象中二进制位的个数,返回值是size_t的类型

posted @ 2020-07-23 09:50  thsj  阅读(95)  评论(0)    收藏  举报