当前位置: 代码网 > it编程>编程语言>C/C++ > C++指针、引用与取地址运算符对比分析

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

2026年04月15日 C/C++ 我要评论
一、引言在学习 c++ 的过程中,初学者很容易会被这几个概念搞混:指针(pointer)引用(reference)取地址运算符(&)尤其是初学者,经常会问:int* p 和 int *p 有区

一、引言

在学习 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++指针、引用与地址运算符内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com