C++ const指针与二级指针权限规则详解

一只小鹿
一只小鹿
发布时间:2026-10-13| 6人浏览过
原创

在C++编程中,正确使用const修饰指针是避免内存错误的关键。本文将指针的权限划分为“指向权限”(能否改变指针地址)和“修改权限”(能否改变指针指向的值),并结合一级和二级指针的具体代码案例,讲解权限缩小赋值规则及常见错误分析。

指针权限:指向与修改

为了便于理解,可以将指针的操作权限简化为两类:

  • 指向权限:允许修改指针变量本身所存储的地址(例如从指向变量a改为指向变量b)。
  • 修改权限:允许通过解引用操作符 * 修改指针所指向内存单元中的值。

const 关键字的作用就是限制这两种权限。具体限制位置取决于 const 相对于星号 * 的位置:

	int a = 10, b = 20;
	
	// 1. int* p = &a; -> 拥有完全权限
	int* p = &a;
	p = &b;        // 改变指向的权限 ✔
	*p = 30;       // 修改内存的权限 ✔

	// 2. const int* cp = &a; -> 限制修改权限
	// 此时 *cp 视为常量,不可修改
	const int* cp = &a;
	//*cp = 100;   // error:表达式必须是可修改的左值 ❌ 修改失败
	cp = &b;       // ok.          ✔ 指向成功

	// 3. int* const pa = &a; -> 限制指向权限
	// 此时 pa 本身被视为常量,不可改变其指向
	int* const pa = &a;
	*pa = 100;     // ok.          ✔ 修改成功
	//pa = &b;     // error:表达式必须是可修改的左值 ❌ 指向失败

指针赋值的权限缩小原则

C++ 中指针赋值的核心逻辑是“权限缩小式赋值”。可以类比现实生活中的借阅关系:如果我把一本书借给你,你只拥有“阅读权限”(不能涂改),而我没有损失任何原本拥有的权利;反之,若我只有阅读权限,你却想获得“使用权”(能涂改),这是不允许的。

在代码层面,这意味着:右指针类型 包含的权限必须小于或等于 左指针类型 限制的权限。

第1步:一级指针赋值法则

针对基本数据类型的一级指针,赋值公式如下:

	int a = 10;
	int* p = &a;		      // 标准指针
	
	// 合法:普通指针指向 const 指针 (权限缩小)
	const int* cp = p;	      
	
	// 合法:普通指针指向 const 限定地址的指针
	int* const pa = p;	      
	
	// 非法:普通指针接收 const 指针 (权限放大,存在修改常量的风险)
	// int* p1 = cp;      // error

核心结论:

  • int* 本质上包含了 int* 和 int* const 的特征,但无法兼容 const int* 对值的保护。
  • const int* 等同于 int const *。
  • 反方向赋值(如 int* = const int*)通常会导致编译错误,因为这意味着可能破坏 const 对象的只读性。

进阶练习:一级指针辨析

判断下列赋值语句的合法性:

A选项

	int a = 10;
	const int* p = &a;
	int* q = p;		

分析: const int* 限制了对 a 的修改,试图将其赋值给无限制的 int* 属于权限放大,错误。

B选项

	int a = 10;
	int* const p = &a;
	int* q = p;

分析: int* const 仅限制指针本身的移动,不限制值的修改。q 也是 int*,两者权限一致,正确。

C选项

	int a = 10;
	int* const p = &a;
	int* const q = p;

分析: 左右两侧均为 int* const,类型完全匹配,正确。

D选项

	int a = 10;
	int* const p = &a;
	const int* q = p;

分析: 左侧 p 可修改值,右侧 q 被要求禁止修改值。这是标准的权限缩小,正确。

难点突破:二级指针的 const 规则

二级指针涉及两层解引用,const 出现在不同层级会产生不同的限制效果。我们逐一分析以下选项:

	int a = 10;
	int* p1 = &a; // p1 类型为 int*
	
	// A. const int** q1 = &p1;
	// B. int* const* q2 = &p2;
	// C. int** const q3 = &p3;
	// D. int* const p4 = &a; int** q4 = &p4;
	// E. const int* p5 = &a; int* const* q5 = &p5;

A选项:const 修饰二级指针

const int** q1 = &p1; 是错误的。

原因: const int** 表示最内层(解引用两次后)的值是常量。但是 p1 是 int*,它指向可变内存。如果允许此赋值,未来通过 q1 修改内容可能会破坏 a 的不变性(尽管 a 此处非常量,但在语义上构成了风险)。编译器禁止这种潜在的权限跨越。

修正: 需要保证中间环节也是常量或更严格的限制,例如将 p1 改为 const int*。

B选项:const 修饰一级指针(剥离法)

int* const* q2 = &p2; 是正确的。

原因: int* const* 中 const 紧跟在第一个 * 之后,说明它修饰的是解引用一次后的结果(即一级指针)。去掉左边的 int,看核心逻辑:* <= const *,这是一个标准的“普通指针赋值给常量指针”的权限缩小过程,完全合法。

C选项:const 修饰二级指针整体

int** const q3 = &p3; 是正确的。

原因: 这里 const 位于类型末尾且远离所有 *,或者理解为修饰 q3 本身(指针变量),而非它所指向的内容。只要右边的 &p3 地址能赋值给 q3 即可。由于两边最终处理的是地址传输,不涉及内部值的权限冲突判定(或者说 const 在此处限制了 q3 变量的重定向),在类型转换上是匹配的。

D选项:混合限制

int* const p4 = &a;
int** q4 = &p4;

分析: p4 是 int* const 类型(指向权限受限),取地址后为 int* const *。尝试赋值给 int**(无限制)。这相当于试图用高权限(带约束)的数据去初始化低权限(无约束)的目标,可能导致后续通过 q4 修改 a,违反了 p4 的限制初衷。因此错误。

E选项:双向限制

const int* p5 = &a;
int* const* q5 = &p5;

分析: 分为两部分看:

  1. 左边部分提取:意图让 int* 指向 const int*,权限冲突,错误。
  2. 右边部分提取:const * 指向 *,即 const int* <= int*,合法。

由于左边部分已经报错,故整个赋值错误。

方法总结

面对复杂的二级指针 const 判断,可遵循以下策略:

  • 定位 const 位置:查看 const 是位于最后一个 * 之前,还是之后。
  • 拆解分析法:
  • 若 const 靠近最右侧(如 int* const *),可直接套用一级指针 int* <= const int* 的规则进行判断。
  • 若 const 靠近最左侧(如 const int **),需警惕解引用一层的权限穿透问题,通常要求两侧都有对应的 const 保护,或者左侧必须有更严格的 const 声明。
  • 安全原则:永远不要试图绕过 const 限制去获取修改常量的权限。

以上就是C++指针与const结合使用的详细内容,更多关于C++二级指针权限的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。