const int * p与int * const p

本文探讨了C++中指针与常量的结合使用,包括int*const p、int const*p和const int*p的含义。它们都限制了对指针所指向的数据进行修改,但约束点有所不同。理解这些用法对于编写安全且可维护的C++代码至关重要。

const int * p, int const * p, int * const p
int * const p:意义表示p可以改变其指向字符串的值,但是不能改变p指针的指向。
int const * p与 const int * p是等价的,只是两者写法不同。c++中无const * 运算符。表示指针可以有不同的指向,但是不能改变原有字符串数据的值。

const char const p 两者皆限定为只读,不能改写。

<think>我们正在讨论C++中两种指针声明方式的区别:`const int* p` `int* const p`。 根据引用内容,我们可以总结如下: 1. `const int* p` (或等价的 `int const* p`)是指向常量的指针(pointer to constant)。这意味着: - 指针 `p` 所指向的内容(即 `*p`)是常量,不能通过 `p` 来修改。 - 但指针 `p` 本身可以改变,即可以重新指向另一个地址。 2. `int* const p` 是常量指针(constant pointer)。这意味着: - 指针 `p` 本身是常量,一旦初始化后就不能再指向其他地址。 - 但可以通过 `p` 修改它所指向的内容(即 `*p` 可以修改)。 我们通过示例对比表格来详细说明。 示例代码(参考引用[4][5]): ```cpp #include <iostream> using namespace std; int main() { int a = 10; int b = 20; // 情况1: const int* p (指向常量的指针) const int* p1 = &a; // 指向a // *p1 = 30; // 错误:不能通过p1修改a的值 p1 = &b; // 正确:p1可以指向b // 情况2: int* const p (常量指针) int* const p2 = &a; // p2将始终指向a *p2 = 30; // 正确:通过p2修改a的值 // p2 = &b; // 错误:p2不能指向其他地址 return 0; } ``` 对比表格: | 特性 | `const int* p` (指向常量的指针) | `int* const p` (常量指针) | |----------------------|--------------------------------|---------------------------| | **指针指向的内容** | 不可修改(`*p = ...` 非法) | 可修改(`*p = ...` 合法) | | **指针自身的指向** | 可修改(`p = ...` 合法) | 不可修改(`p = ...` 非法)| | **初始化要求** | 可不初始化(但通常初始化才有意义)| 必须初始化 | | **const关键字位置** | 在`*`左边(或类型前) | 在`*`右边(变量名前) | 另外,引用[2]提到,在引用中,`int& const b`是非法的,因为引用本身是常量(不能改变引用对象),所以不需要显式加const。而`const int&``int const&`是等价的,表示对常量的引用。 总结记忆口诀:**左定值,右定向**。 - 当const出现在`*`左边时,限定的是指针指向的内容为常量(定值)。 - 当const出现在`*`右边时,限定的是指针本身为常量(定向)。 注意:`const int* p``int const* p`是等价的,因为C++标准规定,const放在类型之前或之后(但必须在`*`之前)是等价的。而`int* const p`则是不同的。 应用场景: - 指向常量的指针:用于函数参数,表示函数不会修改指针指向的数据,增加安全性(如打印函数)[^5]。 - 常量指针:常用于固定指向某个内存地址(如硬件寄存器映射)[^4]。 最后,关于用户之前的问题,我们已经做了对比分析。现在生成相关问题: </think> ### `const int* p` `int* const p` 对比分析 #### 一、核心区别总结 | 特性 | `const int* p` (常量指针) | `int* const p` (指针常量) | |----------------------|-----------------------------------|-----------------------------------| | **本质** | 指向常量的指针 (Pointer to const) | 指针本身是常量 (Const pointer) | | **修改指向的值** | ❌ 禁止 (`*p = val` 非法) | ✅ 允许 (`*p = val` 合法) | | **修改指针指向** | ✅ 允许 (`p = &x` 合法) | ❌ 禁止 (`p = &x` 非法) | | **const关键字位置** | `*` 左侧 (`const int*` 或 `int const*`)| `*` 右侧 (`int* const`) | | **初始化要求** | 可不初始化 | **必须初始化** | | **内存保护重点** | 保护数据内容 | 保护指针地址 | > 💡 **记忆口诀**: > `const` 在 `*` 左 → **定值** (值不可变) > `const` 在 `*` 右 → **定向** (指针不可变) #### 二、代码示例详解 ```cpp #include <iostream> using namespace std; int main() { int a = 10, b = 20; // === 示例1: const int* p (常量指针) === const int* p1 = &a; // ✅ 指向a cout << *p1 << endl; // 输出: 10 // *p1 = 15; // ❌ 编译错误: 不能修改指向的值[^3] p1 = &b; // ✅ 允许改变指向 cout << *p1 << endl; // 输出: 20 // === 示例2: int* const p (指针常量) === int* const p2 = &a; // ✅ 必须初始化 *p2 = 15; // ✅ 允许修改值 (a变为15) cout << a << endl; // 输出: 15 // p2 = &b; // ❌ 编译错误: 不能改变指向 // === 特殊场景 === const int c = 100; const int* p3 = &c; // ✅ 常量指针指向常量 // int* const p4 = &c; // ❌ 错误: 非const指针不能指向常量[^2] } ``` #### 三、底层原理分析 1. **`const int* p` 内存模型** ```mermaid graph LR p[指针变量p] -->|存储| A[地址A] A -->|指向| B[常量数据] ``` - 指针 `p` 存储在栈/堆中(可修改) - 目标数据被标记为只读(不可修改) 2. **`int* const p` 内存模型** ```mermaid graph LR p[常量指针p] -->|固定指向| A[地址A] A -->|指向| B[可变数据] ``` - 指针 `p` 的地址值被锁定(不可修改) - 目标数据可自由修改 #### 四、典型应用场景 1. **`const int* p` 适用场景** - 函数参数保护(防止意外修改): ```cpp void print(const char* str) { // 保证不修改原始字符串[^5] cout << str; } ``` - 访问只读硬件寄存器 2. **`int* const p` 适用场景** - 固定地址映射(如嵌入式系统): ```cpp volatile uint32_t* const PORT_A = (uint32_t*)0x4000; *PORT_A = 0xFF; // 向固定地址写入 ``` - 资源句柄的不可变引用 #### 五、特殊注意事项 1. **类型等价性** - `const int*` `int const*` 完全等价[^1][^3] - 但 `const int*` `int* const` **不等价** 2. **常量传播规则** - 常量指针可指向非常量变量(添加保护层): ```cpp int x = 5; const int* p = &x; // ✅ 合法 ``` - 指针常量**不能**指向常量变量(除非双重const): ```cpp const int y = 10; // int* const p = &y; // ❌ 非法 const int* const p = &y; // ✅ 合法[^2] ``` > ⚠️ **危险操作**: > 使用 `const_cast` 绕过 `const int*` 限制可能导致未定义行为: > ```cpp > const int val = 100; > const int* p = &val; > int* hack = const_cast<int*>(p); > *hack = 200; // 未定义行为!(可能引发崩溃) > ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值