指针、常量指针和指针常量
- 常量指针(Pointer to const):指针指向的值是常量,不能修改该值,但指针本身可以改变。
const int* p = &x; // p 是指向常量整数的指针 |
- 常量引用(Reference to const):引用的对象是常量,不能通过引用修改该对象,但引用本身不能改变(引用无法重新绑定到其他对象)。
const int& ref = x; // ref 是 x 的常量引用 |
- 常量指针(Const pointer):指针本身是常量,指针不能改变指向其他地址,但指向的值可以修改。
int* const p = &x; // p 是常量指针,指向 int 类型 |
- 常量指针指向常量(Const pointer to const):既不能通过指针修改指向的值,也不能改变指针的指向。
const int* const p = &x; // p 是常量指针,指向常量整数 |
auto和decltype
- auto 是 C++11 引入的关键字,用于让编译器自动推断变量的类型。这样做可以减少冗长的类型声明,尤其在复杂类型(如迭代器)时非常有用。
- 一次性使用
auto声明多个变量的时候,不同变量的类型推导必须一致,包括常量特性 auto推断的类型一般不是引用类型,除非特殊声明decltype是 C++11 引入的,用来获取一个表达式的类型,通常用于推导复杂类型。decltype 可以在不执行表达式的情况下获取其类型。decltype((x))推导出的类型是x的引用类型- 当
auto和decltype一起使用时,decltype获取的是表达式的类型,而auto则用于推断值类型int x = 10;
decltype(x) y = 20; // y 的类型是 int
auto z = x; // z 的类型是 int,自动推导
decltype(auto) w = x; // w 的类型是 int,和 z 一样 - 使用范围for循环的时候,如果想修改容器中的元素的内容的时候,需要显式的声明应用类型比如
for(auto& c : s){}
单独声明某个命名空间中的一些对象
- 比如想在代码中使用std中的
cin,cout等,可以这样写
using std::cin;
using std::cout; - 如上操作,在使用的时候就不需要显式的给出作用域限定符了
C++使用C标准库
- C++使用C标准库的时候,将库名前面加一个
c,然后去掉结尾的.h,比如C语言的ctype.h库在C++中调用就会变成cctype
vector
- vector初始化可以用花括号,比如
vector<T> a{1, 2, 3, ...};
// or
vector<T> a={1, 2, 3, ...};
string
- 支持使用
.c_str()获取C风格的字符串const char* - 但是如果s的值被改变,返回的字符串可能失效
迭代器
- vector的迭代器:
vector<T>::iterator it; - string的迭代器:
string::iterator it; - 类似地,常量迭代器(不可修改内容)就是
const_iterator - 迭代器可以比大小,比如
<,>等,实际上比较的是谁先谁后
const和constexpr
- const是表示一个变量不可被修改,但是这个变量地值可能没有在编译的时候就被确定下来,可以是运行时确定的
- constexpr要求一个值必须在编译阶段就可以被确定
数组
- 数组的类型不能使用auto声明
- 数组的大小可以不在方括号中声明,比如
int a[] = {1, 2, 3}; - 如果花括号中提供的元素不能覆盖掉数组的全部元素,则使用0(int类型)或者空字符串(string)等自动填充剩余的。
- 数组不可以拷贝初始化,也不能直接对其赋值
int* ptrs[10]声明的是长度为10的int*指针数组int (*array)[10]是一个指向含有10个元素数组的指针int (&array)[10]是一个含有10个元素的int数组的引用int& array[10]是不对的,不可以有成员为引用类型的数组- 执行类似于
int a1[] = {1, 2};
auto a2 a1; - 推导出来的a2是
int*类型 - 使用标准库得到类似容器迭代器的指针
int ia[] = {1, 2, 3};
int* beg = std::begin(ia);
int* end = std::end(ia); // 尾后迭代器 - 这个迭代器可以用来初始化对应类型的
vector,比如vector<int> a(begin, end);