Skip to content

指针 vs 引用 (Pointer vs Reference)

核心摘要:指针是一个存放地址的变量,而引用是原变量的别名。

在 C++ 中,指针和引用都可以间接访问对象,但它们在行为和使用场景上有本质区别。

🔍 主要区别

特性指针 (Pointer)引用 (Reference)
本质变量:存储的是另一个变量的内存地址别名:原变量的另一个名字,不占独立内存(通常)
空值 (Null)可以为空 (nullptr)必须绑定对象,不存在空引用
初始化定义时可以不初始化 (不推荐)定义时必须初始化
重指向可以改变指向 (指向不同的对象)不可改变 (一旦绑定,终身不换)
语法操作需要解引用 (*p),访问成员用 ->直接像普通变量一样使用,访问成员用 .
算术运算支持指针运算 (如 p++ 移动地址)不支持 (对引用做运算是修改原值)
多级嵌套有多级指针 (int**)没有引用的引用 (但有右值引用 &&)
sizeof指针本身的大小 (4或8字节)引用对象的大小

💻 代码示例

1. 初始化与重指向

cpp
int a = 10;
int b = 20;

// --- 指针 ---
int* p = &a;  // 初始化指向 a
p = &b;       // ✅ 合法:可以改为指向 b
p = nullptr;  // ✅ 合法:可以为空

// --- 引用 ---
int& r = a;   // 初始化绑定 a
r = b;        // ⚠️ 陷阱:这不是让 r 指向 b,而是把 b 的值(20)赋值给 r 绑定的对象(a)
              // 此时 a 变成了 20,r 依然是 a 的别名
// int& r2;   // ❌ 编译错误:引用必须初始化

2. 作为函数参数

  • 指针传参:如果参数可能为空,或者需要改变指针本身的指向(极少),用指针。
  • 引用传参:C++ 中更推荐的方式。如果不需要处理空值,优先使用 const T& (只读) 或 T& (修改)。
cpp
// 指针版本 (调用者需要传地址,内部需要判空)
void addOnePtr(int* p) {
    if (p) (*p)++; 
}

// 引用版本 (调用者直接传变量,内部不需要判空,代码更洁)
void addOneRef(int& r) {
    r++; 
}

int main() {
    int x = 10;
    addOnePtr(&x); // 传地址
    addOneRef(x);  // 传变量,就像操作 x 本身一样
}

🧠 什么时候用哪个?

  1. 优先使用引用:在函数参数传递、返回值、范围 for 循环中,引用更安全、语法更简洁。
  2. 必须使用指针的场景
    • 对象可能不存在 (需要 nullptr 表示)。
    • 需要指针算术运算 (如数组遍历)。
    • 需要在运行时改变指向的对象。
    • 与 C 语言接口兼容时。

总结

  • 指针与引用最主要的区别:指针是一个独立的变量,存放对象的地址,可以不依赖于对象存在;引用是对象的别名,必须要绑定到对象中,且一旦绑定就不可修改

Released under the MIT License.