c++ primer 小知识速查-更新中
这篇文章记录了c++ primer这本书中的一些知识点(通常是那些比较关键但又不是很显眼的知识点),简单的会直接在文章中写清,复杂的会超链接到另外的文章。建议使用crtl+f 根据关键词迅速找的自己的需求,在评论区求助作者也会根据需求更新。
变量和基本类型
- 字符型有三种类型 char,signed char,unsigned char,但表现形式只有两种:带符号的和无符号的。char的表现形式由编译器决定。
- 执行浮点运算首选double,float精度常常不够。代价几乎无差别,甚至double更快。
- 浮点到整型的转换直接截断。
- 无符号类型赋值超出值的范围,采取取模取值。有符号这是结果未定义,什么都可能发生了。
- 把负数转换陈无符号数类似于直接给无符号数赋一个负值,结果等于(这个负数+无符号数)取模。
- 不能用无符号数据现在循环,当小于0又取模变正数。
- 转义字符反斜线\后面跟着的八进制数字超过三个,只有前三个数字与\构成转义序列。而泛化的转义序列则是\X后跟多个字符。
- 初始化不是赋值,初始化的含义是创建变量是赋予其一个初始值,而赋值的含义是把对象的当前值擦除而以一个新的值代替。
- 初始化多种方式 int x=0; int x={0}; int x{0}; int x(0);
- 当使用列表初始化存在丢失信息的风险时,编译器将报错。 c++ primer p40.
- 声明使得名字为程序所知,定义负责创建与名字关联点的实体。声明规定了变量的类型和名字,定义则负责申请存储空间。
- c++是静态类型语言,含义是在编译阶段检查类型。其中检查类型的过程称为类型检查,就是在编译阶段检查参与运算的每个变量的类型是否满足要求。
- 变量命名规范:
- 变量名一般用小写字母。
- 用户自定义的类名一般以大写字母开头,Sales_item.
- 多个单词构成,单词间应有明显区分
- 第一次使用变量时再定义。
- 通过::variants_name ,显式的访问全局变量。:: 是作用域操作符,若左侧为空,向全局作用域提出请求。
- 引用并非对象,相反的,它只是为一个已经存在的对象所起的另外一个名字。
- 引用本身不是对象,没有引用的引用。
- 指针本身就是一个对象。
- 要想获得某个变量的地址需要加&,如 &variants。
- void* 指针可以存放任何类型变量的地址。这个指针能干的事情很有限。
- 建议:初始化所有指针。
- 指向指针的指针:int **ppi = π
- 要理解r的类型到底是什么,最简单的办法是从向左阅读r的定义。*&r是一个对指针的引用。
- const对象仅在文件内有效。加上exter,extern const x能被其他文件读取。
- 常量引用要加const。
- 指向常量的const 和指针,本身都需要是const。
- 要分清指向常量指针和常量的指针const double *variants ,double *const variants。指向非常量的常量指针可以修改非常量的值。顶层const 指针本身是常量,底层const 指针所指的对象是常量。
- auto 一般会忽略顶层const,同时底层const会被留下了,比如当初始值是一个指向常量的指针时。希望auto类型是指针需要明确指出,引用也是同理
- decltype 相当于数据类型的别名 decltype(y) x=0,能使x获得y的类型,decltype对顶层const也同样生效。如果括号中是解引用表达式,则复制的类型是指针。p63最下 warning!
第三章 字符串向量和数组
- 头文件中不应该有using 声明,头文件中的using声明会传递到每个包含头文件的文件中去。
- string的初始化方法 string s4(10,‘c')
- 有拷贝初始化和直接初始化。用’=‘的是拷贝初始化,也没什么优势。
- string 读取字符会忽略所有空白从第一个字符读起,结尾的空白也会被忽略。
- 想要对空格的读取一整行要用getline ,getline(cin,string)。这种读取方法中结束getline的换行符会被丢弃。
- string.size()函数的数据类型是size_type.
- string的大小对比,比较的是第一对相异字符的字典顺序,字典顺序小的赢。
- string的加法当中必须保证两侧至少有一个是string。
- 建议使用cctype 头文件中的函数判断string中字符的类型。c++ primer p82
- 遍历string 建议使用 for(declaration:expression)
- 可以通过设置下标为string::size_type使其为无符号数,从而避免下标越界。
-
#include <typeinfo> cout << typeid('a' - 0).name() << endl; 用于查看数据类型 - vector 对象可以只提供对象容纳的元素数量而略去初值 如 vector<int> ivec(10);
- vector ()圆括号初始化是初始化格式,{}花括号是初始化值。 p89
- 花括号是列表初始化,括号中值的类型必须与vector标准的类型相同。
- 对于vector来说高效的添加方法是一开始不设定其大小,使用push_back后续添加。
- 范围for语句不应该改变其所遍历序列大小。
- vector对象之间的比较也符合字典序。
- vector 的下标只能用于读取不能用于添加元素。
- begin 迭代器指代头一个元素,end迭代器指代尾元素的后一个元素,通常情况下都为空。当begin==end时对象为空。
- 迭代器的操作运算符在p96
- 解引用迭代器可以获得迭代器所指的对象,如果对象是类,可以进一步访问。但是必须加圆括号
(*it).empty()应为. 比*更早生效。 - 上条操作的简化操作是it->mem,it->mem 和(*it).mem
- 使用了迭代器的循环体,都不要向迭代器所属的对象添加元素。
- 迭代器操作运算p99
- 创建数组是要声明维度的,维度必须是一个常量表达式。
- 定义时必须指明类型,不能用auto,元素必须时对象不可以时引用。
- 字符数组初始化必须有一个位置用于容纳空字符/
- 数组不能用于其他字符的拷贝或赋值。
- 数组的引用及指针 p102,他们的声明理解顺序时由内向外 而不是由右向左的。
- 使用指针指向元素时往往得到的是指向第一个元素的指针。int *p=arr 与 int *p =&arr[0]相同
- 指针也可以当做迭代器使用,通过 begin(arr) 和 end(arr)可以获得数组的头指针和尾后指针。
- 两个指针相减,得到的是一种名为ptrdiff_t的标准库类型。若两个指针不是指向同一个数组,则不能比较。
- p108 int *p=&ia[2]; 则p[1]=*(p+1)
- 比较C风格字符数组时比较的实际是指向数组首元素的指针,因此是不好用的。
- 字符数组的拼接和复制也和字符串不太一样。要使用 strcpy 函数或者strcat函数。
- c_str()返回的数组未必一直有效,因为对数组使用的是指向首个元素的指针的形式,如果后续的值改变了,那么数组就失效了。c_str()函数如果想一直使用其返回的数组,最好是将该数组重新拷贝一份。
- 数组可以用于初始化vector,方法是在圆括号中使用begin 和end
- p105 在很多用到数组名字的地方 编译器都会自动地将其替换为指向数组首元素的指针。
- 使用for语句处理数组,除了最内层的循环,其他所有循环的控制变量都应该是应用类型p114.
第四章
- 当一个对象被用作右值时,用的是对象的值(内容),当对象被用作左值时,用的是对象的身份。

浙公网安备 33010602011771号