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

C++入门-引用

C++入门-引用

  • 前置知识点:函数栈帧的复用
  • 前置知识点:类型转换时产生的临时变量
  • 1.含义
  • 2.代码形式
  • 3.引用的价值
    • 1.传参数
      • 传参效率测试
      • 补充:C++与Java中引用的区别
    • 2.引用做返回值(前置知识:栈帧复用)
      • 1.传值返回
      • 2.传引用返回
      • 传引用返回并用引用接收
      • 3.静态变量传引用返回
      • 4.引用做返回值真正的价值
  • 4.常引用(前置知识:类型转换时产生的临时变量)
  • 5.引用的底层实现
  • 6.引用和指针的区别

注意:引用的价值无法再这一节中全部说完,引用的更大价值在类和对象当中有所体现

前置知识点:函数栈帧的复用

首先请大家看一句话:

时间是一去不复返的
而空间是可以重复利用的

结合我们的日常生活,这句话没毛病,同样的,在C和C++中也是如此

其中空间是可以重复利用的这一点就被函数栈帧的复用所深刻地体现出来了
其中函数栈帧的销毁并不是说把这块内存空间销毁了,而是把这块内存空间的管理权归还给操作系统了,而申请内存空间就是向操作系统申请一块内存空间的管理权

释放空间就像是酒店退房间一样,退了的房间还能再租给下一个客人

下面写一份代码让大家更清晰的看一下

在这里插入图片描述
如图我们可以看出test1函数跟test2函数相继调用,在test1函数的栈帧销毁之后,再建立了test2函数的栈帧

我们发现a和b的地址相同,这也就说明了函数栈帧的复用

为什么a和b的地址会相同呢?
1.函数栈帧的复用
2.a和b的都是同大小的变量

如果我们修改一下test2函数的代码
在这里插入图片描述
我们发现,a和x的地址相同,但是a跟b的地址不相同了,
这个说明了即使函数内部所使用的空间大小不同,但是依然会进行函数栈帧的复用

所有的函数相继调用时都会复用上一个战帧
只不过开的栈帧的大小不同

这里先介绍一下函数栈帧的复用,为了后面讲解引用作为返回值的地方打下基础

前置知识点:类型转换时产生的临时变量

类型转换会产生临时变量!!!,临时变量具有常性,也就是不能再被修改了

在这里插入图片描述

1.含义

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

C++对C语言最大的改进:引用
因为C++设计者极其不喜欢指针,认为指针太麻烦
在语法上讲:引用就是取别名

2.代码形式

int main()
{int a = 1;int b = a;//把a的值拷贝给b//c是a的别名//c和a共用一块内存空间int& c = a;b++;cout << a << endl;//1c--;cout << a << endl;//0//取多少别名都可以//也就是说一个对象可以有多个引用int& d = a;//这么取别名也可以(也可以给别名取别名)int& e = d;//a,c,d,e的地址是一样的cout << &a << endl;cout << &c << endl;cout << &d << endl;cout << &e << endl;/*0031FC380031FC380031FC380031FC38*/return 0;
}

3.引用的价值

1.传参数

引用还可以再传参的时候提升效率,不用再去额外的开辟空间

比方说我们要实现一个Swap函数交换两个整形变量

void Swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}
//这两个函数构成重载
void Swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}
int main()
{int num1 = 1, num2 = 2;Swap(&num1, &num2);cout << num1 << " " << num2 << endl;Swap(num1, num2);cout << num1 << " " << num2 << endl;/*2 11 2*/return 0;
}

学习了引用之后,我们就能对单链表进行优化了
在这里插入图片描述
在这里插入图片描述
单链表是不可以传入一级指针建表的,除非你虚拟一个哨兵位的头节点,但是不推荐这样做
在这里插入图片描述
这里传入的实参是一个一级指针,如果传入的那个一级指针是一个NULL指针的话,如果我们的形参也是一个一级指针的话,只能改变这个结构体的成员
(可以改变next指针,增长这个链表的长度)
无法改变这个指针本身(因为形参的改变不会影响实参)

也就是说如果传入的这个链表不是空链表的话,传一级指针可以
但是如果传入的是一个空链表,想要改变这个空链表,那么只能传二级指针
在这里插入图片描述
这里SListPushBack(LNode** pphead,int x);
中的*pphead就是传入的plist

但是传二级指针未免有些麻烦了吧,但是引用可以让我们继续只需要传一级指针

typedef struct ListNode
{struct ListNode* next;int val;
}LNode,*PLNode;//PLNode:结点指针的typedef,也就是一个结构体指针
LNode* CreateNode(int x)
{LNode* newnode = (LNode*)malloc(sizeof(LNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->val = x;newnode->next = NULL;return newnode;
}
//二级指针版本
void SListPushBack(LNode** pphead, int x)
{LNode* newnode = CreateNode(x);if (*pphead == NULL){//没有头节点*pphead = newnode;}else{//找尾指针,再链接newnodeLNode* tail = *pphead;while (tail->next){tail = tail->next;}tail->next = newnode;}
}//phead是plist2的一个别名,也就是说phead就是plist2
void SListPushBack1(PLNode& phead, int x)
{PLNode newnode = CreateNode(x);if (phead == NULL){//没有头节点phead = newnode;}else{//找尾指针,再链接newnodePLNode tail = phead;while (tail->next){tail = tail->next;}tail->next = newnode;}
};
//phead是plist3的一个别名,也就是说phead就是plist3
void SListPushBack2(LNode*& phead, int x)
{LNode* newnode = CreateNode(x);if (phead == NULL){//没有头节点phead = newnode;}else{//找尾指针,再链接newnodeLNode* tail = phead;while (tail->next){tail = tail->next;}tail->next = newnode;}
};void SListPrint(LNode* phead)
{LNode* cur = phead;while (cur){cout << cur->val << " -> ";cur = cur->next;}cout << endl;
}int main()
{LNode* plist1 = NULL;SListPushBack(&plist1, 1);SListPushBack(&plist1, 2);SListPushBack(&plist1, 3);SListPushBack(&plist1, 4);SListPrint(plist1);PLNode plist2 = NULL;SListPushBack1(plist2, 1);SListPushBack1(plist2, 2);SListPushBack1(plist2, 3);SListPushBack1(plist2, 4);SListPrint(plist2);LNode* plist3 = NULL;SListPushBack2(plist3, 1);SListPushBack2(plist3, 2);SListPushBack2(plist3, 3);SListPushBack2(plist3, 4);SListPrint(plist3);/*1 -> 2 -> 3 -> 4 ->1 -> 2 -> 3 -> 4 ->1 -> 2 -> 3 -> 4 ->*/return 0;
}

传参效率测试

那么引用传参比起值传参来效率的提升能有多大呢?
我们来测试一下:
在这里插入图片描述
可见引用传参比起值传参还是有一定效率提升的,不过比起指针传参来,效率提升并不是很大,因为传指针也就多开辟4或者8个字节而已

补充:C++与Java中引用的区别

既然引用这么好,那么是不是C++就可以跟Java一样不需要指针了?
答案是:并不是这样的,C++中指针和引用是相辅相成的两种语法,缺一不可
而Java中的确不需要指针

为什么呢?

int main()
{int a = 10;int& b = a;int c = 16;//请问:b=c;这行代码是什么意思?//选项1:b不再是a的别名,而是成为了c的别名//选项2:b和a赋值为cb = c;cout << "&a = " << &a << endl;cout << "&b = " << &b << endl;cout << "&c = " << &c << endl;cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;return 0;
}

请大家先结合我们所学过的指针的特性来选择一下
在这里插入图片描述
选项2是正确的,也就是说b依然是a的别名,只不过a(也就是b)的值被赋值为16而已

但是如果是指针的话,情况就不一样了

int main()
{int a = 10;int* b = &a;int c = 16;b = &c;cout << "&a = " << &a << endl;cout << "b = " << b << endl;cout << "&c = " << &c << endl;cout << "a = " << a << endl;cout << "*b = " << *b << endl;cout << "c = " << c << endl;return 0;
}

在这里插入图片描述
在这里插入图片描述

2.引用做返回值(前置知识:栈帧复用)

引用的第二大价值:引用作为返回值

1.传值返回

下面我们来看一个函数

int Count()
{int n=0;n++;return n;
}

这里return n;
返回的并不是n,而是n的一个拷贝,这个拷贝是一个临时变量,具有常属性,
是一个右值,而不是左值

因为当Count函数调用完了之后Count函数的栈帧会销毁,所以再返回n的时候要先对返回值n进行拷贝,并把拷贝的临时变量返回给调用方,然后Count函数就可以安心的销毁了

2.传引用返回

int& Count()
{int n=0;n++;return n;
}

在这里插入图片描述
在这里插入图片描述

出了作用域,返回对象就销毁了,不能用引用返回,否则结果是不确定的

在这里插入图片描述
在这里尽管我们加上了这几行,不过也依然不会让ret变为随机值,
因为我们每次调用完Count时都会立即用ret来接收n,ret已经保存了n的值,
继续使用cout来开辟栈帧并不会影响ret的值
所以打印出来的依然是1

传引用返回并用引用接收

如果我们用引用去接收引用的返回值呢?

这样的话会有很多坑点,有很多程序的运行结果是无法解释的,
因为传引用返回本来就是个非常严重的错误,你还用引用接收,那错误更加严重了

这就像是薛定谔的猫,猫到底是死的还是活的你并不知道
到底是随机值还是原数值你也并不知道

这是给大家举的一些样例:
1.
在这里插入图片描述
第二次变成了随机值
2.
但是如果我们在两次cout当中再次调用Count函数的话
在这里插入图片描述
根据前面讲过的函数的栈帧复用原则,在第二次调用Count函数时新开辟的Count函数栈帧会复用第一次调用Count函数时开辟的栈帧,第二次调用Count函数时n的地址跟第一次的相等

而ret是通过引用接收的n,所以说ret就是n的别名,显然两次ret的地址也相同
在这里插入图片描述
所以两次ret的值也是1(VS编译器下)或者随机值

在这里插入图片描述
在这里第二次调用Add函数的时候,复用了第一次调用Add函数时所产生的栈帧,所以c的地址不变,值变为了7或者随机值

3.静态变量传引用返回

那么什么时候可以传引用返回呢?
1.堆上的数据
2.静态变量
反正只要不是局部变量就可以传引用返回(只要除了作用域后并没有销毁即可)

//局部的静态变量只初始化一次
//静态变量只在第一次调用的时候被初始化
int& Add1(int a, int b)
{static int c = a + b;return c;
}int& Add2(int a, int b)
{static int d;d = a + b;return d;
}int main014()
{int& ret = Add1(1, 2);cout << ret << endl;//3Add1(3, 4);cout << ret << endl;//3int& ret2 = Add2(1, 2);cout << ret2 << endl;//3Add2(3, 4);cout << ret2 << endl;//7return 0;
}

4.引用做返回值真正的价值

1:提高效率
2:后面在类和对象当中会有体现,到时候会详细说明的

这里先以静态的顺序表作为一个例子来看一下引用作为返回值的价值

//这里还没有对数组a进行初始化
//静态顺序表
typedef struct SeqList
{int a[100];int size = 100;
}SL;
#include <assert.h>
void SLModify(SL* ps,int pos,int x)
{assert(ps);assert(pos >= 0 && pos < ps->size);ps->a[pos] = x;
}
//应用于at函数
//这里要用引用返回:可以修改返回对象
//在类和对象当中有很广泛的作用
int& SLat(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);return ps->a[pos];
}
int main()
{SL sl;//想要修改顺序表,让每个位置的值++//这样做的话就很方便,比返回指针方便//后面还会有一些场景是指针解决不了的,必须要使用引用for (int i = 0; i < sl.size; i++){SLat(&sl, i)++;//SLat(&sl,i):想打印打印,想赋值赋值,想修改修改}return 0;
}

4.常引用(前置知识:类型转换时产生的临时变量)

引用跟指针类似,也存在const修饰的引用

权限放大只存在于引用和指针当中

const用于形参 修饰引用/指针
也叫做:预防性编程

int main016()
{const int a = 10;int& b = a;//err,这时b不能作为a的别名//因为a是常变量,不能修改,但是如果b又作为a的别名,但是b又不具有常属性,所以不能这样//这里的本质是权限的放大//权限可以不变,可以变小,但是不可以放大const int& b = a;//yes,权限没有变大int c = 20;const int& d = c;//yes,权限可以缩小const int& e = 10;//yes,可以的,因为e具有常属性,跟10都是不可以改变的,也就是说权限并未放大int& f = 10;//err,权限放大const int f = 10;int g = f;//可以,g是f的值拷贝,跟权限无关,g跟f不是同一块空间int i = 1;double j = i;double& k = i;//err,为什么不可以呢?const double& l = i;//这里是可以的,本质还是权限放大缩小的问题//类型转换会产生临时变量!!!!!!,临时变量具有常性,也就是不能再被修改了//所以加上const就行了return 0;
}

5.引用的底层实现

引用底层是用汇编实现的,是用指针实现的,也就是说引用在底层上是跟指针一样都开辟了空间的

但是语法上认为引用并没有开辟空间,认为引用就是取别名,语法上并不管底层是如何实现的

日常学习中我们以语法为主,认为引用没有开辟空间的

1.证明引用的底层跟指针一样

int main()
{int a = 10;int& b = a;int* ptr = &a;return 0;
}

我们查看汇编代码:
在这里插入图片描述
发现引用跟指针的汇编代码极其相似,也就证明了引用在底层上是通过指针实现的

2.证明在语法上引用并没有开辟空间

int main()
{//证明在语法上引用并没有开辟空间//语法上不管底层:char ch = 'x';char& r = ch;cout << sizeof(r) << endl;//1//底层上r开了4个或者8个字节,因为底层上引用是用指针实现的//但是语法上r就是char类型,就是1个字节return 0;
}

6.引用和指针的区别

引用和指针(更多是使用上和概念上的区别)

引用更加安全一些,但是引用不是绝对安全,只是相对指针来说更安全
引用也可能会出现"野引用"的情况,此时并不安全
在这里插入图片描述

以上就是C++入门-引用的全部内容,希望能对大家有所帮助,谢谢大家!

相关文章:

C++入门-引用

C入门-引用 前置知识点:函数栈帧的复用前置知识点:类型转换时产生的临时变量1.含义2.代码形式3.引用的价值1.传参数传参效率测试补充:C与Java中引用的区别 2.引用做返回值(前置知识:栈帧复用)1.传值返回2.传引用返回传引用返回并用引用接收3.静态变量传引用返回4.引用做返回值真…...

问题:Qt中软件移植到笔记本中界面出现塌缩

这是由于软件之前运行的设备DPI较低&#xff0c;移植到笔记本中显示设备DPI较高&#xff0c;导致窗体显示进行了缩放。 解决方案&#xff0c;在main.cpp中加入以下代码&#xff1a; if(QT_VERSION>QT_VERSION_CHECK(5,6,0)) QCoreApplication::setAttribute(Qt::AA_EnableHi…...

NDK编译脚本:Android.mk or CMakeLists.txt

本文来自于&#xff1a;https://github.com/xufuji456/FFmpegAndroid/blob/master/doc/NDK_compile_shell.md 前言 Android NDK以前默认使用Android.mk与Application.mk进行构建&#xff0c;但是在Android Studio2.2之后推荐使用CMake进行编译。 CMake是跨平台编译工具&#…...

低代码提速应用开发

低代码介绍 低代码平台是指一种能够帮助企业快速交付业务应用的平台。自2000年以来&#xff0c;低代码市场一直充斥着40大大小小的各种玩家&#xff0c;比如国外的Appian、K2、Pega Systems、Salesforce和Ultimus&#xff0c;国内的H3 BPM。 2015年以后&#xff0c;这个市场更是…...

Hi3516DV500 SVP_NNN添加opencv库记录

默认没有带opencv库&#xff0c;但是实际项目中需要用到opencv库&#xff0c;因此添加一下此库&#xff1b; 1&#xff1a;编译opencv源码&#xff0c;这里具体可以参考 海思Hi3516移植opencv以及错误调试_海思hi3516摄像头开发-CSDN博客 2&#xff1a;在工程的根目录下新建…...

BIO实战、NIO编程与直接内存、零拷贝深入剖析

原生 JDK 网络编程 BIO BIO&#xff0c;意为 Blocking I/O&#xff0c;即阻塞的 I/O。   BIO 基本上就是我们上面所说的生活场景的朴素实现。在 BIO 中类 ServerSocket 负责绑定 IP 地址&#xff0c;启动监听端口&#xff0c;等待客户连接&#xff1b;客户端 Socket 类的实例…...

计网第六章(应用层)(四)(电子邮件)

电子邮件采用客户/服务器的方式。 1、三个构成 电子邮件系统的三个组成构件&#xff1a;用户代理、邮件服务器以及电子邮件所需的协议。 用户代理是用户与电子邮件系统的接口&#xff0c;又称为电子邮件客户端软件。 邮件服务器是电子邮件系统的基础设施。因特网上所有的服…...

Lua篇笔记

. 和 : 的区别 lua的面向对象 Lua数据类型 nil number bool table string userdata thread function Lua-字符串连接 C#与Lua交互过程及原理 Lua中的闭包 常见的一些Lua功能 热重载&#xff1a; function reload_module(module_name) local old_module _G[module_name] --取…...

一种更具破坏力的DDoS放大攻击新模式

近日&#xff0c;内容分发网络&#xff08;CDN&#xff09;运营商Akamai表示&#xff0c;一种使网站快速瘫痪的DDoS放大攻击新方法正在被不法分子所利用。这种方法是通过控制数量巨大的中间设备&#xff08;middlebox&#xff0c;主要是指配置不当的服务器&#xff09;&#xf…...

WordPress 常规设置页面调用媒体中心上传图片插入URL(新版可用)

首先&#xff0c;我们需要在主题或插件文件夹中创建一个 JavaScript 文件&#xff08;如&#xff1a;media-uploader.js&#xff09;&#xff0c;该文件中包含如下代码。 /*** 媒体中心上传 js **/ jQuery(document).ready(function($){var mediaUploader;$(#upload_image_but…...

Elasticsearch实现检索词自动补全(检索词补全,自动纠错,拼音补全,繁简转换) 包含demo

Elasticsearch实现检索词自动补全 自动补全定义映射字段建立索引测试自动补全 自动纠错查询语句查询结果 拼音补全与繁简转换安装 elasticsearch-analysis-pinyin 插件定义索引与映射建立拼音自动补全索引测试拼音自动补全测试繁简转换自动补全 代码实现demo结构demo获取 自动补…...

LaunchView/启动页 的实现

1. 创建启动画板&#xff0c;LaunchScreen.storyboard 添加组件如图: 2. 项目中设置只支持竖屏&#xff0c;添加启动画板&#xff0c;如图: 3. 创建启动画面动画视图&#xff0c;LaunchView.swift import SwiftUI/// 启动视图 struct LaunchView: View {/// 字符串转换为字符串…...

windows安装npm教程

在安装和使用NPM之前&#xff0c;我们需要先了解一下&#xff0c;NPM 是什么&#xff0c;能干啥&#xff1f; 一、NPM介绍 NPM&#xff08;Node Package Manager&#xff09;是一个用于管理和共享JavaScript代码包的工具。它是Node.js生态系统的一部分&#xff0c;广泛用于构…...

网络端口验证

网络端口连通性验证 1、背景2、目标3、环境4、部署4.1、准备工作4.2、安装4.3、场景测试 1、背景 在日常运维过程中经常会遇到以下两种场景&#xff1a; 1、程序业务端口的开具及验证 2、业务程序访问异常网络排障 2、目标 1、验证端口的正确开具 2、网络策略的连通性 3、环…...

MongoDB 索引和常用命令

一、基本常用命令 1.1 案例需求 存放文章评论的数据存放到 MongoDB 中&#xff0c;数据结构参考如下&#xff0c;其中数据库为 articledb&#xff0c; 专栏文章评论 comment 字段名称 字段含义 字段类型 备注 _id ID ObjectId或String Mongo的主键的字段 articlei…...

【超详细】win10安装docker

win10安装docker 因为要在win10复现一个CVE漏洞&#xff0c;需要用到docker所以特地自己亲自安装了一下&#xff0c;其实在win10上安装docker与在Linux上面的原理一致&#xff0c;都是将docker安装在虚拟机里&#xff0c;不同的是win10是安装在Hyper-V虚拟机上的&#xff0c;需…...

JVM调优(一)

什么时候会有内存泄漏&#xff0c;怎么排查&#xff1f; 答&#xff1a; 首先内存泄漏是堆中的一些对象不会再被使用了&#xff0c;但是无法被垃圾收集器回收&#xff0c;如果不进行处理&#xff0c;最终会导致抛出 java.lang.OutOfMemoryError 异常。 内存泄露&#xff1a; …...

Parallels Desktop 19中文-- PD19最新安装

Parallels Desktop 19可以让我们在Mac电脑上运行Windows和其他操作系统&#xff0c;而无需重启计算机。这款软件的稳定性较高&#xff0c;能够在Mac上同时运行多个操作系统&#xff0c;如Windows、Linux等&#xff0c;而无需重启电脑。它可以让用户无缝地在不同操作系统之间切换…...

【c++】向webrtc学比较1:AheadOf、IsNewerTimestamp

webrtc源码分析-rtp序列号新旧比较 大神文章分析的非常到位。大神分析:AheadOrAt(a, b)是判断a是否比b新的核心,其原理是这样的:rfc1982规定了序列号递增间隔不能超过取值范围的1/2(这是自己理解的),那么要判断a是否比b新,只要判断b到a的递增是否在1/2即可,递增超过1/2,…...

华为云云耀云服务器L实例评测|企业项目最佳实践之docker部署及应用(七)

华为云云耀云服务器L实例评测&#xff5c;企业项目最佳实践系列&#xff1a; 华为云云耀云服务器L实例评测&#xff5c;企业项目最佳实践之云服务器介绍(一) 华为云云耀云服务器L实例评测&#xff5c;企业项目最佳实践之华为云介绍(二) 华为云云耀云服务器L实例评测&#xff5…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...