C++ · 代码笔记3 · 引用

news2024/10/26 2:29:01

目录

  • 前言
  • 011引用初探_引用与普通变量
  • 012引用初探_引用作为函数参数
  • 013引用初探_引用作为函数返回值
  • 014引用初探_引用返回局部函数造成的错误
  • 015引用初探_多级引用
  • 020引用与指针递增的区别
  • 030const与引用
  • 040使用const限定的函数形参引用

前言

  本笔记所涉及到的编程环境与 《C++ · 代码笔记1 · 从C到C++》 中的编程环境一致,具体可参考此笔记。

011引用初探_引用与普通变量

  相关代码:

#include <iostream>

int main()
{
    int a = 99;                               // 定义整型变量a并初始化为99
    int &r = a;                               // 定义整型引用r并初始化为a的引用
    std::cout << a << ", " << r << std::endl; // 输出a的值和r的值,由于r是a的引用,所以它们的值相同
    std::cout << &a << std::endl;             // 输出a的地址
    std::cout << &r << std::endl;             // 输出r的地址,由于r是a的引用,所以它们的地址也相同

    return 0;
}

  运行结果:

在这里插入图片描述

012引用初探_引用作为函数参数

  相关代码:

#include <iostream>

/**
 * 函数swap1:值传递方式交换两个整数
 * @param a 第一个整数
 * @param b 第二个整数
 * 注意:此函数不会改变实参的值,因为它是通过值传递的
 */
void swap1(int a, int b)
{
    int temp = a; // 使用临时变量保存a的值
    a = b;        // 将a的值设置为b
    b = temp;     // 将b的值设置为a原始的值
}

/**
 * 函数swap2:指针传递方式交换两个整数
 * @param p1 指向第一个整数的指针
 * @param p2 指向第二个整数的指针
 * 注意:此函数会改变实参的值,因为它是通过指针传递的
 */
void swap2(int *p1, int *p2)
{
    int temp = *p1; // 使用临时变量保存p1指向的值
    *p1 = *p2;      // 将p1指向的值设置为p2指向的值
    *p2 = temp;     // 将p2指向的值设置为p1原始的值
}

/**
 * 函数swap3:引用传递方式交换两个整数
 * @param r1 第一个整数的引用
 * @param r2 第二个整数的引用
 * 注意:此函数会改变实参的值,因为它是通过引用传递的
 */
void swap3(int &r1, int &r2)
{
    int temp = r1; // 使用临时变量保存r1的值
    r1 = r2;       // 将r1的值设置为r2
    r2 = temp;     // 将r2的值设置为r1原始的值
}

int main()
{
    int num1, num2;
    std::cout << "值传递,请输入两个整型数据: ";
    std::cin >> num1 >> num2;
    swap1(num1, num2);
    std::cout << num1 << " " << num2 << std::endl;

    std::cout << "指针传递,请输入两个整型数据: ";
    std::cin >> num1 >> num2;
    swap2(&num1, &num2);
    std::cout << num1 << " " << num2 << std::endl;

    std::cout << "引用传递,请输入两个整型数据: ";
    std::cin >> num1 >> num2;
    swap3(num1, num2);
    std::cout << num1 << " " << num2 << std::endl;

    return 0;
}

  运行结果:

在这里插入图片描述

013引用初探_引用作为函数返回值

  相关代码:

#include <iostream>
using namespace std;

/**
 * 函数func:通过引用修改参数并返回引用
 * @param r 输入的整型引用参数
 * @return 返回修改后的整型引用
 * 注意:此函数通过引用修改传入的参数,并且返回修改后的引用
 */
int &func(int &r)
{
    r += 10;  // 将传入的引用参数的值增加10
    return r; // 返回修改后的引用参数
}

int main()
{
    int num1 = 10;         // 定义并初始化整型变量num1为10
    int num2 = func(num1); // 调用func函数,传入num1的引用,并将返回的引用赋值给num2
    
    // 此时num1和num2的值都为20,因为它们引用的是同一个变量
    cout << num1 << " " << num2 << endl; // 输出num1和num2的值

    return 0;
}

  运行结果:

在这里插入图片描述

014引用初探_引用返回局部函数造成的错误

  相关代码:

#include <iostream>
using namespace std;

/**
 * 函数plus10:计算输入整型引用参数加10的结果,并返回一个新的整型引用
 * @param r 输入的整型引用参数
 * @return 返回一个新的整型引用,其值为输入参数加10
 * 注意:此函数返回的是一个局部变量的引用,这是一个危险的操作,
 * 因为局部变量在函数调用结束后会被销毁,返回其引用可能会导致未定义行为。
 */
int &plus10(int &r)
{
    int m = r + 10; // 创建一个局部变量m,其值为输入参数r加10
    return m;       // 返回局部变量m的引用
}

int main()
{
    int num1 = 10;           // 定义并初始化整型变量num1为10
    int num2 = plus10(num1); // 调用plus10函数,返回的是一个局部变量的值,此处是安全的
    cout << num2 << endl;    // 输出num2的值,即20

    int &num3 = plus10(num1); // 调用plus10函数,返回局部变量的引用并赋值给num3

    // 这里是危险的,因为num3现在引用了一个已经销毁的局部变量
    int &num4 = plus10(num3); // 再次调用plus10函数,返回局部变量的引用并赋值给num4
    
    // 这里同样是危险的,因为num4现在引用了一个已经销毁的局部变量
    cout << num3 << " " << num4 << endl; // 输出num3和num4的值,这是未定义行为

    return 0; // 程序结束,返回0
}

  运行结果:
在这里插入图片描述
  简单解释:事实上在编译的时候编译器已经发出了警告,其内容为返回了一个局部变量的引用。这是一个错误,因为局部变量在函数返回后就会销毁,返回的引用将指向一个不再有效的内存位置。

  在运行的时候直接出现“段错误”,从此可以看出,绝对不要使用引用去返回一个局部变量,否则将会出现程序崩溃的后果。

015引用初探_多级引用

  相关代码:

#include <iostream>

int main(int argc, char const *argv[])
{
    int a = 10;  // 定义整型变量a并初始化为10
    int &r = a;  // 定义整型引用r,并初始化为a的引用
    int &rr = r; // 定义整型引用rr,并初始化为r的引用,即rr也是a的引用

    // 输出rr、r和a的值,由于rr和r都是a的引用,它们的值与a相同
    std::cout << "rr = " << rr << "\nr = " << r << "\na = " << a << std::endl;

    return 0;
}

  运行结果:
在这里插入图片描述

020引用与指针递增的区别

  相关代码:

#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{
    int a = 10;        // 定义整型变量a并初始化为10
    int &r = a;        // 定义整型引用r,并初始化为a的引用
    r++;               // 通过引用r增加a的值
    std::cout << r << std::endl; // 输出r的值,即a的值,现在是11

    int arr[2] = {27, 84}; // 定义并初始化一个整型数组arr,包含两个元素27和84
    int *p = arr;          // 定义一个整型指针p,并初始化为指向数组arr的首地址
    p++;                   // 将指针p向后移动一个位置,指向数组arr的第二个元素
    std::cout << *p << std::endl;    // 输出指针p所指向的值,即数组arr的第二个元素,值为84

    return 0;
}

  运行结果:

在这里插入图片描述

030const与引用

  相关代码:

#include <iostream>

/* 引用不能绑定到临时数据,但是当使用 const 关键字对引用加以限定后,引用就可以绑定到临时数据了。 */

// 定义一个结构体S,包含两个整型成员a和b
typedef struct
{
    int a; // 成员a
    int b; // 成员b
} S;

// 函数func_int,返回一个整型值100
int func_int()
{
    int n = 100; // 初始化整型变量n为100
    return n;    // 返回n的值
}

// 函数func_s,返回一个结构体S的实例,其成员a和b分别被赋值为100和200
S func_s()
{
    S a;       // 定义结构体变量a
    a.a = 100; // 设置a的成员a为100
    a.b = 200; // 设置a的成员b为200
    return a;  // 返回结构体变量a
}

// 重载+运算符,用于两个结构体S的实例相加
S operator+(const S &A, const S &B)
{
    S C;             // 定义结构体变量C,用于存储A和B相加的结果
    C.a = A.a + B.a; // 设置C的成员a为A和B的成员a之和
    C.b = A.b + B.b; // 设置C的成员b为A和B的成员b之和
    return C;        // 返回结构体变量C
}

// 程序的入口点
int main()
{
    int m = 100, n = 36; // 定义并初始化整型变量m为100,n为36

    // 以下都是通过字面量或表达式初始化的常量引用,注意它们都没有实际的对象与之绑定
    const int &r1 = m + n;      // 常量引用r1绑定到m和n的和上
    const int &r2 = m + 28;     // 常量引用r2绑定到m和28的和上
    const int &r3 = 12 * 3;     // 常量引用r3绑定到12和3的乘积上
    const int &r4 = 50;         // 常量引用r4绑定到字面量50上
    const int &r5 = func_int(); // 常量引用r5绑定到函数func_int的返回值上

    S s1 = {23, 45}; // 定义并初始化结构体变量s1的成员a为23,b为45
    S s2 = {90, 75}; // 定义并初始化结构体变量s2的成员a为90,b为75

    const S &r6 = func_s(); // 常量引用r6绑定到函数func_s的返回值上
    const S &r7 = s1 + s2;  // 常量引用r7绑定到s1和s2的和上

    return 0; // 程序结束
}

  运行结果:

在这里插入图片描述

040使用const限定的函数形参引用

  相关代码:

#include <cstdio>

// 计算长方体的表面积
// @param len 长方体的长度
// @param width 长方体的宽度
// @param hei 长方体的高度
// @return 返回长方体的表面积
/* 使用 const 能让函数接收 const 和非 const 类型的实参,否则将只能接收非 const 类型的实参; */
double volume(const double &len, const double &width, const double &hei)
{
    return len * width * 2 + len * hei * 2 + width * hei * 2;
}

// 程序的入口点
int main()
{
    int a = 12, b = 3, c = 20; // 定义并初始化整型变量a为12,b为3,c为20

    double v1 = volume(a, b, c);                   // 调用volume函数计算长方体的表面积,并存储结果到v1
    double v2 = volume(10, 20, 30);                // 调用volume函数计算长方体的表面积,并存储结果到v2
    double v3 = volume(89.4, 32.7, 19);            // 调用volume函数计算长方体的表面积,并存储结果到v3
    double v4 = volume(a + 12.5, b + 23.4, 16.78); // 调用volume函数计算长方体的表面积,并存储结果到v4
    double v5 = volume(a + b, a + c, b + c);       // 调用volume函数计算长方体的表面积,并存储结果到v5

    printf("%lf, %lf, %lf, %lf, %lf\n", v1, v2, v3, v4, v5); // 打印出v1, v2, v3, v4, v5的值

    return 0;
}

  运行结果:

在这里插入图片描述

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

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

相关文章

社区店选址案例分享:从成功案例中汲取经验

想开实体店或创业的朋友们&#xff0c;大家好&#xff01;我是一名鲜奶吧5年的创业者&#xff0c;今天我将以开店专家的角度&#xff0c;为大家分享一些社区店选址的成功案例&#xff0c;希望能给你们带来启发和帮助。 选址是实体店成功的关键之一&#xff0c;而社区店更是要注…

16 进程终止

终止的结果 进程终止后&#xff0c;释放申请的相关内核数据结构和对应的数据和代码。本质就是释放系统资源 终止的场景 代码跑完&#xff0c;结果正确代码跑完&#xff0c;结果不正确代码没有跑完&#xff0c;程序崩溃 进程常见退出方法 正常退出&#xff1a; 1.main返回 …

selenium-java web自动化测试工具抓取百度搜索结果实例

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

高中数学:函数类高阶题目考法汇总(较难)

1、基本性质类问题 2、解抽象函数不等式问题 在1的基础上 解题思路&#xff1a; 根据f的单调性&#xff0c;去f 将问题转化成具体不等式问题。 例题&#xff1a; 对于第三小问&#xff0c;每一个变形前面&#xff0c;都要加上只要证、即证关键词&#xff0c;才不会被扣过程…

【STM32+HAL】姿态传感器陀螺仪MPU6050模块

一、准备工作 有关OLED屏初始化的问题&#xff0c;详见【STM32HAL】OLED显示初始化配置 二、所用工具 1、芯片&#xff1a;STM32F10C8T6 2、CUBEMX配置软件 3、 6 轴运动处理组件MPU6050 三、实现功能 OLED屏显示姿态角 四、HAL配置步骤 1、开启I2C1进行MPU6050通信 2、开…

红队攻击手“实战”特训

伴随着新的一年的到来&#xff0c;我们最新一期的红队攻防&#xff0c;也如约而至~ 每一期我们都会做二次学员反馈&#xff0c;根据同学们的真实反馈和需求&#xff0c;来调整讲师及授课内容 新的一期我们增加了C基础&#xff0c;python基础&#xff0c;汇编基础的课程&#…

LeetCode 刷题 [C++] 第139题.单词拆分

题目描述 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。 注意&#xff1a;不要求字典中出现的单词全部都使用&#xff0c;并且字典中的单词可以重复使用。 题目分析 背包问题特征&#xff1a; 是否…

用云手机进行舆情监测有什么作用?

在信息爆炸的时代&#xff0c;舆情监测成为企业和政府决策的重要工具。通过结合云手机技术&#xff0c;舆情监测系统在品牌形象维护、市场竞争、产品研发、政府管理以及市场营销等方面发挥着关键作用&#xff0c;为用户提供更智能、高效的舆情解决方案。 1. 品牌形象维护与危机…

Codeforces Round 928 G. Vlad and Trouble at MIT 【树形DP】

G. Vlad and Trouble at MIT 题意 给定一颗 n n n 个节点的树&#xff0c;每个节点有一个学生&#xff0c;学生有三种类型&#xff1a; 参加派对的 P P P 类型&#xff0c;会制造噪音想要睡觉的 S S S 类型&#xff0c;不希望被吵到有没有噪音都可以的 C C C 类型 噪音会…

VUE3中ArcGIS JsAPI 4.27 Map 隐藏地图黑色边框

问题&#xff1a; vue3中引入arcgis jsapi 地图加载后&#xff0c;点击地图会出现黑色边框&#xff0c;看起来很不协调 解决方案&#xff1a; 新建自定义CSS文件&#xff0c;输入一下样式内容&#xff0c;并在vue页面直接用import引入即可。 注意&#xff1a;直接写到vue页面…

C++复习笔记——泛型编程模板

01 模板 模板就是建立通用的模具&#xff0c;大大提高复用性&#xff1b; 02 函数模板 C另一种编程思想称为 泛型编程 &#xff0c;主要利用的技术就是模板 C 提供两种模板机制:函数模板和类模板 函数模板语法 函数模板作用&#xff1a; 建立一个通用函数&#xff0c;其函…

【洛谷 P8682】[蓝桥杯 2019 省 B] 等差数列 题解(数学+排序+差分)

[蓝桥杯 2019 省 B] 等差数列 题目描述 数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一部分的数列&#xff0c;只记得其中 N N N 个整数。 现在给出这 N N N 个整数&#xff0c;小明想知道包含这 N N N 个整数的最短的等差数列有几项&#xff1f; 输…

Mybatis-Plus:几个好的用法

项目使用mybatis-plus&#xff0c;同事的用法让我很难苟同&#xff0c;于是自己百度了一些用法&#xff0c;分享一下。 一、静态适配器 最好使用官方提供的ObjectUtils,比较全面&#xff0c;不用加载不同的对象工具。 com.baomidou.mybatisplus.core.toolkit /*** 设置查询适配…

C# 由左上、右下两个坐标点计算矩形的长、宽以及两点的距离

一、计算长、宽 直接使用坐标点计算 // 定义矩形左上角和右下角的坐标 Point topLeft new Point(0, 0); Point bottomRight new Point(5, 10); // 计算矩形的长和宽 int width bottomRight.X - topLeft.X;//矩形宽度 int height bottomRight.Y - topLeft.Y;//矩形高度或是…

实战-Sealos一键部署k8s集群-2024.3.7(测试成功)

目录 [toc] 原文链接 实战-Sealos一键部署k8s集群-2024.3.7(测试成功) | 彦 推荐文章 我的开源项目&#xff1a; 开源项目 | 彦 实验环境 centos7.6 1810,5.4.270-1.el7.elrepo.x86_64sealos v5.0.0-beta4k8s v1.28.7 &#xff08;当前时间&#xff1a;2024年3月7日 k8s最新版…

ruoyi-vue框架密码加密传输

先看一下改造后的样子&#xff0c;输入的密码不会再以明文展示。 下面我主要把前后端改造的代码贴出来。 1.后端代码 RsaUtils类 在com.ruoyi.common.utils包下新建RsaUtils类&#xff0c;RsaUtils添加了Component注解 generateKeyPair()构建密钥对添加了Bean注解 在项目启动…

AI助力剧本创作:如何5分钟内构思出热门短剧大纲

人工智能重塑短剧行业&#xff1a;从剧本创作到市场推广 在当今短剧行业的飞速发展中&#xff0c;剧本创作的质量及其更新的速度已然成为短剧能否转化为热门作品的关键性因素。然而&#xff0c;随着短剧创作成本的日益攀升&#xff0c;一个卓越的剧本无论在创作时间上还是在构思…

java中的多线程通信问题介绍

在多线程编程中&#xff0c;通信是线程间协调和同步的重要手段。由于线程是独立执行的&#xff0c;它们需要一种机制来交换信息和协调它们的行为。Java 提供了多种方式来实现线程间的通信&#xff0c;包括共享内存、消息传递、条件变量和共享对象等。 1. 共享内存 在 Java 中&a…

vue2的element UI 表格单选

代码 this.$refs.multipleTable.toggleRowSelection(selection.shift(), false);multipleTable 是定义的表格的ref

Kubernetes(K8S之存储)

configmap configMap描述信息 configMap功能在Kubernetes1.2版本中引入&#xff0c;许多应用程序会从配置文件&#xff0c;命令行参数或环境变量中读取配置信息。ConfigMap API给我们提供了向容器中注入配置信息的机制。ConfigMap可以被用来保存单个属性。 也可以用来保存整…