常规变量的地址赋给const修饰的指针
注意,以下三种情况中的例子中的a和b都没有被const修饰
根据 const 关键字的位置不同,常量指针可以分为以下几种情况:
指向常量的指针
常规变量的地址赋给const修饰的指针
这种指针指向的数据是常量,不能通过指针修改数据,但指针本身可以指向其他地址。
例:
const int* ptr;
性质:
- 指针指向的数据是常量,不能通过指针修改。
- 但如果该数据没有被const修饰,则可以通过直接访问的方式进行修改。
- 指针本身可以指向其他地址。
int a = 10;//注意这里的a没有被const修饰
int b = 20;
const int* ptr = &a; // ptr 指向 a
// *ptr = 30; // 错误:不能通过 ptr 修改 a 的值
ptr = &b; // 正确:ptr 可以指向其他地址
//但是,可以直接通过a修改a的值
a = 20; //正确
接下来是C++ Primer Plus 中的原话
指针常量
常规变量的地址赋给const修饰的指针
这种指针本身是常量,不能指向其他地址,但可以通过指针修改所指向的数据。
例:
int* const ptr;
性质:
- 指针本身是常量,不能指向其他地址。
- 可以通过指针修改所指向的数据。
int a = 10;
int b = 20;
int* const ptr = &a; // ptr 是常量,始终指向 a
*ptr = 30; // 正确:可以通过 ptr 修改 a 的值
// ptr = &b; // 错误:ptr 不能指向其他地址
指向常量的指针常量
常规变量的地址赋给const修饰的指针
这种指针本身是常量,不能指向其他地址,同时也不能通过指针修改所指向的数据。(1+2)
例:
const int* const ptr;
性质:(同时具有1和2的常量性质)
- 指针本身是常量,不能指向其他地址。
- 指针指向的数据也是常量,不能通过指针修改。
int a = 10;
int b = 20;
const int* const ptr = &a; // ptr 是常量,始终指向 a
// *ptr = 30; // 错误:不能通过 ptr 修改 a 的值
// ptr = &b; // 错误:ptr 不能指向其他地址
总结
类型 | 语法 | 修改指针指向 | 修改指针指向的数据 |
---|---|---|---|
指向常量的指针 | const int* ptr; | 可以 | 不可以 |
指针常量 | int* const ptr; | 不可以 | 可以 |
指向常量的指针常量 | const int* const ptr; | 不可以 | 不可以 |
const修饰的常量的地址赋给const修饰的指针
注意,在这一部分当中的变量a和b都被const修饰,即代表他们都是常量。
这个时候就只有两种情况了,即:
指向常量的指针
const int* ptr;
指向常量的指针常量
const int* const ptr;
常量不能赋给一般指针常量(即第一部分的第二中类型)
指向常量的指针
指向 a 的指针必须是指向常量的指针,但这个指针可以是指针也可以是指针常量。
const int a = 10;
const int* ptr = &a; // 合法:ptr 是指向常量的指针
// int* ptr2 = &a; // 非法:不能用普通指针指向常量
此时,不能通过直接访问a修改a的值,也不能通过指针修改 a 的值,
const int a = 10;
const int* ptr = &a;
// a = 0; // 非法:不能通过 a 修改 a 的值----------a是常量
// *ptr = 0; // 非法:不能通过 ptr 修改 a 的值--------ptr是指向常量的指针
但此时,这个指针是个指向常量的一般指针,这个指针的指向可以修改,但在指向修改之后,无论指向的是一个const修饰的常量还是一个变量,都不能通过这个指针修改所指向内容的值,即这个指针是个指向常量的指针。
const int a = 10;
const int b = 20;
int c = 30;
const int* ptr = &a; // ptr 指向 a
ptr = &b; // 合法:ptr 可以指向其他常量
// *ptr = 0; // 非法:不能通过 ptr 修改 b 的值--------ptr是指向常量的指针
ptr = &c; // 合法:ptr 也可以指向变量
// *ptr = 0; // 非法:不能通过 ptr 修改 c 的值--------ptr是指向常量的指针
指向常量的指针常量
还是那句话,指向 a 的指针必须是指向常量的指针,但这个指针可以是指针也可以是指针常量。
const int a = 10;
const int* const ptr = &a; // ptr 是指向常量的指针常量
// *ptr = 20; // 非法:不能通过 ptr 修改 a 的值
// ptr = nullptr; // 非法:ptr 的指向不能改变
总结
本文中的const关键字一共在三个位置出现,分别是
- 定义变量时(const修饰就变成常量了)(这里就是2当中提及的指向的内容的性质)
- int*前面,在这里修饰代表的是指向内容的性质,指向的内容的性质与这个指向内容的性质无关。(注意这个的,希望大家能懂笔者的意思),没有const表示可以通过指针修改变量,有const表示不可以通过指针修改变量。
- int*后面,在这里修饰代表指针的性质,没有const表示一般指针,有const表示指针常量(指向不能被修改)
汇总以下表格:有const打勾✔没有const打叉×
定义变量时 | (这里)int* | int*(这里) | 性质 |
---|---|---|---|
× | × | × | 普通的指针指向普通的变量,可以普通的修改(普通的disco我们普通的摇) |
× | × | ✔ | 指针常量指向普通的变量,可以通过指针修改指向内容的值,但是指针指向无法修改 |
× | ✔ | × | 指针指向内容为只读,不可以通过指针修改指向内容的值,但是指针指向可以修改 |
× | ✔ | ✔ | 指针指向内容为只读,不可以通过指针修改指向内容的值,指针指向无法修改 |
✔ | × | × | 语法错误 |
✔ | × | ✔ | 语法错误 |
✔ | ✔ | × | 指针指向内容为只读,不可以通过指针修改指向内容的值,但是指针指向可以修改 |
✔ | ✔ | ✔ | 指针指向内容为只读,不可以通过指针修改指向内容的值,指针指向无法修改 |
希望对大家有所帮助,如有错误欢迎指正