【C++】入门(二):引用、内联、auto
书接上回:【C++】入门(一):命名空间、缺省参数、函数重载
文章目录
- 六、引用
- 引用的概念
- 引用的使用场景
- 1. 引用做参数
- 作用1:输出型参数
- 作用2:对象比较大,减少拷贝,提高效率
- 2. 引用作为返回值
- 错误示范
- 正确示范
- 3.总结引用的价值
- 引用特性
- 引用和指针的区别(面试题)
- 常引用
- 七、内联函数
- 回顾:C语言如何避免函数频繁调用的问题?
- 面试题1:实现两个数相加的宏函数
- 面试题2:宏的优缺点
- 面试题3:C++有哪些技术替换宏?
- 内联的概念
- 内联函数的缺点
- 使用内联:vs:不使用内联
- 为什么做声明和定义分离?
- 总结:解决重定义的方案?
- 八、auto关键字
- 简介
- 使用细则
- auto不能推导的场景
- 九、基于范围的for循环(C++11)
- 十、指针空值nullptr(C++11)
六、引用
引用的概念
引用就是给已经存在的变量 取别名。编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。
引用的使用场景
1. 引用做参数
作用1:输出型参数
学习C的时候 写Swap()函数 通过传实参地址的方式,使用指针交换两个变量里面的值 。而加入引用这个语法,则通过别名的方式 交换两个变量里面的值。
void Swap(int* a, int *b){//...}void Swap(int& a, int &b){int tmp = a;a = b;b = tmp;}int main(){int x = 0, y = 1;Swap(&x, &y);Swap(x, y);return 0;}
作用2:对象比较大,减少拷贝,提高效率
对象较大的情况下,对比传值传参 和 传引用传参 的代码效率
#include <time.h>
#include<iostream>
using namespace std;
struct A { int a[10000]; };
void TestFunc1(A a) {}
void TestFunc2(A& a) {}
void main()
{A a;// 以值作为函数参数size_t begin1 = clock();for (size_t i = 0; i < 10000; ++i)TestFunc1(a);size_t end1 = clock();// 以引用作为函数参数size_t begin2 = clock();for (size_t i = 0; i < 10000; ++i)TestFunc2(a);size_t end2 = clock();// 分别计算两个函数运行结束后的时间cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}
我们可以看到一个40000字节的对象,分别使用传值传参、传引用传参,且传参次数10000次。两种传参方式使用的时间有一定差异。引用作为函数参数 消耗的时间小于1 ms,所以是0。
总结:这些使用场景,指针也可以适应,但是引用更方便
2. 引用作为返回值
错误示范
- 一般情况
1️⃣ 被调函数传值返回。 返回a的拷贝 寄存在寄存器里的临时空间 函数栈帧销毁之前 这块要返回的临时空间就已经生成好了
int func()
{int a = 0;return a;
}
int main()
{int ret = func();cout << ret << endl;return 0;
}
- 错误使用引用的情况
2️⃣ 被调函数func传引用返回。 返回a的别名 但函数调用结束,栈帧销毁,a的别名还在访问这个空间——野引用。
int& func()
{int a = 0;return a;
}int main()
{int ret = func();cout << ret << endl;return 0;
}
3️⃣被调函数传引用返回 ,主函数引用接收。返回a的别名、用a的别名接收,意味着ret也是a的别名,但栈帧结束,变量a已经被销毁了,ret还回去访问那块空间,所以ret是野引用。
int& func()
{int a = 0;return a;
}int main()
{int& ret = func();cout << ret << endl;return 0;
}
结论:返回变量出了函数作用域就生命周期就结束了,所以不能用引用返回
正确示范
什么情况下,可以用引用返回?
答:全局变量、静态变量、堆上变量 可以用引用返回
🌰 实际场景中的例子:
使用引用语法修改用C语言写的链表
struct SeqList
{int* a;int size;int capacity;
};void SLInit(SeqList& sl)
{sl.a = (int*)malloc(sizeof(int) * 4);// ..sl.size = 0;sl.capacity = 4;
}void SLPushBack(SeqList& sl, int x)
{//...扩容sl.a[sl.size++] = x;
}// 修改
void SLModity(SeqList& sl, int pos, int x)
{assert(pos >= 0);assert(pos < sl.size);sl.a[pos] = x;
}int SLGet(SeqList& sl, int pos)
{assert(pos >= 0);assert(pos < sl.size);return sl.a[pos];
}int main()
{SeqList s;SLInit(s);SLPushBack(s, 1);SLPushBack(s, 2);SLPushBack(s, 3);SLPushBack(s, 4);for (int i = 0; i < s.size; i++){cout << SLGet(s, i) << " ";}cout << endl;for (int i = 0; i < s.size; i++){int val = SLGet(s, i);if (val % 2 == 0){SLModity(s, i, val * 2);}}cout << endl;for (int i = 0; i < s.size; i++){cout << SLGet(s, i) << " ";}cout << endl;return 0;
}
演进为C++玩法的版本
C++中结构体中可以定义函数 ➡️ 类 成员变量 、 成员函数
// C++
struct SeqList
{// 成员变量int* a;int size;int capacity;// 成员函数void Init(){a = (int*)malloc(sizeof(int) * 4);// ...size = 0;capacity = 4;}void PushBack(int x){// ... 扩容a[size++] = x;}// 读写返回变量int& Get(int pos){assert(pos >= 0);assert(pos < size);return a[pos];}int& operator[](int pos){assert(pos >= 0);assert(pos < size);
return a[pos];}
};
int main()
{SeqList s;s.Init();s.PushBack(1);s.PushBack(2);s.PushBack(3);s.PushBack(4);for (int i = 0; i < s.size; i++){//cout << s.Get(i)<< " ";cout << s[i] << " ";//cout << s.operator[](i) << " ";}cout << endl;for (int i = 0; i < s.size; i++){/*if (s.Get(i) % 2 == 0){s.Get(i) *= 2;}*/if (s[i] % 2 == 0){s[i] *= 2;}}cout << endl;for (int i = 0; i < s.size; i++){cout << s.Get(i) << " ";}cout << endl;return 0;
}
3.总结引用的价值
1️⃣引用做参数
🅰️可以作为输出型参数 。🅱️对象较大,减少拷贝提高效率
2️⃣做返回值
🅰️修改返回对象。 🅱️减少拷贝提高效率
引用特性
引用必须初始化:定义的引用的时候就要确定该引用是谁的别名
引用定义后,不能改变指向
一个变量可以有多个引用 、多个别名
int main()
{int a = 0;// 1、引用必须初始化//int& b;// b = c;// 2、引用定义后,不能改变指向int& b = a;int c = 2;b = c; // 不是改变指向,而是赋值// 3、一个变量可以有多个引用,多个别名int& d = b;return 0;
}
思考:引用可以替代指针吗?
答:引用不能完全替代指针,指针和引用的功能是类似的,C++的引用,对指针使用比较复杂的场景进行一些替换,让代码更简单易懂,但是不能完全替代指针,引用不能完全替代指针原因:引用定义后,不能改变指向
🌰引用不可以替代指针的栗子:
双向链表中,必须要改变指向,但引用不能改变指向。
🌰C++的引用 对指针使用比较复杂的场景 可以进行一些替换:
例如:
原来C语言 写链表头插入 实参传头节点指针 的 地址 。形参需要用二级指针接收。
void PushBack(struct Node* phead, int x)
{// phead = newnode;
}void PushBack(struct Node** pphead, int x)
{// *pphead = newnode;
}
现在C++ 使用引用: 给指针类型的变量(头节点指针)取别名
void PushBack(struct Node*& phead, int x)
{//phead = newnode;
}int main()
{struct Node* plist = NULL;return 0;
}
📘杂七杂八的小知识点:数据结构教科书常见代码解读
//给 结构体 重命名为LNode
//给 结构体类型的指针 重命名为 PNode
typedef struct Node
{struct Node* next;struct Node* prev;int val;
}LNode, *PNode;
//PNode& phead 给PNode变量(结构体类型的指针)取别名 phead
void PushBack(PNode& phead, int x)
{//phead = newnode;//给引用赋值相当于改变PushBack()函数外面的链表头结点指针的指向
}
引用和指针的区别(面试题)
从两个维度对比 语法角度、底层角度对比
语法:
1. 引用是别名,不开空间。指针是地址,语法上需要开空间存储地址
2. 引用必须初始化 、指针可以初始化也可以不初始化。
3. 引用不可以改变指向、指针可以改变指向
4. 引用相对更安全 ,没有空引用、但是有空指针,容易出现野指针,不容易出现野引用
底层:
汇编层面上,没有引用,引用都是用指针实现的,引用编译后也转换成指针了。
调到反汇编调试观察:
结论:底层都需要开空间1、引用在底层是用指针实现的。2、语法含义和底层实现是背离的
常引用
由于引用存在一些隐患,所以我们可以加关键字const 使用常引用 。例如下面代码,对于变量b,它是a的别名,如果对引用b修改, 那么a的值就会改变。但是如果不希望a的值被修改,我们就可以给引用前面加上const 使得引用只有读取a的值的权限,但不能修改。例如,a的引用c就是这样的权限。
int main()
{int a = 0;//eg.1权限正常的引用 int &b =a;//b对a可读可写b++;//eg.2权限缩小const int& c = a;//c对a只有读取权限//eg.3权限放大(错误示范)const int x = 10;//int& y = x; //注意不能权限放大//eg.4 权限平移(正确示范)const int& y = x //y可以读取x的值//eg.5 const int& z =10; //z是常量的别名//eg.6const int& m = a+x;// a+x表达式的返回值 是一个临时变量 临时变量具有常性//eg.7 (错误示范)int& n = a+x;return 0;
}
七、内联函数
回顾:C语言如何避免函数频繁调用的问题?
➡️宏
面试题1:实现两个数相加的宏函数
#define Add(x,y) ((x)+(y))
易错点:1、宏不是函数 2、不要写分号 3、括号控制优先级
核心点:宏是预处理阶段进行替换
提问:为什么要加里面的括号?
答:因为x、y可能不是被单一变量所替换,而是其他表达式替换x、y ,防止表达式中的个别值先进性加法运算,从而运算符执行顺序和预期不符,导致运算结果错误。
面试题2:宏的优缺点
缺点:
1️⃣坑很多,不易控制 2️⃣ 不能调试 3️⃣没有安全类型的检查
优点:
增强代码复用性、提高效率
面试题3:C++有哪些技术替换宏?
- 常量定义 换用 const enum
- 短小函数定义 使用内联inline修饰
内联的概念
内联 : 在调用地方展开 。所指的展开就是:不建立栈帧,在当前函数的栈帧里执行要调用函数的代码
反汇编演示 具体是如何不建立栈帧展开的
思考:能不能为所有函数 都加上inline ?
不行 ,➡️ 内联函数的缺点
内联函数的缺点
使用内联🆚不使用内联
假设func()函数100 行代码,并且一共要调用1w次分别考虑使用内联 、不使用内联的情况合计起来有多少指令?
使用内联
假设inline展开,合计指令数目为:100*1w。意味着 最后的可执行程序会变得很大
解释:100行代码在1W个位置调用,那么1w个位置都会多出100行,所以就是100W行
不使用内联
假设inline不展开,合计指令数目:100+1w
解释:1W个位置调用 底层就会是汇编指令 call func(),call func()后会从符号表找到这个函数的地址 然后去执行该函数的代码。
总结:由此可见,如果是代码量较大的函数 使用inline 内联展开调用的话,会造成代码膨胀。所以内联函数只适合加在代码量较小的函数上!
注意:
1.inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小、不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。
2.inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就无法找到该函数。
为什么做声明和定义分离?
如果在头文件中进行函数定义,以下代码存在函数名重定义的问题。
问题分析:
Stack.cpp 包含了头文件 Test.cpp也包含了头文件。头文件的包含 在预处理阶段 会进行内容替换。也就是说Add()函数被定义两次。Stack.cpp Test.cpp 会分别产生Stack.o、Test.o。链接的时候 会把他们的符号表合并在一起,各自都有叫函数名修饰过的Add()函数,编译器就会认为函数重定义。
所以我们要做声明和定义分离!
//Stack.h
#progam once
#include<iostream>
using namespace std
int Add(int a,int b)
{cout<<"int Add(int a,int b)"<<endl;return a+b;
}
//Stack.cpp
#include"Stack.h"
//Test.cpp
#include"Stack.h"
int main()
{Add(1,2);return 0;
}
总结:解决重定义的方案?
1.声明和定义分离
2.Static,改变链接属性,该函数地址不会加入符号列表,只在当前文件可见。(适用于大函数)
3.使用内联函数,因为要在调用处展开,所以该函数地址也不会加入符号列表。(适用于小函数)
//Stack.h
#progam once
#include<iostream>
using namespace std
inline int Add(int a,int b)
{cout<<"int Add(int a,int b)"<<endl;return a+b;
}
//Stack.cpp
#include"Stack.h"
//Test.cpp
#include"Stack.h"
int main()
{Add(1,2);return 0;
}
八、auto关键字
简介
C++11规定,程序员使用auto关键字就可以不指定数据类型,编译器通过右边的值的类型自动推导出左边值的数据类型。使用auto关键字 必须初始化,因为在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。
使用细则
1.auto与指针和引用结合起来使用
auto* 必须初始化为指针 ,auto声明引用类型时则必须加&
🌰栗子
auto p1 = &i
auto* p2 = &i;
//auto* p3 = i;//会报错
auto& r = a;
2.当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量
void TestAuto()
{auto a = 1, b = 2; auto c = 3, d = 4.0; // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}
auto不能推导的场景
1、auto不能作为函数的参数
// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)
{}
2、auto不能直接用来声明数组
void TestAuto()
{
int a[] = {1,2,3};
auto b[] = {4,5,6};
}
3、为了避免与C++98中的auto发生混淆,C++11只保留了auto作为类型指示符的用法
4、auto在实际中最常见的优势用法就是跟以后会讲到的C++11提供的新式for循环,还有 lambda表达式等进行配合使用
九、基于范围的for循环(C++11)
依次取数组中值赋值给e,自动迭代,自动判断结束
for (auto e : array)
{cout << e << " ";
}
cout << endl;
十、指针空值nullptr(C++11)
C语言中 我们这样初始化指针:
int* p1 = NULL;
但在C++中, NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码:
#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif#endif
可以看到,NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。不论采取何种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦,比如:类型匹配的问题
void f(int)
{cout << "f(int)" << endl;
}
void f(int*)
{cout << "f(int*)" << endl;
}
int main()
{f(0);f(NULL);f((int*)NULL);return 0;
}
程序本意是想通过f(NULL)调用指针版本的f(int*)函数,但是由于NULL被定义成0,因此与程序的 初衷相悖。
在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器 默认情况下将其看成是一个整形常量,*如果要将其按照指针方式来使用,必须对其进行强转(void )0。
注意:
1、在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入 的。 比特就业课
2、在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
3、为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr
相关文章:

【C++】入门(二):引用、内联、auto
书接上回:【C】入门(一):命名空间、缺省参数、函数重载 文章目录 六、引用引用的概念引用的使用场景1. 引用做参数作用1:输出型参数作用2:对象比较大,减少拷贝,提高效率 2. 引用作为…...

编程学习 (C规划) 6 {24_4_18} 七 ( 简单扫雷游戏)
首先我们要清楚扫雷大概是如何实现的: 1.布置雷 2.扫雷(排查雷) (1)如果这个位置是雷就炸了,游戏结束 (2)如果不是雷,就告诉周围有几个雷 3.把所有不是雷的位置都找…...

【AI】llama-fs的 安装与运行
pip install -r .\requirements.txt Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved.Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows(venv) PS D:\XTRANS\pythonProject>...
Android NDK系列(五)内存监控
在日常的开发中,内存泄漏是一种比较比较棘手的问题,这是由于其具有隐蔽性,即使发生了泄漏,很难检测到并且不好定位到哪里导致的泄漏。如果程序在运行的过程中不断出现内存泄漏,那么越来越多的内存得不到释放࿰…...

软件设计师,下午题 ——试题六
模型图 简单工厂模式 工厂方法模式抽象工厂模式生成器模式原型模式适配器模式桥接模式组合模式装饰(器)模式亨元模式命令模式观察者模式状态模式策略模式访问者模式中介者模式 简单工厂模式 工厂方法模式 抽象工厂模式 生成器模式 原型模式 适配器模式 桥…...

《Kubernetes部署篇:基于麒麟V10+ARM64架构部署harbor v2.4.0镜像仓库》
总结:整理不易,如果对你有帮助,可否点赞关注一下? 更多详细内容请参考:企业级K8s集群运维实战 一、环境信息 K8S版本 操作系统 CPU架构 服务版本 1.26.15 Kylin Linux Advanced Server V10 ARM64 harbor v2.4.0 二、部…...

远程工作/线上兼职网站整理(数字游民友好)
文章目录 国外线上兼职网站fiverrupwork 国内线上兼职网站甜薪工场猪八戒网云队友 国外线上兼职网站 fiverr https://www.fiverr.com/start_selling?sourcetop_nav upwork https://www.upwork.com/ 国内线上兼职网站 甜薪工场 https://www.txgc.com/ 猪八戒网 云队友 …...

elasticsearch7.15实现用户输入自动补全
Elasticsearch Completion Suggester(补全建议) Elasticsearch7.15安装 官方文档 补全建议器提供了根据输入自动补全/搜索的功能。这是一个导航功能,引导用户在输入时找到相关结果,提高搜索精度。 理想情况下,自动补…...
掌握正则表达式的力量:全方位解析PCRE的基础与进阶技能
Perl 兼容正则表达式(PCRE)是 Perl scripting language 中所使用的正则表达式语法标准。这些正则表达式在 Linux 命令行工具(如 grep -P)及其他编程语言和工具中也有广泛应用。以下是一些基础和进阶特性,帮你掌握和使用…...
FastFM库,一款强大神奇的Python系统分析预测的工具
FastFM库概述 在机器学习领域,Factorization Machines(FM)是处理稀疏数据集中特征间交互的重要工具.Python的fastFM库提供了高效的实现,特别适合用于推荐系统、评分预测等任务.本文将全面介绍fastFM的安装、特性、基本和高级功能,并结合实际应用场景展示…...

R语言绘图 --- 饼状图(Biorplot 开发日志 --- 2)
「写在前面」 在科研数据分析中我们会重复地绘制一些图形,如果代码管理不当经常就会忘记之前绘图的代码。于是我计划开发一个 R 包(Biorplot),用来管理自己 R 语言绘图的代码。本系列文章用于记录 Biorplot 包开发日志。 相关链接…...
用于日常任务的实用 Python 脚本
Python 是一种多功能编程语言,以其简单易读而闻名。它广泛应用于从 Web 开发到数据分析等各个领域。Python 脚本,它们可以通过自动执行常见任务来使您的生活更轻松。 用于日常任务的实用 Python 脚本 1. 使用 Pandas 进行数据分析2. 使用 BeautifulSoup …...
7-Zip是什么呢
1. 简介 7-Zip 是一个功能强大、免费开源的文件压缩和解压缩工具,适用于个人用户和企业用户,可以在多种操作系统上进行使用,并且支持广泛的压缩格式和高级功能。 2. 特点与优势 开源免费:7-Zip 是免费的开源软件,可…...

Satellite Stereo Pipeline学习
1.在Anaconda某个环境中安装s2p pip install s2p 2.在Ubuntu系统中安装s2p源代码 git clone https://github.com/centreborelli/s2p.git --recursive cd s2p pip install -e ".[test]" 3.在s2p中进行make all处理 中间会有很多情况,基本上哪个包出问题…...
linux-gpio
在Linux shell中测试GPIO通信,通常需要使用GPIO的设备文件,这些文件通常位于/sys/class/gpio目录下。要使用特定的GPIO引脚,比如GPIO92,你需要执行以下步骤: 导出GPIO引脚:首先,需要确保GPIO92已…...

C# 代码配置的艺术
文章目录 1、代码配置的定义及其在软件工程中的作用2、C# 代码配置的基本概念和工具3、代码配置的实践步骤4、实现代码配置使用属性(Properties)使用配置文件(Config Files)使用依赖注入(Dependency Injection…...

268 基于matlab的模拟双滑块连杆机构运动
基于matlab的模拟双滑块连杆机构运动,并绘制运动动画,连杆轨迹可视化输出,并输出杆件质心轨迹、角速度、速度变化曲线。可定义杆长、滑块速度,滑块初始位置等参数。程序已调通,可直接运行。 268 双滑块连杆机构运动 连…...
进口铝合金电动隔膜泵
进口铝合金电动隔膜泵是一种高效、可靠的工业泵,其特点、性能与应用广泛,以下是对其的详细分析: 特点 材质与结构: 采用铝合金材料制造,具有良好的耐腐蚀性和轻量化特点。铝合金材质使得泵体结构紧凑、轻便ÿ…...

G4 - 可控手势生成 CGAN
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 目录 代码总结与心得 代码 关于CGAN的原理上节已经讲过,这次主要是编写代码加载上节训练后的模型来进行指定条件的生成 图像的生成其实只需要使用…...

使用 DuckDuckGo API 实现多种搜索功能
在日常生活中,我经常使用搜索引擎来查找信息,如谷歌和百度。然而,当我想通过 API 来实现这一功能时,会发现这些搜索引擎并没有提供足够的免费 API 服务。如果有这样的免费 API, 就能定时获取“关注实体”的相关内容,并…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...

Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...