C++ Primer
1.开始
C++最初的一个设计焦点就是能定义像内置类型一样自然的类类型。
类类型:类定义的类型。类名即为类类型
数据结构:数据及其所允许的操作的一种逻辑组合。
初始化:在一个对象创建的时候赋予它一个值。
成员函数:类定义的操作。
标准库:一个类型和函数的集合,每一个c++编译器都必须支持。
2.变量和基本类型
2.1基本内置类型
C++定义了一套算术类型和空类型在内的基本数据类型
2.1.1 算术类型
可寻址的最小内存块称为字节,存储的基本单位称为字。
2.1.2类型转换
类型转换是一种操作被大多数类型支持,就是将对象从一种给定的类型转换成另一种相关类型
2.2.2 字面值常量
整形和浮点型字面值
字符和字符串字面值
转义序列
指定字面值的类型
2.2变量
变量提供一个具名的、可供程序操作的存储空间。对程序员来说,变量和对象一般可以互相使用。
2.2.1 变量定义
变量的定义是首先是类型名和紧跟其后的一个变量名列表组成。其实上变量的定义是类型名和一组声明符,声明符的形式不同可能造就不同类型的变量
类型声明符属于声明符而不属于类型
定义指针变量时应该int *p,而不是int* p。因为此时的类型名是int而非int*。*仅仅是修饰了p
初始化:在一个对象创建的时候赋予它一个值。
初始化不是赋值,初始化的含义是在创建变量的时候赋予其一个初始值,而赋值的含义是把对象当前的值擦除而以一个新值来替代。
对同时存在引用和指针的变量从右向左读
顶层const和底层const
顶层const修饰的是对象本身
底层const修饰的是指向的对象是一个常量(只有指针和引用会存在底层const,且引用本身一定是顶层const的)
常量表达式仅由字面量(如 5、“Hello”)和编译时常量(如 constexpr 变量)组成。
不依赖运行时的任何状态(如用户输入、内存动态分配)
constexpr变量
变量声明为constexpr类型一遍由编译器来验证变量的值是否是一个常量表达式。
constexpr只起到顶层constexpr的作用
类型别名
关键字typefef 和别名声明
事实上别名声明比typedef要好用多
决不能简单将类型别名理解为替换
顶层const修饰cstr,单纯的替换会误以为是底层const,cstr是指向常量的指针。
auto类型说明符
编译器推断出来的auto类型有时候和初始值的类型并不完全一样
decltype类型提示符
返回操作数的数据类型却不实际计算表达式的值
decltype与auto的区别在于,decltype并不会自己去推断一定和表达式的值一样。对函数推断就会得到函数类型而不是函数指针类型,对数组推断就会得到数组类型而不是指针,
3.String
3.1初始化String的方式
3.2 String的操作
4.vector
4.1定义和初始化String的对象
5.迭代器
迭代器(Iterator) 提供了一种统一的方式来遍历不同类型的数据结构。
理解复杂的数组声明
从内向外读,写的时候也如此
多维数组
缓存区溢出:用严重的程序故障,主要的原因是试图访问一个越界的索引访问容器内容。
尾后迭代器:end函数返回的迭代其实上一个并不存在的元素。该元素位于容器为元素的下一个位置。
优先级(多个运算符),结合性(多个优先级相同的运算符考虑结合性),求值顺序(单一运算符,f()+g(),f()和g()谁先调用结果未知)
溢出
类型转换
合法的类型转换
算数转换
整形提升
算术转换
其他隐式类型转换
数组转换成指针
转换成布尔类型
指针的转换转换成常量
try语句块和异常
只有在try语句块抛出的异常会被后面的catch子句处理
列表初始化返回值
函数指针
候选函数:与调用函数同名在作用域可见
可行函数:形参数量与本次调用提供实参数量相同,二类型一直或者能转换
寻找最佳匹配,否则二义性
类
常量成员函数后面加const
合成的默认构造函数
=default
委托构造函数
隐式类型转换
单参构造函数支持隐式类型转换
多参可以用初始化列表
explicit
IO
假定左闭右开区间
泛型算法
顺序容器只定义了很少的操作:在多数情况下我们希望做其他有用的操作
大多数算法都定义在头文件中,如果还在头文件中定义了一组数值泛型算法
迭代器令算法不依赖于容器但算法依赖于元素类型的操作,支持迭代器就支持泛型算法,但算法可能要求元素类型支持特定的运算符
只读算法
只会读取范围内的元素,而从不改变元素
accumulate(begin,end,初始值)
equal(r1.begin,r1.end,r2.cbegin)r2的元素数量至少和r1元素的数量一样多,且支持==
写容器的算法
fiil(begin,end,初始值)
算法不检查写操作
fill_n(begin,size,初始值)
不要在空容器上调用fill_n,因为算法操作不会改变容器本身的结构。
back_inserter
算法保证元素有足够的空间来容纳输出数据的方法使用back_inserter
auto it=back_inserter(vec);
*it=初始值(当我们使用此迭代器时,会调用容器操作)
拷贝算法
copy(r1.begin,r1.end,r2)返回拷贝后的尾元素的后一个位置
replace(begin,end,要替换的,替换);
replace_copy(r1.cbegin,r1.cend,back_inserter(r2),要替换的,替换);r2是r1的拷贝,只不过一些值被替换
重排容器元素的算法
只有容器操作才能删除元素
定制操作
谓词是一个可调用的表达式,返回一个bool值。一元谓词和二元谓词表示接受参数的数量,可以通过谓词来更改库函数的效果
插入迭代器
当我们不想插入元素时用find代替下标操作
使用lower_bound和upper_bound我们可以得到一个左闭右开的区间
无序关联容器