常量引用
对常量的引用
常量指针
指向常量的指针
指针常量
不可变的指针
顶层 const 和 底层 const
用名词顶层const(top-level const)表示指针本身是个常量(地址不变)
用名词底层const(low-level const)表示指针所指的对象是一个常量(值不变)
一般化:
顶层const 适用于表示一切对象是常量(顶层const用于指针也就是表示指针本身是常量)
底层const 与复合类型的引用、指针有关
const int *const p3=p2;// 靠右的const是顶层const,靠左的是底层const执行对象拷贝时,顶层const无影响,底层const有影响
拷入和拷出的对象必须具有相同的底层const资格,或者两个对象的数据类型必须能够转换。
(一般来说,非常量可以转换成常量,反之则不行)
auto
直接使用auto,对引用会解除引用,对常量忽略顶层const而保留底层const
除非显示的添加const * 或 &
int i = 0;
const int ci = 0;
auto p1 = &ci;
*p1 = 1; // 错误,对常量取地址是底层constdelctype
返回该变量的类型(包含顶层const和引用)
decltype 与 引用
struct
类内初始值
类定义在头文件
预处理器防止重复定义,无视作用域
使用命名空间
using std::cin;
string 类
直接初始化与拷贝初始化
string s0("123");
string s1 = "123";
输入
cin >> s; // 忽略前导空白字符
getline(cin, s); // 读取一行忽略换行符string::size_type
字符串字面值和string 不同类型
<cctype>
vector
类模板和函数模板,编译器编译时自动实例化
初始化方式:
构造初始化,拷贝初始化(单初始值可与构造初始化等效),{}列表初始化(优先考虑列表初始化,再考虑其他初始化)
vector 值初始化,每个元素由类默认初始化
vector<int> vi = 10; //
forrange 循环不可对 vector 进行增加或删除元素
索引下标不存在,成为缓冲区溢出 buffer overflow
迭代器
*iter
iter->mem
++iter
--iter
iterl== iter2
iterl!= iter2
c++ style 尝试用 != 作为循环的判断结束条件
begin()
end()
cbegin()
cend()
vector 和 string 对迭代器的支持:增加算术运算(+,-)和偏序关系运算(<,⇐,>,>=)
减运算返回值是 difference_type
数组
指针数组,数组指针和数组引用
int *ptrs[10];
int (*Parray)[10] = &arr;
int (&arrRef)[10] = arr;
int *(&arry)[10] = ptrs;
在很多用到数组名字的地方,编译器都会自动地将其替换为一个指向数组首元素的指针:
int ia[] = { 0, 1, 2, 3, 4 };
auto ia2(ia); // ia2 是指针
decltype(ia) ia3; // ia3 是数组
数组的指针也是迭代器
利用 begin 和 end 可以获取首址针和尾后指针
两个指针相减,结果类型为 ptrdiff_t
数组的下标运算是内置的(可以为负值),vector是类所定义的
c-string
strlen
strcat
strcmp
strcpy
string→c-string
s.c_str()
多维数组
多维数组初始化,可以多层括号或者直接单层括号
要使用范围for语句处理多维数组,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型
左值和右值
当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。