C++引用指针大对比

news/2024/12/22 2:54:59/

文章目录

      • 相似之处
      • 不同之处
        • **语法上的区别**
        • **是否允许重新绑定**
        • **空值(Null)状态**
        • **内存地址**
        • **初始化要求**
        • **与数组的关系**
      • 总结
      • 何时使用引用 vs 指针

相似之处

间接访问对象引用指针都可以通过它们来间接访问和操作某个对象的值,而不是直接使用该对象的名字。

作为函数参数传递:两者都可以作为函数参数,允许函数操作调用者传递的对象,而不是对象的副本。

  • 引用示例:

    void modify(int& ref) {ref = 20; // 直接修改传入的参数
    }
    
  • 指针示例:

    void modify(int* ptr) {*ptr = 20; // 通过解引用修改传入的参数
    }
    

不同之处

语法上的区别
  • 引用

    • 语法上类似变量的别名,一旦定义,必须绑定到一个对象,且无法重新绑定。
    • 使用时不需要显式解引用,访问时与直接使用变量一样。
    int x = 10;
    int& ref = x; // ref 是 x 的引用
    ref = 20;     // 相当于修改 x,x 现在是 20
    
  • 指针

    • 是一种变量,存储的是另一个对象的地址。
    • 使用时需要通过解引用运算符*来访问指向的对象。
    • 可以指向nullptr或指向不同的对象,可以动态改变指向。
    int x = 10;
    int* ptr = &x; // ptr 存储 x 的地址
    *ptr = 20;     // 通过解引用修改 x,x 现在是 20
    
是否允许重新绑定
  • 引用:一旦绑定到一个对象,就不能再指向别的对象,即引用不能“重定向”。

    int a = 10;
    int b = 20;
    int& ref = a;  // ref 绑定到 a
    ref = b;       // 修改 a 的值为 20,ref 仍然引用 a,而不是重新绑定到 b
    
  • 指针指针可以在运行时指向不同的对象,具有更大的灵活性。

    int a = 10;
    int b = 20;
    int* ptr = &a; // ptr 指向 a
    ptr = &b;      // ptr 现在指向 b,可以修改它指向的对象
    
空值(Null)状态
  • 引用引用必须绑定到一个有效的对象,不能为null。因此,引用总是指向某个有效的对象,使用起来比较安全。

  • 指针指针可以指向nullptr,也可以指向一个未初始化的或无效的内存地址(悬空指针),这可能会导致运行时错误。

    int* ptr = nullptr; // 指针可以为空
    
内存地址
  • 引用引用本身并不占用额外的内存,它只是被引用对象的别名,没有独立的地址。

  • 指针指针是一个变量,存储的是对象的内存地址,它本身占用一定的内存空间,并且可以通过取地址符&获取指针本身的地址。

    int x = 10;
    int* ptr = &x;
    std::cout << &ptr;  // 输出指针变量 ptr 自己的地址
    
初始化要求
  • 引用引用在声明时必须初始化,且绑定后无法更改。

    int x = 10;
    int& ref = x;  // 引用必须初始化
    
  • 指针指针声明时可以不初始化,也可以在后面动态分配内存或改变指向的对象。

    int* ptr;      // 可以声明但不初始化
    ptr = new int(10); // 动态分配内存
    
与数组的关系
  • 引用引用不能指向数组的元素之间,它只能引用整个数组或数组中的某个元素。

  • 指针指针可以指向数组,并通过指针的偏移操作访问数组中的各个元素。

    int arr[] = {1, 2, 3};int* ptr = arr;     // ptr 指向数组首元素
    std::cout << *(ptr + 1);  // 访问第二个元素,输出 2
    

总结

特性引用指针
是否需要初始化必须在声明时初始化可以声明后再初始化
是否能为空不能可以为空 (nullptr)
是否可重新绑定不能,绑定后不能更改可以重新指向不同的对象
访问方式直接使用需要使用*引用
是否可指向不同对象
内存占用不占用额外内存占用内存,存储对象地址
能否指向数组不能用于遍历数组可以用于数组遍历

何时使用引用 vs 指针

  • 使用引用:当你希望变量始终引用某个对象,且不希望修改它所引用的对象时。通常用于函数参数传递,链式调用,返回值等,使用方便且安全。
  • 使用指针:当你需要指向不同的对象,或者需要动态管理内存时。指针灵活,但需要更加小心处理内存管理,防止出现悬空指针或内存泄漏等问题。

http://www.ppmy.cn/news/1534559.html

相关文章

rabbitMq------连接管理模块

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言管理的字段连接内存管理对象 前言 我们的网络通信框架使用的muduo库&#xff0c;而在mudu库中是已经有了连接的概念&#xff0c;但是我们呢还有一个信道的概念…

02:(寄存器开发)流水灯/按键控制LED

寄存器开发 1、LED流水灯2、按键控制LED 1、LED流水灯 通过第一章的学习&#xff0c;我们已然知晓了LED的点亮和熄灭的方式&#xff0c;下面学习流水灯的制作流程。 流水灯呈现的样子&#xff1a;就是第一个LED灯点亮&#xff0c;延迟一段时间&#xff0c;第一个LED灯熄灭第二…

UE4_Niagara基础实例—5、骨架网格体表面生成粒子及过滤骨骼位置生成粒子

效果图&#xff1a; 步骤&#xff1a; 1、学习了静态网格体位置生成粒子之后这个就比较简单了&#xff0c;把粒子生成位置更改为SkeletalMeshLocation。 2、小白人的骨骼网格体为&#xff1a; 你会发现骨骼的每一个节点处都有粒子产生。 3、我们还可以修改骨骼采样类型 4、我们…

React表单:formik、final-form和react-hook-form

表单无处不在&#xff0c;它是每个网站的必备部分。在用React构建web应用时&#xff0c;处理表单是不可避免的。 你可以选择自己的方式来处理&#xff0c;或者选择社区中现成的库。然而&#xff0c;当你选择一个第三方库时&#xff0c;你会立即面临一个问题&#xff1a;有太多的…

2.4 Spring系列教程4-Spring的数据库编程

数据库用于处理持久化业务产生的数据&#xff0c;应用程序在运行过程中经常要操作数据库。一般情况下&#xff0c;数据库的操作由持久层来实现。作为扩展性较强的一站式开发框架&#xff0c;Spring也提供了持久层Spring JDBC功能&#xff0c;Spring JDBC可以管理数据库连接资源…

黑马程序员pink 教js ,查漏补缺版,耗时4天

JS基础-D1 变量类型 1.js编程语言&#xff0c;html标记语言 2.不用jdk&#xff0c;运行在浏览器 3.交互&#xff0c;用户点击1就数值1 4.服务端编程&#xff0c;nodejs 5.js遵循ecma-script的语法规范 6.js由ecma-s和dom bom组成&#xff0c;或者也可以叫做ecma-s和weba…

新高考的五大变化‌‌(AI生成)

新高考的五大变化‌‌1 考试科目和考试时间的变化 ‌考试科目‌&#xff1a; 改革前&#xff0c;考试科目为‌语文、‌数学&#xff08;文/理&#xff09;、‌外语、‌理科综合/文科综合。 改革后&#xff0c;实行“312”模式&#xff0c;即全国统考科目3门&#…

安全服务面试

118.什么叫脱壳? 而从技术的角度出发&#xff0c;壳是一段执行于原始程序前的代码。原始程序的代码在加 壳的过程中可能被压缩、加密……。当加壳后的文件执行时&#xff0c;壳&#xff0d;这段代码先于 原始程序运行&#xff0c;他把压缩、加密后的代码还原成原始程序代码…