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++ Opengl图形颜色功能附源码下载

    C++ Opengl图形颜色功能附源码下载

    这篇文章主要介绍了C++ Opengl图形颜色功能附源码下载,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • C++实现LeetCode(15.三数之和)

    C++实现LeetCode(15.三数之和)

    这篇文章主要介绍了C++实现LeetCode(三数之和),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C语言中调用Python脚本的方法详解

    C语言中调用Python脚本的方法详解

    在C语言中调用 Python 脚本的方式有很多,这篇文章主要为大家介绍了人家使用 Python 的 C API 进行调用 Python 脚本,需要的可以参考一下
    2025-05-05
  • C语言中sscanf()函数的字符串格式化用法

    C语言中sscanf()函数的字符串格式化用法

    这篇文章介绍的是C语言中sscanf()函数,本文介绍了sscanf()函数的含义与用法,对大家日常使用C语言的sscanf()函数很有帮助,有需要的可以参考借鉴。
    2016-08-08
  • 详解c++11以正确的姿势输出enum class的值

    详解c++11以正确的姿势输出enum class的值

    这篇文章主要介绍了详解c++11以正确的姿势输出enum class的值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • LZ77压缩算法原理的理解

    LZ77压缩算法原理的理解

    这篇文章主要介绍了LZ77压缩算法原理的理解的相关资料,数据压缩是一个减小数据存储空间的过程,目前被应用在软件工程的各个地方,了解其一些原理,方便我们更好的甄选压缩方案,需要的朋友可以参考下
    2017-08-08
  • C++超详细讲解引用和指针

    C++超详细讲解引用和指针

    引用是C++一个很重要的特性,顾名思义是某一个变量或对象的别名,对引用的操作与对其所绑定的变量或对象的操作完全等价,这篇文章主要给大家总结介绍了C++中引用的相关知识点,需要的朋友可以参考下
    2022-06-06
  • 用c语言编写一个通讯录代码详解

    用c语言编写一个通讯录代码详解

    大家好,本篇文章主要讲的是用c语言实现一个通讯录代码详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • C/C++使用socket实现判断ip是否能连通

    C/C++使用socket实现判断ip是否能连通

    这篇文章主要为大家详细介绍了C/C++如何使用socket实现判断ip是否能连通,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解一下
    2023-07-07
  • 十个C++恶搞朋友的代码合集

    十个C++恶搞朋友的代码合集

    这篇文章主要为大家整理了十个C++中可以恶搞朋友的代码合集(注意!从第五个开始为危险/永久性程序,请慎重使用),感兴趣的小伙伴可以收藏一下
    2023-02-02

最新评论