一、前言
在 C/C++ 学习中,const、指针、引用 永远是绕不开的三座大山。
const int*和int* const到底谁不能改引用和指针本质区别是什么
为什么
const int& a = 10;可以编译通过函数传参什么时候用
const,什么时候用指针 / 引用
本文从基础到实战,用清晰逻辑 + 典型代码,一次性把这些问题讲透。
二、 const 关键字基本概念
const 是 constant 的缩写,表示只读、不可修改。
被 const 修饰的变量,在初始化之后不能被赋值修改。
cpp
const int a = 100;
a = 200; // 编译错误:a 是只读变量
作用:
-
保护数据,防止意外修改
-
提高代码可读性和安全性
-
便于编译器优化
-
函数传参时明确 "不修改参数" 的语义
三、const 与指针(重点难点)
const 和指针结合时,const 的位置决定了它修饰谁。
判断规则:看 const 是在 * 左边还是右边。
1 指向常量的指针:const int* /int const*
cpp
const int* p;
// 等价于
int const* p;
含义:
-
*指针指向的内容是常量,不能通过 p 修改
-
指针本身可以修改,可以指向其他变量
示例:
cpp
int a = 10;
int b = 20;
const int* p = &a;
*p = 100; // 错误:不能修改指向的值
p = &b; // 正确:指针可以重新指向
适用场景:函数只想读取数据,不希望被修改。
2 指针常量:int* const
cpp
int* const p;
含义:
-
指针本身是常量,不能改变指向
-
指针指向的内容可以修改
示例:
cpp
int a = 10;
int b = 20;
int* const p = &a;
*p = 100; // 正确:可以修改值
p = &b; // 错误:指针不能重新指向
3 指向常量的指针常量:const int* const
cpp
const int* const p;
含义:
-
指针不能改指向
-
指向的值也不能改
最严格的只读形式。
4 总结与判断口诀
| 写法 | 指针能否改指向 | 指向的值能否改 | 记忆口诀 |
|---|---|---|---|
| const int* p | 是 | 否 | 左定值 |
| int const* p | 是 | 否 | 左定值 |
| int* const p | 否 | 是 | 右定向 |
| const int* const p | 否 | 否 | 都不能 |
口诀:const 在 * 左边,定的是值; const 在 * 右边,定的是指针。
四、const 与引用
1 引用的基本特性
引用 & 是变量的别名,必须初始化,且一旦绑定无法更换。
cpp
int a = 10;
int& ra = a;
ra = 20; // 等价于 a = 20
特点:
-
不能为空
-
必须初始化
-
不能重新绑定到其他变量
-
用法和原变量一样,不需要解引用
2 const 引用(常引用)
cpp
const int& ra = a;
表示:
-
通过 ra 不能修改 a 的值
-
原变量 a 本身可以改
cpp
int a = 10;
const int& ra = a;
ra = 100; // 错误
a = 100; // 正确
3 const 引用绑定临时对象
普通引用不能绑定字面量、临时对象,但 const 引用可以。
cpp
// int& ra = 10; // 错误
const int& ra = 10; // 正确
编译器会在内存中创建一个临时变量存储 10,再让 ra 绑定它。这也是函数参数推荐使用 const T& 的重要原因。
五、 指针与引用的区别
| 对比项 | 指针 (pointer) | 引用 (reference) |
|---|---|---|
| 本质 | 存放地址的变量 | 变量别名 |
| 能否为空 | 可以 | 不可以 |
| 能否重新指向 | 可以 | 不可以 |
| 是否需要初始化 | 不必 | 必须 |
| 多级使用 | 支持二级指针 | 无二级引用 |
| 操作方式 | 需要 * 解引用 |
直接使用 |
| 空指针检查 | 必须判断 | 无需判断 |
一句话总结:引用是更安全、受限更少的指针;指针是更灵活、更危险的引用。
六、 const 在函数参数中的实战用法
实际开发中,const 配合指针 / 引用,主要用于函数传参。
1. 不想修改数据,用 const
cpp
void show(const int* p) {
// *p = 999; // 报错,安全
}
void show(const int& a) {
// a = 999; // 报错,安全
}
2.对象较大时,用 const& 避免拷贝
cpp
// 高效、安全、标准写法
void printInfo(const Student& stu) {
// ...
}
比值传递快,比指针更安全。
七、试题总结
1.const int* p 和 int* const p 的区别?
前者值不能改,后者指针不能改。
2.引用可以为空吗?
不可以,必须初始化。
3.指针和引用的本质区别?
指针是实体变量,引用是别名。
4.为什么 const int& a = 10 合法?
const 引用允许绑定临时对象。
5.函数参数优先用什么?
内置类型用值传递;复杂类型优先 const &。
6.非 const 指针可以指向 const 变量吗?
不可以,会丢失 const 属性,编译报错。
八、总结
-
const 离谁近,就修饰谁,谁就不能改
-
引用 = 别名,不能为空,不能重新绑定
-
指针 = 地址,可以空,可以改
-
函数传参优先用 const &,安全高效