【C++漂流记】简易理解引用的基本语法和使用及其注意实现

news2024/10/2 12:16:46

引用是C++中的一种数据类型,它允许我们使用一个已经存在的变量来创建一个新的名称或别名,以便可以通过这个别名来访问和修改原始变量的值。引用的本质是一个别名或者一个变量的别名。
在这里插入图片描述

文章目录

    • 基本语法
    • 引用的注意事项
    • 引用做函数参数
    • 引用的本质
    • 常量引用


基本语法

C++中的引用是一个别名,它允许我们使用一个已经存在的变量来创建一个新的引用变量。引用在声明时必须初始化,并且一旦初始化后,就不能再引用其他变量。

引用的基本语法如下:

type &ref = variable;

其中,type是引用的类型,ref是引用变量的名称,variable是已经存在的变量。

示例代码:

#include <iostream>

int main() {
    int num = 10;
    int &ref = num;  // 创建一个整型引用ref,引用变量num

    std::cout << "num: " << num << std::endl;  // 输出:num: 10
    std::cout << "ref: " << ref << std::endl;  // 输出:ref: 10

    ref = 20;  // 修改引用变量ref的值,也会修改num的值

    std::cout << "num: " << num << std::endl;  // 输出:num: 20
    std::cout << "ref: " << ref << std::endl;  // 输出:ref: 20

    return 0;
}

在上述示例中,我们创建了一个整型变量num,并使用引用ref来引用它。当我们修改引用变量ref的值时,也会修改num的值。因此,最后输出的num和ref的值都是20。

需要注意的是,引用只是一个别名,它并不占用额外的内存空间,只是指向了已经存在的变量。引用在函数传递参数、函数返回值、避免拷贝大对象等场景中非常有用。


引用的注意事项

  1. 引用必须在声明时进行初始化:引用在声明时必须初始化,并且一旦初始化后,就不能再引用其他变量。例如,int &ref; 是错误的,必须写成 int &ref = num;

  2. 引用不能引用临时变量:引用不能引用临时变量,即不能将引用绑定到一个临时对象上。例如,int &ref = 5; 是错误的。

  3. 引用不能改变绑定的变量:一旦引用绑定了某个变量,就不能再改变绑定的变量。例如,int num1 = 10; int num2 = 20; int &ref = num1; ref = num2; 这段代码不是将num1的值改为num2的值,而是将num1的值改为20。

  4. 引用作为函数参数时的注意事项:当引用作为函数参数传递时,函数内部对引用的修改会影响到原始变量。这可以用来实现函数的返回多个值或者修改传入的参数的效果。但需要注意,如果函数参数是引用类型,传入的参数必须是一个可修改的左值,而不能是一个常量或者临时变量。

  5. 引用作为函数返回值时的注意事项:引用可以作为函数的返回值,但需要注意返回的引用不能指向局部变量,因为局部变量在函数返回后会被销毁。如果返回一个引用,应该确保返回的是一个静态变量、全局变量、或者是通过new运算符在堆上分配的内存。


引用做函数参数

  1. 通过引用参数返回多个值:当函数需要返回多个值时,可以使用引用参数。通过引用参数,函数可以将计算结果直接存储到传入的参数中,而不需要使用函数返回值。这样可以避免创建临时变量或者使用指针来传递结果。

例如,下面的函数通过引用参数返回两个整数的和与差:

void calculateSumAndDifference(int a, int b, int& sum, int& difference) {
    sum = a + b;
    difference = a - b;
}

int main() {
    int num1 = 10;
    int num2 = 5;
    int sum, difference;

    calculateSumAndDifference(num1, num2, sum, difference);

    std::cout << "Sum: " << sum << std::endl;  // 输出:Sum: 15
    std::cout << "Difference: " << difference << std::endl;  // 输出:Difference: 5

    return 0;
}
  1. 通过引用参数修改传入的变量:通过引用参数,函数可以修改传入的变量的值。这样可以避免使用指针来传递变量的地址,并且可以直接在函数内部修改传入的变量。

例如,下面的函数通过引用参数将传入的整数变量加倍:

void doubleNumber(int& num) {
    num *= 2;
}

int main() {
    int num = 10;

    doubleNumber(num);

    std::cout << "Doubled number: " << num << std::endl;  // 输出:Doubled number: 20

    return 0;
}

需要注意的是,当引用作为函数参数时,传入的参数必须是一个可修改的左值,而不能是一个常量或者临时变量。因为引用需要绑定到一个已经存在的变量上。如果传入的参数是常量或者临时变量,可以使用const引用参数来接收,以避免对其进行修改。

void printValue(const int& num) {
    std::cout << "Value: " << num << std::endl;
}

int main() {
    int num = 10;

    printValue(num);  // 输出:Value: 10
    printValue(20);  // 输出:Value: 20

    return 0;
}

在上述示例中,printValue函数接收一个const引用参数,即使传入的参数是常量或者临时变量,也可以通过const引用来访问其值,但不能修改其值。


引用的本质

引用的本质是一个别名或者一个变量的别名。引用是C++中的一种数据类型,它允许我们使用一个已经存在的变量来创建一个新的名称或别名,以便可以通过这个别名来访问和修改原始变量的值。

在内部实现上,引用通常是通过指针来实现的,但是在使用引用时,我们无需关注指针的细节,可以像使用原始变量一样使用引用。编译器会自动处理引用的底层指针操作。

引用的本质可以通过以下几个特点来理解:

  1. 引用必须在声明时进行初始化,并且一旦初始化后,就不能再改变其绑定的变量。这意味着引用始终指向同一个变量,不能重新绑定到其他变量。

  2. 引用与其绑定的变量共享同一块内存空间,它们指向同一个地址。因此,通过引用可以直接访问和修改绑定的变量的值。

  3. 引用在使用时可以像普通变量一样进行操作,包括赋值、传递给函数、作为函数的返回值等。

  4. 引用可以作为函数参数传递,可以用于实现函数的返回多个值或者修改传入的参数的效果。


常量引用

常量引用是指通过引用来绑定到一个常量对象上的引用。常量引用在声明时使用关键字const来修饰引用类型,表示引用的对象是一个常量,不能被修改。

常量引用的主要特点是:

  1. 常量引用可以绑定到常量对象或者非常量对象上,但是不能通过常量引用来修改被引用的对象的值。

  2. 常量引用可以用于函数参数,以避免在函数中对传入的参数进行修改。

  3. 常量引用可以接收常量对象、非常量对象和临时对象。

下面是一些常量引用的示例:

void printValue(const int& num) {
    std::cout << "Value: " << num << std::endl;
}

int main() {
    int num1 = 10;
    const int num2 = 20;

    printValue(num1);  // 输出:Value: 10
    printValue(num2);  // 输出:Value: 20
    printValue(30);    // 输出:Value: 30

    return 0;
}

在上述示例中,printValue函数接收一个常量引用参数,可以接收常量对象、非常量对象和临时对象。由于参数是常量引用,函数内部不能修改传入的参数的值。

常量引用在函数参数中的使用可以避免对传入的参数进行修改,同时还可以提高程序的性能,因为常量引用不需要创建临时副本。此外,常量引用还可以用于避免不必要的拷贝操作,提高程序的效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/983299.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

04 卷积神经网络搭建

一、数据集 MNIST数据集是从NIST的两个手写数字数据集&#xff1a;Special Database 3 和Special Database 1中分别取出部分图像&#xff0c;并经过一些图像处理后得到的[参考]。 MNIST数据集共有70000张图像&#xff0c;其中训练集60000张&#xff0c;测试集10000张。所有图…

vue表格不显示列号123456

我在网上找了半天&#xff0c;都是如何添加列号123456的&#xff0c;没有找到不显示列号的参考&#xff0c;现在把这个解决了&#xff0c;特此记录一下。 没有加右边的就会显示&#xff0c;加上右边的就隐藏了

python+django协同过滤算法的音乐推荐系统研究vue

本系统提供给管理员对用户、音乐分类、歌手、热门歌曲等诸多功能进行管理。本系统对于用户输入的任何信息都进行了一定的验证&#xff0c;为管理员操作提高了效率&#xff0c;也使其数据安全性得到了保障。本音乐推荐研究以Django作为框架&#xff0c;B/S模式以及MySql作为后台…

QtCreator CMakeLists.txt添加模块(Modules)

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Sql) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Sql) target_link_libraries(HookeViscometer PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Sql) 蓝色部分为添加的Q…

13分钟聊聊并发包中常用同步组件并手写一个自定义同步组件

本篇文章通过AQS自己来实现一个同步组件&#xff0c;并从源码级别聊聊JUC并发包中的常用同步组件 本篇文章需要的前置知识就是AQS&#xff0c;阅读本篇文章大概需要13分钟 自定义同步组件 为了更容易理解其他同步组件&#xff0c;我们先来使用AQS自己来实现一个常用的可重入…

(数字图像处理MATLAB+Python)第十二章图像编码-第三、四节:有损编码和JPEG

文章目录 一&#xff1a;有损编码&#xff08;1&#xff09;预测编码A&#xff1a;概述B&#xff1a;DM编码C&#xff1a;最优预测器 &#xff08;2&#xff09;变换编码A&#xff1a;概述B&#xff1a;实现变换编码的主要问题 二&#xff1a;JPEG 一&#xff1a;有损编码 &am…

Kafka3.0.0版本——消费者(消费者总体工作流程图解)

一、消费者总体工作流程图解 角色划分&#xff1a;生产者、zookeeper、kafka集群、消费者、消费者组。如下图所示: 生产者发送消息给leader&#xff0c;followerr主动从leader同步数据&#xff0c;一个消费者可以消费某一个分区数据或者一个消费者可以消费多个分区数据。如下图…

9月6日上课内容 redis高可用

RDB 持久化 RDB持久化是指在指定的时间间隔内将内存中当前进程中的数据生成快照保存到硬盘(因此也称作快照持久化)&#xff0c;用二进制压缩存储&#xff0c;保存的文件后缀是rdb&#xff1b;当Redis重新启动时&#xff0c;可以读取快照文件恢复数据。 1. 触发条件 RDB持久化…

解锁前端Vue3宝藏级资料 Vue3全面解析 第二章 Vue3 基础语法指令

本章主要介绍vue3中的基础指令使用方式和一些开发技巧。分为基础指令&#xff0c;逻辑指令&#xff0c;列表指令&#xff0c;事件&#xff0c;MVVM数据绑定与监听。本章中所有代码例子都是在使用Vite 创建的 vue项目中来完成的。 基础语法指令 2.1 基础指令2.1.1 设置变量2.1.2…

记一次生产环境服务卡死排查记录

接现场运维报告某java服务CPU狂飙&#xff0c;服务处于卡死无响应状态 询问现场运维什么场景造成的&#xff0c;答复是偶发现象&#xff0c;没有规律&#xff0c;和请求高峰期并没有关系。 因为服务是负载均衡的&#xff08;A、B两台&#xff09;&#xff0c;临时处理让运维重…

【AIGC系列】Stable Diffusion 小白快速入门课程大纲

一、前言 本文是《Stable Diffusion 从入门到企业级应用实战》系列课程的前置学习引导部分&#xff0c;《Stable Diffusion新手完整学习地图课程》的课程大纲。该课程主要的培训对象是&#xff1a; 没有人工智能背景,想快速上手Stable Diffusion的初学者&#xff1b;想掌握St…

这些国外客户真直接

最近在某平台上遇到的客户&#xff0c;很大一部分都是非英语国家的客户&#xff0c;然而他们也有很多共性的习惯。 第一种&#xff1a;直接表达自己对这个产品感兴趣&#xff0c;然后接下来就没有下文了&#xff0c;而之所以可以看得懂&#xff0c;则是借助平台本身的翻译系统&…

三维数字沙盘电子沙盘虚拟现实模拟推演大数据人工智能开发教程第15课

三维数字沙盘电子沙盘虚拟现实模拟推演大数据人工智能开发教程第15课 现在不管什么GIS平台首先要解决的就是数据来源问题&#xff0c;因为没有数据的GIS就是一个空壳&#xff0c;下面我就目前一些主流的数据获取 方式了解做如下之我见&#xff08;主要针对互联网上的一些卫星…

解锁前端Vue3宝藏级资料 第三章 Vue Router路由器的使用

Vue Router 是 Vue.js 的官方路由器。通过使用 Vue Router&#xff0c;你可以构建一个包含多个页面的应用程序。它可以样多个页面之间流畅地跳转&#xff0c;而无需每次移动到另一个页面时都要重新加载整个页面。Vue Router 路由是使用 Vue.js 构建单页应用项目的必备库。官网地…

IMAU鸿蒙北向开发-2023年9月6日学习日志

1. TextArea 基本使用 //TextArea 基本使用 Entry Component struct Index {State message: string Hello Worldbuild() {Column() {TextArea({placeholder: "请输入个人介绍",text: "个人介绍控制在200字以内。"}).margin({top: 100}).caretColor(Color…

【正版软件】Air Explorer - 一个程序访问您的所有云服务

前言&#xff1a;Air Explorer支持最好的云服务。 功能特点&#xff1a; 直接管理云中的文件 设置同一服务上的多个帐户 您可以在任何云服务或计算机之间同步文件夹 云文件浏览器易于使用 通过加入您的所有云服务来增加存储空间 应用程序适用于Windows/Mac Air Explorer…

Druid LogFilter输出可执行的SQL

配置 测试代码&#xff1a; DruidDataSource dataSource new DruidDataSource(); dataSource.setUrl("xxx"); dataSource.setUsername("xxx"); dataSource.setPassword("xxx"); dataSource.setFilters("slf4j"); dataSource.setVal…

2023年大数据平台数据安全厂商汇总

大数据时代&#xff0c;大数据平台数据安全至关重要&#xff0c;这关系着大家的切身安全。所以企业一定要慎重选择大数据平台数据安全厂商。这里给大家简单汇总一下&#xff0c;同时给大家推荐一下&#xff0c;仅供参考哦&#xff01; 2023年大数据平台数据安全厂商汇总 1、…

Kafka3.0.0版本——消费者(消费方式)

目录 一、Kafka 消费方式1.1、pull&#xff08;拉&#xff09; 模式1.2、push &#xff08;推&#xff09;模式1.3、Kafka采用pull&#xff08;拉&#xff09; 模式缺点 一、Kafka 消费方式 1.1、pull&#xff08;拉&#xff09; 模式 consumer采用从broker中主动拉取数据。K…

【Python小项目之Tkinter应用】随机点名/抽奖工具大优化:实现背景图与其他组件自适应窗口大小变化并保持相对位置和比例不变

文章目录 前言一、需求分析与实现思路明确需求实现思路二、关键代码2.1 实现背景图随着窗口大小变化而变化2.2 更换place的参数三、完整代码四、总结4.1 意外收获前言 话不多说,直接看优化后的效果: 优化前: 是不是非常的哇塞,相比于之前只能固定窗口大小来运行,优化后…