C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++指针、引用与地址运算符

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

作者:Binary-Jeff

文章解释了C++中指针、引用和取地址运算符(&)的概念,并分析了它们的区别,文章还讨论了函数传参、右值引用以及智能指针等,感兴趣的朋友跟随小编一起看看吧

一、引言

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

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

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

二、一句话快速理解

三、指针(Pointer)

1️⃣ 基本定义

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

含义:

2️⃣ 指针的特点

 可以修改指向

int b = 20;
p = &b;

 可以为空

int* p = nullptr;

 需要解引用访问

cout << *p;

四、引用(Reference)

1️⃣ 基本定义

int a = 10;
int& 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;

实际含义是:

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

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

您可能感兴趣的文章:
阅读全文