一、定义与声明
常量指针(Pointer to Constant)
- 定义:指针指向的内容为常量,不可通过该指针修改,但指针本身可改变指向。
- 声明方式:
const int* p
或int const* p
const int a = 10; const int* p = &a; // p是常量指针 // *p = 20; // 错误!内容不可修改 p = &b; // 正确,指针指向可修改
指针常量(Constant Pointer)
- 定义:指针本身是常量,不可修改指向的地址,但可通过指针修改指向的内容。
- 声明方式:
int* const p
int b = 20; int* const p = &b; // p是指针常量 *p = 30; // 正确,内容可修改 // p = &a; // 错误!指针指向不可修改
常指针常量(Constant Pointer to Constant)
- 定义:指针本身和指向的内容均为常量。
- 声明方式:
const int* const p
const int c = 30; const int* const p = &c; // 两者均不可修改 // *p = 40; // 错误! // p = &a; // 错误!
二、核心区别对比
特性 | 常量指针 | 指针常量 | 常指针常量 |
---|---|---|---|
指针指向可变性 | 可修改指向(p = &b ) |
不可修改指向 | 不可修改指向 |
内容可变性 | 不可通过指针修改内容 | 可通过指针修改内容 | 不可通过指针修改内容 |
初始化要求 | 无强制初始化 | 必须初始化 | 必须初始化 |
典型应用场景 | 函数参数保护数据 | 固定地址操作硬件/资源 | 完全不可变的全局配置 |
三、使用场景与注意事项
常量指针的典型应用
- 函数参数保护:避免函数内部修改外部数据,如
strlen(const char* s)
。 - 指向字面量:如
const char* str = "Hello";
,防止修改字符串常量。
- 函数参数保护:避免函数内部修改外部数据,如
指针常量的典型应用
- 硬件寄存器操作:固定地址的硬件寄存器访问,如
volatile int* const reg = 0x8000;
。 - 资源句柄管理:如文件指针需固定指向某个资源句柄。
- 硬件寄存器操作:固定地址的硬件寄存器访问,如
常见错误
- 混淆声明顺序:
int const* p
与const int* p
等价,但int* const p
完全不同。 - 未初始化指针常量:
int* const p;
会导致编译错误。 - 通过常量指针修改数据:需确保原始变量本身不是常量(如
const int a
不可修改,但int a
可通过其他方式修改)。
- 混淆声明顺序:
四、示例代码解析
#include <iostream>
using namespace std;
int main() {
int x = 10, y = 20;
// 常量指针
const int* p1 = &x;
// *p1 = 15; // 编译错误
p1 = &y; // 合法
// 指针常量
int* const p2 = &x;
*p2 = 15; // 合法
// p2 = &y; // 编译错误
// 常指针常量
const int* const p3 = &x;
// *p3 = 20; // 错误
// p3 = &y; // 错误
return 0;
}
五、记忆技巧
- 从右向左读声明:
const int* p
→ “p是指针,指向int常量”。int* const p
→ “p是常量,指向int”。
- 口诀:
- 常量指针:内容不变,指向可变(如看门狗,只读不写)。
- 指针常量:指向不变,内容可变(如固定管家,可改内容)。