C++ 引用和指针的区别对比分析

 更新时间:2025年10月08日 10:05:33   作者:木杉的园子  
在C++ 中,指针(Pointer)和引用(Reference)都用于间接访问变量,但是它们在语法和语义上都有显著的差异,下面通过本文给大家介绍C++ 引用和指针的区别,感兴趣的朋友一起看看吧

在 C++ 中,指针(Pointer)和引用(Reference)都用于间接访问变量,但是它们在语法和语义上都有显著的差异。指针是一个变量,它可以保存另一个变量的内存地址;引用是另一个变量的别名,由编译器进行处理,使用时与使用原变量无异。

指针和引用使用的一些差异如下:

初始化

指针:可以先定义后赋值,也可以指向不同的对象。

int a = 10, b = 20;
int* p = &a;
p = &b; // 改变指向

引用:必须在定义时就进行初始化,绑定到一个特定的对象,并且不能绑定到其他的对象。

int a = 10, b = 20;
int& r = a;  
r = b; // 修改的是 a 的值,而不是重新绑定,等价于 a=b

可空性

指针:可以被定义为 nullptr,表示不指向任何对象。

引用:必须绑定有效对象,不能为 null,否则会产生为定义的行为。

内存占用

指针:由于存储的是内存地址,因此需要占用内存空间,一般为 32 bit 或 64 bit。

引用:语义上不占用内存空间,实际可能由编译器实现为一个隐藏指针。

这里我们参考一篇博客: C++ 中指针和引用的区别

参考以下使用引用和指针实现的 swap 函数。

void swap(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

引用版本 swap() 函数的汇编代码如下:

# void swap(int &a, int &b)
__Z4swapRiS_:                           ## @_Z4swapRiS_
        .cfi_startproc
## %bb.0:
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset %rbp, -16
        movq    %rsp, %rbp          
        .cfi_def_cfa_register %rbp
        movq    %rdi, -8(%rbp)         # 传入的第一个参数存放到%rbp-8  (应该是采用的寄存器传参,而不是常见的压栈)
        movq    %rsi, -16(%rbp)        # 第二个参数 存放到 %rbp-16
        movq    -8(%rbp), %rsi         # 第一个参数赋给 rsi
        movl    (%rsi), %eax           # 以第一个参数为地址取出值赋给eax,取出*a暂存寄存器
        movl    %eax, -20(%rbp)        # temp = a
        movq    -16(%rbp), %rsi        # 将第二个参数重复上面的
        movl    (%rsi), %eax
        movq    -8(%rbp), %rsi    
        movl    %eax, (%rsi)           # a = b
        movl    -20(%rbp), %eax        # eax = temp
        movq    -16(%rbp), %rsi
        movl    %eax, (%rsi)           # b = temp
        popq    %rbp
        retq
        .cfi_endproc
                                        ## -- End function

指针版本 swap() 函数的汇编代码如下:

# void swap(int *a, int *b)
__Z4swapPiS_:                           ## @_Z4swapPiS_
        .cfi_startproc
## %bb.0:
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset %rbp, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register %rbp
        movq    %rdi, -8(%rbp)
        movq    %rsi, -16(%rbp)
        movq    -8(%rbp), %rsi
        movl    (%rsi), %eax
        movl    %eax, -20(%rbp)
        movq    -16(%rbp), %rsi
        movl    (%rsi), %eax
        movq    -8(%rbp), %rsi
        movl    %eax, (%rsi)
        movl    -20(%rbp), %eax
        movq    -16(%rbp), %rsi
        movl    %eax, (%rsi)
        popq    %rbp
        retq
        .cfi_endproc
                                        ## -- End function

可以看到,两个函数的汇编代码几乎完全一致。引用所赋的初值也就是绑定对象的内存地址,访问和修改对象内容也是通过这个内存地址完成的。

既然引用和指针的底层实现机制几乎没有区别,那么为什么我们需要使用引用呢?我认为有以下两点:

  • 便捷性:能够让使用者使用引用与使用对象本身一致,由编译器自动进行取地址、解引用的操作。
  • 安全性:引用必须初始化,且不能更换绑定,避免了悬空指针和野指针的问题,这在接口设计中更可靠,要求必须传入合法的对象。

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

相关文章

  • C++之多态(内容不错)

    C++之多态(内容不错)

    什么是多态?顾名思义就是同一个事物在不同场景下的多种形态,需要的朋友可以参考下
    2020-01-01
  • C++实用库之DNS解析的实现

    C++实用库之DNS解析的实现

    DNS解析是一种将域名转换为相应的IP地址的过程,本文主要介绍了C++实用库之DNS解析的实现,实现了快速、准确的域名到IP地址的转换,感兴趣的可以了解一下
    2025-03-03
  • C++中虚继承时的构造函数示例详解

    C++中虚继承时的构造函数示例详解

    在虚继承中,虚基类是由最终的派生类初始化的,换句话说,最终派生类的构造函数必须要调用虚基类的构造函数,这跟普通继承不同,在普通继承中,派生类构造函数中只能调用直接基类的构造函数,不能调用间接基类的,所以本文将通过代码示例给大家介绍一下C++虚继承构造函数
    2023-09-09
  • C语言之把数组名作函数参数的四种情况说明

    C语言之把数组名作函数参数的四种情况说明

    这篇文章主要介绍了C语言之把数组名作函数参数的四种情况说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • C语言实现直角坐标转换为极坐标的方法

    C语言实现直角坐标转换为极坐标的方法

    这篇文章主要介绍了C语言实现直角坐标转换为极坐标的方法,涉及C语言进行三角函数与数值运算相关操作技巧,需要的朋友可以参考下
    2017-09-09
  • C++中std::sort函数介绍和使用场景

    C++中std::sort函数介绍和使用场景

    std::sort函数是C++标准库中常用的排序函数之一,它可以对各种类型的序列进行排序,本文就来介绍一下C++中std::sort函数介绍和使用场景,感兴趣的可以了解一下
    2024-02-02
  • 基于排列与组合输出多少中情况详解

    基于排列与组合输出多少中情况详解

    本篇文章对排列与组合输出多少中情况进行了介绍。需要的朋友参考下
    2013-05-05
  • NDK 数据结构之队列与栈等的实现

    NDK 数据结构之队列与栈等的实现

    这篇文章主要介绍了NDK 数据结构之队列与栈等的实现的相关资料,希望通过本文大家能理解掌握这部分内容,需要的朋友可以参考下
    2017-10-10
  • 利用Matlab制作抖音同款含褶皱面料图

    利用Matlab制作抖音同款含褶皱面料图

    这篇文章主要介绍了如何利用Matlab制作抖音的同款含褶皱面料图,文中的示例代码讲解详细,对我们学习Matlab有一定帮助,需要的可以参考一下
    2022-03-03
  • 纯C语言实现火车售票系统

    纯C语言实现火车售票系统

    这篇文章主要为大家详细介绍了纯C语言实现火车售票系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12

最新评论