doc/docs/summary/2.顶层 const 和底层 const.md
sairate c34823a3bd docs(book): 添加现代 C++教程及相关代码
- 新增现代 C++ 教程的 Preface 章节,包括英文和中文版本
- 添加 C++ Primer 练习代码
- 新增 Learn C++ 教程的 C++ 开发简介章节
- 添加头文件解析文档
- 更新 mkdocs.yml,包含新教程的目录结构
- 修改项目设置,使用 Python 3.10环境
2025-07-06 14:46:58 +08:00

64 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
sort: 2
---
# 顶层 const 和底层 const
简单说顶层const是指“指针本身是常量”而底层const是指“指针指向的对象是常量”。
底层是常量的指针,本身不可改变。(常量指针)
顶层是指针的常量,指向不可改变。(指针常量)
从 const 指针开始说起。`const int* pInt`; 和 `int *const pInt = &someInt`;,前者是 `*pInt` 不能改变,而后者是 `pInt` 不能改变。因此指针本身是不是常量和指针所指向的对象是不是常量就是两个互相独立的问题。用顶层表示指针本身是个常量,底层表示指针所指向的对象是个常量。
更一般的,顶层 `const` 可以表示任意的对象是常量,这一点对任何数据类型都适用;底层 `const` 则与指针和引用等复合类型有关,比较特殊的是,指针类型既可以是顶层 `const` 也可以是底层 `const` 或者二者兼备
`const char * p``char * const p `两种声明的意思分别应该是:
- `p` 是一个指向常量字符的指针,不变的是 `char` 的值,即该字符的值在定义时初始化后就不能再改变。
- `p` 是一个指向字符的常量指针,不变的是 `p` 的值,即该指针不能再指向别的。
一个比较好的记忆方法:
“以`*`分界,把一个声明从右向左读”
注意语法,`*` 读作 `pointer to` (指向...的指针)`const` (常量) 是形容词,`char` (变量类型) 和 `p` (变量名)
- `const char * p` 读作:`p is a pointer to a const char`
- 译:`p` 是一个指针(变量),它指向一个常量字符(const char)。
- `char * const p` 读作:`p is a const pointer to a char`
- 译:`p` 是一个常量指针(const p),它指向一个字符(变量)。
- 另外`const`位置多变, `const char * p``char const * p`,首先以 `*` 分界,虽然 `const` 的位置改变了,但它都是在修饰 `char`,常量字符。
```cpp
int i = 0;
int *const p1 = &i; //p1为顶层const其值不能改变
const int ci = 42; //ci为顶层const其值不能改变
const int *p2 = &ci; //允许改变p2的值这是一个底层const
const int *const p3 = p2; //靠右的为顶层const靠左的为底层const
const int &r = ci; //用于声明引用的都为底层const
```
```cpp
i = ci; //正确ci顶层const不受影响
p2 = p3;//正确p2和p3指向的对象都相同且p3又是一个顶层const其本身也为常量
int *p = p3; //错误p3包含底层const定义但是p没有
p2 = &i;//正确int i 可以转换为常量
int &ri = ci;//错误普通的int &不能绑定到int常量上
const int &r2 = i;//正确const int& 可以绑定到一个普通的int上
vector<int>::iterator /*可以理解为*/ int* //代表非常量
vector<int>::const_iterator /*可以理解为*/ const int* //代表底层const
const vector<int>::iterator /*可以理解为*/ int* const //代表顶层const
const vector<int>::iterator /*可以理解为*/ const int* const //左侧的const为底层const右侧的顶层const
```
const修饰规则:
`const int *p1`可看作是`const`修饰的类型是`int`,修饰的内容是`*p1`,即`*p1`不允许改变。
`int const *p2` 可以看作`const`修饰的类型是`int`,修饰的内容是`*p2`,即`*p2`不允许改变。
`int *const p3` 可以看作`const`修饰的类型是`int *`,修饰的内容是`p3`,即`p3`不允许改变
简单来说就是在 *号左边还是右边
## 参考资料
- <https://www.zhihu.com/question/24785843/answer/1819676752>
- <https://zhuanlan.zhihu.com/p/161560391>