当前位置: 首页 > 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;目的是取得较好的视觉效果&…...

ABAP AMDP 示例

AMDP 是HANA开发中的一种优化模式 按SAP的官方建议&#xff0c;在可以使用Open SQL实现需要的功能或优化目标的时候&#xff0c;不建议使用AMDP。而在需要使用Open SQL不支持的特性&#xff0c;或者是大量处理流和分析导致了数据库和应用服务器之间有重复的大量数据传输的情况…...

发票查验接口C++语言如何集成、发票OCR

说起发票查验工作&#xff0c;繁琐的发票信息录入与反复查验令财务人员头疼不已。数字化时代&#xff0c;企业财务管理的自动化需求越来越高&#xff0c;翔云发票查验API搭配发票识别接口为企业提供一种高效的财务管理解决方案。仅需上传发票图片即可快速提取发票四要素信息&am…...

【图论 | 数据结构】用链式前向星存图(保姆级教程,详细图解+完整代码)

一、概述 链式前向星是一种用于存储图的数据结构,特别适合于存储稀疏图,它可以有效地存储图的边和节点信息,以及边的权重。 它的主要思想是将每个节点的所有出边存储在一起,通过数组的方式连接(类似静态数组实现链表)。这种方法的优点是存储空间小,查询速度快,尤其适…...

【蓝桥杯3.23小白赛】(详解)

第一题签到题不多说 【二进制王国】 #include <iostream> #include <vector> #include <algorithm> using namespace std;//int Cmp(string s1, string s2)测试了一下时间差确实很明显&#xff0c;还是用下面的内个 int Cmp(const string &s1,const st…...

设计模式之抽象工厂模式精讲

概念&#xff1a;为创建一组相关或相互依赖的对象提供一个接口&#xff0c;而且无须指定他们的具体类。 抽象工厂模式是工厂方法模式的升级版本。在存在多个业务品种或分类时&#xff0c;抽象工厂模式是一种更好的解决方式。 抽象工厂模式的UML类图如下&#xff1a; 可以看…...

初识云原生、虚拟化、DevOps

文章目录 K8S虚拟化DevOpsdevops平台搭建工具大数据架构 K8S master 主节点&#xff0c;控制平台&#xff0c;Master节点负责核心的调度、管理和运维&#xff0c;不需要很高性能&#xff0c;不跑任务&#xff0c;通常一个就行了&#xff0c;也可以开多个主节点来提高集群可用度…...

怎麼實現Nginx反向代理?

Nginx是一款開源軟體&#xff0c;可以作為Web伺服器、負載均衡器和反向代理使用&#xff0c;是高性能的HTTP和反向代理伺服器。其中反向代理是Nginx的一項重要特性。接下來&#xff0c;我們詳細講一下Nginx反向代理的實現和應用。 反向代理是什麼&#xff1f; 代理一詞通常指的…...

IOS面试题编程机制 71-75

71. 简述有哪几种手势通知方法?-(void)touchesBegan:(NSSet*)touchedwithEvent:(UIEvent*)event; -(void)touchesMoved:(NSSet*)touched withEvent:(UIEvent*)event; -(void)touchesEnded:(NSSet*)touchedwithEvent:(UIEvent*)event; -(void)touchesCanceled:(NSSet*)touchedw…...

JMeter元件作用域和执行顺序

JMeter元件作用域和执行顺序 元件的基本介绍基本元件总结 作用域的基本介绍作用域的原则元件执行顺序Jmeter第一个案例&#xff1a; Jmeter三个重要组件&#xff08;重点&#xff09;线程组特点线程组分类线程组的属性案例分析 HTTP请求案例一&#xff08;使用HTTP请求路径来传…...

Jmeter 聚合报告之 90% Line 正确理解

今天看了些关于Jmeter 聚合报告之 90% Line 的一些博客 关于90% Line 的算法各有各自的见解 。 90%Line可以用公式计算&#xff1a; 100/总个数每一个所占的百分比&#xff0c;90%/每一个所占的百分比90%Line的序号&#xff08;从小到大排&#xff09; 例如&#xff1a;1.2.3.…...