在C/C++中,指针常量和常量指针是两个容易混淆但非常重要的概念,它们的主要区别在于指针本身和指针所指向的内容的可变性。
一、基本概念
1. 常量指针 (Pointer to Constant)
-
特点:指针可以改变指向,但不能通过指针修改所指向的值
-
声明格式:
const 类型* 指针名
或类型 const* 指针名
2. 指针常量 (Constant Pointer)
-
特点:指针的指向不能改变,但可以通过指针修改所指向的值
-
声明格式:
类型* const 指针名
3. 指向常量的指针常量 (Constant Pointer to Constant)
-
特点:指针的指向不能改变,也不能通过指针修改所指向的值
-
声明格式:
const 类型* const 指针名
二、代码示例
int main() {
int a = 10, b = 20;
// 1. 常量指针 - 指向的内容不可变,但指针可以指向其他地址
const int* ptr1 = &a;
// *ptr1 = 30; // 错误:不能通过ptr1修改a的值
ptr1 = &b; // 正确:可以改变ptr1的指向
// 2. 指针常量 - 指针的指向不可变,但可以修改指向的内容
int* const ptr2 = &a;
*ptr2 = 30; // 正确:可以通过ptr2修改a的值
// ptr2 = &b; // 错误:不能改变ptr2的指向
// 3. 指向常量的指针常量 - 都不能改变
const int* const ptr3 = &a;
// *ptr3 = 40; // 错误:不能通过ptr3修改a的值
// ptr3 = &b; // 错误:不能改变ptr3的指向
return 0;
}
三、记忆技巧
-
从右向左读法:
-
const int* ptr
→ ptr is a pointer to int const (指向const int的指针) -
int* const ptr
→ ptr is a const pointer to int (指向int的const指针)
-
-
星号位置法:
-
const在
*
左边 → 指向的内容是常量 -
const在
*
右边 → 指针本身是常量
-
四、常见应用场景
1. 常量指针的典型用途
void printString(const char* str) {
// 函数承诺不会通过str修改字符串内容
while (*str) {
std::cout << *str++;
}
}
2. 指针常量的典型用途
int configValue = 100;
int* const configPtr = &configValue; // 配置指针固定指向configValue
// 在整个程序中,configPtr始终指向configValue
// 但允许通过它修改配置值
*configPtr = 200; // 允许修改配置值
3. 指向常量的指针常量的用途
const int MAX_SIZE = 100;
const int* const maxPtr = &MAX_SIZE; // 固定指向不可修改的值
// 常用于定义不会改变的系统常量
五、与引用的关系
引用在行为上类似于一个自动解引用的指针常量:
int a = 10;
int& ref = a; // 类似于 int* const ptr = &a;
ref = 20; // 类似于 *ptr = 20;
六、总结对比表
类型 | 声明格式 | 指针可变 | 指向内容可变 | 类似引用类型 |
---|---|---|---|---|
普通指针 | int* ptr | 是 | 是 | - |
常量指针 | const int* ptr | 是 | 否 | - |
指针常量 | int* const ptr | 否 | 是 | int& |
指向常量的指针常量 | const int* const ptr | 否 | 否 | const int& |
理解这些概念对于编写安全、高效的C/C++代码非常重要,特别是在处理字符串、函数参数传递和硬件寄存器访问等场景中。