C++入门基础(二)
6. 引用(引用就是取别名)
6.1 引用的概念和定义
引用不是新定义一个变量,而是给已存在变量取了⼀个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。比如:水浒传中李逵,宋江叫"铁牛",江湖上人称"黑旋风";林冲,外号豹子头;
类型& 引用别名 = 引用对象;
C++中为了避免引入太多的运算符,会复用C语言的⼀些符号,比如前面的<< 和 >>,这里引用也和取地址使用了同⼀个符号&,大家注意使用方法角度区分就可以。
int a = 0;
// 引⽤:b和c是a的别名
int& b = a;
int& c = a;
// 也可以给别名b取别名,d相当于还是a的别名
int& d = b;

这串代码在底层的角度是这样的

对指针变量取别名:
int* p1 = &a;
int*& p2 = p1;
指针变量的使用: 
typedef struct ListNode
{
int val;
struct ListNode* next;
}LTNode, *PNode;
int main()
{
PNode plist = NULL;
ListPushBack(plist, 1);
return 0;
}
这里的*PNode是指把typedef struct ListNode* 定义为PNode。
6.2 引用的特性

这里的d的地址没变,说明d还是a的别名,d没有指向e,只是把e的值赋给了d。
当我们实现链表的时候,我们要删除一个结点,但这时的地址之间是相互关联的,因为引用不能改变指向,所以就不可能完成。所以C++的指针引用不能完全替代指针。

6.3 引用的使用
减少拷贝的案例:


传值传参会生成一个拷贝,传值返回也会生成一个拷贝。C++中是这样规定的,在红线这里进行一个传值返回,返回这个对象的时候, 他不会引用这个对象做函数调用的返回值,不会返回要返回的东西,它会生成一个临时对象,把这的值给临时变量,再用临时变量做这个整个表达式的返回值。STTop(st1)+=1;这是的加1就是加到临时对象上面。临时对象具有常性。
那临时对象是什么呢?
临时变量通常是指编译器在栈里面临时开一块空间存储中间值的这种,也有可能是用寄存器去存。
这里如何使用STTop(st1)+=1呢?只需要采用引用返回就可以了。传引用返回就是返回他的别名,也就是这里的2。也就a数组指向的top-1这里的对象。这时候就把引用对象给改变了。


typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;void STInit(ST& rs, int n = 4)
{
rs.a = (STDataType*)malloc(n * sizeof(STDataType));
rs.top = 0;
rs.capacity = n;
}// 栈顶
void STPush(ST& rs, STDataType x)
{
// 满了, 扩容
if (rs.top == rs.capacity)
{
printf("扩容\n");
int newcapacity = rs.capacity == 0 ? 4 : rs.capacity * 2;
STDataType* tmp = (STDataType*)realloc(rs.a, newcapacity *
sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail");
return;
}
rs.a = tmp;
rs.capacity = newcapacity;
}
rs.a[rs.top] = x;
rs.top++;
}
int& STTop(ST& rs)
{
assert(rs.top > 0);return rs.a[rs.top - 1];
}
int main()
{
ST st1;
STInit(st1);
STPush(st1, 1);
STPush(st1, 2);
cout << STTop(st1) << endl;
//修改栈顶的数据呢
(STTop(st1)) += 1;
cout << STTop(st1) << endl;
return 0;
}
其实指针也可以做到:

并不是任何场景都能用引用返回(后面结合类和对象讲),比如说:

ret是局部变量,这里类似于野引用。
int* fun( )
{
int ret = 10;
return *ret;
}
这里的指针就越界了,指针越界不一定报错。


在vs中设置了抽查位置,这两个位置不分配给别人,给两个固定的值,在程序运行结束时看这两个位置的值有没有发生改变,没有被修改就说明没有越界。
6.4 const引用



这里是把x的这块空间拷贝给给y,x不能修改这块空间。
下面这个也是经典的权限放大:

下图这个是权限的缩小:


p1对于a的权限是只读不能写的,p1拷贝给给p2,p2又变成可读可写的了,p2的权限被放大,p5指向b的权限是可读可写的,p6指向p5也是可读可写的(这里不存在权限放大,因为const修饰的是p5本身不是指向的内容)。

a * 3这里存在一个临时变量,临时变量具有常性,这里加个const就行了。

这里的d给给rd其实也不是直接给过去的,中间也会产生一个临时变量来存储中间的结果。d给给中间的临时对象,这个临时对象是int类型,临时对象再给给rd。

类型转换会产生临时对象,d给了临时对象,这里的临时对象给给rd。也就是说rd引用了临时对象。
那上面这些到底有什么用呢?
这里的传值传参就不说了,对于引用传参
void fun(int& rx)如果变量 rx 不改变形参,建议前面加 const,void fun(const int& rx),加const的好处是什么呢?传参就非常宽泛。

const引用的价值是什么?
1.可以引用const对象
2.可以引用普通对象
3.可以引用临时对象
6.5 指针和引用的关系
野引用的案例:

从底层汇编的角度看,引用也是用指针实现的。
7. inline


可执行程序是一个文件,它会以一个进程的角度来进行运行(可执行程序会生成一个进程),进程才会给它分配内存,进程会把可执行程序的那个指令加载到内存的里面。
10000*100是指10000行指令*100行Add的指令总和的指令,10000+100是指10000行指令+100行Add的指令总和的指令。内联展开会导致一个问题:代码膨胀,代码膨胀会导致可执行程序变大,可执行程序变大,加载到进程也会变大,加载到内存导致内存变大。(可执行程序就是安装包)

// F.h# include <iostream>using namespace std;inline void f ( int i);// F.cpp# include "F.h"void f ( int i){cout << i << endl;}// text.cpp# include "F.h"int main (){
// 链接错误:⽆法解析的外部符号 "void __cdecl f(int)" (?f@@YAXH@Z)f ( 10 );return 0 ;}//那要怎么做呢?把// F.cpp这个文件中的f(int i)给注释掉# include "F.h"//void f ( int i)//{//cout << i << endl;//}在// F.h中定义inline void f ( int i){cout << i << endl;}
// 实现⼀个Add宏函数的常见问题
//#define Add(int a, int b) return a + b;//#define Add(a, b) a + b;//#define Add(a, b) (a + b)// 正确的宏实现(宏本质是一种替换)//宏函数坑很多,但是由于替换机制,调用函数时不用建立函数栈帧,能做到提效的作用。# define Add(a, b) ((a) + (b))// 为什么不能加分号 ?int main(){int ret = Add(1,2);//这里是将a替换成1,b替换成2;//int ret = Add(1,2);;//在这种场景下不会有问题cout << Add(1,2) << endl;//如果加分号在这种情况下就会报错,还有下面这种if(Add(1,2)){//...}cout << ret << endl;}// 为什么要加外⾯的括号 ?//有下面这种情况int main(){int ret = Add(1,2);//这里是将a替换成1,b替换成2;//int ret = Add(1,2);;cout << Add(1,2)*3 << endl;//cout << (1) + (2) * 3 << endl;}// 为什么要加里面的括号 ?int main(){int x =1,y = 2;Add(x & y ,x | y); // -> (x & y + x | y)}
8. nullptr
#ifndef NULL
#ifdef __cplusplus
#define NULL 0//C++
#else
#define NULL ((void *)0)//C语言
#endif
#endif
• C++11中引入nullptr,nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字⾯量,它可以转换 成任意其他类型的指针类型。使用nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被 隐式地转换为指针类型,而不能被转换为整数类型。
相关文章:
C++入门基础(二)
6. 引用(引用就是取别名) 6.1 引用的概念和定义 引用不是新定义一个变量,而是给已存在变量取了⼀个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。比如:水浒传中李逵&…...
fabricjs 实现图像的二值化功能
一、效果图 二、图像二值化的作用 二值化是图像处理中常用的一种方法,其作用是将灰度图像转换为二值图像,即将图像中的像素点根据其灰度值分成两类:黑色和白色。这种处理方法可以帮助我们更清晰地识别图像中的目标,简化图像的复杂…...
修改本地hosts文件及外部访问机器本地hosts文件后,rancher UI网站仍然不能访问
原因排查 kubectl get svc # 输出: NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d17hkubectl get svc -A # 输出: NAMESPACE …...
西北潮榆林范儿,新榆林首个360°沉浸式剧场发布会闪耀亮相
这是一场城市更迭的未来大赏,也是一场商业蝶变的复合对话 8月3日,朗阁集团商业品牌发布会在榆林银杏熙悦酒店隆重启幕。朗阁集团董事长杨志成携众多集团领导出席;多家主流媒体代表联袂参加;喜茶、中影时光国际影城、汉堡王、鲍师傅…...
如何创建响应式移动端网页设计?最佳实践详解
移动端网页设计是一个耗时而复杂的过程开发,包括UI设计、UX设计、检测、发布、改进、维护和持续的错误修复。通过学习这篇文章,你将掌握什么是移动端网页,如何制作移动端网页,以及设计网页的技巧。 什么是移动端网页?…...
Python 如何进行Web抓取(BeautifulSoup, Scrapy)
Web抓取(Web Scraping)是一种从网站提取数据的技术。Python有许多用于Web抓取的库,其中最常用的是BeautifulSoup和Scrapy。 BeautifulSoup BeautifulSoup是一个用于解析HTML和XML文档的Python库,适合处理简单的Web抓取任务。它将…...
白骑士的PyCharm教学进阶篇 2.5 数据库连接与管理
系列目录 上一篇:白骑士的PyCharm教学进阶篇 2.4 Django开发支持 在Web开发中,数据库是必不可少的部分。PyCharm不仅是一款功能强大的IDE,还提供了丰富的数据库连接和管理工具,使开发者可以更方便地浏览和操作数据库。本篇将详细…...
(五)activiti-modeler 编辑器初步优化
最终效果: 1..首先去掉顶部的logo,没什么用,还占用空间。 修改modeler.html文件,添加样式: <style type"text/css"> #main-header{display: none; } #main{padding: 0px; } </style> 2.左边组…...
(学习总结12)C++类和对象3
C类和对象3 一、初始化列表二、类型转换三、static成员四、友元五、内部类六、匿名对象 以下代码环境在 VS2022。 一、初始化列表 之前我们实现构造函数时,初始化成员变量主要使用函数体内赋值,构造函数初始化还有⼀种方式,就是初始化列表&a…...
docxtpl,一个强大的 Python 库!
更多资料获取 📚 个人网站:ipengtao.com 大家好,今天为大家分享一个强大的 Python 库 - docxtpl。 项目地址:https://docxtpl.readthedocs.io/en/latest/ 在日常工作中,自动生成和处理 Word 文档是一个常见需求。doc…...
捷途山海T2:超长续航,节能环保的驾驶新星
在当今的汽车市场中,消费者的购车选择日趋多样化,不再仅限于传统的燃油车。随着环保理念的深入人心以及人们对用车成本的日益关注,像捷途山海T2这样配备高效混动系统的车型逐渐受到大众的青睐。 捷途山海T2,以其杰出的节能性、强劲…...
[Day 45] 區塊鏈與人工智能的聯動應用:理論、技術與實踐
區塊鏈的可擴展性挑戰 概述 區塊鏈技術在過去幾年中取得了顯著的進展,其去中心化、透明和安全的特性使其在金融、供應鏈管理、醫療等領域得到了廣泛應用。然而,區塊鏈技術的一個重大挑戰是其可擴展性。可擴展性是指系統能夠有效處理日益增長的數據和用…...
白骑士的PyCharm教学实战项目篇 4.3 自动化测试与持续集成
系列目录 上一篇: 在现代软件开发过程中,自动化测试与持续集成(CI)是确保代码质量和快速交付的关键环节。PyCharm作为一款强大的集成开发环境(IDE),为自动化测试和持续集成提供了全面的支持。本…...
权限模块开发+权限与角色关联(完整CRUD)
文章目录 🌞 Sun Frame:SpringBoot 的轻量级开发框架(个人开源项目推荐)🌟 亮点功能📦 spring cloud模块概览常用工具 🔗 更多信息1.easycode生成代码1.配置2.AuthPermissionDao.java剪切到mapp…...
llama神经网络的结构,llama-3-8b.layers=32 llama-3-70b.layers=80; 2000汉字举例说明
目录 llama-3-8b.layers=32 llama-3-70b.layers=80 llama神经网络的结构 Llama神经网络结构示例 示例中的输入输出大小 实际举例说明2000个汉字文本数据集 初始化词嵌入矩阵 1. 输入层 2. 嵌入层 3. 卷积层 4. 全连接层 llama-3-8b.layers=32 llama-3-70b.laye…...
单细胞数据怎么表现genes mRNA表达的热图?
愿武艺晴小朋友一定得每天都开心 #热图 library("ComplexHeatmap") exp <- AverageExpression(subset(fasting_memory, Celltype %in% c("Pre-B")), layer = "data", #即CPM值 features …...
Java聚合快递对接云洋系统小程序源码
🚀【物流新纪元】聚合快递如何无缝对接云洋系统,效率飙升秘籍大公开!✨ 🔍 开篇揭秘:聚合快递的魅力所在 Hey小伙伴们,你是否还在为多家快递公司账号管理繁琐、订单处理效率低下而头疼?&#…...
MySQL——数据表的基本操作(三)修改数据表
有时候,希望对表中的某些信息进行修改,这时就需要修改数据表。所谓修改数据表指的是修改数据库中已经存在的数据表结构,比如,修改表名、修改字段名、修改字段的数据类型等。在 MySQL中,修改数据表的操作都是使用 ALTER…...
医学图像分割的基准:TransUnet(用于医学图像分割的Transformer编码器)器官分割
1、 TransUnet 介绍 TransUnet是一种用于医学图像分割的深度学习模型。它是基于Transformer模型的图像分割方法,由AI研究公司Hugging Face在2021年提出。 医学图像分割是一项重要的任务,旨在将医学图像中的不同结构和区域分离出来,以便医生可…...
java-swing编写学生成绩查询管理系统
本文是本人大二上实训项目-学生成绩查询管理系统,采用本项目使用Java、MySQL技术。界面框架由Java Swing搭建,用JDBC实现Java与MySQL的连接。 本项目适合初学java和mysql的同学,来做一些小项目来提升自己,因为兴趣所以想要做去尝…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
