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 内容和指针都不可变 不可修改 不可修改
相关推荐
白杨尚青2 小时前
C++进阶篇(二):多态——虚函数、重写、虚函数表与三个经典坑(附完整代码仓库)
开发语言·c++·多态·虚函数·重写·动态绑定
syagain_zsx2 小时前
spdlog实战:日志分级、滚动与性能调优
linux·c++·日志库·二次开发日志库
WJ.Polar20 小时前
Java封装、继承、多态
java·开发语言
摇滚侠20 小时前
Java 中如何表示负数,有符号和无符号的区别,补码的计算规则,char byte short int long 的范围
java·开发语言
weixin_3077791320 小时前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
AI wins20 小时前
c++新增頭文件
c++
Shadow(⊙o⊙)20 小时前
仿muduo实现高并发服务器——事件就绪管理Channel.hpp
服务器·c++
爱读书的小胖20 小时前
Codewars:Rot13(C)解题分析
c语言·开发语言
鸽鸽程序猿20 小时前
【项目】【在线判题系统】b端题目增删改
开发语言·python
by2099920 小时前
哈希表——快速找到数据:冲突、删除与扩容的实现
数据结构·c++·哈希算法·散列表