转载请注明原文出处:http://blog.youkuaiyun.com/roddick621
以下的知识点全部都是来自于C++ Primer 第四版,如果需要详细了解的话,可以查看原版的书籍。
第2章所设计的类型都是低级数据类型:这些类型表示数值货字符的抽象,并根据其具体机器来表示定义。除了这些语言中定义的类型外,C++标准库还定义了需要高级的抽象数据类型(abstract data type)。之所以说这些标准库类型是高级的,因为其中反映了更复杂的概念;之所以说它们是抽象的,是因为我们在使用时不需要关心他们是如何表示的,只需要知道这些抽象数据类型只是哪些操作就可以了。
1.命名空间的using声明。
在本章之前看到的程序,都是通过直接说明名字癞子std命名空间,来引用标准库中的名字。显然这种方法是非常麻烦的,C++提供了更加简介的方式来使用命名空间。本节讲介绍一种最安全的机制:using声明
使用using声明可以在不需要加前缀namespace_name::情况下使用该命名空间中的名字。using声明的格式如下:
using namespace::name;
一旦使用了using声明,我们就可以直接引用名字,而不许再引用该名字的命名空间。
1.1每个名字都需要一个using声明。
一个using声明一次只能够作用于一个命名空间成员。using声明可以用来明确指定在程序中用到的命名空间中的名字,如果需要使用std中的几个名字,则必须为要用到的每个名字都提供一个using声明。
using std::cin;
using std::cout;
using std::endl;
1.2使用标准库类型的类定义
有一种情况下,必须总是使用完全限定的标准库名字:在头文件中。理由是头文件的内容会被预处理器复制到程序中。用#include包含头文件时,相当于头文件中的文本讲成为我们编写的文件的一部分。如果在头文件中放置using声明,就相当于在包含该头文件的每个程序中都放置了同一using声明,不论该程序是否需要using声明。
2.标准库string类型。
string类型支持可变长度的支付穿,C++标准库讲负责管理与存储字符相关的内存,遗迹提供各种有用的操作。如果需要用到string类型对象,必须包含相关的头文件和合适的using声明。
#include <string>
using std::string;
2.1string对象的定义和初始化。
string s1; | 默认构造函数,s1为空串 |
string s2(s1); | 将s2初始化为s1的一个副本 |
string s3("value"); | 将s3初始化为ige字符串字面值副本 |
string s4(n,'c'); | 将s4初始化为字符'c‘的n个副本 |
2.2 string对象的读写
从标准输入读取string,并将读入的串存储在s中(cin >> s),string类型的输入操作符:
- 读取并忽略开头所有的空白字符(如空格符,换行符,制表符)。
- 拂去字符知道在此遇到空白字符,读取终止。
1.读入位置数目的string对象。
把输入操作作为判断条件
int main()
{
string word;
whild (cin >> word)
cout << word <<endl;
return 0;
}
2.用getline读取整行文本。
getline接受两个参数:一个输入流对象和一个string对象。getline函数从输入流的下一行读取,并保存读取的内容到string中,但不包括换行符。并且getline不会忽略开头的换行符。
2.3string对象的操作
s.empty() | 如果s为空串,则返回true,否则返回false |
s.size() | 返回s中字符的个数 |
s[n] | 返回s中位置为n的字符,位置从0开始计数 |
s1 + s2 | 把s1和s2连接成一个新字符串,返回新生成的字符串 |
s1 = s2 | 把s1内容替换成s2的副本 |
v1 == v2 | 比较v1和v2的内容,相等则返回true,否则返回false. |
!=,<, <=, > 和>= | 保持这些操作符惯有的含义 |
1.string::size_type类型
从逻辑上讲,size()成员函数似乎应该返回整型数值,但是事实上,size操作返回的是string::size_type类型的值。我们需要对这种类型做一些解析。string类类型和许多其他库都定义了一些配套类型。通过这些配套类型,库类型的使用就能够与机器无关。size_type就是这些配套类型中的一种。它定语为与unsigned型(unsigned int或unsigned long)具有相同的含义,而且可以保证组否达能够存储任意string对象的长度。为了使用由string类型定义的size_type类型,程序员必须加上作用域操作符来说明使用的size_type是又string类定义的。
2.string关系操作符
string对象比较操作是区分大小写的。关系操作符比较两个string对象是采用了和(大小写敏感的)字典排序相同的策略:
- 如果两个string对象长度不同,且短的string对象与长的string对象的前面部分相匹配,则短的string对象小于长的string对象。
- 如果两个string对象的字符不同,则比较第一个不匹配的字符。
2.4string对象中字符串的处理
我们经常要对string对象中的单个字符进行处理,可以通过定义在cctype头文件中的函数进行操作。
isalnum(c) | 如果c是字幕或数字,则为true |
isalpha(c) | 如果c是字幕,则为true |
iscntrl(c) | 如果c是控制字符,则为true |
isdigit(c) | 如果c是数字,则为true |
isgraph(c) | 如果c不是空格,但可以打印,则为true |
islower(c) | 如果c是小写字母,则为true |
isprint(c) | 如果c是可打印的字符,则为true |
ispunct(c) | 如果c是标点符号,则为true |
isspace(c) | 如果c是空白字符,则为true |
isupper(c) | 如果c是大写字母,则为true |
isxdigit(c) | 如果c是十六进制数,则为true |
tolower(c) | 如果c是大写字母,则返回小写字母形式,否则直接返回c |
toupper(c) | 如果c是小写字母,则返回大写字母形式,否则直接返回c |
表中的这些函数,可打印的字符失职那些可以显式表示的字符。空白字符则是空格、制表符、垂直制表符、回车符、换行符和进纸符的任意一种;标点符号择食除了数字、字母或(可打印的)空白字符(如空格)以外的其他可打印字符。
3.标准vector类型
vector是同一种类型的对象的集合,对每个对i徐昂都有一个对象的整数索引值。和string对象一样,标准库讲负责管理与存储元素相关的内容。我们把vector成为容器,因为他/她可以包含其他对象。在使用vector之前,必须包含相应的头文件。
#include <vector>
using std::vector;
vector是一个类模板。使用模板可以编译一个类定义或函数定义,而用于不同的数据类型。
3.1 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中元素的数据类型。如果为in则用0来初始化,如果保存的是含有构造函数的类类型(如string)的元素,标准库将用该类型的默认构造函数来创建元素初始化式。
3.2 vector对象的操作
v.empty() | 如果v为空,则返回true,否则返回false |
v.size() | 返回v中元素的个数。 |
v.push_back(t) | 在v的末尾增加一个值为t的元素。 |
v[n] | 返回v中位置为n的元素。 |
v1 = v2 | 把v1的元素替换为v2中元素的副本 |
v1 == v2 | 如果v1与v2相等,则返回true。 |
!=, <, <=, >, >= | 保持这些操作符惯有的含义 |
- 使用size_type类型时,必须指出该类型是在哪里定义的。vector类型总是包括vector的元素类型。eg:vector<int>::size_type
- 下标操作不添加元素,下标只能用于获取已存在的元素。
4.迭代器简介。
除了使用下标来访问vector对象的元素外,标准库还提供了另外一种访问元素的方法:使用迭代器(iterator)。迭代器是一种检查容器内元素并遍历元素的数据类型。标准库为每一种标准容器都定义了一种迭代器类型。
4.1 容器的iterator类型
每种容器都定义了自己的迭代器类型,如vector: vector<int>::iterator iter;
这条语句定义了一个名为iter的变量,它的数据类型是由vecotr<int>定义的iterator类型。
4.2 begin和end操作
每种容易都定义了一堆明明为begin和end的函数,用于返回迭代器。如果容器中有元素的话,由begin返回迭代器指向的第一个元素:vector<int>::iterator iter=ivec.begin();
又end操作返回的迭代器指向vector的“末端元素的下一个”。通常称为超出末端迭代器,标明它指向一个不存在的元素。
4.3 vector迭代器的自增和解引用运算
迭代器类型可使用解引用操作符(*操作符)来访问迭代器所指向的元素。eg : *iter = 0; 如果iter指向vector对象ivec的第一个元素,那么*iter和ivec[0]就是指向同一个元素。
迭代器使用自增操作符向前移动迭代器指向容器中的下一个元素。如果iter指向第一个元素,则++iter指向第二个元素。
4.4 迭代器的其他操作
另一对可执行与迭代器的操作就是比较:用==或者!=操作符来比较两个迭代器,如果两个迭代器指向同一个元素,则他们相等,否则就不相等。
4.5 const_iterator
前面的程序用vector::iterator改变vector中的元素值。每种容器类型还定义了一种名为const_iterator的类型,该类型只能用于读取容器内元素,但不能改变其值。当我们对普通iterator类型解引用是,得到某个元素的非const引用。而如果我们对const_iterator类型解引用时,则可以得到一个指向const对象的引用,如同任何常量一样,该对象不能进行重写。
4.6 迭代器算术操作
- iter +/- n : 指向元素之前(加)或之后(减)n个位置的操作。
- iter1 - iter2 :计算两个迭代器对象的距离。该距离是名为difference_type的signed类型的值。
5.标准库bitset类型
标准库提供的bitset类简化了处理二进制位的有序集的处理。要用bitset,需要包含头文件和using声明:
#include <bitset> using std::bitset
5.1 bitset对象的定义和初始化
类似与vector,bitset类是一种类模板;而与vector不一样的是bitset类型对象的区别仅在其长度而不在其类型。在定义bitset时,要名且bitset含有多少位。
初始化bitset对象的方法 bitset<n> b; b有n位,每位都为0 bitset<n> b(u); b是unsigned long型u的一个副本 bitset<n> b(s); b是string对象s中含有的位串的副本 bitset<n> b(s,pos,n) b是s中存位置pos开始的n个位的副本 1.用unsigned值初始化bitset对象。
当用unsigned long值作为bitset对象的初始值,该值讲转化为二进制的位模式。而bitset对象中的位集作为这种模式的副本。如果bitset类型长度大雨unsigned long值的二进制位数,则其余的高阶位设置为0;如果bitset类型少于unsigned long值的二进制位数,则只是用unsigned值中的低阶位,超过bitset类型长度的高阶位将被抛弃。
bitset<16> bitvec1(0xffff) //bits 0...15 are set to 1 bitset<32> bitvec2(0xffff) //bits 0...15 are 1; 16...31 are 0 bitset<128> bitvec3(0xffff) //bits 32...127 are 0
2.用string对象初始化bitset对象
当用string对象初始化bitset对象时,string对象直接表示为位模式。从string对象读入位集的顺序是从右到左。
string strval("1100"); bitset<32> bitvec4(strval);
5.2 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流 |
输出二进制位。可以用输出操作符输出bitset对象中的位模式:
bitset<32> bitvec2(0xffff); cout << "bitvec2:" << bitvec2 <<endl; //bitvec2 : 00000000000000001111111111111111