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

来源:互联网 发布:centos ftp服务器配置 编辑:程序博客网 时间:2024/06/07 15:42

一、命名空间的using指示与using声明

1、using声明

(1)一个using声明一次只引入一个命名空间成员。

(2)using声明的作用域为:从using声明点开始,直到包含该using声明的作用域的末尾,名字都是可见的。类作用域中的using声明局限于被定义类的基类中定义的名字。

using std::string;using std::vector;

2、using指示(待续)

(1)using指示使得特定命名空间的所有名字可见,没有限制。

(2)可以尝试使用using指示编写程序,但在使用多个库的时候,这样做会重新引入名字冲突的所有问题。因此,使用using指示应有所限制。

3、除了在函数或其他作用域内部,头文件不应该包含using声明或using指示。在顶级作用域包含using指示或using声明的头文件,具有将该名字注入所有包含该头文件的文件中的效果。在头文件中,最好总是使用完全限定的标准库名字,比如 std::cout 等。

注:头文件中应该只定义确实必要的东西。

二、标准库string类型

1、string对象的定义和初始化

(1)string标准库的默认构造函数将string对象初始化为空串。

(2)编程时要注意区分字符串字面值和string数据类型的使用。

2、string对象的读写

(1)可以用iostream和string标准库,使用标准输入输出操作符来读写string对象。

cin操作符会读取并忽略开头所有的空白字符(空格、换行、制表符等);并读取字符直至再次遇到空白字符,读取终止。

int main(){    string result_str, str;    cout << "Enter strings(Ctrl + z to end):" << endl;    while(cin >> str)        result_str = result_str + str;    return 0;}

(2)用getline读取整行文本

此函数接受两个参数:一个输入流对象和一个string对象。将读取的内容保存到string对象,但不包括换行符。getline不忽略开头的换行符,即便它是输入的第一个字符,geline也将停止读入并返回。

int main(){    string line;    while(getline(cin, line))        cout << line << endl;    return 0;}

3、string对象的操作

(1)string::size_type类型

这是string类类型的配套类型,通过这些类型,库类型的使用就与机器无关。存储string的size操作结果的变量必须为string::size_type类型。注意,不要把size的返回结果赋给一个int变量。

string对象支持下标操作,string对象的索引变量最好也用string::size_type类型。

(2)string对象与字符串字面值的连接

当进行string对象和字符串字面值混合连接操作时,+操作符的左右操作数必须至少有一个是string类型的。

string s1 = "hello";string s2 = s1 + ", " + "world";       //OKstring s3 = "hello" + ", " + "world";  //Error 

对于s2和s3,依次来看每个子表达式。子表达式s1 + ", "将返回一个新string对象。

 三、标准库vector类型

vector不是一种数据类型,而只是一个类模板。vector<int>和vector<string>都是数据类型。

1、vector的定义和初始化

(1)vector对象(以及其他标准库容器对象)的重要属性就在于可以在运行时高效的添加元素。因此,虽然可以对给定元素个数的vector对象预先分配内存,但更有效的方法是先初始化一个空vector对象,然后再动态地增加元素。

(2)若没有指定vector中元素的初始化式,则标准库将自行提供一个元素初始化值进行值初始化。此值依赖于元素的数据类型。

2、vector对象的操作

(1)vector对象的下标操作。vector对象支持下标操作。但应注意:下标仅能用于获取已经存在的元素,且通过下标操作进行赋值时,不会添加任何元素。

(2)关于vector的for循环常常写成如下形式:

for(vector<int>::size_type ix = 0; ix != ivec.size(); ++ix)    ivec[ix] = 0;

应注意两点:

第一,优先选用 != 而不是 < 来编写循环判断条件(但当循环变量的步长大于1时,则应使用< 。否则可能出现无限循环的情况)。

第二,调用size成员函数而不提前保存它返回的值,这是一个良好的编程习惯。这是因为,C++中有些数据结构(比如vector)可以动态增长,循环可以很容易的增加新的元素。这样的运行代价其实很小,因为像size这样的小库函数几乎都定义为内联函数。

(3)不能用cout输出操作符直接输出vector对象。

四、标准库bitset类型

1、bitset对象的定义和初始化

(1)与vector类似,bitset类也是类模板。不同bitset对象的区别在于长度而不是类别。定义bitset时,需明确指出bitset含有多少位,且给出的长度必须是常量表达式。

(2)用string对象初始化bitset对象。string对象与bitset对象之间是反向转化的。string对象最右边字符(下标最大)用来初始化bitset对象的低阶位(下标为0)。

2、bitset对象的操作

(1)bitset对象支持下标操作。但是,bitset对象的下标编号从右向左,最右边编号为0;而string对象的下标编号从左向右,最左边编号为0。

(2)可用cout输出操作符输出bitset对象中的位模式。

五、迭代器简介

1、容器的iterator类型

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

(2)标准库为每一种标准容器(包括vector)定义了相应的iterator类型,而这种类型支持(概念上的)迭代器的各种操作。但是只有少数的容器支持下标操作

2、begin和end操作

vector<int>::iterator iter = ivec.begin();
iter指向元素ivec[0],类似一个指针。

由end操作返回的迭代器指向vector的“末端元素的下一个”,指向了一个不存在的元素

3、自增和解引用运算

(1)解引用运算符:*。*iter = 0;

(2)迭代器的自增,是把容器中的迭代器“向前移动一个位置”。

(3)不能对end操作返回的迭代器进行解引用或自增运算。

4、const_iterator与const迭代器

(1)使用const_iterator类型时,我们可以得到一个迭代器,它自身的值可以改变,但不能用来改变其所指向的元素的值。可以对迭代器进行自增以及使用解引用操作符来读取值,但不能对该元素赋值。若只需遍历容器中的元素而无需修改他们,则可以使用const_iterator。

(2)const_iterator既可以用于const vector或非const vector。

(3)const迭代器是迭代器常量,该迭代器本身的值不能修改,即该迭代器在定义时需要初始化,而且初始化之后,就不能再指向其他元素。const迭代器几乎没有用。

vector<int> nums(10);const vector<int>::iterator cit = nums.begin();*cit = 1;  //OK++cit;     //error
5、迭代器的算术操作

有两种:

第一,iter + n;n的类型应为vector的size_type类型或difference_type类型。

第二,iter1 - iter2;结果为difference_type的signed类型的值。iter1和iter2都必须指向同一vector中的元素。

没有定义两个迭代器相加的操作:iter1 + iter2(非法)。

注意:任何改变vector长度的操作都会使已存在的迭代器失效!!比如push_back之后。