美文网首页
第三章 摘录

第三章 摘录

作者: 带鱼去兜风 | 来源:发表于2018-03-27 21:49 被阅读0次

3.3 标准库类型vector

c++既有类模板,也有函数模板,其中vector是一个类模板。表示对象的集合,其中所有对象的类型都相同。集合中的每个对象都有一个与之对应的索引,索引用于访问对象。也称作“容器”。

模板本身不是类或函数,相反可以将模板看作为编译器生成类或函数编写的一份说明。编译器根据模板创建类或函数的过程称为实例化,当使用模板时,需要指出编译器应把类或函数实例化成何种类型。

vector是模板而非类型,能容纳绝大多数类型的对象作为其元素,但是因为引用不是对象,所以不存在包含引用的vector。

vector确认无法执行列表初始化后,编译器会尝试用默认值初始化vector对象。例如:vector<string> v1{10}; //v1有10个默认初始化的元素。vector<string> v2{10,"hi"}; //v2有10个值为"hi"的元素。

vector对象能高效增长,因此和大多数语言不同,除非所有元素的值都一样,否则不在定义vector对象时设定其大小(这可能会让性能更差),而是动态加入。

两个vector对象的大小判断和string类型一样。若两者容量(长度)不同,但相同位置上的元素一样,则元素较少的小于元素较多的;若两者容量(长度)相同,则大小关系由第一对相异的元素值的大小关系决定。

vector下标运算符可用于访问已存在的元素,而不能用于添加元素。

3.4迭代器介绍

所有标准库容器都可以使用迭代器,但只有少数集中才同时支持下标运算符;这些类型都拥有名为begin和end的成员,begin负责返回指向第一个元素的迭代器,end则负责返回指向容器“尾元素的下一位置”(尾后元素)的迭代器,该迭代器常被称为尾后迭代器,这样的迭代器没什么意义,仅是个标记而已,表示我们已处理完了容器中的所有元素。若容器为空,begin和end返回的是同一个迭代器。

c++程序员习惯性使用!=而非<,原因是这种编程风格在标准库提供的所有容器上都有效。因此,以后保持使用!=,这样就不用太在意用的到底是哪种容器类型。

如果对象只需要读操作而无须写操作的化最好使用常量类型(如const iterator),c++ 11中为此专门引入了cbegin和cend。

箭头运算符(->)把解引用和成员访问两个操作结合在一起。如(*it).empty()可以写为it->empty()。

已知的一个限制是不能在范围for循环中向vector对象添加元素。另外一个限制是任何一种可能改变vector对象容量的操作,比如push_back,都会使该vector 对象的迭代器失效。

两个迭代器的差是距离,类型是带符号整型数difference_type。

3.5数组

与vector不同的是,数组的大小确定不变,不能随意向数组中增加元素。因为大小固定,因此对某些特殊的应用来说程序的运行性能较好,但相应地也损失了一些灵活性。

如果不清楚元素的确切个数,请使用vector。

数组是一种复合类型(基于其他类型定义的类型)。数组中元素的个数也属于数组类型的一部分,编译时候维度应该是已知的,即维度必须是个常量表达式。

默认情况下,数组的元素会默认初始化(全局下)。定义数组的时候必须指定数组的类型,不允许用auto关键字由初始值的列表推断类型。另外和vector一样,数组的元素应为对象,因此不存在引用的数组。

当字符数组使用字符串字面值对此类数组初始化时,一定要注意结尾处还有一个空字符。

不能将数组的内容拷贝给其他数组作为初始值,也不能用数组为其他数组赋值(除非编译器扩展,但最好避免非标准特性)。如int a[]={0,1,2}; int a2[] = a;//错误  a2=a;  //错误。因为数组名称代表的是数组第一个元素的地址,是指针型“常量”,不能对常量赋值。

因为数组本身是对象,所以存在数组的引用和数组的指针。(&arr)[]和(*arr)[]。

如何理解复杂数组声明见P103。

使用数组下标时,通常使用size_t类型。

数组有一个特性:在很多用到数组名字的地方,编译器都会自动将其替换为一个指向数组首元素的指针。

c风格字符串(char []和char *)不是一种类型,而是为了表达和使用字符串而形成的一种约定俗成的写法。c语言标准库提供了一组操作字符串的函数如strlen(),strcmp(),strcat()和strcpy()等。如果把>,<等运算符用在两个c风格字符串上,实际比较的将是指针而非字符串本身,这和c++的string对象就不同。

个人见解:可见对于c,字符串并非开始就完美支持,而是由于出现了这种约定俗成的写法后才引入了标准库函数供用户使用。而对于c++就不同了,string类型本身就是为字符串而生的。

尽管c++支持c风格字符串,但在c++程序中最好还是不要使用它们。这是因为c风格字符串不仅使用起来不太方便,而且极易引发程序漏洞,是诸多安全问题的根本原因。

建议:尽量使用标准库类型而非数组。使用指针和数组很容易出错。现代c++程序应当尽量使用vector和迭代器,避免使用内置数组和指针;应该尽量使用string,避免使用c风格基于数组的字符串。

3.6多维数组

严格来说,c++中没有多维数组,通常所说的多维数组其实是数组的数组。谨记这一点,对今后的理解和使用大有益处。

遍历多维数组时使用:

for (auto &row : ia)

    for(auto col : row)

        cout << col <<endl;

外层循环条件中row为何要加&?这是因为如果不这么做,编译器初始化row时会自动将这些数组形成的元素转换成指向该数组内首元素的指针,这样内层循环就不合法了。所以,用for处理多维数组时,除了最内层的循环外,其他所有循环的控制变量都应该时引用类型。

相关文章

网友评论

      本文标题:第三章 摘录

      本文链接:https://www.haomeiwen.com/subject/sdqdcftx.html