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++中判断成员函数是否重写

    这篇文章主要介绍了C++中判断成员函数是否重写的相关资料,需要的朋友可以参考下
    2017-04-04
  • C语言版简单扫雷游戏

    C语言版简单扫雷游戏

    这篇文章主要为大家详细介绍了C语言版简单扫雷游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • strcat函数与strncat函数的深入分析

    strcat函数与strncat函数的深入分析

    本篇文章是对strcat函数与strncat函数进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • Mac OS X 10.8 中编译APUE(Unix环境高级编程)的源代码过程

    Mac OS X 10.8 中编译APUE(Unix环境高级编程)的源代码过程

    这篇文章主要介绍了Mac OS X 10.8 中编译APUE(Unix环境高级编程)的源代码过程,对于用MAC学习Unix环境高级编程的同学会有些作用,需要的朋友可以参考下
    2014-09-09
  • c++实现简单随机数的代码

    c++实现简单随机数的代码

    在本篇文章里小编给大家整理的是一篇关于c++实现简单随机数的代码内容,有需要的朋友们可以跟着学习下。
    2021-05-05
  • C语言形参和实参传值和传址详解刨析

    C语言形参和实参传值和传址详解刨析

    形参出现在函数定义中,在整个函数体内都可以使用, 离开该函数则不能使用。实参出现在主调函数中,进入被调函数后,实参变量也不能使用,形参和实参的功能是作数据传送。发生函数调用时, 主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送
    2021-11-11
  • C++中抽象类和接口的区别介绍

    C++中抽象类和接口的区别介绍

    抽象类(abstract class)和接口(interface)的概念是面向对象设计中常用的概念, 也是比较容易混淆的概念. 在这里, 我提出一种区分它们的思路
    2013-04-04
  • 最小生成树算法之Prim算法

    最小生成树算法之Prim算法

    这篇文章主要讲解了普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树,需要的朋友可以参考下
    2015-07-07
  • C++ 中引用与指针的区别实例详解

    C++ 中引用与指针的区别实例详解

    这篇文章主要介绍了C++ 中引用与指针的区别实例详解的相关资料,需要的朋友可以参考下
    2017-06-06
  • Qt向ini文件写入中文出现乱码问题的解决方法详解

    Qt向ini文件写入中文出现乱码问题的解决方法详解

    这篇文章主要为大家详细介绍了当Qt向ini文件写入中文出现乱码问题时的解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-12-12

最新评论