C++之入门之引用,内联函数
一、引用
1、引用的概念
在C++中,引用的本质其实就是给一个已经存在的变量”起别名“。也就是说,引用与它所引用的对象共用一块空间。(同一块空间的多个名字)
就比如说,李逵又叫黑旋风,而黑旋风就是指李逵本人,只是名字换了而已。
int a = 20;int* pa = &a; //指针
int& ra = a; //引用
2、引用的特性
1、引用在使用时必须初始化
2、一个变量可以有多个引用,但一个引用只能有一个实体对象
可以看出:地址相同,abcd共用一个空间。
引用还有几点需要注意:1、引用无法改变指向
char& ra = a;
char& ra = b; //错误,引用一旦确立后,就无法再改变其指向
ra = b; //这个没问题,实际结果为 a = 'B' 即将 b 的内容赋值给 a
2、引用不存在多级引用
char& ra = a;
char&& b = ra; //非法,不存在多级引用
char& b = ra; //合法,实际结果为 char& b = a;
三、常引用
指针和引用在赋值或者初始化时,权限可以被缩小或者保持,但不可进行修改。
来看如下代码:
// 权限放大(error)//const int c = 2;//const 修饰的常量不可以进行修改,可以理解只具有读的属性,不具有写的属性,而d可以修改,所以权限被放大//int& d = c;//这里正确写法应为const int& d=c;//const int* p1 = NULL;//int* p2 = p1;//同上,前面加个const即可,const int* p2=p1; (√)// 权限保持const int c = 2;const int& d = c;const int* p1 =NULL;const int* p2 = p1;// 权限缩小int x = 1;//x可以进行修改,可以理解为具有读和写的属性,而x是const修饰的,只具有读的属性,权限缩小了const int& y = x;int* p3 = NULL;const int* p4 = p3;//同上
引用主要有以下的使用场景:
1、做参数:
void swap(int& ra, int& rb)
{//有了引用之后,不需要再解引用,也能达到指针的效果int tmp = ra;ra = rb;rb = tmp;
}
2、做返回值:
//返回值
int& Test()
{static int a = 10;a++;return a;//也会产生临时变量,但是临时变量的类型是int& 也就是a的别名,即临时变量就是返回的a,减少了拷贝操作
}
int main()
{int ret = Test();return 0;
}
这就是引用返回,即在返回类型前面加上&,虽然也需要借助临时变量的存在,但是由于临时变量的类型为int& ,即临时变量就是a,所以就减少了临时变量的拷贝工作,会使效率得到提升。当引用做返回值时,接收到的变量就是函数返回时的本体,就是变量ret。
不过需要注意的是:
这段代码是错误的,原因是:val是函数 func 中的局部变量,当函数结束后,变量就被销毁了,此时可能得到正确的结果(编译器未清理),也可能得到错误的结果(编译器已清理)。
这就告诫我们如果是局部变量就不适合使用引用调用,而生命周期是较长的变量,适合使用引用返回,不需要创建临时变量。
二、内联函数
1、内联函数的概念
我们知道在创建函数的过程中:一个函数在开始调用时会建立函数栈帧,结束调用时会销毁函数栈帧,而函数栈帧的建立与销毁是有空间和时间上的开销的。
对于功能简单,而调用次数很多的函数来说,每次调用都重新开辟栈帧势必就会造成效率的降低,在C语言中们使用宏函数来解决这个问题:我们直接将 要调用的函数写成宏函数,这样使得程序在预处理阶段直接将调用的函数替换成相应的代码,从而不再建立函数栈帧。
比如交换函数代码:
#define Add(x,y) ((x)+(y)) //宏函数
宏定义除了复杂以外还有如下缺点:
1、不能进行调试,宏是直接进行替换的
2、没有类型的安全检查
所谓内联函数就是在函数实现前加上 inline
修饰,此时函数会被编译器标记为内联函数。
//此时的 Add 函数就是一个内联函数
inline int Add(int x, int y)
{return x + y;
}
内联函数有如下特点:
- 在
Debug
模式下,函数不会进行替换,可以进行调试- 在
Realse
模式下,函数会像宏函数一样展开,提高程序运行速度- 内联函数弥补了宏函数的不足,同时吸收了宏函数速度快的优点
三、auto关键字
在代码的编写中,随着程序的越来越复杂,所用的类型也越来越复杂,所以我们就需要引入auto关键字。
1、auto功能
auto
关键字能直接识别目标变量类型,然后自动转换为相应类型
int a = 10;
int* b = &a;auto aa = a; //此时 aa 为 int
auto bb = b; //此时 bb 为 int*
不过在以后的学习过程中会遇到名字很长的变量,这就要用到auto关键字了。
#include <string>
#include <map>
int main()
{std::map<std::string, std::string> a{ { "apple", "苹果" }, { "orange","橙子" },{"pear","梨"} };std::map<std::string, std::string>::iterator it = a.begin();while (it != m.end()){//....}return 0;
}
auto的功能还可以指定转化类型。
int a = 10;auto* pa = a; //指定 pa 为 int*
auto& ra = a; //指定 pa 为 int&
不过要记住:
auto a = 1, b = 2.2; //非法,类型不统一
这个定义变量是错误的。
四、基于范围的for循环
在C++中,我们有更简介的方法来使用for循环,不用向之前这么繁杂。就像Python中使用for循环方法类似,在一个范围里进行for循环的。
来看如下的代码:
void TestFor()
{int array[] = { 1,2,3,4,5 };//使用引用进行迭代--可以修改原数组for (auto& e : array)e *= 2;//使用局部变量进行迭代--不能修改原数组for (auto e : array)cout << e << " ";cout << endl; //换行
}int main() {TestFor();
}
for循环后的括号被冒号分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。
范围for的使用条件:1、范围大小必须确定 2、迭代对象要使用++,==的操作。
相关文章:

C++之入门之引用,内联函数
一、引用 1、引用的概念 在C中,引用的本质其实就是给一个已经存在的变量”起别名“。也就是说,引用与它所引用的对象共用一块空间。(同一块空间的多个名字) 就比如说,李逵又叫黑旋风,而黑旋风就是指李逵…...
linux kprobe使用
使用场景 监控某个内核函数是否被调用获取某个内核函数耗费的时间获取某个内核函数的入参获取某个内核函数的调用栈(dump_stack())获取某个内核函数的返回值 参数传递规则 x86平台对pt_regs的定义 arch/x86/include/asm/ptrace.h // i386架构 #ifdef…...
2023年超全前端面试题-背完稳稳拿offer(欢迎补充)
HTML、CSS相关 HTML5 HTML5新特性 增强了表单,input新增了一些type: color----定义调色板 tel-----定义包含电话号码的输入域 email—定义包含email地址的输入域 search–定义搜索域 number–定义包含数值的输入域 date----定义选取日、月、年的输入域…...

python之web自动化测试框架
梳理下搭建web自动化框架的流程: 创建目录: cases:存放测试用例,unittest框架要求用例名必须以test开头,所以命名test_case.py test_case.py代码如下:继承unittest.TestCase类下面的方法setupclass(),te…...

算法笔记(十五)—— 动态规划(暴力递归到动态规划)习题训练!
通过递归到记忆化搜索再到严格表结构的动态规划 递归方法的评价:1. 单可变参数的维度;2. 可变参数的个数 记忆化搜索 在暴力递归中会存在很多的重复计算,可以使用存储结构来实现空间换时间。 严格表结构的动态规划 整理位置之间的依赖关系…...

云原生架构基础概念及应用办法
什么是云原生? 云原生是一种基于容器、微服务和自动化运维的软件开发和部署方法。它可以使应用程序更加高效、可靠和可扩展,适用于各种不同的云平台。 如果要更直接通俗的来解释下上面的概念。 云原生更准确来说就是一种文化,是一种潮流&a…...

RedisTemplate 的基本使用手把手教
下载实例源码 使用步骤 1、引入 spring-boot-starter-data-redis 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency>2、在 application.yml 配置 R…...

Hbase -- Compact工具梳理
1. 背景 当前,线上HBase集群的自动Major Compact是关闭的,我们选择在凌晨业务空闲的时候进行手动触发Major Compact,Compact工具就是在运维平台上对资源组、RS、表进行Major Compact。目前线上有2种版本的Compact程序:Compact_v1…...
【java代码审计】SQL注入
1 原理 没有正确的对用户的输入进行检查,将用户的输入以拼接的方式带入到SQL语句中,导致SQL注入。 2 产生SQL注入的原因 2.1 JDBC拼接不当造成SQL注入 前置知识: JDBC执行SQL语句的两种方式: PrepareStatement:会对…...
前置知识-辛 Runge-Kutta 方法
1.3.3 辛 Runge-Kutta 方法 将方程 ( 1.10.2 ) (1.10 .2) (1.10.2) 改写为 d z d x =...
require 与 import 两种引入模块方式到底有什么区别?
关于JavaScript 的模块化规范,可以移步至: 【JavaScript高级】模块化规范「一文让你彻底搞懂前端模块化规范 & 区别」 下面进入正题 require 与 import 两种引入模块方式,到底有什么区别呢? 大致可以分为以下几个方面&#…...

软考信息系统监理师备考建议
用好备考方法,两三个月就可以过的。信息系统监理师备考最好以教材和历年真题为主,教学视频模拟题为辅。考试介绍与复习建议:考试设置的科目包括:(1)信息系统工程监理基础知识,考试时间150分钟&a…...

第八届蓝桥杯省赛——4承压计算(二维数组,嵌套循环)
题目:X星球的高科技实验室中整齐地堆放着某批珍贵金属原料。每块金属原料的外形、尺寸完全一致,但重量不同。金属材料被严格地堆放成金字塔形。7 5 8 7 8 8 9 2 7 2 8 1 4 9 1 8 1 8 8 4 1 7 9 6 1 4 5 4 5 6 5 5 6 9 5 6 5 5 4 7 9 3 5 5 1 7 5 7 9 7 4…...
【ECNU】3645. 莫干山奇遇(C++)
目录 题目 输入格式 输出格式 样例 提示 思路 代码 题目 单点时限: 2.0 sec 内存限制: 512 MB 出题人当然是希望出的题目有关 oxx,于是想方设法给题目配上一些有关 oxx 的背景故事,使得它看起来不那么无趣。但有的时候却无法引入合适的小姐姐&…...

为什么需要学习shell、shell的作用
课程基于B站于超课程笔记 03 Shebang的正确玩法_哔哩哔哩_bilibili P1 shell的作用 P2 shell执行命令的流程 P3 Shebang的正确玩法 什么是shell及组成 shell概念 shelll组成 Shebang概念 /bin/sh /bin/bash一样,都是指向一个bash解释器 [rootlocalhost ~]#…...
pgsql-Create_ALTER_GRANT_REVOKE命令语法
pgsql-Create_ALTER_GRANT_REVOKE命令语法 资料 语法约定 CREATE ROLE ALTER ROLE GRANT授权 REVOKE回收授权 权限类型说明 语法约定 下面的约定被用于命令的大纲:方括弧([和])表示可选的部分(在 Tcl 命令里,使…...

【linux】:进程概念
文章目录 冯诺依曼体系结构一:操作系统二: 进程总结冯诺依曼体系结构 我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系。 冯诺依曼体系如下图: 那么输入设备有哪些呢?…...

创建对象的方式和对属性的操作
javaScript支持多种编程范式,包括函数式编程和面向对象编程,javaScript的对象被设计成一组属性的无序集合,由key和value组成。 创建对象的两种方式 早期使用创建对象方式最多的是使用Object类,使用new关键字来创建一个对象&…...
GO时间相关操作说明
文章目录 GO时间相关操作时间转换成字符串字符串转换成时间时间戳和时间操作时间比较操作时间增加和减少操作休眠操作time.AfterFunc操作time.NewTicker操作GO时间相关操作 GO语言在使用时间转换的时候会用到2006-01-02 15:04:05 这是固定参数写法,类似java语言中的yyyy-M…...
选择和分支结构
选择和分支结构选择和分支结构一、复习问答二、选择结构2.1 基础选择结构2.2 if-else结构2.3 多重if结构2.4 嵌套if结构三、分支结构四、局部变量选择和分支结构 一、复习问答 1、Java中基本数据类型 2、类型的转换的两种情形 3、数据类型提升的规则 二、选择结构 2.1 基础选…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...