c++primer 第三章阅读笔记

3.1 头文件不应包含using声明

3.2/*string*/(p75)
表示可变长的字符序列

等号初始化叫做拷贝初始化 不使用=则执行的是直接初始化(用多个值进行初始化)

/*string 对象会自动忽略开头的空白(空格,换行,制表等),并从一个真正的字符开始读起,直到遇见下处空白*/

/*getline*/参数是一个输入流和一个string对象 
直到遇见换行符为止(换行符也被读进),然后把所读内容存入string对象中(不存换行符)

如果一条表达式有了size()函数,就不要使用int,避免int和unsigned混用可能带来的问题

== !=用于验证两个string对象相不相等,关系运算符则按第一对相异字符做比较(字典序)

/*对于string类而言,允许把一个对象的值赋给另一个对象*/

两个string对象相加得到一个新的string对象

/*字面值与string对象相加*/
string s1="hello",s2="world";
string s3=s1+","+s2;
/*当把string对象和字符字面值及字符串字面值混在一起时,必须确保每个加法运算符的两侧对象至少有一个是string类型*/
string s4="hello"+","+s2;//0  字面值直接相加
string s4="hello"+(","+s2);//1

/*cctype*/(p82)

处理string中的每个字符 for(auto c : str)
如果想改变string对象中字符的值,必须将循环变量定义为引用类型
(如将字符串变为大写) for(auto &c : s)c=toupper(c);

访问string对象中的单个字符有两种方式:下标和迭代器 (p84)


3.3/*vector*/(p86)
表示对象的集合,其中所有对象的类型都相同。
vector是一个/*类模板*/,c++还包括函数模板,模板本身不是类或者函数,可以将模板看作为编译器生成类或者函数编写的一份说明。
编译器根据模板创建类或者函数的过程称为/*实例化*/,当使用模板时,需要指出编译器应把类或函数实例化成何种类型。

vector能容纳绝大多数类型的对象,但/*引用不是对象*/

老编译器:vector<vector<int> >;

/*三种初始化方式*/
1,拷贝初始化只能提供一个初始值 2,类内初始化用拷贝和列表初始化{} 3,初始元素列表用列表初始化{}

创建指定数量 vector<string>(10,"str");

可以只提供vector对象容纳的元素数量而省略初始值,此时库会创建一个值初始化的元素初值,并赋给容器中的所有元素,这个值由
vector 对象中国元素的类型决定
如果是内置类型,比如int,自动设为0.
如果是某种类类型,比如string,则由类默认初始化
这种方式有两个限制:1,有些类型要求必须明确的提供初始值 2,如果只提供数量而没有初值,只能用直接初始化,不能用拷贝(=)
                                                           
vector<int>v1(10);//10个元素都是0
vector<int>v2{10};//1个元素为10
vector<int>v3(10,1);//10个元素都是1
vector<int>v4{10,1};//2个元素为10,1
/*圆括号*/提供的值用来构造vector对象
/*花括号*/把括号内的值当成是元素初始值的列表进行列表初始化
/*如果初始化时使用了花括号的形式但是提供的值又不能用来列表初始化,就要考虑用这样的值来构造vector对象。*/

vector对象(以及string对象)的下标运算符可以用于访问已经存在的元素而不能用于添加元素

3.4/*迭代器*/(提供了对对象的间接访问)
所有标准库容器都可以使用迭代器,但是其中只有少数几种才同时支持下标运算符。

其中的/*对象*/是容器中的元素或者string对象中的字符

迭代器有有效和无效之分,有效的指向某个元素或者尾元素的下一位置;其他所有情况都属于无效

如果容器为空,则begin和end都返回尾后迭代器

和指针类似,能通过解引用迭代器来获取它所指示的元素,执行解引用的迭代器必须合法并确实指示着某个元素,试图
解引用一个非法迭代器或者尾后迭代器都是未被定义的行为

/*泛型编程*/ 在for循环中使用!=进行判断是因为这种编程风格在标准库提供的所有容器上都有效

vector<int>::iterator it;
vector<int>::const_iterator;
/*begin和end返回的具体类型由对象是否是常量决定,如果对象是常量返回const_iterator 不是则返回iterator*/
为了便于得到const_iterator类型的返回值,c++11加入了cbegin和cend

*it.empty();//0 试图访问it的名为empty的成员,但it是一个迭代器,没有empty成员
箭头运算符/*(->)*/把解引用和成员访问两个操作结合在一起
(*it).empty==it->men;

/*某些对vector对象的操作会使迭代器失效*/
凡是使用了迭代器的循环体,任何一种可能改变vector对象容器容量的操作都会使该vector对象的迭代器失效

/*迭代器的运算*/
关系运算判断的是两迭代器的位置关系,两迭代器相减的结果是它们之间的距离(类型为带符号的整形数)

3.5/*数组*/
数组的元素应为对象,所以不存在引用的数组

/*字符串字面值*/等于一个以空字符结束的字符数组来代替

不予许使用一个数组初始化另一个数组,不能把一个数组直接赋值给另一个数组

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

(头文件iterator)begin与end,用数组作为他们的参数

两个空指针也允许相加,结果为0

/*c风格字符串*/
strlen();strcmp();strcat();strcpy(); /*传入此类函数的指针必须指向以空字符作为结束的数组*/

混用string对象和c风格字符串
允许使用字符串字面值来初始化string对象

在string对象的加法中允许以空字符结尾的字符数组作为其中一个运算对象
不能使用string对象直接初始化指向字符的指针,string对象专门提供了c_str的成员函数
(const char*str=s.c_str())

使用数组初始化vector对象//vector<int>ivec(begin(a),end(a));

/*尽量使用vector和迭代器 ,避免使用内置数组和指针, 尽量使用string,避免使用c风格基于数组的字符串*/

3.6/*多维数组*/
通常说的多维数组其实是数组的数组

表达式含有的下标运算符数量和数组的维度一样多,是给定类型的元素,小则是一个内层数组

/*使用范围for语句处理多维数组*/
int a[5][5],cnt=0;
for(auto &row : a){
    for(auto &col : row)col=cnt++;
}

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

通过auto 与 decltype 能尽可能的避免在数组前加上一个指针类型
for(auto p=a;p!=a+5;++p){
    for(auto q=(*p);q!=*p+5;++q)*q=cnt++;
}

使用标准库函数begin和end能看起来更简洁
for(auto p=begin(a);p!=end(a);++p){
    for(auto q=begin(*p);q!=end(*p);q++)*q=cnt++;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值