当前位置: 首页 > news >正文

c++的学习之路:3、入门(2)

一、引用

1、引用的概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空
间,它和它引用的变量共用同一块内存空间。

怎么说呢,简单点理解就是你的小名,家里人叫你小名,你就不是你了?显然不是,这个就是引用的概念,在变成过程中,引用的用法就是如下方图片就是最简单的引用表示,我先定义一个变量a然后给a取别名为b然后这里是把他们的地址都打印出来了,然后发现他们的地址都是一个,这样就能最简单的证明了引用就是取别名,就是共同访问同一个地址。

那么能否给b接着取别名呢?

当然可以了,如果收,别人叫你的小名,再给这个小名去一个小名就不是自己了?,代码测试如图,这样就可以得出引用是可以套用的。而&这个就是引用的符号,他和取地址符是同一个,那是因为他的原理其实就是一个指针。

2、引用的特性

引用在定义时必须初始化,因为引用和指针不同,指针是存放这个变量的地址,也就是说,这个指针,也可以不初始化,放入空值都是可以的。

 一个变量可以有多个引用,这个就像上文中说的,可以取好几个别名,最间的的说明就是一个人是可以有很多称呼的,如下图就可以看出,对d取地址就可以看出也是a。

引用一旦引用一个实体,再不能引用其他实体 ,这个引用不学指针可以更改地址,引用是只可以对一个变量引用,也就是说b是a的引用,那么b只能是a的别名,不可能存在b是别的别名,那么就可以说明引用具有唯一性。

引用是具有等级权限的 ,最简单就是常量,如下如图所示,就可以看出,如果对一个常量进行引用,就会报错,这就是引用的权限,引用是只可以限制权限,不能放大权限,就像下图所示,a是一个常量,然后他的属性是只读,那么b想引用他,并且变成可以写的变量,那肯定是不可以的,但是假如说,变量a是可以读写的,引用的时候只限制成只读,可以吗?答案是可以的,因为引用可以把权限变小,如下图二所示是没有报错的就是可以的,那么如何引用常量呢,就是把权限限制为平级,也就是也变成常量,如下图三就是把别名也变成常量,那么权限就是平级的了,所以也就是可以使用引用了。

 3、引用可以做什么?

最简单的就是传参,例如以前想要改变一个变量的值,那么就需要传递一个指针过去,但是有了引用就轻松多了,可以直接传参过去,然后函数内引用,访问的还是这个变量的地址,效果如图就是利用引用进行传参,还有就是返回值,就是经常使用的函授返回值,例如ADD返回两数相加的和,那么利用引用的话可以直接接收,不会产生临时变量,毕竟函数返回时,在栈帧销毁时,返回的值也是一个局部变量,会在函数结束时,随着栈帧的销毁而销毁,所以函数的返回时本质是创建一个临时变量,进行传参,在销毁,用引用传参如下图所示。

 但是一般的函数是不能这样使用的,因为如果一个函数在销毁后,接着去访问这个地址可能会找到啥?这个是不确定的,因为临时变量是在会销毁的,如果这个空间在销毁时,没被随机值刷新,那么可能会找到正确的值,但是如果这个空间在销毁时被随机值刷新了 ,那么就是访问到随机值,这个就是一个典型的越界访问了,所以这样使用引用时是有限制的,只有在静态变量、全局变量、栈帧还没没有销毁时、malloc等情况下才能用引用去取返回值,其他的情况就需要使用返回值了,那么对比一下引用和返回值的效率吧,代码测试如下图可以看出差别还是挺大的。

#include <time.h>
struct A { int a[10000]; };
void test1(A a) {}
void test2(A& a) {}
void test3()
{
    A a;
    size_t begin1 = clock();
    for (size_t i = 0; i < 100000; ++i)
        test1(a);
    size_t end1 = clock();
    size_t begin2 = clock();
    for (size_t i = 0; i < 100000; ++i)
        test2(a);
    size_t end2 = clock();
    cout << end1 - begin1 << endl;
    cout << end2 - begin2 << endl;
}

int main()
{
    test3();
    return 0;
}

4、引用和指针的区别

在上面说过引用的原理其实就是指针,但是引用和指针还是有点区别的,区别如下:

① 引用概念上定义一个变量的别名,指针存储一个变量地址。

② 引用在定义时必须初始化,指针没有要求

③引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体

④没有NULL引用,但有NULL指针

⑤在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)

⑥引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小

⑦有多级指针,但是没有多级引用

⑧访问实体方式不同,指针需要显式解引用,引用编译器自己处理

⑨引用比指针使用起来相对更安全 

二、内联函数

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调
用建立栈帧的开销,内联函数提升程序运行的效率。

简而言之就是和宏的用处差不多,宏是有缺陷,因为在宏的使用时是直接替换的,这样代码的安全性就大大下降了,总结一下宏的优缺点

优点:

1.增强代码的复用性。

2.提高性能。

缺点:

1.不方便调试宏。(因为预编译阶段进行了替换)

2.导致代码可读性差,可维护性差,容易误用。

3.没有类型安全的检查 。

而内联函数的用法就是和宏差不多,但是它可以把一个函数变成宏,但是有一点就是内联时,函数的代码是要求尽量简短,当然如果过多时编译器依然会把他当成函数处理,在简短 时内联函数就是直接替代,从下图反汇编就可以看出内敛函数是直接替代的,而不是call这个函数但是当行数过多时依然会当成函数调用了,测试如下,就可以看出内联函数也不是所有都可以替代。内联函数也不建议声明和定义分离,分离会导致链接错误。因为内联函数被展开,就没有函数地址了,链接就会找不到

inline int ADD(int a, int b)
{
    return a + b;
}

inline int ADD1(int a, int b, int c)
{
    c = a + b;
    a = a + b;
    b = a + b;
    c = a + b;
    a = a + b;
    b = a + b;
    c = a + b;
    a = a + b;
    b = a + b;
    c = a + b;
    a = a + b;
    b = a + b;
    c = a + b;
    a = a + b;
    b = a + b;
    c = a + b;
    a = a + b;
    c = a + b;
    b = a + b;
    return c;
}
int main()
{
    int ret = ADD(1, 3);
    int ret1 = ADD1(1, 3,2);
    return 0;
}

相关文章:

c++的学习之路:3、入门(2)

一、引用 1、引用的概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空 间&#xff0c;它和它引用的变量共用同一块内存空间。 怎么说呢&#xff0c;简单点理解就是你的小名&#xff0c;家里人叫你小名&#…...

面试经典150题【91-100】

文章目录 面试经典150题【91-100】70.爬楼梯198.打家劫舍139.单词拆分322.零钱兑换300.递增最长子序列77.组合46.全排列39.组合总和&#xff08;※&#xff09;22.括号生成79.单词搜索 面试经典150题【91-100】 五道一维dp题五道回溯题。 70.爬楼梯 从递归到动态规划 public …...

在 nginx 中使用 JavaScript

前些日子尝试了在 nginx 中写 JavaScript 的效果。考虑到 JavaScript 作为编程语言不是强需求&#xff0c;在nginx生态上还是 lua 独大&#xff0c;并且还有 openresty 这样一直强力输血&#xff0c;大部分应用场景都能找到参考的解决方案。 插件生态来说&#xff0c;github 上…...

【pytorch】安装合集

使用conda或者pip安装的指令 https://pytorch.org/get-started/previous-versions/ 测试pytorch_gpu是否可用的代码 # 测试pytorch是否安装成功 import torch print(torch.__version__) print(torch.cuda.is_available())...

【教程】PLSQL查看表属性乱码解决方法

一、前言 PL/SQL是Oracle数据库的编程语言&#xff0c;用于编写存储过程、触发器、函数等。 今天用plsql想查看表的属性&#xff0c;看看各个字段的注释&#xff0c;可是打开一看&#xff0c;居然是乱码的&#xff0c;如下面这样 如果在使用PL/SQL查看表属性时出现乱码&…...

新书速览|Django 5企业级Web应用开发实战:视频教学版

掌握Django框架开发技能&#xff0c;实战投票应用系统和内容管理系统 本书内容 《Django 5企业级Web应用开发实战&#xff1a;视频教学版》精选当前简单、实用和流行的Django实例代码&#xff0c;帮助读者学习和掌握Django 5框架及其相关技术栈的开发知识。本书系统全面、内容…...

excel创建和部分使用

一.excel导出是在开发中经常操作的内容,对于excel的导出也是有各种成熟的api组件 这里是最近的项目有通过ts处理,这里的内容通过ts ①引入const XlsxPopulate require("xlsx-populate"); const XLSXChart require("xlsx-chart"); 通过命令行操作, pnp…...

pycharm使用远程服务器的jupyter环境

1、确保服务器上安装了jupyter,如果没有&#xff0c;执行下面命令安装 pip install jupyter2、启动jupyter notebook服务 jupyter notebook --no-browser --port8888 --ip0.0.0.0 --allow-root表明在服务器的8888 端口上启动 Jupyter Notebook&#xff0c;并允许从任何 IP 地…...

ES6 基础

文章目录 1. 初识 ES62. let 声明变量3. const 声明常量4. 解构赋值 1. 初识 ES6 ECMAScript6.0(以下简称ES6)是JavaScript语言的下一代标准&#xff0c;已经在2015年6月正式发布了。它的目标&#xff0c;是使得」JavaScript语言可以用来编写复杂的大型应用程序&#xff0c;成为…...

【双指针】Leetcode 有效三角形的个数

题目解析 611. 有效三角形的个数 算法讲解 回顾知识&#xff1a;任意两数之和大于第三数就可以构成三角形 算法 1&#xff1a;暴力枚举 int triangleNumber(vector<int>& nums) {// 1. 排序sort(nums.begin(), nums.end());int n nums.size(), ret 0;// 2. 从…...

python项目练习——4.手写数字识别

使用Python和Scikit-learn库进行机器学习模型训练的项目——手写数字识别。 项目分析&#xff1a; 数据准备&#xff1a;使用公开数据集&#xff08;如MNIST&#xff09;作为训练和测试数据。数据预处理&#xff1a;对图像数据进行归一化、展平等操作&#xff0c;以便输入到机…...

【目标检测】NMS算法的理论讲解

将NMS就必须先讲IOU&#xff0c; IOU就是交并比&#xff0c;两个检测框的交集除以两个检测框的并集就是IOU 为什么要做NMS操作&#xff0c;因为要去除同一个物体的多的冗余检测框 那么NMS算法是如何做的呢&#xff1f; 以上是算法的流程图 下面讲解算法的流程 首先输入是预…...

3-iperf3 使用什么工具可以检测网络带宽、延迟和数据包丢失率等网络性能参数呢?

(1)iperf3简介 1.iperf3简介 2.用途&#xff08;特点&#xff09; 3.下载iperf3地址 &#xff08;2&#xff09;实战 1.iperf3参数 &#xff08;1&#xff09;通用参数&#xff08;客户端和服务器端都是适用的&#xff09; &#xff08;2&#xff09;客户端参数 实验1&…...

阳光倒灌高准直汽车抬头显示器HUD太阳光模拟器

阳光倒灌高准直汽车抬头显示器HUD太阳光模拟器是一种高级别的模拟设备&#xff0c;用于模拟太阳光的光谱、强度及照射角度&#xff0c;应用于太阳能电池板、光伏系统等领域的研究和测试。其参数包括光谱范围、光强度、光源、照射角度、均匀性和稳定性&#xff0c;可根据需求调整…...

jdk11中自定义java类在jvm是如何被查找、加载

yym带你了解jvm源码&#xff0c;openjdk11源码&#xff0c;java类jvm加载原理 jdk11中java类在jvm是如何被1查找、2加载 以下说明的是MiDept类是如何被java classloader 和 jvm加载步骤 上源代码 public static void main(String[] args) {Thread.currentThread().setName…...

单片机---独立按键

[3-1] 独立按键控制LED亮灭_哔哩哔哩_bilibili 按下的时候连接&#xff0c;松开的时候断开。 一头接GND&#xff08;电源负极&#xff09;&#xff0c;另一头接I/O口。 单片机上电时&#xff0c;所有I/O口为高电平。 按键没有按下&#xff0c;I/O口为高电平。 按键按下&…...

java分布式面试快问快答

目录 Java分布式面试宝典50题DubboRedisZookeeper分布式系统设计性能优化与监控安全实践经验 解答DubboRedisZookeeper分布式系统性能优化与监控安全 Java分布式面试宝典50题 Java分布式开发涉及到Dubbo、Redis、Zookeeper等技术&#xff0c;这些技术在实际工作中扮演着重要角…...

AI:148-开发一种智能语音助手,能够理解和执行复杂任务

AI&#xff1a;148-开发一种智能语音助手&#xff0c;能够理解和执行复杂任务 1.背景介绍 随着人工智能技术的飞速发展&#xff0c;智能语音助手已经逐渐成为人们日常生活中不可或缺的一部分。从简单的查询天气、播放音乐&#xff0c;到复杂的日程安排、智能家居控制&#xf…...

Kindling the Darkness:A Practical Low-light Image Enhancer

Abstract 在弱光条件下拍摄的图像通常会出现&#xff08;部分&#xff09;可见度较差的情况。,除了令人不满意的照明之外&#xff0c;多种类型的退化也隐藏在黑暗中&#xff0c;例如由于相机质量有限而导致的噪点和颜色失真。,换句话说&#xff0c;仅仅调高黑暗区域的亮度将不…...

图像处理与视觉感知---期末复习重点(4)

文章目录 一、图像复原与图像增强1.1 概述1.2 异同点 二、图像复原/退化模型2.1 模型图简介2.2 线性复原法 三、彩色基础四、彩色模型五、彩色图像处理 一、图像复原与图像增强 1.1 概述 1. 图像增强技术一般要利用人的视觉系统特性&#xff0c;目的是取得较好的视觉效果&…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...