C/C++ const:修饰变量和指针的区别(和引用底层关系)

在C++学习中,const 是一个非常基础但极易混淆的关键字,尤其是当它和指针结合时,很多新手都会被 const int *p、int *const p 这类写法搞懵。

其实不用慌,核心就一个原则:const 离谁近,谁就不能改。

一、先搞懂基础:const 修饰普通变量

这是最简单、最常用的用法,一句话就能说透:const 修饰普通变量,就是给变量"上锁",让它变成只读的,不能再修改。

代码示例:

cpp 复制代码
const int a = 10; // 用const修饰变量a
a = 20; // 报错!不能修改const修饰的变量

核心特点:变量本身的值不可变,一旦初始化,就不能再赋值。这是 const 最基础的用法,没什么难度,重点在后面和指针的结合。

二、重点难点:const 修饰指针(3种情况)

const 和指针结合,之所以容易乱,是因为 const 可以修饰"指针本身",也可以修饰"指针指向的内容"。记住一个口诀,瞬间理清:

cpp 复制代码
const 在 * 左边 → 指针指向的内容不能改
const 在 * 右边 → 指针本身不能改
两边都有 → 内容和指针都不能改

1. const 在 * 左边:指向的内容不能改(此时const 修饰*p,也就是地址里存的值不能改)

写法有两种,效果完全一样,随便写哪种都可以:

cpp 复制代码
const int *p; // 写法1
int const *p; // 写法2

核心规则:不能通过指针 p 修改它指向的内容,但指针 p 本身可以指向别的变量。

代码示例:

cpp 复制代码
int a = 10, b = 20;
const int *p = &a; // 指针p指向a

*p = 100; // 报错!不能修改指向的内容
p = &b;   // 正确!指针可以换指向

2. const 在 * 右边:指针本身不能改(此时const修饰p,也就是地址不能改)

写法只有一种,注意 const 的位置

cpp 复制代码
int *const p;

:指针 p 不能再指向别的变量,但可以修改它指向的内容:

cpp 复制代码
int a = 10, b = 20;
int *const p = &a; // 指针p固定指向a(初始化时必须赋值,否则报错)

*p = 100; // 正确!可以修改指向的内容(电视可以调音量)
p = &b;   // 报错!指针不能换指向(遥控器不能换台)

注意:这种写法,指针 p 必须在初始化时就指定指向的变量,不能先定义再赋值(比如 int *const p; 单独写会报错)

2.1 引用的底层实现 = const指针(int *const ref)

:即"指针本身不能改指向",这也是引用不能改绑的原因;

我们写一句简单的引用代码:

cpp 复制代码
int a = 10;
int &ref = a; // 引用ref绑定变量a

这段代码,编译器在底层会悄悄翻译成类似这样的指针操作(注意:这是底层实现,我们写代码不能这么写):

cpp 复制代码
int a = 10;
int *const ref = &a; // 底层用const指针实现引用

这就解释了两个关键问题:

  1. 为什么引用必须初始化? → 因为const指针(int *const ref)必须在初始化时指定指向,引用底层是const指针,所以语法上要求引用必须绑定变量才能定义,不能先定义再赋值(比如int &ref;会报错)。

  2. 为什么引用不能改绑? → 因为底层的const指针,本身不能改指向(ref = &b会报错),所以引用一旦绑定某个变量,就不能再绑定其他变量(比如ref = b是给a赋值,不是改绑)。

3. 两边都有 const:内容和指针都不能改

cpp 复制代码
const int *const p;

核心规则:既不能修改指向的内容,也不能修改指针本身的指向,相当于"双重锁定"。

cpp 复制代码
int a = 10, b = 20;
const int *const p = &a;

*p = 100; // 报错!不能改内容
p = &b;   // 报错!不能改指向

三、一张表彻底记牢(建议收藏)

为了方便大家快速查阅,整理了所有情况的对比,一目了然:

写法 通俗含义 指向的内容(*p) 指针本身(p)
int *p 普通指针 可修改 可修改
const int *p / int const *p 指向常量的指针 不可修改 可修改
int *const p 指针本身是常量 可修改 不可修改
const int *const p 内容和指针都不可变 不可修改 不可修改
相关推荐
andyweike5 小时前
php笔记
开发语言·笔记·php
蒸蒸yyyyzwd5 小时前
秋招学习笔记 day46
c++·八股
Circ.6 小时前
Python 调试 Litellm 本地大模型接口:模型列表与对话接口实操踩坑记录
开发语言·python
现任明教教主~7 小时前
Thinkphp站群蜘蛛池SaaS系统YanyvSEO含多用户/积分/六大引擎计费/易支付对接
java·开发语言·spring
Zhou1411368 小时前
SpringSecurity_02_授权与高级功能
开发语言·python
码匠许师傅8 小时前
【C++三方组件】cpp-httplib:一个头文件起 HTTP 服务
开发语言·c++·http
无名猿9 小时前
new/delete 与 malloc/free:为什么绝对不能混用
c++·内存管理·现代c++·踩坑记录
小小小小钰儿10 小时前
1.5-Python网络编程
开发语言·网络·python·web安全·计算机·网络安全