引用和指针的区别

embedded/2024/9/25 15:23:05/

        引用(reference)指针(pointer)都是 C++ 中用来间接访问内存中对象的机制,但它们有一些重要的区别。以下是它们在语法、用法和特性上的详细区别。

下面从7个方面来详细说明引用和指针的区别

1. 定义与语法区别

  • 引用(reference) 是某个变量的别名。它在声明时必须被初始化,并且初始化后不能改变引用的目标。
  • 指针(pointer) 是一个变量,它存储另一个变量的内存地址。指针可以在运行时被重新赋值,并且可以为空(nullptr)。
    int a = 10;
    int &ref = a;  // ref 是 a 的引用int a = 10;
    int *ptr = &a;  // ptr 是指向 a 的指针
    

    2. 初始化与重新赋值

  • 引用必须在声明时进行初始化,并且一旦引用了某个变量,就不能再引用其他变量。引用不能指向 nullptr,它必须始终有效。

  • 指针可以在声明时不初始化,并且可以在任何时候指向不同的对象。指针可以是空指针(nullptrNULL),即指向无效的内存。

    int x = 5;
    int &ref = x;  // 引用必须在声明时初始化
    ref = 10;      // 改变的是 x 的值int x = 5;
    int y = 10;
    int *ptr;     // 可以不初始化
    ptr = &x;     // 指向 x 的地址
    ptr = &y;     // 重新指向 y 的地址
    

    3. 访问对象的方式

  • 引用直接使用对象的名字来访问所引用的对象,无需解引用。

  • 指针需要使用解引用运算符 * 来访问指针所指向的对象。

    int x = 5;
    int &ref = x;   // ref 是 x 的引用
    std::cout << ref << std::endl;  // 直接访问 x 的值int x = 5;
    int *ptr = &x;
    std::cout << *ptr << std::endl;  // 通过解引用访问 x 的值
    

    4. 内存地址的访问

  • 引用本身没有自己的内存地址,它只是所引用对象的别名。你不能获取引用本身的地址,只能获取它所引用的对象的地址。

  • 指针有自己的内存地址,并且存储的是它所指向对象的内存地址。你可以获取指针的地址,也可以获取它指向的对象的地址。

int x = 5;
int &ref = x;
std::cout << &ref << std::endl;  // 输出的是 x 的地址int x = 5;
int *ptr = &x;
std::cout << ptr << std::endl;   // 输出的是指针存储的 x 的地址
std::cout << &ptr << std::endl;  // 输出的是指针本身的地址

5. 指向空值或无效值

  • 引用不能指向 nullptr 或者无效的对象。它在声明时就必须引用有效的对象。

  • 指针可以是 nullptr,表示不指向任何对象,或者指向无效的内存地址(虽然指向无效地址是危险的)。

    int &ref = nullptr;  // 错误!引用不能为 nullptr
    int *ptr = nullptr;  // 指针可以为 nullptr
    

6. 修改所指对象的值

  • 引用可以修改所引用对象的值,引用本质上就是对该对象的直接访问。

  • 指针可以通过解引用来修改所指对象的值。

    int x = 5;
    int &ref = x;
    ref = 10;   // x 的值被修改为 10
    int x = 5;
    int *ptr = &x;
    *ptr = 10;  // 通过解引用修改 x 的值为 10
    

    7. 常量引用与指针

  • 常量引用(const reference):常量引用允许引用一个对象,但不允许修改它的值。常用于函数参数中,避免拷贝对象,但又能确保函数不会修改对象。

  • 常量指针与指向常量的指针

  • 指向常量的指针:指针可以指向一个常量对象,不能通过指针修改对象的值。

  • 常量指针:指针本身是常量,不能改变指针指向的地址,但可以修改指向对象的值。

  • int x = 5;
    const int &ref = x;
    // ref = 10;  // 错误,不能通过 const 引用修改值
    const int x = 5;
    const int *ptr = &x;
    // *ptr = 10;  // 错误,不能通过指向常量的指针修改值
    int x = 5;
    int *const ptr = &x;
    *ptr = 10;  // 可以修改 x 的值
    // ptr = &y;  // 错误,不能修改 ptr 指向的地址
    

 

 


http://www.ppmy.cn/embedded/116684.html

相关文章

十三、SOA(企业服务总线ESB架构实现)

**企业服务总线&#xff08;Enterprise Service Bus&#xff0c;ESB&#xff09;**是SOA架构中的核心组成部分&#xff0c;主要用于促进企业内部异构系统和应用程序之间的集成与通信。ESB提供了一个统一的服务集成平台&#xff0c;通过使用消息路由、协议转换、服务编排等功能&…

js判断一个对象里有没有某个属性

1. 使用in操作符 in操作符可以用来检测属性是否存在于对象或其原型链中。 const obj {a: 1, b: 2}; if (a in obj) { console.log(属性a存在于obj中); } else { console.log(属性a不存在于obj中); } 2. 使用hasOwnProperty()方法 hasOwnProperty()方法用来检测一个…

Android String资源文件中,空格、换行以及特殊字符如何表示

空格&#xff1a; 例&#xff1a;<string name"test">test test</string> 换行&#xff1a;\n 例&#xff1a;<string name"test">test \n test</string> tab&#xff1a;\t …

[redis命令]列表命令

列表操作 命令含义LSET通过索引设置列表元素的值LPUSH将一个或多个值插入到列表头部LPUSHX将一个值插入到已存在的列表头部RPUSH在列表中添加一个或多个值LPOP移出并获取列表的第一个元素RPOP移除并获取列表最后一个元素BLPOP移出并获取列表的第一个元素BRPOP移出并获取列表的…

CSS中的多种关系选择器

后代选择器 选择所有被E元素包含的F元素&#xff0c;中间用空格隔开。 例&#xff1b; <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title…

【Python】Windows下安装使用FFmpeg

FFmpeg是一套可以用来记录、转换数字音频、视频&#xff0c;并能将其转化为流的开源计算机程序。之前为了MP3转wav&#xff0c;需要pip安装并import AudioSegment&#xff0c;但是会报错&#xff1a;FileNotFoundError: [WinError 2] 系统找不到指定的文件。 因为FFmpeg需要另…

运维加分技能,完整学习手册值得收藏

在运维领域掌握一项编程技能是打怪升级、升职加薪的重要条件&#xff0c;而python往往会成为我们选择的热门技能。在实际工作中&#xff0c;我们经常会使用PythonDjango的框架来实现一些Restful接口服务&#xff0c;或者用其来编写运维平台等&#xff0c;这时Django将变得极为重…

qt--压缩图片的大小

该函数 是输入图片的字节流 然后再内部转换后输出文件的字节流 头文件部分 /*!* brief compressImage* param format 图片的压缩格式* param imageByteArray 源图像字节流* param fileSize 压缩指定的文件大小 默认180kb* param limitHeight 限制图片的高度* return QBy…