常量引用

对常量的引用

常量指针

指向常量的指针

指针常量

不可变的指针

顶层 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; // 错误,对常量取地址是底层const

delctype

返回该变量的类型(包含顶层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

stringc-string

s.c_str()

多维数组

多维数组初始化,可以多层括号或者直接单层括号

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

左值和右值

当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。