C++-模板与容器

1、模板

模板可以让类或者函数支持一种通用类型,这种通用类型在实际运行过程中可以使用任何数据类型。因此程序员可以写出一些与类型无关的代码。这种编程方式也叫“泛型编程”。

通常有两种形式:

  • 函数模板
  • 类模板

1.1 函数模板

//模板类型声明
template<class T>//T 模板类型

是让一个函数支持模板编程,可以使函数支持通用数据类型。

#include <iostream>
#include <string.h>
using namespace std;
// 模板函数
template<class T>//T 模板类型
add(T a,T b)
{return a+b;
}
int main()
{
    cout << add(1,2) << endl; // 3
    string s1 = "hello";
    string s2 = "world";
    cout << add(s1,s2) << endl; // helloworld
    cout << add(2.3,23.12) << endl;
//  cout << add(1,23.3) << endl; 
//编译器自动识别数据类型
//错误,无法推导,局限性:只能用同一种类型
//错误,两个指针无法相加,如果想要实现这个功能,想要将+运算符重载
//cout << add("hello","world") << endl;return 0;
}

1.2 类模板

使一个类支持模板编程,可以使类支持通用数据类型。

作用域:只有一个花括号大小

#include <iostream>
#include <string.h>
using namespace std;
// 模板函数
//template<typename T>
//T add(T a,T b)
//{
//   return a+b;
//}
template<class T>    // 可以class 也可以typename
class Test
{
private:
    T val;
public:Test(T v){
        val = v;}
    T get_val(){return val;}void set_val(T v){
        val = v;}
};
int main()
{// 类模板需要执行模板类型,通过<>。只要在之后的程序中看到<>,肯定是个模板类
    Test<int> t1(20);
    cout << t1.get_val() << endl;
    t1.set_val(10);
    cout << t1.get_val() << endl;
    t1.set_val(2.34);
//    cout << t1.get_val() << endl; // 数据窄化 输出2
    Test<double> t2(2.14); // 指定类模板为double
    cout << t2.get_val() << endl;
    t2.set_val(3);
    cout << t2.get_val() << endl;return 0;
}

类内定义,类外声明

上面的写法可以改为类内声明类外定义的形式:

#include <iostream>
#include <string.h>
using namespace std;
template<class T>    // 可以class 也可以typename
class Test
{
private:
    T val;
public:Test(T v){
        val = v;}
    T get_val();//类内定义 类外声明void set_val(T v);
};template<class T>
Test<T>::get_val()//类内定义 类外声明
{return val;
}template<class T>
//返回值类型 模板类型作用域 函数名(传参)
void Test<T>::set_val(T v)
{
    val = v;
}int main()
{
    Test<int> t1(20);
    cout << t1.get_val() << endl;
    t1.set_val(10);
    cout << t1.get_val() << endl;
    t1.set_val(2.34);
//    cout << t1.get_val() << endl; // 数据窄化输出2
    Test<double> t2(2.14);
    cout << t2.get_val() << endl;
    t2.set_val(3);
    cout << t2.get_val() << endl;return 0;
}

2、容器

2.1 标准模板库STL

标准模板库(Standard Template Library,STL)是惠普实验室开发的一系列软件的统称。虽然说它主要出现在C++中,但是它在被引入C++之前,该技术就已经存在很长时间了。

STL的代码从广义上讲分为三部分,algorithm(算法)、container(容器)、iterator(迭代器)。几乎所有的代码都采用了模板类和模板函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用的机会。

2.2 概念

容器是用来存储数据的集合,数据元素可以是任何类型(因为是使用模板实现的)

容器类的使用,都要引入对应的头文件。

2.3 顺序容器

顺序容器中每个元素均有固定的位置并呈线性排布。除非使用删除或者是插入操作改变元素的位置。

2.3.1 array数组

array是C++11新增的容器类型,与传统数组相比更加安全,易于使用。array数组是定长的。没法方便的伸缩。array创建数组必须是定长的,且不能用变量定长。

QMAKE_CXXFLAGS += -std=c++11

array数组常用函数

#include <array> // 头文件
array<int,5> arr = {1,2,3}; // 后面两位补零

#include <iostream>
#include <array> // 头文件
using namespace std;
int main()
{// 创建一个长度为5的int数组
    array<int,5> arr = {1,2,3}; // 后面两位补零
    cout << arr[0] << endl; // 1
    cout << arr[4] << endl; // 0
    cout << arr.at(2) << endl; // 3 推荐使用at
    arr[3] = 200;// forfor(int i = 0; i < arr.size(); ++i){
        cout << arr.at(i) << " ";}
    cout << endl;// for eachfor(int i:arr){
        cout << i << " ";}
    cout << endl;//迭代器遍历,后面讲// TODOreturn 0;
}

2.3.2 vector 向量

vector向量内部是由数组实现的,比较适合进行随机的存取操作,不擅长插入删除操作。

不是定长,方便伸缩。(大量数据存取时且不经常插入删除)

vector向量常用函数

#include <vector> // 头文件
vector<int> vec(50);//创建一个大小为5类型为int,默认值为0的vector向量数组
vec.push_back(222);//在最后面追加新元素
vec.insert(vec.begin()+2,333);//begin()指向第一个元素位置
vec.pop_back();  // 删除最后一个元素
vec.erase(vec.end()-2);//end()指向最后一个元素后面,删除了倒数第二个元素
vec.empty()// 判断是否为空,0非空,1空
vec.clear();// 清空

#include <iostream>
#include <vector> // 头文件
using namespace std;
int main()
{
//    vector<int> vec(5,0);//创建一个大小为5类型为int,默认值为0的vector向量数组
//    cout << vec.size() << endl;
//    for(int i = 0; i < vec.size(); ++i)
//    {
//        cout << vec[i] << endl;
//    }
    vector<int> vec = {1,2,3};// 增
    vec.push_back(222);//在最后面追加新元素for(int i :vec){
        cout << i <<" ";}
    cout << endl;
    cout<<"--------------------"<<endl;
    cout <<"向量大小:"<< vec.size() << endl;// 插入操作,定向插入// begin()可以返回指向第一个元素的迭代器指针,+2是在第三个位置上插入333
    vec.insert(vec.begin()+2,333);//begin()指向第一个元素位置
    cout<<"定向插入:"<<endl;for(int i :vec){
        cout << i <<" ";}
    cout << endl;
    cout<<"--------------------"<<endl;// 删// 删除最后一个元素
    cout<<"删除最后一个元素:"<<endl;
    vec.pop_back();for(int i :vec){
        cout << i <<" ";}
    cout << endl;
    cout<<"--------------------"<<endl;// 删除了第二个元素
    cout<<"删除了第二个元素:"<<endl;
    vec.erase(vec.begin()+1);for(int i :vec){
        cout << i <<" ";}
    cout << endl;
    cout<<"--------------------"<<endl;// 删除了倒数第二个元素
    cout<<"删除了倒数第二个元素:"<<endl;
    vec.erase(vec.end()-2);//end()指向最后一个元素后面for(int i :vec){
        cout << i <<" ";}
    cout << endl;
    cout<<"--------------------"<<endl;// 改
    cout<<"改:"<<endl;
    vec[1] = 666;
    vec.at(0) = 888;for(int i :vec){
        cout << i <<" ";}
    cout << endl;
    cout<<"--------------------"<<endl;// 查
    cout << vec[1] << endl;for(int i :vec){
        cout << i <<" ";}
    cout << endl;
    cout << "---------------------" <<  endl;for(int i = 0; i < vec.size(); ++i){
        cout << vec[i] << " ";}
    cout <<  endl;// 判断是否为空,0非空,1空
    cout << vec.empty() << endl;// 清空
    vec.clear();
    cout << vec.empty() << endl;// 迭代器遍历先省略return 0;
}

2.3.3 list列表

list内部是由双向循环链表实现的。不支持下标。优点:可以高效的删除和插入操作。但不适合随机的存取操作。

list列表常用函数

#include <list> // 头文件
list<string> lis2{"hello","world"};
//创建了一个长度为2的列表,第一个元素就是hello,第二个world
list<string> lis(5,"hello");
// 创建一个长度为5的列表,每个元素都是“hello”
lis.push_back("world"); // 向后追加一个单元素
lis.push_front("hahaha");   // 向前追加一个单元素
lis.insert(++lis.begin(),"2222"); // 在第二个位置上插入“2222”,lis.begin()只能自增,不能加数值
lis.pop_back(); // 删最后一个元素
lis.pop_front();    // 删除第一个元素
lis.push_back("world"); // 向后追加一个单元素
list<string>::iterator iter = lis.begin();// 保存迭代器指针
advance(iter,1); // 移动迭代器指针

#include <iostream>
#include <list> // 头文件
using namespace std;
int main()
{// 创建了一个默认无数值的list
    list<string> lis1;//创建了一个长度为2的列表,第一个元素就是hello,第二个world
    list<string> lis2{"hello","world"};for(string s:lis2){
        cout << s << " ";}
    cout <<endl;// 创建一个长度为5的列表,每个元素都是“hello”
    list<string> lis(5,"hello");
    cout<<"创建一个长度为5的列表,每个元素都是“hello”"<<endl;for(string s:lis){
        cout << s << " ";}
    cout<<endl;
    cout<<"___________________"<<endl;// 增
    lis.push_back("world"); // 向后追加一个单元素
    cout<<"向后追加一个单元素"<<endl;for(string s:lis){
        cout << s << " ";}
    cout<<endl;
    cout<<"___________________"<<endl;    lis.push_front("hahaha");   // 向前追加一个单元素
    cout<<"向前追加一个单元素"<<endl;for(string s:lis){
        cout << s << " ";}
    cout<<endl;
    cout<<"___________________"<<endl;    lis.insert(++lis.begin(),"2222"); // 在第二个位置上插入“2222”,lis.begin()只能自增,不能加数值
    cout<<"在第二个位置上插入“2222”"<<endl;for(string s:lis){
        cout << s << " ";}
    cout<<endl;
    cout<<"___________________"<<endl;// 删
    lis.pop_back(); // 删最后一个元素
    cout<<"删最后一个元素"<<endl;for(string s:lis){
        cout << s << " ";}
    cout<<endl;
    cout<<"___________________"<<endl;    lis.pop_front();    // 删除第一个元素
    cout<<"删除第一个元素"<<endl;for(string s:lis){
        cout << s << " ";}
    cout<<endl;
    cout<<"___________________"<<endl;    lis.push_back("world"); // 向后追加一个单元素
    cout<<"删除第一个元素"<<endl;for(string s:lis){
        cout << s << " ";}
    cout<<endl;
    cout<<"___________________"<<endl;// 保存迭代器指针
    list<string>::iterator iter = lis.begin();advance(iter,1); // 移动迭代器指针
    lis.insert(iter,"3333");  // 插入3333
    cout<<"通过移动迭代器指针定向插入,插入3333"<<endl;for(string s:lis){
        cout << s << " ";}
    cout<<endl;
    cout<<"___________________"<<endl;// 删除最后一个元素
    iter = lis.end();
    iter--;
    lis.erase(iter);//删除iter指针指向的元素
    cout<<"通过移动迭代器指针定向删除"<<endl;for(string s:lis){
        cout << s << " ";}
    cout<<endl;
    cout<<"___________________"<<endl;// 返回第一个元素的引用
    cout << "打印第一个元素* = " << lis.front() << endl;// 返回最后一个元素
    cout << "打印最后一个元素* = " << lis.back() << endl;// 改
    iter = lis.end();advance(iter,2);//将迭代器指针移动到第二个位置*iter = "200";
    cout<<"通过移动迭代器指针定向修改元素"<<endl;for(string s:lis){
        cout << s << " ";}
    cout<<endl;
    cout<<"___________________"<<endl;// 查
    cout<<"迭代器指针查看"<<endl;
    cout << *iter << endl;for(string s:lis){
        cout << s << " ";}
    cout<<endl;
    cout<<"___________________"<<endl;// 迭代器遍历
    cout << lis.size() << endl;// 清空
    lis.clear();
    cout << lis.size() << endl;return 0;
}

2.3.4 deque队列

deque几乎支持所有vector的API。性能位于vector与list二者之间。最擅长两端存取的顺序容器。

#include <iostream>
#include <deque> // 头文件using namespace std;int main()
{
//    deque<int> deq(5);
//    cout << deq.size() << endl;
//    for(int i = 0; i < deq.size(); ++i)
//    {
//        cout << deq[i] << endl;
//    }
    deque<int> deq = {1,2,3};// 增
    deq.push_back(222);
    cout << deq.size() << endl;// 插入操作// begin()可以返回指向第一个元素的迭代器指针,+2是在第三个位置上插入333
    deq.insert(deq.begin()+2,333);// 删// 删除最后一个元素
    deq.pop_back();// 删除了第二个元素
    deq.erase(deq.begin()+1);// 删除了倒数第二个元素
    deq.erase(deq.end()-2);// 改
    deq[1] = 666;
    deq.at(0) = 888;// 查
    cout << deq[1] << endl;for(int i :deq){
        cout << i <<" ";}
    cout << endl;
    cout << "---------------------" <<  endl;for(int i = 0; i < deq.size(); ++i){
        cout << deq[i] << " ";}
    cout <<  endl;// 判断是否为空,0非空,1空
    cout << deq.empty() << endl;// 清空
    deq.clear();
    cout << deq.empty() << endl;// 迭代器遍历先省略return 0;
}

2.4 关联容器

关联容器的各个元素之间没有严格顺序,虽然内部具有排序特点。但是在使用时没有任何顺序相关的接口。底层是由树构成,(红黑树)

最常见的关联容器就是map-键值对映射

对于map而言,键具有唯一性,键通常使用字符串类型,值任何类型。通过键找到对应的值。

关联容器常用函数

#include <map> // 头文件
map<string,int> ma;//创建一个value为int类型的关联容器
map<string,int> ma1 = {{"年龄",99},{"身高",250}};
ma.insert(pair<string,int>("体重",70));   // 插入元
if(ma.find("身高") == ma.end())
    {
        cout << "没有身高元素" << endl;
    }
int re = ma.erase("身高"); // 删除元素,返回值1成功,0失败

#include <iostream>
#include <map> // 头文件using namespace std;int main()
{// map创建初始化 C++11支持
    map<string,int> ma1 = {{"年龄",99},{"身高",250}};
    cout << ma1.size() << endl; // 2    map<string,int> ma;//创建一个value为int类型的关联容器
    cout << ma.size() << endl;//0:容器大小// 增
    cout << "增操作:"<< endl;
    ma["身高"] = 180;
    ma.insert(pair<string,int>("体重",70));   // 插入元素
    cout <<"身高"<< ma["身高"] << endl;
    cout <<"体重"<<ma["体重"] << endl;
    cout << "--------------------" << endl;// 改
    cout << "改操作:"<< endl;
    ma["身高"] = 165;
    cout << "身高"<<ma["身高"] << endl;
    cout << "--------------------" << endl;// 查
    cout << "查操作:" << endl;
    cout << "身高"<<ma["身高"] << endl;if(ma.find("身高") == ma.end()){
        cout << "没有身高元素" << endl;}else{
        cout << "身高"<<ma["身高"] << endl;}
    cout << "--------------------" << endl;// 删
    cout << "删除操作前 "<<ma.size() << endl;
    cout << "删除操作:" << endl;int re = ma.erase("身高"); // 删除元素,返回值1成功,0失败
    cout << "身高删除返回值:" << re << endl;if(ma.find("身高") == ma.end()){
        cout << "没有身高元素" << endl;}else{
        cout << "身高"<<ma["身高"] << endl;}
    cout <<"删除操作后 "<< ma.size() << endl;
    cout << "--------------------" << endl;//清空操作
    cout << "清空操作" << endl;
    ma.clear();
    cout << ma.size() << endl;
    cout << "--------------------" << endl;return 0;
}

2.5 迭代器

迭代器是一个特殊的指针,主要用于容器的元素读写以及遍历。

如果迭代器不进行修改,建议使用只读迭代器,const_iterator,反之使用iterator.

#include <array>
#include <vector>
#include <list>
#include <deque>
#include <map> // 头文件// 迭代器遍历 string
for(string::const_iterator iter = s.begin();iter != s.end(); ++iter)
// 迭代器遍历array
for(array<int,5>::const_iterator iter = arr.begin();iter != arr.end();iter++)
// vector 迭代器遍历
for(vector<string>::const_iterator iter = vec.begin();iter != vec.end();iter++)
// 迭代器遍历list
for(list<string>::const_iterator iter = lis.begin();iter != lis.end();++iter)
// 迭代器遍历deque
for(deque<string>::const_iterator iter = de.begin();iter != de.end();iter++)
// 迭代器遍历map
for(map<string,int>::const_iterator iter = ma.begin();iter != ma.end(); iter++)
{
    // first 是键 second 是值
    cout << iter->first << " " << iter->second << endl;
}

#include <iostream>
#include <array>
#include <vector>
#include <list>
#include <deque>
#include <map> // 头文件using namespace std;int main()
{
    string s = "abdcdfg";
    // 迭代器遍历 string
    cout<<"迭代器遍历 string:"<<endl;
    for(string::const_iterator iter = s.begin();
        iter != s.end(); ++iter)
    {
        cout << *iter << " ";
    }
    cout << endl;
    cout << "--------------" << endl;    // 迭代器遍历array
    cout<<"迭代器遍历array:"<<endl;
    array<int,5> arr = {23,2,5,87,2};
    for(array<int,5>::const_iterator iter = arr.begin();
        iter != arr.end();iter++)
    {
         cout << *iter << " ";
    }
    cout << endl;
    cout << "--------------" << endl;    // vector 迭代器遍历
    cout<<"vector 迭代器遍历:"<<endl;
    vector<string> vec(6,"hello");
    for(vector<string>::const_iterator iter = vec.begin();
        iter != vec.end();iter++)
    {
        cout << *iter << " ";
    }    cout << endl;
    cout << "--------------" << endl;    // 迭代器遍历list
    cout<<"迭代器遍历list:"<<endl;
    list<string> lis(6,"world");
    for(list<string>::const_iterator iter = lis.begin();
        iter != lis.end();++iter)
    {
        cout << *iter << " ";
    }    cout << endl;
    cout << "--------------" << endl;    // 迭代器遍历deque
    cout<<"迭代器遍历deque:"<<endl;
    deque<string> de(6,"nihao");
    for(deque<string>::const_iterator iter = de.begin();
        iter != de.end();iter++)
    {
        cout << *iter << " ";
    }    cout << endl;
    cout << "--------------" << endl;    // 迭代器遍历map
    cout<<"迭代器遍历map:"<<endl;
    map<string,int> ma;
    ma["年龄"] = 23;
    ma["身高"] = 180;
    ma["体重"] = 65;    for(map<string,int>::const_iterator iter = ma.begin();
        iter != ma.end(); iter++)
    {
        // first 是键 second 是值
        cout << iter->first << " " << iter->second << endl;
    }    return 0;
}

练习:

写一个函数show_array,要求传入两个参数。

void show_array(T t,int len)

第一个参数为数组默认值,第二个参数为数组的长度。

此函数的功能为创建一个长度为len类型是T,默认值为t的数组并输出。

尽量不用使用c语言的数组。

#include <iostream>#include <vector>
using namespace std;
template<class T>
void show_array(T t,int len)
{
    vector<T> vec(len,t);for(T i:vec){
        cout << i << " ";}}int main()
{show_array("a",5);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/595013.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中文自然语言处理库(SnowNLP)的简单使用

snownlp 是一个简单易用的 Python 库&#xff0c;专为处理中文文本而设计。它基于自然语言处理技术&#xff0c;提供了多种功能&#xff0c;包括分词、词性标注、情感分析、文本转换&#xff08;简繁转换&#xff09;等。这个库的核心优势在于对中文文本的处理能力&#xff0c;…

Navicat 技术干货 | 聚合查询的介绍

基础 SQL 查询可以检索、插入、更新和删除记录&#xff0c;而聚合查询可通过提供求和、平均值或最大/最小值等的大型结果集&#xff0c;将数据库交互提升到一个新的水平。本文中&#xff0c;我们将探索聚合 SQL 查询的基础知识&#xff0c;并研究如何有效的利用他们来分析和汇总…

14.1 Linux 并发与竞争

一、并发与竞争 并发&#xff1a;多个执行单元同时、并行执行。 竞争&#xff1a;并发的执行单元同时访问共享资源(硬件资源和软件上的全局变量等)易导致竞态。 二、原子操作 1. 原子操作简介 原子操作&#xff1a;不能再进一步分割的操作&#xff0c;一般用于变量或位操作。 …

关于设计模式的一点总结

一、GoF 23种设计模式 1.分类 GoF 23种设计模式可分为几类&#xff1a;创建型、结构型和行为型。如下表 分类设计模式创建型单例模式、工厂方法模式、抽象工厂模式、原型模式、建造者模式结构型代理模式、适配器模式、装饰者模式、桥接模式、组合模式、门面模式、享元模式行…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)添加 删除 修改 释放

在上篇文章&#xff08;处理任务队列中的任务&#xff09;中我们讲解了处理任务队列中的任务的具体流程&#xff0c;eventLoopProcessTask函数的作用&#xff1a; 处理队列中的任务&#xff0c;需要遍历链表并根据type进行对应处理,也就是处理dispatcher中的任务。 // 处理任…

Idea启动运行“错误:java: 无效的源发行版: 13”,如何解决?

以上是以JDK1.8的项目作为举例&#xff0c;如果您用的是其他版本请选择对应的language level idea中项目的language level的含义 language level指的是编译项目代码所用的jdk版本。那么&#xff0c;从这个定义出发会有两个小问题。 ❶ 如果project sdk是jdk8&#xff0c;那么la…

2020年认证杯SPSSPRO杯数学建模C题(第一阶段)抗击疫情,我们能做什么全过程文档及程序

2020年认证杯SPSSPRO杯数学建模 C题 抗击疫情&#xff0c;我们能做什么 原题再现&#xff1a; 2020 年 3 月 12 日&#xff0c;世界卫生组织&#xff08;WHO&#xff09;宣布&#xff0c;席卷全球的冠状病毒引发的病毒性肺炎&#xff08;COVID-19&#xff09;是一种大流行病。…

解析大语言模型LLM的幻觉问题:消除错觉、提高认知

文章目录 前言一、幻觉介绍二、幻觉产生的原因三、幻觉的现象四、幻觉的分类五、幻觉解决方案六、幻觉待解决问题后记 前言 在人类的感知和认知过程中&#xff0c;幻觉一直是一个被广泛讨论和研究的问题。幻觉指的是一种虚假的感知或认知经验&#xff0c;使我们看到、听到或感…

企业微信开发:自建应用:应用形态(网页,小程序,默认页面)

概述 问题&#xff1a; 企业微信&#xff0c;自建应用&#xff0c;应该实现成什么样子&#xff1f;应用里是一个网页应用吗&#xff1f; 企业微信自建应用可以实现为多种形态&#xff0c;根据实际需求和功能设计&#xff0c;它可以是一个网页应用、一个小程序或者结合企业微信提…

【Pytorch】学习记录分享9——新闻数据集文本分类任务实战

【Pytorch】学习记录分享9——PyTorch新闻数据集文本分类任务 1. 认为主流程code2. NLP 对话和预测基本均属于分类任务详细见3. Tensorborad 1. 认为主流程code import time import torch import numpy as np from train_eval import train, init_network from importlib impo…

Python基础-05(输出输入、if、if else和elif)

文章目录 前言一、输出&#xff08;print()&#xff09;和输入&#xff08;input()&#xff09;二、if、if else、elif1.if2.if else3.关于输入input的默认值4.elif 前言 今天复习一些非常基础的内容&#xff0c;以及if、if else和elif语句 一、输出&#xff08;print()&…

CMake入门教程【核心篇】添加应用程序(add_executable)

&#x1f608;「CSDN主页」&#xff1a;传送门 &#x1f608;「Bilibil首页」&#xff1a;传送门 &#x1f608;「本文的内容」&#xff1a;CMake入门教程 &#x1f608;「动动你的小手」&#xff1a;点赞&#x1f44d;收藏⭐️评论&#x1f4dd; 文章目录 1. 概述2. 使用方法2…

ARM Cortex-A学习(3):MMU内存管理单元

内存管理单元(MMU)负责虚拟地址到物理地址的转换。MMU通过翻译表将程序使用的虚拟地址映射到实际的物理内存位置&#xff0c;实现对内存的动态管理和隔离。这不仅允许更灵活的内存分配&#xff0c;还提高了系统的安全性和稳定性。了解MMU的工作原理对于开发底层代码、BootLoade…

【数据结构】二叉树的创建和遍历:前序遍历,中序遍历,后序遍历,层次遍历

目录 一、二叉树的定义 1、二叉树的定义 2、二叉树的五种形态 二叉树的子树 &#xff1a; 3、满二叉树与完全二叉树 4、二叉树的性质 5、二叉树的存储结构 1、顺序存储 ​编辑 2、链式存储 二、二叉树的遍历 按照前序序列构建二叉树 1、前 (先) 序遍历(Preorder …

神经网络:激活函数的介绍

神经网络的激活函数是一种非线性函数&#xff0c;它被应用于每个神经元的输出&#xff0c;以引入非线性性质到网络中。 激活函数的目的是将输入转换为输出&#xff0c;并且将输出限制在特定的范围内。它们非常重要&#xff0c;因为线性变换&#xff08;例如加法和乘法&#xf…

【UEFI基础】EDK网络框架(环境配置)

环境配置 为了能够让使用测试BIOS的QEMU与主机&#xff08;就是指普通的Windows系统&#xff0c;我们使用它来编译BIOS和启动QEMU虚拟机&#xff09;通过网络连接&#xff0c;需要额外的配置。 首先是下载和安装OpenVPN&#xff08;这里安装的是OpenVPN-2.5.5-I601-amd64.msi…

重新认识一下 vue3 应用实例

重新认识一下 vue 应用实例 &#x1f495; 创建应用实例 每个 Vue 应用都是通过 createApp 函数创建一个新的 应用实例 应用实例必须在调用了 .mount() 方法后才会渲染出来。该方法接收一个“容器”参数&#xff0c;可以是一个实际的 DOM 元素或是一个 CSS 选择器字符串 //…

【GoLang入门教程】Go语言几种标准库介绍(四)

编程语言的未来&#xff1f; 文章目录 编程语言的未来&#xff1f;前言几种库fmt库 (格式化操作)关键函数&#xff1a;示例 Go库标准库第三方库示例 html库(HTML 转义及模板系统)主要功能&#xff1a;示例 总结专栏集锦写在最后 前言 上一篇&#xff0c;我们介绍了debug、enco…

魔术表演Scratch-第14届蓝桥杯Scratch省赛真题第1题

1.魔术表演&#xff08;20分&#xff09; 评判标准&#xff1a; 4分&#xff1a;满足"具体要求"中的1&#xff09;&#xff1b; 8分&#xff1a;满足"具体要求"中的2&#xff09;&#xff1b; 8分&#xff0c;满足"具体要求"中的3&#xff09…

GPU的硬件架构

SM: streaming Multiprocessor 流多处理器 sm里面有多个(sp)cuda core 32个线程称为一个warp&#xff0c;一个warp是一个基本执行单元 抽象概念&#xff1a;grid 网格 block 块 thread 线程 块中的线程大小是有讲究的&#xff0c;关乎到资源的调度&#xff0c;一般是128&#x…