C++ Primer 学习笔记(三)

第三章

3.1使用using声明就无须专门的前缀,usingnamespace::name

3.2头文件不应该使用using声明,因为头文件的内容会拷贝到所有引用它的文件中去,如果头文件里有某个using声明,那么每个使用了该头文件的文件就都会有这个声明

3.3使用等号初始化一个变量,实际上执行的是拷贝初始化,编译器把右侧的初始值拷贝到新创建的对象中去,如果不使用等号,则执行的是直接初始化

3.4有时候我们希望能在最终得到的字符串中保留输入时的空白符,这时应该用getline函数代替原有的>>运算符。getline函数的参数是一个输入流和一个string对象,函数从给定的输入流读取,遇到换行符为止,将换行符也读入,然后把所读的内容存到string对象中去,不存换行符。getline只要一遇到换行符就结束读取操作并返回结果。

3.5 string类与其他大多数标准库类型都定义了几种配套的类型,这些配套类型体现了标准库类型与及其无关的特性,类型size_type就是其中的一种。

3.6 C++11中允许编译器通过auto或者decltype来推断变量的类型。例如auto len = line.size()

3.7如果一条表达式中已有了size函数就不要再使用int了,这样可以避免使用int和unsigned可能带来的问题。

3.8当把string对象和字符字面值以及字符串字面值混在一条语句中使用时间,必须确保每个加法运算符的两侧的运算对象至少有一个是string,将两个字符串字面值加在一起是错误的。字符串字面值和string是不同的类型。

3.9C语言的头文件形如name.h,C++则将这些文件命名为cname,表示这是一个属于C语言标准库的文件。在名为cname的头文件中定义的名字从属于命名空间std,而定义在name.h的头文件中的则不然。

3.10基于范围的for语句:遍历给定序列中的每个元素并对序列中的每个值执行某种操作,语法格式为for(declaration : expression) statement,其中expression是一个对象,用于表示一个序列,declaration部分负责定义一个变量,该变量将被用于访问序列中的基础元素。每次迭代,declaration部分的变量会被初始化为expression部分的下一个元素值。一个string对象表示一个字符的序列,因此string对象可以作为范围for语句的expression部分。

3.11如果想要改变string对象中的字符的值,必须把循环变量定义成引用类型。

3.12只有当左侧运算对象为真的时候,才会检查右侧运算对象的情况。

3.13下标必须合法,一是大于等于零,二是要小于字符串的size值。可以令下标的类型为string::size_type,因为此类型是无符号数,可以确保其不为零,剩下的只要保证下标小于size值就可以了。

3.14标准库类型Vector表示对象的集合,其中所有对象的类型都相同,集合中的每个对象都有一个与之对应的索引,索引用于访问对象。也被称为容器,Vector是一个类模版,模版本身不是类或者函数,相反可以将模版看作为编译器生成类或函数编写的一份说明。编译器根据模版创建类或者函数的过程称为实例化。

3.15初始化三种例外情况是:一,使用拷贝初始化时,只能提供一个初始值,二,如果提供的是一个类内初始值,则只能使用拷贝初始化或使用花括号的形式初始化,三,如果提供的是初始元素值的列表,则只能把初始值都放在花括号里进行列表初始化,而不能放在圆括号里。

3.16可以利用vector的成员函数push_back来向其中添加元素。push_back负责把一个值当作vector对象的尾元素压到vector对象的尾端。

3.17如果循环体内部包括有向vector对象添加元素的语句,则不能使用范围for循环。在范围for语句体内不应改变其所遍历序列的大小。

3.18vector的empty和size两个成员与string的同名成员功能完全一致,empty检查vector对象是否包含元素然后返回一个布尔值,size则返回vector对象中的元素个数,返回值的类型是由vector定义的size_type类型。

3.19要使用size_type需首先指定它是由哪种类型定义的,vector对象的类型总是包含着元素的类型,例如vector <int> :: size_type

3.20vector对象以及string对象的下标运算符可用于访问已存在的元素,而不能用于添加元素。只能对确知存在的元素执行下标操作,确保下标合法的有效手段就是使用范围for语句。

3.21string对象不属于容器类型,但是string支持很多与容器类型类似的操作。迭代器也可以用来访问string、vector对象中的元素。

3.22迭代器都拥有名为begin和end的成员,分别指向第一个元素的迭代器和最后一个元素的下一个位置的迭代器。如果迭代器为空,则begin和end返回的是同一个迭代器,都是尾后迭代器。一般来讲我们不在意迭代器的类型到底是什么,所以我们采用auto来让编译器自动确定其类型。

3.23迭代器的递增是将迭代器向前移动一个位置,因为end返回的迭代其并不实际指向某个元素,所以不能对其进行递增或解引用的操作。

3.23箭头运算符(—>)把解引用和成员访问两个操作结合在一起,也就是说,it—>mem和(*it).mem表达的意思相同。

3.24任何一种可能改变vector对象容量的操作,都会使该vector对象的迭代器失效,但凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素。

3.25字符数组有一种额外的初始化形式,可以用字符串字面值对此类数组初始化。字符串字面值的结尾处还有一个空字符,可以显式给出,也可以让系统自动补全,但是数组必须给出一个空间来存放这个空字符。

3.26 int (*Parray)[10] = &arr; *Parray说明Parray是一个指针,接下来看右边,可知道Parray是个指向大小为10的数组的指针,最后看左边,知道数组中的元素是int。可知,Parray是一个指针,指向一个包含10个int类型的元素的数组。想要理解数组声明的含义,最好的办法是从数组的名字开始按照由内到外的顺序阅读。

3.27在使用数组下标的时候,通常是将其定义为size_t类型,size_t是一种机器相关的无符号类型,它被设计得足够大以便能够表示内存中任意对象的大小。在cstddef头文件中定义了size_t类型,这个文件是C标准库stddef.h头文件的C++语言版本。

3.28在大多数表达式中,使用数组类型的对象其实是使用一个指向该数组首元素的指针。

3.29begin函数返回指向作为参数的数组的首元素的指针,end函数返回指向作为参数的数组的尾元素的指针

3.30一个指针如果指向了某种内置类型数组的尾元素的“下一位置”,则其具备与vector的end函数返回的与迭代器类似的功能。特别要注意,尾后指针不能执行解引用和递增操作。

3.31两个指针相减的结果的类型是一种名为ptrdiff_t的标准库类型,和size_t一样,ptrdiff_t也是一种定义在cstddef头文件中的机器相关的类型,因为差值可能为负值,所以ptrdiff_t是一种带符号类型

3.32只要指针指向的是数组中的元素(或者数组中尾元素的下一位置),都可以执行下标运算。

int *p = &ia[2];             //p指向索引为2的元素

int j = p[1];            //p[1]等价于*(p+1)就是ia[3]表示的那个元素

int k = p[-2];          //p[-2]是ia[0]

3.33严格来说,C++没有多维数组,所谓的多维数组其实是数组的数组

3.34for(const suto &row : ia)

       For(autocol : row)

              Cout<< col <<endl;

这个循环中并没有任何写操作,但是我们还是将外层循环的控制变量声明成了引用类型,这是为了避免数组被自动转成指针。

要使用范围for语句处理多维数组,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值