c++ primer (5)2
第三章
1.头文件不应包含using声明,因为头文件的内容会拷贝到所有引用它的文件中去。
2.初始化string对象的方式:
string s1; //默认初始化,s1是一个空串
string s2(s1); //s2是s1的一个副本
string s2=s1; //等价于s2(s1)
string s3("value"); //s3是字面值"value"的副本,除了字面值最后那个空字符外
string s3="value"; //等价于s3("value")
string s4(n,'c'); //把s4初始化为由连续n个字符c组成的串
用等号初始化一个变量,执行的是拷贝初始化,不使用等号,是直接初始化。
对于多个初始值一般用直接初始化,如s4,如要用拷贝初始化,需要显示创建一个临时对象用于拷贝:
string s8=string(,'c');
这条语句等价于:
string temp(,'c');
string s8=temp;
3.读取一行使用getline(),getline()参数是一个输入流和一个string对象,会读入换行符,把所读内容存入string对象时不存换行符。getline()也会返回它的流参数,因此可以作为判断条件。
4.string类及其他大多数标准库类型都定义了几种配套的类型,这些配套类型体现了标准库与机器无关的特性。string::size_type就是其中一种,是size函数返回值的类型。string::size_type是无符号类型的值并且能足够放下任何string对象的大小。
5.如果一条表达式中已经有了size()函数就不要再使用int了,这样可以避免int和unsigned可能带来的问题。
auto len=line.size(); //len的类型是string::size_type
if(line.size()<n) //如果n为负值,结果几乎为真,n会转化为一个比较大的无符号值
6.字面值和string对象相加:
string s1="hello",s2="world";
string s3=s1+","+"world"; //正确,右边的值可以转换成string
string s4="hello"+","+s2; //错误,试图把两个字符串字面值加在一起
7.建议使用c++版本的c标准库头文件,即将name.h改为cname,标准库中的名字总能在std中找到,使用.h,就必须记住哪些是c语言继承,哪些是c++独有的。
8.范围for语句遍历给定序列中的每个元素并对序列中的每个值执行某种操作:
string s("Hello World!!!");
decltype(s.size()) punct_cnt=;
for (auto c : s)
if (ispunct(c))
++punct_cnt;
cout<<punct_cnt<<" punctuation characters in "<<s<<endl;
要改变字符串中的字符,必须把循环变量定义成引用类型:
string s("Hello World");
for (auto &c:s)
c=toupper(c);
cout<<s<<endl;
9.string的下标运算符([])接收的输入参数是string::size_type,如果某个索引是带符号类型的值将自动转换成string::size_type表达的无符号类型。
10.逻辑与运算符(&&)只有当左侧运算对象为真时才会检查右侧运算对象。
11.vector是容器,也是类模板:
vector<int> ivec;
vector<string> svec;
vector<vector<string>> file;
vector是模板而非类型,由vector生成的类型必须包含vector中元素的类型,由于引用不是对象,所以不存在包含引用的vector。
在早期C++标准中如果vector的元素还是vector,必须在外层的vector对象的右尖括号和其元素类型之间添加一个空格,如应写成vector<vector<int> >。
12.C++初始化方式例外情况是1:使用拷贝初始化时(即使用=)只能提供一个初始值;2.如果提供类内初始值,只能使用拷贝初始化或使用花括号的形式初始化;3.如果提供的是初始元素值的列表,只能使用花括号,不能使用圆括号。
13.只提供vector对象容纳的数量,此时库会创建一个值初始化的元素初值,并赋给容器中的所有元素。有两个限制:
(1)如果vector对象中元素的类型不支持默认初始化,我们必须提供初始的元素值。
(2)只提供元素的数量而没有初始值,只能用直接初始化:
vector<int> vi=;//错误,只能用直接初始化的形式
14.使用圆括号,值是用来构造vector对象的;使用花括号,值是用来列表初始化vector对象的,初始化过程会尽可能把花括号的值当成元素初始值的列表来处理,只有无法执行列表初始化时才会考虑其他初始化方式(如构造vector对象):
vector<int> v1();//v1有10个元素,每个都是0
vector<int> v2{};//v2有1个元素,是10
vector<int> v3(,);//v3有10个元素,每个的值都是1
vector<int> v4{,};//v4有2个元素,分别是10和1
vector<string> v5{"hi"};//列表初始化:v5有一个元素
vector<string> v6("hi");//错误:不能使用字符串字面值构造vector对象
vector<string> v7{};//v7有10个默认初始化的元素
vector<string> v8{,"hi"};//v8有10个"hi"元素
15.vector用push_back添加元素,vector对象能高速增长,在创建vector时设定其大小性能可能更差,只有一种例外,就是所有的元素值都一样时。
16.范围for语句体内不应该改变其所遍历序列的大小。
17.用下标的形式去访问一个不存在的元素将引发错误,不过这种错误不会被编译器发现,而是在运行时产生一个不可预知的值,缓冲区溢出就是这类错误,确保下标合法的方式是使用范围for语句。
18.begin返回指向第一个元素的迭代器,end返回指向尾元素的下一位置的迭代器,如果容器为空,则begin和end返回的是同一个迭代器,都是尾后迭代器
*iter 返回迭代器iter所指元素的引用
iter->mem 解引用iter并获取该元素名为mem的成员,等价于(*iter).mem
++iter 令iter指示容器中下一个元素
--iter
iter1==iter2 如果两个迭代器指示的是同一个元素或者他们是同一个容器的尾后迭代器,
iter1!=iter2 则相等;反之,则不相等
所有标准库容器的迭代器都有==和!=,但大多数没有<运算符
19.iterator和const_iterator表示迭代器类型,const_iterator和指向常量的指针一样(书上有误,书上写的常量指针),能读取但不能修改它所指元素的值。
如果vector或string对象是常量,只能使用const_iterator,否则,iterator和const_iterator都可以。
20.迭代器有三种含义:1.迭代器概念本身;2.容器定义的迭代器类型;3.某个迭代器对象。
某个类型是迭代器当且仅当它支持一套操作,这套操作使得我们能访问容器的元素或者从某个元素移动到另外一个元素。
每个容器类定义了一个名为iterator的类型,该类型支持迭代器概念所规定的一套操作。
21.begin()和end()返回const_iterator或iterator,由对象决定。
cbegin()和cend()返回const_iterator,不管对象是否是常量。
22.箭头运算符it->mem和(*it).mem表达一个意思。
23.凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素。
24.string和vector迭代器支持的运算有:
iter+n;
iter-n;
iter+=n;
iter-=n;
iter1-iter2;
>,>=,<,<=;
25.数组的维度必须是常量表达式,默认情况下,数组的元素被默认初始化,如果在函数内部定义了某种内置类型的数组,默认初始化会令数组含有未定义的值。
string strs[get_size()];//get_size是constexpr时正确,否则错误
26.字符数组特殊性:
const char a[]="aaa";//错误,没有空间存放空字符
27.复杂的数组声明:
int *ptrs[];//10个整型指针的数组
int &ptrs[];//错误,不存在引用的数组
int (*parray)[]=&arr;//parray指向一个含有10个整数的数组
int (&aref)[]=arr;//aref引用一个含有10个整数的数组
int *(&array)[]=ptrs;//array是数组的引用,该数组含有10个指针
从数组名字开始由内向外阅读,&array说明是一个引用,然后观察右边,引用的对象是一个大小为10的数组,再观察左边,数组元素是指向int的指针。
28.数组下标定义成size_t类型,size_t是一种机器相关的无符号类型。
当数组或其他类似数据结构的下标越界并试图访问非法内存区域时,会产生缓冲区溢出错误。
29.使用数组时编译器会把它转换成指针,使用数组作为auto变量的初始值时,推断得到的类型是指针而非数组:
int a=;
int *b=&a;
int ia[]={,,};
auto ia2(ia);//相当于auto ia2(&ia[0])
ia2=b;//ia2指向b所指对象,即a
当用decltype时上述转换不会发生:
decltype(ia) ia3={,,};
ia3=b;//错误,ia3是数组
c++ primer (5)2的更多相关文章
- C Primer Plus 学习体会
本月刚刚开始学习<C primer plus>,之前课上草草学过一遍,讲到指针就结束了.现在重新开始看感觉难度不大只是刚开始接触有些语言细节比较琐碎.学习这一周的体会如下: 诸多前辈推荐的 ...
- C++ Primer Plus 第六版笔记
C++ Primer Plus 第六版笔记 关于对象声明的思考 转自:http://www.cnblogs.com/weiqubo/archive/2009/11/02/1930042.html C+ ...
- 《3D Math Primer for Graphics and Game Development》读书笔记2
<3D Math Primer for Graphics and Game Development>读书笔记2 上一篇得到了"矩阵等价于变换后的基向量"这一结论. 本篇 ...
- 《3D Math Primer for Graphics and Game Development》读书笔记1
<3D Math Primer for Graphics and Game Development>读书笔记1 本文是<3D Math Primer for Graphics and ...
- 再读《C++ Primer》——变量和基本类型
刚上大学那时,几个室友一块买了本<C++ Primer>第4版,看了一遍后就没怎么碰了,偶尔拿出来翻翻,当作工具书使用.后来知道有第5版了,一直觉得内容差不多吧.直到最近,再读其中的一些内 ...
- C Primer Plus_第6章_循环_编程练习
1.题略 #include int main(void) { int i; char ch[26]; for (i = 97; i <= (97+25); i++) { ch[i-97] = i ...
- C Primer Plus_第5章_运算符、表达式和语句_编程练习
Practice 1. 输入分钟输出对应的小时和分钟. #include #define MIN_PER_H 60 int main(void) { int mins, hours, minutes; ...
- C++Primer 5th 练习 12.19
这阵子真是太忙了, 连续做了四个课设. 当然这并不能作为好久没写博客的借口, 没写博客的主要原因只有一个: 懒. 最近又开始回顾C++的语法与特性(据说C++就是一门需要反复回顾的语言),以及学习C+ ...
- [翻译]Primer on Cognitive Computing(认知计算入门)
Source Kelly J., Primer on Cognitive Computing 20150216. 侵删,联系方式:zhoujiagen\@gmail.com. 按A candidate ...
- c++ Primer 第四版 第一阶段 const总结
由于期末值考一门软件安全,所以果断看起c++Primer ,因为之前看谭浩强的c++感觉没什么用啊.所以这本书每阶段做个总结!!! 1.Const限定符作用: 在for循环中上限应该用一个固定变量来设 ...
随机推荐
- 使用JavaScript实现分页效果
应公司需求,有时需要制作静态页面网站,而一旦涉及到文章的分页,实现起来非常麻烦,自己又刚入门,对js不是很熟悉,所以就拿来练练手. 首先页面结构如下,分别展示数据跟分页: <!DOCTYPE h ...
- 了解CSS/CSS3原生变量var
一.变量是个好东西 在任何语言中,变量的有一点作用都是一样的,那就是可以降低维护成本,附带还有更高性能,文件更高压缩率的好处. 随着CSS预编译工具Sass/Less/Stylus的关注和逐渐流行,C ...
- 编写一个Java应用程序,该程序包括3个类:Monkey类、People类和主类 E。要求: (1) Monkey类中有个构造方法:Monkey (String s),并且有个public void speak() 方法,在speak方法中输出“咿咿呀呀......”的信息。 (2)People类是Monkey类的子类,在People类中重写方法speak(),在speak方法 中输出“小样的,不
package homework1; public class Monkey { //构造方法 Monkey(String s) { } //成员方法 public void speak() { Sy ...
- Android开发日志问题
以前在Android开发中发现,日志打印好多,调试的时候各种加Log,之后就各种不删除,导致项目后期花大把时间删除日志打印. 学到一个好方法: 在所有尽可能高的父类里面加上一个常量 DEBUG ,一开 ...
- 淘宝IP地址查询
官方网址:http://ip.taobao.com/index.php 相关文章: http://www.cnblogs.com/zetee/p/3482085.html http://www.cnb ...
- Update操作浅析,一定是先Delete再Insert吗?
Update操作一定是先Delete再Insert吗? Update在数据库中的执行是怎么样的?“Update操作是先把数据删除,然后再插入数据”.在网上看了很多也都是这么认为的.但在查阅到一些不同看 ...
- hibernate uniqueResult方法
假设查询返回多个值用list()方法 public void testQuery(){ Configuration config = new Configuration().configure(); ...
- Preparing for Different Databases
Preparing for Different Databases In the previous chapter, we created a PostRepository that returns ...
- 手把手教你使用UICollectionView写公司的项目
在很多app中都有这样通用的页面,一直没有机会使用UICollectionView,只是简单的看过他的使用方法.今天公司美工出图,使用了他,并且遇到了好多的坑.记录一下过程,不确定使用的方法是不是最优 ...
- VS版本下载
tfs2012:BVGTF-T7MVR-TP46H-9Q97G-XBXRB http://www.microsoft.com/zh-cn/download/details.aspx?id=30658 ...