C++指针与引用
概述
C++ 中指针(*)和引用(&)的核心区别:引用是对象的不可改绑别名,指针是可变的地址值。const 修饰左边的东西(左边无则修饰右边),决定"谁只读"。指针源于直接控制硬件的需求,引用是为更安全的别名传递而引入的后续设计。
关键内容
- 从右往左读法:先抓变量名,再往两边扩展。
*左边有const T→ "指向只读 T 的指针";&→ "别名"。 - 四种核心写法对比:
T&:可写引用,改别名即改原对象;绑定后不可改绑。const T&:只读引用,不能通过它修改对象;常用于"传大对象避免拷贝且不允许修改"。T*:可写指针,可改*p(对象值),也可改p(指向)。const T*(等价T const*):指向只读对象的指针,不能改*p,但可改p指向。- const 的位置决定修饰目标:
const T* p:"指向常量的指针",*p不可改,p可改。T* const p:"常量指针",p不可改,*p可改。const T* const p:两者均不可改。- 引用无"改指向"语义:引用在绑定时固定,
r = b是给原对象赋值,不是改绑;这与指针根本不同。 - 函数参数实用口诀:
void f(T x)→ 传值拷贝;void f(T& x)→ 可写引用;void f(const T& x)→ 只读引用;void f(T* p)→ 指针(可为空);void f(const T* p)→ 只读指针。
速记表
| 写法 | 中文直觉 | 能改值 | 能改绑定/指向 |
|---|---|---|---|
T& |
可写引用 | 可以 | 不行 |
const T& |
只读引用 | 不可以 | 不行 |
T* |
可写指针 | 可以(*p) |
可以 |
const T* |
指向只读对象的指针 | 不可以(*p) |
可以 |
T* const |
常量指针 | 可以(*p) |
不行 |
const T* const |
指向常量的常量指针 | 不可以 | 不行 |
设计哲学:为什么要有指针和引用
指针的起源
C/C++ 诞生于离机器很近的时代,需要直接操作内存地址以实现:
- 间接访问数据(避免拷贝大对象)
- 动态申请内存(new int[100])
- 构造链表、树、图等复杂数据结构(节点间存地址)
- 与操作系统底层接口交互("地址 + 长度"形式)
指针本质:存地址的变量。
引用的引入
指针太容易出错(野指针、空指针解引用、随意改指向),C++ 引入引用作为更安全的"别名":
- 一旦绑定不可改绑(比指针更安全)
- 函数参数无需手动解引用(x++ vs (*x)++)
- 支持运算符重载、返回值优化等高级语义
- const T& 是现代 C++ 的基础用法
设计定位区分
指针(显式地址操作)适合:可能为空、需要改指向、动态内存、数据结构链接、底层接口。
引用(对象别名)适合:参数传递、返回对象本身、operator 重载、避免拷贝。
核心原则:指针负责表达底层控制;引用负责表达高级语义。
与 Python 的对比
Python 不是没有指针,而是不暴露给开发者。Python 内部有引用计数和对象指针,但由解释器管理:
- b = a(列表):两个名字绑定同一对象,改 b 同时改 a
- Python 变量名绑定到对象,这个绑定效果类似引用,但不是语言级语法
Python 选择隐藏内存细节的原因:设计目标是简单、可读、开发效率高、少踩内存错误、跨平台兼容(不绑定具体实现如 CPython/PyPy)。
关键误区:Python 不是"没有引用关系",而是把引用关系做成了默认语义,不单独给 & 和 *。
来源
- C++ 指针引用解读 — ChatGPT 对话整理,从右往左读法 + 四类写法 + const 位置辨析
- c++指针和引用 — ChatGPT 对话,指针/引用设计起源 + Python 对比
相关
- C++ — 本概念所属编程语言