C++指针、引用与取地址运算符对比分析

 更新时间:2026年04月15日 09:16:30   作者:Binary-Jeff  
文章解释了C++中指针、引用和取地址运算符(&)的概念,并分析了它们的区别,文章还讨论了函数传参、右值引用以及智能指针等,感兴趣的朋友跟随小编一起看看吧

一、引言

在学习 C++ 的过程中,初学者很容易会被这几个概念搞混:

  • 指针(Pointer)
  • 引用(Reference)
  • 取地址运算符(&)

尤其是初学者,经常会问:

  • int* pint *p 有区别吗?
  • & 到底是取地址还是引用?
  • 指针和引用是不是一回事?

这篇文章帮你一次性彻底搞懂这些核心概念

二、一句话快速理解

  • 指针:存储“地址”的变量
  • 引用:变量的“别名”
  • &:取地址运算符(同时也用于定义引用)

三、指针(Pointer)

1️⃣ 基本定义

int a = 10;
int* p = &a;

含义:

  • p 存的是 a 的地址
  • *p 才是访问 a 的值

2️⃣ 指针的特点

 可以修改指向

int b = 20;
p = &b;

 可以为空

int* p = nullptr;

 需要解引用访问

cout << *p;

四、引用(Reference)

1️⃣ 基本定义

int a = 10;
int& r = a;

含义:

  • r 就是 a 的另一个名字

2️⃣ 使用效果

r = 20;
// 此时 a 也变成 20

3️⃣ 引用的特点

 必须初始化
 不能重新绑定
 使用时像普通变量(不需要 *

五、取地址运算符&

int a = 10;
int* p = &a;

&a 表示:获取变量 a 的地址

⚠️ 注意:& 有两种用途!

int& r = a;   // 定义引用
int* p = &a;  // 取地址

下面用一个表格对上面的内容做一个总结:

特性指针引用&运算符
本质变量别名操作符
是否占内存是(通常实现为指针)
是否可为空-
是否可改变指向-
使用方式*p直接用&a
安全性较低更安全-

在 C/C++ 中,取地址运算符 & 得到的是变量在程序中的“内存地址”,但这个地址本质上是由操作系统提供的虚拟地址,而不是真实的物理内存地址;程序可以通过这个地址访问数据,但底层还需要经过操作系统和硬件(如内存管理单元)的转换才能映射到实际的物理内存。

六、进阶与易错点总结

6.1int *p和int* p的区别

很多人会纠结这一点,其实结论很简单:

 两者完全等价,没有任何本质区别

int *p;
int* p;

都表示:p 是一个指向 int 的指针,编译器处理完全一致

6.1.1 为什么会有两种写法?

因为在 C++ 中:

 * 实际是“修饰变量”,不是类型的一部分

看下面代码:

int* p1, p2;

实际含义是:

  • p1 是指针
  • p2 是普通 int

这也是很多初学者踩坑的地方

6.1.2 推荐写法

int *p1, *p2;

或者:

int* p1;
int* p2;

 保持风格统一最重要

6.2 指针 vs 引用(核心对比)

特性指针引用
本质存地址的变量变量别名
是否可为空
是否可改指向
访问方式*p直接使用
安全性较低更安全

其中:

  • 指针更灵活,但更容易出错
  • 引用更安全,但限制更多

6.3 函数传参对比(高频考点)

指针传参

void func(int* p) {
    *p = 100;
}
func(&a);

引用传参

void func(int& r) {
    r = 100;
}
func(a);

6.4 相关扩展知识

6.4.1 解引用运算符*

*p

通过地址来访问变量

6.4.2 常量指针

const int* p;   // 不能修改指向的值,可以修改指针本身!
int* const p;   // 不能修改指针本身

6.4.3 右值引用(C++11 核心特性)

 6.4.3.1 什么是右值引用?
int&& r = 10;

&& 表示 右值引用(rvalue reference)

 6.4.3.2 左值引用 vs 右值引用
int a = 10;
int b = a;   // a 是左值
int c = 10;  // 10 是右值

核心区别:

类型特点
左值(lvalue)有名字、可取地址
右值(rvalue)临时值、不能取地址
 6.4.3.3 为什么需要右值引用?

 为了解决一个核心问题:避免不必要的拷贝,提高性能

看一个例子:

std::string s1 = "hello";
std::string s2 = s1;  // 拷贝(慢)

如果是临时对象(右值),它本身马上就要被销毁,如果还像普通变量一样进行拷贝,就会产生一次不必要的内存复制(比如 std::stringvector 这种内部带堆内存的数据结构),既浪费时间又浪费空间;而引入右值引用(&&)后,程序可以直接“接管”这个临时对象内部已经分配好的资源(如指针指向的内存),而不是重新申请和复制,这就是“移动语义”。右值引用的本质作用就是:针对临时对象,避免不必要的拷贝,通过资源转移来提升性能,同时保持代码安全(由对象自动管理资源)

6.4.4 智能指针(现代 C++ 必备)

6.4.4.1 为什么需要智能指针?

传统指针的问题:

int* p = new int(10);
// 忘记 delete → 内存泄漏

 常见问题:

  • 内存泄漏
  • 重复释放
  • 悬空指针

6.4.4.2 智能指针的本质

 用对象管理指针(RAII思想)

#include <memory>

把原本需要手动 new/delete 的指针资源,交给一个对象来负责生命周期,这个对象在构造时获取资源,在析构时自动释放资源,从而避免内存泄漏和忘记释放的问题。

6.4.4.3 三种常用智能指针

std::unique_ptr<int> p = std::make_unique<int>(10); // 独占所有权
std::shared_ptr<int> p1 = std::make_shared<int>(10); // 共享所有权
std::shared_ptr<int> p2 = p1;
std::weak_ptr<int> wp = p1;                          //解决循环引用

到此这篇关于C++指针、引用与取地址运算符对比分析的文章就介绍到这了,更多相关C++指针、引用与地址运算符内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言职工信息管理系统源码

    C语言职工信息管理系统源码

    这篇文章主要为大家详细介绍了C语言职工信息管理系统源码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • vscode中配置LeetCode插件的教程(愉快刷题)

    vscode中配置LeetCode插件的教程(愉快刷题)

    这篇文章主要介绍了vscode中配置LeetCode插件的教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2020-03-03
  • C++中按引用传递参数的好处有哪些

    C++中按引用传递参数的好处有哪些

    这篇文章主要介绍了C++中按引用传递参数的好处有哪些,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • C++将txt文件内容保存到数组的方法

    C++将txt文件内容保存到数组的方法

    今天小编就为大家分享一篇C++将txt文件内容保存到数组的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • C++读写word文档(.docx)DuckX库的使用详解

    C++读写word文档(.docx)DuckX库的使用详解

    DuckX是C++库,用于创建/编辑.docx文件,支持读取文档、添加段落/片段、编辑表格,解决中文乱码需更改编码方案,进阶功能含文本替换(支持表格)和文档合并(仅限文本)
    2025-09-09
  • 详解Linux的SOCKET编程

    详解Linux的SOCKET编程

    这篇文章主要介绍了Linux的SOCKET编程,并且进行了实例讲解,需要的朋友可以参考下
    2015-08-08
  • C++学习之Lambda表达式的用法详解

    C++学习之Lambda表达式的用法详解

    Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名。本文就来为大家详细讲讲C++中Lambda表达式的使用,需要的可以参考一下
    2022-07-07
  • C++实现两个有序数组的合并

    C++实现两个有序数组的合并

    这篇文章主要为大家详细介绍了C++实现两个有序数组的合并,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • 详解C++函数类型与重载函数

    详解C++函数类型与重载函数

    这篇文章主要为大家介绍了C++函数类型与重载函数,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-11-11
  • C++同步线程实现示例详解

    C++同步线程实现示例详解

    这篇文章主要介绍了C++同步线程实现示例,线程同步是指同一进程中的多个线程互相协调工做从而达到一致性。之因此须要线程同步,是由于多个线程同时对一个数据对象进行修改操做时,可能会对数据形成破坏
    2022-11-11

最新评论