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

目录

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

前言

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

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

  相关代码:

#include <iostream>int main()
{int a = 99;                               // 定义整型变量a并初始化为99int &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的值设置为bb = 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的值设置为r2r2 = 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;  // 将传入的引用参数的值增加10return r; // 返回修改后的引用参数
}int main()
{int num1 = 10;         // 定义并初始化整型变量num1为10int 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加10return m;       // 返回局部变量m的引用
}int main()
{int num1 = 10;           // 定义并初始化整型变量num1为10int num2 = plus10(num1); // 调用plus10函数,返回的是一个局部变量的值,此处是安全的cout << num2 << endl;    // 输出num2的值,即20int &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并初始化为10int &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并初始化为10int &r = a;        // 定义整型引用r,并初始化为a的引用r++;               // 通过引用r增加a的值std::cout << r << std::endl; // 输出r的值,即a的值,现在是11int arr[2] = {27, 84}; // 定义并初始化一个整型数组arr,包含两个元素27和84int *p = arr;          // 定义一个整型指针p,并初始化为指向数组arr的首地址p++;                   // 将指针p向后移动一个位置,指向数组arr的第二个元素std::cout << *p << std::endl;    // 输出指针p所指向的值,即数组arr的第二个元素,值为84return 0;
}

  运行结果:

在这里插入图片描述

030const与引用

  相关代码:

#include <iostream>/* 引用不能绑定到临时数据,但是当使用 const 关键字对引用加以限定后,引用就可以绑定到临时数据了。 */// 定义一个结构体S,包含两个整型成员a和b
typedef struct
{int a; // 成员aint b; // 成员b
} S;// 函数func_int,返回一个整型值100
int func_int()
{int n = 100; // 初始化整型变量n为100return n;    // 返回n的值
}// 函数func_s,返回一个结构体S的实例,其成员a和b分别被赋值为100和200
S func_s()
{S a;       // 定义结构体变量aa.a = 100; // 设置a的成员a为100a.b = 200; // 设置a的成员b为200return 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为45S s2 = {90, 75}; // 定义并初始化结构体变量s2的成员a为90,b为75const 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为20double v1 = volume(a, b, c);                   // 调用volume函数计算长方体的表面积,并存储结果到v1double v2 = volume(10, 20, 30);                // 调用volume函数计算长方体的表面积,并存储结果到v2double v3 = volume(89.4, 32.7, 19);            // 调用volume函数计算长方体的表面积,并存储结果到v3double v4 = volume(a + 12.5, b + 23.4, 16.78); // 调用volume函数计算长方体的表面积,并存储结果到v4double v5 = volume(a + b, a + c, b + c);       // 调用volume函数计算长方体的表面积,并存储结果到v5printf("%lf, %lf, %lf, %lf, %lf\n", v1, v2, v3, v4, v5); // 打印出v1, v2, v3, v4, v5的值return 0;
}

  运行结果:

在这里插入图片描述

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

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

相关文章

经典语义分割(二)医学图像分割模型UNet

经典语义分割(二)医学图像分割模型UNet 我们之前介绍了全卷积神经网络( FCN) &#xff0c;FCN是基于深度学习的语义分割算法的开山之作。 今天我们介绍另一个语义分割的经典模型—UNet&#xff0c;它兼具轻量化与高性能&#xff0c;通常作为语义分割任务的基线测试模型&#x…

opengl 学习(三)-----着色器

着色器 分类demo效果解析教程 分类 OPengl C demo #include "glad/glad.h" #include "glfw3.h" #include <iostream> #include <cmath> #include <vector>#include <string> #include <fstream> #include <sstream>…

苍穹外卖技术栈

Day5 Redis_Spring Data Redis使用方法 Spring Data Redis Spring Date Redis 是Spring的一部分&#xff0c; 对Redis底层开发包进行了高度封装&#xff0c;在Spring项目中&#xff0c;可以使用Spring Data Redis来简化操作。 操作步骤 导入Spring Data Redis 的maven坐标配置…

浮点数和定点数

前言 大家好我是jiantaoyab&#xff0c;这是我所总结作为学习的笔记第七篇,在这里分享给大家,还有一些书籍《深入理解计算机系统》《计算机组成&#xff1a;结构化方法》《计算机体系结构&#xff1a;量化研究方法》&#xff0c;今天我们来了解定点数和浮点数 定点数 BCD编码 …

JavaScript基础4之原型的原型继承、原型链和理解对象的数据属性、访问器属性

JavaScript基础 原型原型继承问题解决 原型链isPrototypeOf()Object.getPrototypeOf() 理解对象数据属性访问器属性 原型 原型继承 继承是面向对象编程的另一个特征&#xff0c;通过继承进一步提升代码封装的程度&#xff0c;JavaScript中大多是借助原型对象实现继承的特性。…

蜘蛛池是什么意思,怎么生成蜘蛛池

蜘蛛池是由自然界中的蜘蛛群落构成的一个小生态系统&#xff0c;也是身处自然界中的游客们可以在风雨中体验到最贴近自然气息的地方。 点开我主页面 Baidu蜘蛛的作用&#xff1a; 引蜘蛛逐渐收录&#xff0c;降权引蜘蛛可以疗伤&#xff0c;排名/收录不稳定&#xff0c;没有收…

等离子体密度诊断集

文章目录 等离子体密度诊断电子密度诊断朗缪尔探针法 (Langmuir Probe)干涉度量法 (Interferometer)全息法 (Holographic Method)离子密度诊断光腔衰减震荡 (Cavity Ring-Down Spectroscopy, CRDS)发射光谱法 (OES)中性粒子密度吸收光谱法 (Absorption Spectroscopy, AS)发射光…

【Linux篇】gdb的使用

&#x1f49b;不要有太大压力&#x1f9e1; &#x1f49b;生活不是选择而是热爱&#x1f9e1; &#x1f49a;文章目录&#x1f49a; 1. 背景知识2. 使用 1. 背景知识 1. 程序发布的方式有两种&#xff0c;debug模式和release模式 2. Linux下&#xff0c;gcc和g编译生成的可执行…

LeetCode每日一题[c++]-找出字符串的可整除数组

题目描述 链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 给你一个下标从 0 开始的字符串 word &#xff0c;长度为 n &#xff0c;由从 0 到 9 的数字组成。另给你一个正整数 m 。word 的 可整除数组 div 是一个长度为 n 的整数数组&#xff0c;并满足&#xff…

mongodb4.2升级到5.0版本,升级到6.0版本, 升级到7.0版本案例

今天一客户想把自己当前使用的mongodb数据库4.2版本升级到7.0版本。难道mongodb能直接跳跃升级吗? 经过几经查找资料&#xff0c;貌似真不行呀。确定升级流程如下: 还得从mongo4.2升级到5.0。其次再从5.0升级到6.0。最后再从6.0升级到7.0。 开始升级之前将数据进行备份 这一步…

国家积极推进长城国家文化公园建设

长城脚下&#xff0c;文化绽放——国家积极推进长城国家文化公园建设 在中华大地的北方&#xff0c;横亘着一条巨龙&#xff0c;它见证着中华民族的沧桑岁月&#xff0c;承载着我们的民族记忆&#xff0c;它就是——长城。这座千年的雄关&#xff0c;不仅是中国的象征&#xf…

WPF —— TextBox 控件详解

TextBox控件是WPF中最基本的文字输入控件。它允许最终用户在一行、对话输入、或多行编写&#xff0c;就像是个编辑器。 关于TextBox常用的属性 FontFamily 字体样式 宋体 楷体等 FontWeight 字体粗细 &#xff0c; Bold加粗 FontStyle 字体样式 斜体和…

Git Cherry-Pick命令详解:轻松选取与移植提交

前言 在Git版本控制系统中&#xff0c;git cherry-pick是一个非常实用的功能&#xff0c;它允许开发人员选择性地将某一个或多个提交&#xff08;commit&#xff09;从一个分支复制到另一个分支&#xff0c;从而实现了对特定改动的精确移植。这对于重现特定补丁、回溯修复bug、…

【软件测试】测试工具推荐

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 本…

[Unity实战]使用NavMeshAgent做玩家移动

其实除了Character Controller, Rigidbody&#xff0c;我们还可以使用NavMeshAgent去做。这么做的好处是能避免玩家去莫名其妙的地方&#xff08;毕竟基于烘焙过的导航网格&#xff09;&#xff0c;一般常见于元宇宙应用和mmo。 根据Unity手册&#xff0c;NavMeshAgent 也有和…

Stringbuffer 和 Stringbuilder 的区别是什么?

StringBuffer 和 StringBuilder 是 Java 中用于处理字符串的两种常用类&#xff0c;它们都允许我们修改字符串&#xff0c;即进行字符串的拼接、插入和删除等操作。尽管两者都提供了可变字符串的功能&#xff0c;但它们之间有一些关键的区别&#xff0c;特别是在线程安全性和性…

学c++对Python有帮助吗?

学习C对Python编程确实有帮助&#xff0c;尽管这两种语言在许多方面有很大的不同。以下是学习C可能对Python编程产生帮助的几个方面&#xff1a; 理解底层概念&#xff1a;C是一种更接近硬件的编程语言&#xff0c;它要求程序员更深入地理解内存管理、指针、数据类型等底层概念…

【在线普法】无端遭受他人殴打,反击抵抗时不慎致滋事者受伤住院,这样的行为是否构成正当防卫?

反击滋事者致其受伤 是否承担民事责任 无端遭受他人殴打&#xff0c;反击抵抗时不慎致滋事者受伤住院&#xff0c;这样的行为是否构成正当防卫&#xff1f;是否应承担民事责任&#xff1f;近日&#xff0c;重庆市九龙坡区人民法院审结了一起健康权纠纷案&#xff0c;认定本案中…

第二十三章 javascript请求方式Ajax

文章目录 一、Ajax的概念二、Ajax的使用使用流程xhr 状态码&#xff1a;xhr.readyStatehttp 状态码&#xff1a;xhr.status 三、发送数据的数据格式 - Content-Type四、其他1. POST和GET的区别2. AJAX的兼容问题3. 个别设备中ajaxGet请求的缓存问题4. XMLHttprequest常见事件 一…

Dubbo分布式服务框架:原理深度解析与实战应用探索(一)

本系列文章简介&#xff1a; 在本系列文章中&#xff0c;我们将深入探索Dubbo分布式服务框架的原理和实战应用。我们将从Dubbo的架构设计开始&#xff0c;详细解析其内部的工作原理和核心组件。我们将探讨Dubbo的服务治理机制、负载均衡策略、容错机制等&#xff0c;并通过实际…