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

目录

  • 前言
  • 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;
}

  运行结果:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

还为没有本科学历发愁?2024年成人学历提升最全攻略

如果你因为学历低而处处不顺的时候&#xff0c; 请记着&#xff0c; 我们还有提升学历的机会&#xff01; 成人想提升学历有三大方式&#xff1a;成人高考&#xff0c;自学考试&#xff0c;开放大学。 通过这几种途径获得的文凭都是国家承认&#xff0c;学信网可查的&#x…

不知开关电源是否短路?这三种测试方法教您判断

开关电源短路是常见的一种故障&#xff0c;容易烧毁元器件、损毁设备&#xff0c;因此在开关电源设计制造过程中常需要对其短路保护功能进行测试。那么要如何判断开关电源是否短路呢&#xff1f;影响开关电源短路的因素有哪些呢&#xff1f; 检测开关电源是否短路的方法 一、用…

信号处理--基于单通道脑电信号EEG的睡眠分期评估

背景 睡眠对人体健康很重要。监测人体的睡眠分期对于人体健康和医疗具有重要意义。 亮点 架构在第一层使用两个具有不同滤波器大小的 CNN 和双向 LSTM。 CNN 可以被训练来学习滤波器&#xff0c;以从原始单通道 EEG 中提取时不变特征&#xff0c;而双向 LSTM 可以被训练来将…

[BUUCTF]-Reverse:SimpleRev解析(字符串比较)

查壳 看ida 这里的中心就是两个字符串和一个计算式子&#xff0c;textkillshadow和str2adsfkndcls&#xff0c;计算式子str2[v2] (v1 - 39 - key[v3 % v5] 97) % 26 97 完整exp&#xff1a; #include<stdio.h> int main() {char key[11]"adsfkndcls";char…

crossover2023激活码分享crossover免费升级2024 crossover24更新内容

CrossOver是一款功能强大的系统兼容软件&#xff0c;它能够让Mac和Linux用户在不安装Windows操作系统的情况下直接运行Windows应用程序。以下是关于CrossOver的更多信息&#xff1a; 一、工作原理 CrossOver的工作原理是通过在Mac或Linux系统上模拟Windows应用程序所需的运行…

私域做不下去的三大因素

私域运营是近年来的一大热门话题&#xff0c;从线下门店到日常外卖、线上购物&#xff0c;几乎所有的企业都在借助微信等社交媒体平台进行推广。然而&#xff0c;据统计&#xff0c;近90%的私域运营最后都不了了之。 原因1&#xff1a;在于企业对私域的认知不足&#xff0c;营…

免费的ChatGPT网站( 6个 )

现在智能化的AI工具&#xff0c;可以实现智能聊天、文本生成、语言翻译等多种功能。 博主归纳总结了6个好用且免费的AI工具网站&#xff0c;供大家参考。 1&#xff0c;insCode 网址&#xff1a; https://inscode.csdn.net/ 简介&#xff1a; InsCode 的 Ins 是 Inspiration&…

Docker-部署若依项目

文章目录 后端一、搭建局域网二、redis安装测试 三、MySQL安装四、后端项目放入位置及使用Dockerfile自定义镜像后端项目放入位置 前端配置检查各个端口是否启动nginx部署 首先得先把内部的文件给删除清空 docker images–查看有哪些文件 docker rmi -f ID–删除ID 后端 一、…

Day23:安全开发-PHP应用后台模块SessionCookieToken身份验证唯一性

目录 具体安全知识点 身份验证-Cookie使用 身份验证-Session使用 唯一性判断-Token使用 总结 源码 思维导图 PHP知识点&#xff1a; 功能&#xff1a;新闻列表&#xff0c;会员中心&#xff0c;资源下载&#xff0c;留言版&#xff0c;后台模块&#xff0c;模版引用&…

云渲染平台都开始涨价了?2024年性价比高的云渲染平台推荐

最近部分云渲染平台开始涨价&#xff0c;不论是通过调整机器性能&#xff0c;还是直接提价&#xff0c;都会对成本产生影响。这对已经习惯了平台价格的用户来说&#xff0c;并不是一件好事。这里举一些例子&#xff1a; 比如平台A&#xff0c;原“首小时渲染0.66元模式”已经下…

信号处理--基于EEG脑电信号处理研究概述

目录 前言 EEG特点 EEG预处理 EEG通道选择 EEG数据增强 EEG 维度降低 EEG特征提取 传统特征提取 深度学习自动提取特征 未来展望 创新的预处理方法 跨被试性能问题 模型融合 参考 前言 脑电信号&#xff08;EEG&#xff09;因其安全性、便携性、易用性、高时间分…

【C++】C/C++内存管理详解

个人主页 &#xff1a; zxctscl 文章封面来自&#xff1a;艺术家–贤海林 如有转载请先通知 目录 1. 前言2. C/C内存分布3. C语言中动态内存管理方式4. C中动态内存管理4.1 new/delete操作内置类型4.2 new和delete操作自定义类型 5. operator new与operator delete函数5.1 oper…

2024 年 AI 辅助研发趋势

随着人工智能技术的持续发展与突破&#xff0c;2024年AI辅助研发正成为科技界和工业界瞩目的焦点。从医药研发到汽车设计&#xff0c;从软件开发到材料科学&#xff0c;AI正逐渐渗透到研发的各个环节&#xff0c;变革着传统的研发模式。在这一背景下&#xff0c;AI辅助研发不仅…

章鱼网络进展月报 | 2024.2.1-2.29

章鱼网络大事摘要 1、Omnity 完成了核心组件的原型开发&#xff0c;正在测试&#xff0c;未来将首先支持 Runes 资产跨链。 2、$NEAR Restaking 质押总量超过400万美元。 3、章鱼网络受邀参加 ETHDenver 2024&#xff0c;并且与 ICP 共同组织活动&#xff0c;介绍 Omnity 的…

多线程:线程池

线程池 认识线程池 什么是线程池 线程池就是一个可以复用线程的技术。 不使用线程池的问题 用户每发起一个请求&#xff0c;后台就需要创建一个新线程来处理&#xff0c;下次新任务来了肯定又要创建新线程处理的&#xff0c;而创建新线程的开销是很大的&#xff0c;并且请…

Hello C++ (c++是什么/c++怎么学/c++推荐书籍)

引言 其实C基础语法基本上已经学完&#xff0c;早就想开始写C的博客了&#xff0c;却因为其他各种事情一直没开始。原计划是想讲Linux系统虚拟机安装的&#xff0c;后来考虑了一下还是算了&#xff0c;等Linux学到一定程度再开始相关博客的写作和发表吧。今天写博客想给C开个头…

java IO 02 IO接口

01.定义 02.IO中的输入和输出的划分 03.流的分类 IO流的所有类中&#xff0c;最先分野的是字节流和字符流。 字节流包括&#xff1a;输入流和输出流 InputStream public abstract class InputStream implements Closeable { }OutputStream public abstract class OutputSt…

20240306-1-大数据的几个面试题目

面试题目 1. 相同URL 题目: 给定a、b两个文件&#xff0c;各存放50亿个url&#xff0c;每个url各占64字节&#xff0c;内存限制是4G&#xff0c;让你找出a、b文件共同的url&#xff1f; 方案1&#xff1a;估计每个文件的大小为50G64320G&#xff0c;远远大于内存限制的4G。所以…

Node.js概述与安装和运行

Node.js概述与安装和运行 一、Node.js1.Node.js概述2.Node.js官网2.Node.js 各系统版本下载网址3.1 Node.js Windows下载网址 二、Node.js安装1.1 打开Node.js下载网址1.2 安装Node.js1.3 同意协议1.4 安装目录1.5 自定义安装1.6 本机模块工具1.7 进行安装Node.js1.8 安装完成1…

NLP自然语言——基础

一、介绍 1、概念 NLP&#xff08;Natural Language Processing&#xff0c;自然语言处理&#xff09;是计算机科学领域以及人工智能领域的一个重要的研究方向&#xff0c;它研究用计算机来处理、理解以及运用人类语言&#xff08;如中文、英文等&#xff09;&#xff0c;达到…