自己的笔记(c++ primer)
对于常量
const int k; // 未初始化 错误
const int i=11; // 正确 const对象必须初始化 并且初始化后 不能改变其值
(const int i=11;i=12;//这是不允许的 编译器会给你报错)
int k=1;const int i=k; // 这样也是允许的 k的值出初始化了i的值 i的值不能再改变
const限定的是一个常量值不可改变
对于引用
const int &i=1;
简单地对常量引用 是被允许的
int k =1;
const int &i=k;
i是一个常量引用 而其引用的对象是变量 所以可以通过改变其引用对象的值来改变i的值
比如
int k =1;
const int &i=k; //这时候i的值是1
k=2; //改变k的值 这时候i的值也改变了
const限定的是i的引用对象不可改变 相当于把i绑定到了k的身上
const int k=1;
const int &i=k;
这时候引用和引用对象都是常量 k的值不能改变 i的值自然也不能改变
const int k=1;
const int &i=k;
const int &p=i;
这时候p也是一个常量引用其值不能改变 当然去掉 k 的const限定 i和p 的值会随k的值而改变
一个非常量引用指向一个常量的对象是不允许的 但是一个常量引用指向一个非常量的对象是可以的
const int k=1;
const int &i=k; //正确 一个常量引用指向一个非常量的对象
int &p=k; // 错误 一个非常量引用指向一个常量的对象
对于指针
指向常量的指针
const int k=1;
const int *p=&k; // *p是一个指向常量的指针 其值是可以改变的 也可以指向非常量
int *q=&k;// 错误 一个普通的指针(不是指向常量的指针)指向了一个常量对象 必须加上const才可以
int n=3;
p=&n; // 正确 可以看出指向常量的指针的值是可以改变的 (对比引用 的不能改变 因为引用一旦绑定就不能重新绑定 而指针是对象 可以改变它的指向 可以说指针并没有绑定)
*p=2; // 不能直接给 *p 赋值
const指针
int k=1;
int *const p=&k;// p是一个常量指针 将一直指向k(注意对比 const int *p) *p的值会 随k的值变化而变化
*p=3; // 这个时候 *p和k的值都是3 但是p指向的地址并没有变 (const int *p 不能给*p赋值)
这个时候 *p 被称为 常量指针 即这个指针是一个常量 但是它不能指向一个常量 要想实现必须在加上一个const限定使它能指向一个常量 即指向常量的常量指针
const int k=1;
int *const p=&k;// 错误 不能指向一个常量
const int *cosnt q=&k;// 正确 *q 是一个指向常量的常量指针 其值和指针指向都不能改变
指针本身就是一个对象 又可以指向一个对象 。因此指针本身是不是一个常量和指针所指的是不是一个常量是俩个独立的问题。
顶层const用于表示指针本身是个常量 底层const表示指针所指的对象是一个常量
顶层const可以表示任何数据类型 底层const则与引用和指针有关
int i=0;
int *const p1=&i; 顶层const p1是个不能改变的地址
const int k=2; 顶层const k不能改变
const int *p2=&k; 底层const p2的值可以改变
const int &p3=p2; 底层const 声明引用都是底层
const int *const p4=&k;顶层const 左边的是底层 右边的是顶层
constexpr限定符
声明为constexpr变量的一定是一个常量,而且必须 用常量表达式初始化
常量表达式是指值不会改变并且在编译过程就能得到计算结果的表达式
cosnt int i=1;
const int j=i+1; // i 和j都是常量表达式
与const最大的区别 就是 constexpr声明的指针仅仅对指针有效 与指针指向的对象无关
const int *p=&i;// p是一个指向常量的指针
constexpr int *q =&i;// q是一个常量指针 与 int *const q 相似
cosntexpr const int *q1=&i; // q1是一个指向常量的常量指针