理解const与指针的规则

在C++中理解const与指针的组合,可以遵循两个简单规则:

  1. 星号(*)前的const:表示指针指向的内容不能修改
  2. 星号(*)后的const:表示指针本身不能改变指向

详细分析各种情况

1. 常量指针

1
2
const int* p1 = &value;
int const* p2 = &value; // 与上面等价

可以理解为const int 和 int const是同一种类型,创建了一个指针指向了这个类型

这两种写法完全等价,都表示:

  • 类型:指向整型常量的指针
  • 限制:不能通过此指针修改所指向的值
  • 可以:改变指针指向的地址
  • 读法:“p1是一个指针,指向const int”

示例:

1
2
3
4
int a = 5, b = 10;
const int* p = &a; // p指向a
*p = 6; // 错误!不能通过p修改a的值
p = &b; // 正确,p可以改变指向

2. 指针常量

1
int* const p3 = &value;
  • 类型:指向整型的常量指针
  • 限制:指针本身不能改变指向(必须始终指向初始化时的地址)
  • 可以:通过此指针修改所指向的值
  • 读法:“p3是一个const指针,指向int”

示例:

1
2
3
4
int a = 5, b = 10;
int* const p = &a; // p指向a
*p = 6; // 正确,可以通过p修改a的值
p = &b; // 错误!p不能改变指向

3. 指向常量的常量指针

1
const int* const p4 = &value;
  • 类型:指向整型常量的常量指针
  • 限制:既不能通过此指针修改所指向的值,也不能改变指针的指向
  • 读法:“p4是一个const指针,指向const int”

示例:

1
2
3
4
int a = 5, b = 10;
const int* const p = &a; // p指向a
*p = 6; // 错误!不能通过p修改a的值
p = &b; // 错误!p不能改变指向

简化记忆方法

一个简单的记忆技巧是从右向左读声明:

  1. const int* p → “p是一个指针,指向const int”
  2. int* const p → “p是一个const指针,指向int”
  3. const int* const p → “p是一个const指针,指向const int”

图解不同情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const int* p;
┌─────┐ ┌─────┐
│ p │───▶│ 数据 │ // p可以改变指向,但不能通过p修改数据
└─────┘ └─────┘

int* const p;
┌─────┐ ┌─────┐
│ p │═══▶│ 数据 │ // p不能改变指向,但可以通过p修改数据
└─────┘ └─────┘

const int* const p;
┌─────┐ ┌─────┐
│ p │═══▶│ 数据 │ // p不能改变指向,也不能通过p修改数据
└─────┘ └─────┘

其中:

  • ───▶ 表示可以改变的指向
  • ═══▶ 表示不可改变的指向
  • 数据是否可通过指针修改取决于是否有const int