Unity学习笔记(零基础到就业)|Chapter02:C#基础

Unity学习笔记(零基础到就业)|Chapter02:C#基础

  • 前言
  • 一、复杂数据(变量)类型part01:枚举+数组
    • 1.特点
    • 2.枚举
      • (1)基本概念
      • (2)申明枚举变量
      • (3)枚举的类型转换
    • 3.一维数组
      • (1)数组的声明(5种方式)
      • (2)数组的使用
    • 4.二维数组
      • (1)声明二维数组变量(类似一维数组)
      • (2)二维数组的使用
    • 5.交错数组(非重点知识,了解就好)
      • (1)交错数组的声明
      • (2)交错数组的使用
    • 6.补充:关于数组的常见考题
      • (1)数组和List的区别
      • (2)数组参数是什么
  • 二、值类型和引用类型
    • 1.存储和使用上的区别
    • 2.特殊的引用类型:String
    • 3.补充:常见考题
      • (1)String和StringBuilder的区别
      • (2)深拷贝和浅拷贝
  • 三、函数(方法)
    • 1.函数基础
      • (1)基本概念
      • (2)函数写的位置
      • (3)基本语法
      • (4)实际运用
      • (5)关于return
    • 2.ref和out:函数参数的修饰符
      • (1)使用ref和out的原因
      • (2)ref和out的使用及区别
    • 3.变长参数和参数默认值
      • (1)变长参数关键字:params
      • (2)参数默认值
    • 4.函数重载
      • (1)基本概念
      • (2)作用
      • (3)实例
    • 5.递归函数
  • 四、复杂数据(变量)类型——结构体
    • 1.基本概念与作用
    • 2.基本语法
    • 3.实例
    • 4.结构体的构造函数
      • (1)基本概念与作用
      • (2)实例


前言

这系列的学习笔记主要是根据唐老狮的unity实战路线课程整理的,加入了自己的一些补充和理解,该课程涉及的知识内容非常多,我并未学完,而是根据就业需求挑选学习的,也对后续框架部分进行了一些修改,希望能通过整理并时常阅读这些笔记巩固开发知识,也希望能跟在学习unity的小伙伴一起分享、探讨,笔记中有疑问或出错的部分也希望大佬们能够给予指导鸭~🙏


一、复杂数据(变量)类型part01:枚举+数组

1.特点

一般是多个数据(变量)集合在一起的,并且一般可以自己取名字自定义。
枚举:整形常量的集合
数组:任意变量类型顺序存储的数据集合
结构体:任意变量的数据集合,可自定义

2.枚举

(1)基本概念

概念:被命名的整形常量的集合。
作用:在游戏开发中,对象很多时候会有许多状态,综合考虑可用int来表示它的状态(例如:行走为1,待机为2,跑步为3等等),将枚举项与数字进行联系,可以方便直观分清状态的含义,增强代码的可读性

(2)申明枚举变量

Step01:申明枚举(创建一个自定义的枚举类型)
【注1】一般不会去赋值,默认第一个整形常量值是0,往后累加
【注2】申明枚举的位置:常在namespace语句块中,也可申明在class/结构体中,但不能申明在函数语句块中

enum E_自定义枚举名
{自定义枚举名1, //默认是0自定义枚举名2=5, //如果更改了就变为从5开始累加了自定义枚举名3, // 6
}

Step02:使用申明的自定义枚举类型创建一个枚举变量
【注】枚举变量常常和分支语句配合使用(如果没有枚举值的话,就要自定义playertype=1表示什么,等于2表示什么,代码的可读性就不强了)
请添加图片描述

(3)枚举的类型转换

枚举和int互转:括号强转

//枚举转int
int i=(int)playerType;
//int转枚举
playerType=0;

枚举和string互转:

//枚举转string
string str=playerType.ToString();
//string转枚举
playerType=(E_playerType)Enum.Prase(typeof(E_playerType),"Other");
//Parse后 第一个参数:你要转为的是哪个类型 第二个参数:用于转换的对应枚举项的字符串
//转换完毕后是一个通用类型,还需要用括号强转成我们想要的目标枚举类型

3.一维数组

【注】(一般一维数组简称为数组):有序存储相同类型数据的集合

(1)数组的声明(5种方式)

在这里插入图片描述

(2)数组的使用

A、获取长度:
数组变量名.length

B、获取数组中的元素(索引值从0开始,一定注意不能越界,索引不能超过数组范围,即0~length-1):
数组变量名[索引值]

C、修改数组元素(同一类型的值):
数组变量名[索引值]=数值

D、遍历数组,for循环获得下标:

for (int i=0;i<array.length;i++)
{Console.WriteLine(array[i]);
}

E、增加/删除数组元素:数组初始化后不能增删元素,非要增删元素只能申明新的数组,用for循环遍历原数组,将其元素存入新数组中

int[] array2=new int[6];
//搬家
for(int i=0;i<array.length;i++)
{array2[i]=array[i];
}
array=array2;

G、查找数组元素,即查找某个数组元素在数组中的什么位置。通过遍历去确定数组中是否存储了这个目标元素

int a=3;for(int i=0;i<array.length;i++)
{if(a==array[i]){Console.WriteLine("和a相等的元素在{0}索引位置",i);break;}
}

4.二维数组

二维数组:使用2个下标(索引)来确定元素的数组,2个下标可以理解为行标和列标,类似于矩阵。
作用:一般用来存储矩阵,在控制台小游戏中可以用二维数组来表示地图格子

(1)声明二维数组变量(类似一维数组)

在这里插入图片描述

(2)二维数组的使用

A、获取长度:GetLength方法

//得到多少行
Console.WriteLine(array.GetLength(0));
//得到多少列
Console.WriteLine(array.GetLength(1));
}

B、获取数组中的元素

Console.WriteLine(array[0,1]);
Console.WriteLine(array[1,2]);
}

C、修改数组元素(同一类型的值)

array[0,0]=99;
Console.WriteLine(array[0,0]);
}

D、遍历(两层循环嵌套)

for(int i=0;i<array.GetLength(0);i++)
{for(int j=0;j<array.GetLength(1);j++){Console.WriteLine(array[i,j]);}
}

E、增加/删除数组元素与一位数组类似

int[,] array2=new int[3,3];for(int i=0;i<array.GetLength(0);i++)
{for(int j=0;j<array.GetLength(1);j++){array2[i,j]=array[i,j];}
}

F、查找数组元素:类似一维数组

5.交错数组(非重点知识,了解就好)

交错数组是数组的数组,每个维度数量可以i不同,二维数组的每行的列数都是相同的,但交错数组每行列数可以不同

(1)交错数组的声明

在这里插入图片描述

(2)交错数组的使用

A、获取长度

//得到多少行
Console.WriteLine(array.GetLength(0));
//得到某一行的列数
Console.WriteLine(array[0].length);
}

B、获取和修改元素

//注意:不要越界
//获取
Console.WriteLine(array[0][1]);
//修改
array[0][1]=99;
Console.WriteLine(array[0][1]);
}

C、遍历交错数组

for(int i=0;i<array.GetLength(0);i++)
{for(int j=0;j<array[i].Length;j++){Console.Write(array[i][j]+" ");}Console.WriteLine();
}

6.补充:关于数组的常见考题

(1)数组和List的区别

从大小可变性和内存分配上:List的本质是一种动态的数组。它可以通过自动扩展内部数组的容量来实现动态增长,当元素被添加到List中时,如果容量不足,它会重新分配一块更大的内存,并将原有元素复制到新的内存中,也由于List需要进行内存重新分配和元素复制,频繁地添加或删除元素可能会导致性能下降。
而Array(数组)在创建时需要指定固定容量,并且无法直接改变容量,若需要扩容,就要创建一个新的更大容量的数组,将原数组元素复制到新的数组中。
从可使用的方法上来说:list有更多的方法如add、remove、insert等,对元素操作更方便。
从使用场景上来说:需要动态增减元素的情况,或者不确定具体需要多少存储空间的时候用list,主要用于索引访问和遍历,而不需要更改内存大小,且对性能有较高要求时使用数组。

(2)数组参数是什么

数组参数指的是将数组作为参数传递给方法或函数。
当数组作为参数传递给方法时,实际上是传递了数组的引用。这意味着在方法内部对数组所做的任何修改都会影响到原始数组,也就是说方法可以访问和修改数组的元素,并且可以获取数组的长度和维度信息,最后方法可以返回对数组元素的修改,因为传递的是引用。

二、值类型和引用类型

在这里插入图片描述

1.存储和使用上的区别

存储上:值类型——存储在栈上,大小由系统分配,自动回收,小而快;
引用类型——存储在堆上,赋值时拷贝的是地址,手动申请和释放,大而慢

使用上:值类型——它变我不变;引用类型——它变我也变

假设值类型对象a赋值给了b,相当于是将内容拷贝给了b,其中a的值发生了改变,b的值不会跟着改变,而引用类型对象a赋值给了b,其实只是将引用地址赋值给了b,两者指向同一个值,若a的值发生了改变,b的值也会改变。

2.特殊的引用类型:String

String是引用类型,但在赋值使用时也是它变我不变的,原因是字符串的值存储在静态存储区,引用地址存储在栈,就算修改了字符串的值,也是在静态存储区中新分配了一块区域存储修改后的值,原先的引用地址发生了改变,指向新的值。因此假设字符串对象a赋值给了b,其中a的值发生了改变,是指a的引用地址改变了,指向了新的值,b的引用地址跟存储的值都不变 。

3.补充:常见考题

除了上述值类型与引用类型的区别、string为什么是特殊的引用类型外,还可能问到:

(1)String和StringBuilder的区别

string每次修改拼接时会重新分配内存空间,产生垃圾,而stringBuilder修改字符串时不会创建新的对象,因此需要频繁修改和拼接的字符串可以用stringBuilder,可以提升性能。但string提供了更多方法供使用,需要使用这些特殊方法来处理一些特殊逻辑时可以使用string。

(2)深拷贝和浅拷贝

浅拷贝复制对象的引用,导致原始对象和拷贝对象共享相同的数据;
深拷贝创建一个新对象并复制所有属性值,使得原始对象和拷贝对象独立开来,对其中一个对象的修改不会影响另一个对象。

三、函数(方法)

1.函数基础

(1)基本概念

函数(也称方法)本质是一块具有名称的代码块,可以使用函数的名称来执行该代码块,函数时封装代码进行重复使用的一种机制,提升代码的复用率

(2)函数写的位置

A、class语句块中 
B、struct语句块中 

【注】不能在函数中定义函数!

(3)基本语法

static 返回类型 函数名(参数类型 参数名1,参数类型 参数名2,...{函数的代码逻;return 返回值; //如果有返回值类型才返回
}//【说明】
//1、关于static 不是必须的,在没有学习类和结构体之前都是必须写的
//2、关于返回值类型引出一个关键字:void(表示没有返回值类型)
//3、返回类型可以写任意的变量类型
//4、关于函数名,一般使用帕斯卡命名法: MyName(帕斯卡命名法) myName(驼峰命名法,一般用于变量命名)
//5、参数不是必须的,可以有0~n个参数,参数也可以是任意类型的,有多个参数时需要用逗号隔开
//6、返回值类型不是void时,必须用新的关键词 return 返回对应类型的内容(即使是void也可以选择性使用return)

(4)实际运用

A、无参无返回值
在class中定义函数:

static void SayHello()
{Console.WriteLine("Hello world");//return ;
}

在main函数中调用该函数:

static void Main(string[] args)
{SayHello();
}

B、有参无返回值
定义:

static void SayYourName(string name)
{Console.WriteLine("your name is:{0}",name);//return ;
}

调用:

static void Main(string[] args)
{string str=“小梁”;SayYourName(str);
}

C、无参有返回值

定义:

static string WhatYourName()
{return "小梁";
}

调用:一般直接拿返回值来用(这里例子用了函数嵌套),要不就是拿变量接收他的结果

static void Main(string[] args)
{//直接拿返回值来用,比如这里作为参数传入其他函数中SayYourName(WhatYourName());//拿变量接收结果string str2=WhatYourName()
}

D、有参有返回值
定义:

static int Sum(int a,int b)
{return a+b;//【注】return后可以是一个值,也可以是表达式,只要表达式的结果和返回值类型是一致的就行
}

调用:

static void Main(string[] args)
{Console.WriteLine(Sum(2,5));
}

E、有参有多个返回值
定义:

static int[] Calc(int a,int b)
{int sum=a+b;int avg=sum/2;return new int[] {sum,avg};
}

调用:

//如果是数组作为返回值,那么前提是使用者知道这个数组的规则
int[] arr=Cals(5,7);
Console.WriteLine(arr[0]+" "+arr[1]);

(5)关于return

即使函数没有返回值,也可使用return;
return可以直接不执行之后的代码,直接返回到函数外部(提前结束函数逻辑)

static viod Speak(string str)
{if(str=="混蛋"){return;}Console.WriteLine(str);
}
static string Speak(string str)
{if(str=="混蛋"){return "";}return str;
}

2.ref和out:函数参数的修饰符

(1)使用ref和out的原因

ref和out都是对函数参数的修饰符,起到的作用都是使参数在函数内部改值或重新声明时,能够将外部传入的这个变量也跟着被更改。
比如定义一个这样的函数:

static void ChangeValue(int value)
{value=3;
}

传入a=1调用函数,a的值还是1:

int a=1;
ChangeValue(a);
Console.WriteLine(a);

原因就在于函数传入参数值时相当于是将a赋值给了value(value=a),结合值类型和引用类型的知识,value的值变了,a是不会变的。要做到value变a也跟着变,就要用到ref和out修饰符

(2)ref和out的使用及区别

static void ChangeValueRef(ref int value)
{value=3;
}static void ChangeValueOut(out int value)
{value=99;
}

ref和out的区别在于:使用ref,传入的变量必须初始化,但在内部可改可不改;使用out,传入的变量不用初始化,但必须在内部赋值

3.变长参数和参数默认值

(1)变长参数关键字:params

static int Sum(params int[] arr)
{int sum=0;for(int i=0;i<arr.Length;i++){sum+=arr[i];}return sum;
}

调用:

static void Main(string[] args)
{Console.WriteLine(“变长参数和参数默认值”);Sum();Sum(1,2,3,4,5,6,7);
}

【注1】params int[ ] 意味着可以传入n个int参数,n可以为0,传入的参数会存在数组中
【注2】params后面必须接数组
【注3】数组的类型可以是任意类型
【注4】参数可以有别的参数和params修饰的参数
【注5】参数中只能最多出现一个params关键字,并且一定在最后一组参数的后面,前面可以有n个其他参数

(2)参数默认值

有默认值的参数称为可选参数,其作用是 当调用函数时可以不传入参数,不传就会使用默认值作为参数的值

static void Speak(string str="无话可说")
{Console.WriteLine(str);
}

调用:

static void Main(string[] args)
{Speak();Speak("我有好多话要说");
}

【注1】支持多参数默认值,每个参数都可以设置默认值
【注2】若要混用普通参数和可选参数,那可选参数必须写在普通参数后面

4.函数重载

(1)基本概念

在同一语句块(class或struct)中,函数名相同,但参数数量不同 或者 参数数量相同但参数类型或顺序不同

(2)作用

命名一组功能相似的函数,减少函数名的数量,避免命名空间的污染,提升程序可读性

(3)实例

在这里插入图片描述

【注1】重载与返回值类型无关,只和参数的个数、类型、顺序有关。在调用时程序会自己根据传入参数的类型判断使用哪个函数进行重载
【注2】加ref、out、params也可以算作重载。但用了ref就不能用out修饰同一参数,反之亦然,可选参数不能算重载

5.递归函数

基本概念:让函数自己调用自己
在这里插入图片描述

【注】一个正确的递归函数必须要有能结束调用的条件

四、复杂数据(变量)类型——结构体

1.基本概念与作用

基本概念:结构体是一种自定义变量类型(类似枚举需要自己定义),它是数据和函数的集合,在结构体中可以申明各种变量和方法。
作用:用来表现存在关系的数据集合

2.基本语法

定义位置:一般申明写在namespace中,使用位置在函数中
作用:将变量包裹到结构体内部,将一些方法封装在结构体中
关键字:struct
访问修饰符(默认不写为private):
private:私有的,只能在内部使用
public:公有的,可以被外部访问
语法:

struct 自定义结构体名
{//第一部分//变量//第二部分//构造函数(可选)//第三部分//函数
}

【注1】结构体的名字规范是帕斯卡命名法
【注2】结构体中变量不能初始化,变量类型可以写任意类型,但不能是自己的结构体

3.实例

声明:
在这里插入图片描述
使用:

4.结构体的构造函数

(1)基本概念与作用

结构体的构造函数:
a.是一个函数,但没有返回值
b.并且函数名必须和结构体名相同
c.必须有参数
d.如果申明了构造函数,那么必须在其中对所有变量数据初始化

作用:帮助使用者快速初始化结构体对象

(2)实例

声明:
在这里插入图片描述
调用:
在这里插入图片描述

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

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

相关文章

Java毕业设计-基于ssm的仓库管理系统-第76期

获取源码资料&#xff0c;请移步从戎源码网&#xff1a;从戎源码网_专业的计算机毕业设计网站 项目介绍 基于ssm的游泳馆管理系统&#xff1a;前端jsp、jquery、bootstrap&#xff0c;后端 springmvc、spring、mybatis&#xff0c;集成游泳课程报名、游泳卡在线售卖、购物车、…

Ubuntu22.04 gnome-builder gnome C 应用程序习练笔记(二)

gnome-builder创建的程序&#xff0c;在工程树中有三个重要程序&#xff1a;main主程序、application应用程序和window主窗口程序。main整个程序的起始&#xff0c;它会操作application生产应用环境&#xff0c;application会操作window生成主窗口&#xff0c;于是就有了 appli…

Postman接口与压力测试实例

Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。它提供功能强大的 Web API & HTTP 请求调试。 1、环境变量和全局变量设置 环境变量可以使用在以下地方&#xff1a; URLURL paramsHeader valuesform-data/url-encoded valuesRaw body contentHelper fi…

AD9361多片同步设计方法

本文基于ZC706FMCOMMS5的平台&#xff0c;介绍了多片AD9361同步的方法。并将该设计移植到自行设计的ZYNQ70354片AD9361(实现8路同步收发)的电路板上。本设计采用纯逻辑的方式&#xff0c;仅使用了ZYNQ芯片的PL部分。 9361多芯片同步主要包括基带同步和射频同步两大块任务。其中…

26.云原生ArgoCD高级之ApplicationSet

云原生专栏大纲 文章目录 ApplicationSet介绍ApplicationSet 特性ApplicationSet 安装ApplicationSet 工作原理ApplicationSet 生成器列表类型生成器集群生成器基础使用方法Label Selector 指定集群Values 字段传递额外的参数 git生成器git目录生成参数排除目录git文件生成器矩…

数据结构与算法-链表(力扣附链接)

之前我们对C语言进行了一定的学习&#xff0c;有了一些基础之后&#xff0c;我们就可以学习一些比较基础的数据结构算法题了。这部分的知识对于我们编程的深入学习非常有用&#xff0c;对于一些基本的算法&#xff0c;我们学习之后&#xff0c;就可以参加一些编程比赛了&#x…

【CV论文精读】【MVDet】Multiview Detection with Feature Perspective Transformation

0.论文摘要 合并多个摄像机视图进行检测减轻了拥挤场景中遮挡的影响。在多视图检测系统中&#xff0c;我们需要回答两个重要问题。首先&#xff0c;我们应该如何从多个视图中聚合线索&#xff1f;第二&#xff0c;我们应该如何从空间上相邻的位置聚集信息&#xff1f;为了解决…

LabVIEW网络测控系统

LabVIEW网络测控系统 介绍了基于LabVIEW的网络测控系统的开发与应用&#xff0c;通过网络技术实现了远程的数据采集、监控和控制。系统采用LabVIEW软件与网络通信技术相结合&#xff0c;提高了系统的灵活性和扩展性&#xff0c;适用于各种工业和科研领域的远程测控需求。 随着…

生成验证码-超简单

引言 在Web开发中&#xff0c;验证码是一种常见的防止恶意破解、自动化提交的有效手段。在Java项目中&#xff0c;我们可以使用Hutool工具库快速实现验证码功能。Hutool是一个Java工具包&#xff0c;它以简洁易用著称&#xff0c;其中包含了验证码模块&#xff0c;可以让我们轻…

今日arXiv最热NLP大模型论文:无需数据集,大模型可通过强化学习与实体环境高效对齐 | ICLR2024

引言&#xff1a;将大型语言模型与环境对齐的挑战 虽然大语言模型&#xff08;LLMs&#xff09;在自然语言生成、理解等多项任务中取得了显著成就&#xff0c;但是在面对看起来简单的决策任务时&#xff0c;却常常表现不佳。这个问题的主要原因是大语言模型内嵌的知识与实际环…

在windows的控制台实现贪吃蛇小游戏

欢迎来到博主的文章 博主id&#xff1a;代码小豪 前言&#xff1a;看懂这篇文章需要具有C语言基础&#xff0c;还要对单链表具有一定的理解。如果你只是想要试玩这个游戏&#xff0c;可以直接在文章末尾找到源码 由于实现贪吃蛇需要调用Win32 API函数&#xff0c;这些函数我会…

npm 上传一个自己的应用(4) 更新自己上传到NPM中的工具版本 并进行内容修改

前面 npm 上传一个自己的应用(2) 创建一个JavaScript函数 并发布到NPM 我们讲了将自己写的一个函数发送到npm上 那么 如果我们想到更好的方案 希望对这个方法进行修改呢&#xff1f; 比如 我们这里加一个方法 首先 我们还是要登录npm npm login然后 根据要求填写 Username 用…

【Linux】linux自动化构建工具make/makefile

linux自动化构建工具make/makefile 一&#xff0c;makefile是什么二&#xff0c;如何写makefile三&#xff0c;文件的三个时间属性四&#xff0c;makefile的推导 一&#xff0c;makefile是什么 对于make和makefile&#xff0c;简单来说&#xff0c;make是一个命令&#xff0c;用…

VSCode python插件:找不到自定义包导致语法解析失败

众所周知&#xff0c;在python源码中&#xff0c;我们可以通过 sys.path.append("path-to-lib") 来为python解释器添加自定义包的寻找路径。 但是vscode的默认python插件可没法聪明到根据这句话去找这个包&#xff0c;这就会导致后续代码中使用了这个库的部分无法享…

个人博客搭建(总结)

文章目录 前言个人基础学习经验耗时最终搭配血泪史总结&#x1fa78;Gitee or GitHub域名-该买还是得买&#xff01;域名后缀服务器 参考博主碎碎念&#x1f64a; 前言 本网站目前只搭好了一个大概框架&#xff0c;博主没学过前端&#xff0c;所以会有许多bug和不合理的设置。…

消息中间件:Puslar、Kafka、RabbigMQ、ActiveMQ

消息队列 消息队列&#xff1a;它主要用来暂存生产者生产的消息&#xff0c;供后续其他消费者来消费。 它的功能主要有两个&#xff1a; 暂存&#xff08;存储&#xff09;队列&#xff08;有序&#xff1a;先进先出 从目前互联网应用中使用消息队列的场景来看&#xff0c;…

c入门第十篇——指针入门

一句话来说: 指针就是存储了内存地址值的变量。 在前面讨论传值和传址的时候&#xff0c;我们就已经开始使用了指针来传递地址。 在正式介绍指针之前&#xff0c;我们先来简单了解一下内存。内存可以简单的理解为一排连续的房子的街道&#xff0c;每个房子都有自己的地址&#…

华清作业day56

SQLite特性&#xff1a; 零配置一无需安装和管理配置&#xff1b;储存在单一磁盘文件中的一个完整的数据库&#xff1b;数据库文件可以在不同字节顺序的机器间自由共享&#xff1b;支持数据库大小至2TB&#xff1b;足够小&#xff0c;全部源码大致3万行c代码&#xff0c;250KB…

midnightsun-2018-flitbip:任意地址写

题目下载 启动脚本 启动脚本如下&#xff0c;没开启任何保护 #!/bin/bash qemu-system-x86_64 \-m 128M \-kernel ./bzImage \-initrd ./initrd \-nographic \-monitor /dev/null \-append "nokaslr root/dev/ram rw consolettyS0 oopspanic paneic1 quiet" 2>…

“掌握温度,感知湿度,一触即知!”DHT11温湿度传感器,为您的生活增添一份关怀与精准。#非标协议【下】

“掌握温度&#xff0c;感知湿度&#xff0c;一触即知&#xff01;”DHT11温湿度传感器&#xff0c;为您的生活增添一份关怀与精准。#非标协议【下】 前言预备知识1.DHT11温湿度传感器初识1.1产品概述1.2与51单片机接线1.3数据传送逻辑和数据格式 2.发送时序检测DHT11温湿度传感…