【C语言必学知识点六】自定义类型——结构体

news2024/11/15 11:54:51

结构体

  • 导读
  • 一、自定义类型
  • 二、结构体
    • 2.1 什么是结构体
    • 2.2 结构的声明
      • 2.2.1 构体的声明格式
      • 2.2.2 结构体的特殊声明
    • 2.3 关键字`typedef`
      • 2.3.1 `typedef`的作用
      • 2.3.2 `typedef`的使用
      • 2.3.2 `typedef`在结构体中的应用
    • 2.4 结构体变量的创建和初始化
      • 2.4.1 结构体变量创建的区别
      • 2.4.2 重命名与变量创建
    • 2.5 结构体的自引用
    • 2.6 结构体传参
    • 2.7 匿名结构体的使用
  • 结语

封面

导读

大家好,很高兴又和大家见面啦!!!

经过前面的学习,我们对C语言中的数据类型有了一个比较清晰的认识。对于数据类型,我们可以简单的理解为数据在内存中存放的形式以及所占空间的大小。

我们现在接触的数据类型char、short、int、long、float、double、bool……都是C语言提供的一些已经设定好的基础数据类型,我们可以将其称为内置数据类型。

在C语言中,除了这些内置数据类型之外,还有一系列的拓展数据类型。我们已经学过的有数组类型,与指针类型。

数组是由多个相同的数据类型的变量所组成的集合,如字符数组是由一个或多个字符类型的变量组成的集合,整型数组是由一个或多个整型变量组成的集合;

而指针类型则是表明了指针在一次操作中的权限大小 ,如字符指针在一次操作中只能够操作一个字节的内容,整型指针在一次操作中可以操作4个字节的内容。

除此之外,C语言中还存在一些自定义数据类型。那什么是自定义数据类型呢?

一、自定义类型

我们知道,计算机语言是程序员与计算机沟通的桥梁。程序员可以通过计算机语言来向计算机描述我们的现实生活中的事物,计算机则会根据计算机语言的描述将这些事物以数据的形式给展现出来。

但是对于现实世界中的事物而言,很少有能够通过单一的内置数据类型就能完成描述的事物,大部分的事物都需要两个或多个不同的数据类型才能完整的进行描述。

如描述一棵树:
我们可以通过单一的浮点型或整型来描述数的高度、宽度、叶子的数量……
我们也可以通过单一的字符型来描述树的品种、种植地、形状……
但是我们要描述一棵完整的树时,这时我们就需要同时借助浮点型或整型的数据与字符型的数据来描述这棵树的各种特征。

对于不同的事物,我们所需要的数据类型也有区别,因此为了完成不同事物的描述,我们就需要像创建函数一样创建一种新的数据类型,这种由程序员自己创建的数据类型就是 C语言中的自定义类型。

在C语言的自定义数据类型中,大致可以分为3种自定义数据类型——结构体、联合体与枚举类型。在今天的内容中我们将会学习第一种自定义数据类型——结构体类型。

二、结构体

2.1 什么是结构体

结构体是一种用来描述复杂对象的自定义的数据类型。

结构与数组一样也是一些值的集合,在结构体中这些值称为成员变量。与数组不同的是,结构的每个成员可以是不同类型的变量。

在结构体中的成员变量的数据类型可以是内置数据类型如字符型、整型、浮点型以及拓展数据类型如数组型、指针型、结构体类型……其中的一种、两种或多种不同的数据类型。

2.2 结构的声明

在函数中我们有学过,当我们要创建一个自定义行数时,我们需要先声明函数的返回类型、函数名以及函数的参数类型

在结构体中也是如此。当我们要创建一个结构体类型时,我们需要声明结构体的类型名、结构体成员的数据类型以及成员名

与创建自定义函数不同的是,在创建结构体时我们需要借助结构体关键字——struct

2.2.1 构体的声明格式

结构的声明指的是描述结构体的标签名,结构体的成员以及通过结构体定义的变量。格式如下:

struct tag {
	member_list;
}variable_list;
//struct——结构体关键字,用于结构体的声明
//tag——结构体的名字,用于表示结构体的用途
//member_list——结构体成员列表
//variable_list——结构体变量列表(可有可无)

在声明一个结构体时,有几个点需要大家注意一下:

  • struct这个关键字是不能省略的;
  • 结构体名可以根据实际情况来进行命名;
  • 结构体成员可以是一个也可以是多个成员的类型可以不相同
  • 结构体变量列表内的变量为全局变量,在声明结构体时可以不用定义变量
  • 结构体在声明完后的;是不能省略的;
  • 结构体的{}是不能省略的;

2.2.2 结构体的特殊声明

与自定义函数不同的是,在声明结构体时我们也可以不完全声明。其格式如下:

struct {
	member_list;
}variable_list;
//struct——结构体关键字,用于结构体的声明
//member_list——结构体成员列表
//variable_list——结构体变量列表

相比于正常的声明格式,特殊声明格式中可以省略结构体的名字,但是在这种情况下结构体变量列表式不能省略的,并且在完成了声明与变量创建后,我们无法再使用该结构体继续创建变量,因此这种特殊声明的结构体只能够使用一次。

2.3 关键字typedef

在C语言中有一个可以对数据类型进行重命名的关键字——typedef。这个关键字可以将内置数据类型、拓展数据类型以及自定义数据类型的名字进行重新命名,如下所示:

关键字typedef
可以看到当我们通过typedef将整型int重命名为I之后,通过I创建的变量a的数据类型就是整型,并且I所在的内存大小同样也是4个字节。

2.3.1 typedef的作用

有朋友可能就会奇怪了,typedef这个关键字的作用似乎有点鸡肋呀,我如果要创建一个整型变量的话,我直接使用int不就完事了吗?简单又方便,何必将其重命名呢?

typedef的作用可以将其总结为两点:1.简化数据类型名、2.方便代码修改。

第一个作用简化数据类型名,相信大家从上面的这个列子都能感受得到。对于int类型原先时三个字母,当我们通过typedef重命名后,就变成了1个字母,确实时简化了数据类型名。

但是对于第二个作用方便代码修改,咱们却没啥感觉。下面我们来看一个列子:

关键字typedef2

在这个例子中我们通过两个函数分别完成值的交换以及输出,可以看到此时我们输出的是整型,当我想输出字符时,按照以往的编程方式,我们要么重新写一下同样的代码,要么将所有函数中的变量类型进行修改,但是借助typedef后,我们只需要修改typedef这一行的int,如下所示:

关键字typedef
可以看到,当我们将int改为char之后,函数在输出时由整数变成了字符。相比于之前的修改方式,很显然借助了typedef后代码的整体修改就简单了很多。

2.3.2 typedef的使用

当我们在使用typedef时我们一定要注意,typedef只能够重命名数据类型,它是无法重命名变量名的,如下所示:

关键字typedef4
可以看到,当我们通过typedef来重命名变量时,系统会提示变量x不是类型名,以及不允许使用类型名y进行输出。这个大家一定要注意,typedef只能够修改数据类型的名字

2.3.2 typedef在结构体中的应用

当我们在创建结构体时,我们需要注意的是我们创建的是一个自定义数据类型,因此,结构体的类型名字是可以通过typedef来进行修改的。

这时有朋友就会说了,我为什么需要借助typedef来修改呢?如果想名字简单点,我直接在声明结构体的时候设置一个简单点的名字不就好了吗?如下所示:

struct t {
	int a;
	char b;
	short c;
};

void test4() {
	t a;
}

这样不就很方便吗?完全用不上typedef

那真的是这样吗?下面我们来运行一下该代码,如下所示:

关键字typedef5
从系统提示中可以看到,我们在完成类型声明并通过该类型名创建变量后,程序居然报错了,报错的原因时't'是一个未声明的标识符。为什么会这样呢?我们在前面不是已经声明了吗?

其实像我们这种使用方式是不对的,对于结构体这种自定义类型而言,其关键字就是该自定义类型的一部分,因此当我们在声明好一个结构体类型之后,我们在使用时,是需要加上关键字struct,也就是说在这个例子中struct t才是我们声明的结构体类型名,如下所示:

关键字typedef6
可以看到,此时我们才是完成了结构体类型的声明与结构体变量的创建。

也就是说,每当我们创建一个结构体变量时,我们都需要使用struct t来完成创建,很显然这样的创建方式是比较繁琐的,因此我们就可以在声明结构体类型时借助typedef来对结构体类型进行重命名,如下所示:

关键字typedef7
可以看到,此时我们再使用t来创建变量时就不会发生错误了。

2.4 结构体变量的创建和初始化

在结构体中,变量的创建有两种方式——1.在声明时创建,2.在使用时创建。如下所示:

//结构体变量的创建与初始化
struct test {
	int a;
	char b;
	short c;
}t1, t2, t3;//在声明时创建了三个结构体变量

void test5() {
	struct test t4, t5, t6;//在使用时创建了三个结构体变量
}

当我们要对其进行初始化时,同样也有两种方式

  1. 按默认顺序进行初始化——根据结构体类型声明时的成员列表中的成员顺序进行初始化
  2. 按指定顺序进行初始化——借助结构体成员访问操作符来指定初始化对象的顺序

这两种初始化方式如下所示:

结构体变量的创建与初始化
可以看到,当我们在初始化时赋值一个0时,表示的是按结构体成员的默认顺序进行值为0的初始化,并且我们在初始化阶段,不管是按默认顺序进行初始化,还是按照指定顺序进行初始化,都不会影响结构体的初始化。

2.4.1 结构体变量创建的区别

当我们在创建结构体变量时,对于不同的创建方式,其效果也是有区别的:

  • 当我们在声明结构体时创建变量,那么该变量的作用域与结构体声明时的作用域是一致的
  • 当我们在使用结构体时创建变量,那么该变量的作用域与结构体使用时的作用域是一致的

如下所示:

结构体变量的创建与初始化2

可以看到,对于结构体struct test而言,它是在全局域中进行声明的,因此其结构体变量t1/t2/t3都是属于全局变量,而结构体struct test2是在局部域中进行声明的,因此其结构体变量t7属于局部变量;

对于变量t4/t5/t6/t8/t10而言他们都是struct test在局部域中使用时创建的变量,因此它们都是局部变量,同理,变量t9struct test2在局部域中使用时创建的变量,因此t9也是一个局部变量。

这里我们需要注意的是,t1/t2/t3t7都是在进行结构体声明时创建的变量,它们实际上等价于先声明再使用的形式,如下所示:

结构体变量的创建与初始化3
这也就是为什么我们在声明时可以没有变量列表的原因。

2.4.2 重命名与变量创建

当我们对数据类型进行重命名时,有一点需要注意,重命名的过程中是无法创建变量的,如下所示:

结构体变量的创建与初始化4
因此,当我们在声明结构体类型并进行重命名时,我们是无法同步创建结构体变量的,如下所示:

结构体变量的创建与初始化5
可以看到,当我们对结构体完成重命名后,并尝试着像之前一样同步创建变量t11时,结果出错了,错误的原因时在'='前并未声明变量,也就是说此时的t11并不是变量名,它实际上和test一样都是属于结构体struct test重命名后的别名,也就是说此时我们是既可以通过test来创建变量,也可以通过t11来创建变量的,如下所示:

结构体变量的创建与初始化6
也就是说当我们在声明结构体时同步创建变量的操作与重命名的操作只能够进行二选一:

  • 如果我们要同步创建变量,那我们就不能够进行重命名
  • 如果我们要对结构体进行重命名,那我们就不能同步创建变量

2.5 结构体的自引用

在前面我们有提过,结构体成员的数据类型可以是内置数据类型、拓展数据类型以及自定义数据类型,中的一种或多种类型。那也就是说这个自定义数据类型既可以指其它的结构体类型,同样也可以指本身的结构体类型。那是不是这样呢?下面我们来简单的测试一下:

结构体的自引用
可以看到,此时系统是报错的,报错的内容时语法错误,test是一个标识符。这是为什么呢?test难道不应该是我们重命名后的数据类型名吗?

这是因为计算机并不具备跳跃性思维,它能够执行的操作就是一步一步的顺着代码从上往下运行。在这个例子中我们可以看到,此时的test在完成重命名的过程是在结构体成员后的,因此,当程序运行到这一行时,结构体并未完成重命名。那是不是说只要我加上了关键字struct就行了呢?下面我们继续来测试:

结构体的自引用2
从测试结果中我们可以看到,此时任然是有问题的,问题的原因时未定义的struct test,但是我们在这句代码前已经完成了定义了呀,为什么会这样呢?

导致这个问题的原因是在结构体成员列表中,能够存在的自定义类型只能够是其它的结构体类型。当在结构体成员列表中含有自身的自定义类型时,我们可以设想一个场景,这个结构体需要占用的内存空间是多少?也就是sizeof(struct test)的值是多少?

相信大家已经意识到这个问题了,在这种情况下,如果要计算该结构体的内存大小时,它会陷入到一个死循环中,这就会导致无法计算该结构体所占的内存空间大小。

那既然在结构体中无法使用自身的类型,那结构体的自引用是指的什么呢?

实际上结构体的自引用的含义是在结构体中包含一个与自身同类型的结构体指针,如下所示:

结构体的自引用3
可以看到此时程序是能够正常运行的。那现在问题来了,这个自引用有什么含义呢?

这里就涉及到【数据结构】的相关内容了。所谓的数据结构我们可以理解为是数据与数据之间一种或多种关系,包括逻辑上的关系、存储上的关系以及数据与数据之间的运算方式。

数据与数据在逻辑上可能是一个挨着一个的线性关系,也有可能是像一棵树一样从一个数据发散开的树形关系,也有可能是像蜘蛛网一样的网状关系,如下所示:

逻辑结构
数据与数据在存储上可能是紧挨着的顺序存储,也可能是由一根链条连接的链式存储,还有可能是根据相应的索引信息进行存放的索引存储,又或者可以通过相应关键字找到对应数据的散列存储,如下所示:

存储关系
数据与数据之间可以进行算术运算、拷贝、连接、比较、增加、删除……

对于不同的数据结构,其数据在逻辑上、存储上、数据之间的运算上都有不同,这里我们需要介绍的是链式存储。

在链式存储中,每个数据都是存放在一个结点中,不同的数据之间是通过一根链条进行连接的,那我们在计算机语言中应该如何描述这根链条呢?

有朋友已经反应过来了,没错,就是借助指针来模拟链条。

我们知道指针存储的是数据的地址,我们可以通过指针中存储的地址来找到对应的数据。在链式存储中,由于结点都是分散的存放在内存中的,因此我们想要从一个结点找到另一个结点,那我们就可以将该结点的数据存放在自己的结点中,用C语言来描述的话就是结构体的自引用操作。

如下所示:

链式存储
在链式存储中,由结构体创建的变量我们可以将其称为结点,在每个结点中我们都需要存放对应的数据,因此我们可以规定结构体中存放数据的区域为数据域,而我们还要能够从一个结点找到其它结点,因此每个结点中我们还需要一个存放下一个结点地址的指针,所以我们可以规定结构体中存放与指针的区域称为指针域,而对于每个结点来说,它们的都是由同一个结构体进行创建的,所以每个结点的数据类型都是一致的,因此结点指针域的数据类型是与自身相同数据类型的指针类型。

2.6 结构体传参

在函数中我们有学过,函数的传参方式有两种——传值传参与传址传参。这两种传参方式的区别是:

  • 传值传参——函数形参是实参的一份临时拷贝
  • 传址传参——函数形参是指向实参的指针

对于结构体变量而言,两种传参方式都是可行的,但是建议大家使用传址传参。有朋友可能会奇怪,为什么要使用传址传参呢?下面大家来看这个例子:

//结构体的传参
typedef struct test {
	int data[100000];//数据域
	struct test* next;//指针域
}test;
void func(test t) {

}

void test8() {
	test t = { 0 };
	func(t);
}

在这个例子中可以看到,结构体的一个结点的数据域就需要100000个整型空间,在这种情况下,如果我直接进行传值传参,那对于形参t来说,它就需要在内存中开辟至少100000个整型空间,很显然,这并不是一个明智之举。

想象一下,在func函数中如果是进行递归操作,那么每一次递进都需要在内存中开辟至少100000个整型空间,这样就很容易导致栈溢出的问题。

但是如果我们是通过传址传参,每次传参只是传入的结点的地址,那也就是说,即使函数是执行的递归操作,那我们在函数中也只需要开辟一个能够存放地址的指针空间即可,这样我们就可以最大程度上的避免栈溢出的问题。

这时有朋友可能就会说了,如果我不想修改实参的数据,那使用传址传参的过程中如果操作失误的话不就容易导致实参中的数据也被修改了吗?

对于这个问题的处理很简单,我们只需要通过const来修饰形参即可,如下所示:

//结构体的传参
typedef struct test {
	int data[100000];//数据域
	struct test* next;//指针域
}test;
void func(const test* pt) {
	func(pt);//这里的pt已经是指针了,所以在递归的过程中就不需要取地址了
}

void test8() {
	test t = { 0 };
	func(&t);
}

这里要注意,我们用const修饰的应该是*pt,也就是说我们不同通过解引用的方式来修改实参的数据。

现在肯定有朋友会存在疑惑,为什么前面介绍的结构体的各种内容都是以正常声明的格式来介绍的,那对于通过特殊声明的格式声明的一个匿名结构体,我们又应该如何使用呢?下面我们就一起来探讨一下匿名结构体的使用;

2.7 匿名结构体的使用

前面我们有提过,当我们声明一个匿名结构体时,该结构体只能够使用一次,我相信有朋友对这个只能使用一次是不能理解的,下面我们就来解释一下为什么它只能够使用一次。如下所示:

匿名结构体的使用

可以看到我们第一次声明了一个匿名结构体,并创建了一个结构体变量t1,之后我们又声明了一个结构体成员与上一个匿名结构体相同的匿名结构体,并创建了一个结构体变量t2与一个结构体指针pt

在测试函数中我们可以看到我们通过指针pt来接收t2的地址时,程序并未报错,说明对于结构体变量t2与结构体指针pt而言,它们的数据类型是相同的。

但是当我们用pt来接收t1的地址时,我们会发现此时程序报了警告,警告的内容是操作符两侧的类型不兼容。

也就是说,即使这两个匿名结构体的结构体成员是一致的,但是,系统会认为它们是两个不同的结构体类型。

这也就是为什么说匿名结构体只能够使用一次。并且由于匿名结构体的这种使用特性,导致它是无法进行自引用操作的。

这时有朋友可能就会说了,咱们不是可以通过typedef来进行重命名吗?那我在声明匿名结构体时对其重命名不就好了吗?如下所示:

匿名结构体的使用2
可以看到,当我们通过typedef对匿名结构体进行重命名后,它就可以多次使用了。那是不是就意味着它也能够执行结构体自引用操作了呢?如下所示:

匿名结构体的使用3
哇……居然一片红,这是为什么呢?

这个问题又回到了计算机的执行流程上了。

对于计算机而言,它只能够根据代码从上往下一行一行的执行,因此当程序走到t* next;这一行时,此时的匿名结构体并未完成重命名,这时的t它也就是一个陌生的标识符,因此程序就出现了报错。

也就是说,结构体的声明失败了,那么对于函数中的结构体变量的创建也自然就不能成功创建,因此测试函数中的所有内容都是错误的,究其根本,是因为结构体的声明并未成功。

因此我们可以得到以下结论:

  • 匿名结构体只能够在声明的同时创建变量,也就是匿名结构体只能使用一次;
  • 当通过typedef将匿名结构体重命名后,该匿名结构体就能够多次使用;
  • 不管有没有对匿名结构体进行重命名,它都无法进行自引用操作;

结语

今天的内容到这里就全部结束了,在下一篇内容中我们将介绍《内存对齐与位段》的相关内容,大家记得关注哦!如果大家喜欢博主的内容,可以点赞、收藏加评论支持一下博主,当然也可以将博主的内容转发给你身边需要的朋友。最后感谢各位朋友的支持,咱们下一篇再见!!!

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

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

相关文章

系统一执行systemctl就报错`No space left on device`,全部拿下

前言 在现代计算机系统中,存储空间似乎总是无尽的,但当你突然看到“No space left on device”的错误消息时,那种突然的焦虑感可不是开玩笑的。这就像是你在一个精心设计的房间里忽然发现最后一块空地也被填满了——这时候你会发现&#xff…

12kg级折叠翼巡飞无人飞行器技术详解

12kg级折叠翼巡飞无人飞行器(以下简称“飞行器”)是一种集高机动性、长续航、易于部署于一体的先进无人机系统。该飞行器设计巧妙,能够在复杂环境中灵活飞行,执行侦察、监测、目标跟踪、通信中继等多种任务。其独特的折叠翼设计大…

电路基础 ---- 电压源、电流源、受控电源

1 电压源 定义:两端电压总是保持定值,与流过它的电流无关 1.1 分析 对于如下电路: 当 R → 0 R\to 0 R→0(短路)时, i ∞ i\infty i∞(会烧坏电压源)当 R → ∞ R\to\infty R…

EPLAN中部件库的导入和使用方法

EPLAN中部件库的导入和使用方法 如下图所示,点击工具-----部件------管理, 在弹出的窗口中点击附加------导入, 找到自己需要导入的文件,后缀名为EDZ,点击打开, 如下图所示,勾选"更新已有数据集并添加新建数据集",点击确定, 如下图所示,正在导

光影漫游者:科技感十足的圆形气膜场馆—轻空间

在现代品牌发布会和大型活动中,场馆的选择往往直接影响活动的整体效果。随着科技的不断进步和品牌对创新展示空间的需求增加,越来越多的企业开始寻求兼具科技感和视觉冲击力的场地。光影漫游者,以其独特的圆形气膜外形和先进的科技感设计&…

基于Django的MySQL项目建设计划

构建一个基于 Django 和 MySQL 的项目需要经过多个阶段的规划和实施。以下是一个详细的建设计划,分为项目准备、开发、测试和部署等几个关键阶段。 1、问题背景 为了完成大学的 “问答网站” 项目,需要在几天内完成项目的计划,并于下周二准备…

Qt QGraphicsView实现图片放缩、鼠标拖动移动、鼠标点位置放大缩小_图片查看

QtQGraphicsView实现图片放缩、鼠标拖动移动、鼠标点位置放大缩小 头文件&#xff1a; #ifndef TIMGWIDGET_H #define TIMGWIDGET_H#include <QGraphicsItem> #include <QMainWindow> #include <QObject> #include <QWidget>// class TImgWidget : pu…

快准齐的机器视觉:用上了就知道,检测还能怎么玩

随着工业4.0的到来 &#xff0c;工厂追求自动化&#xff0c;智能化的发展需求越来越高&#xff0c;机器视觉技术的发展也越来越受到人们关注。机器视觉能做什么&#xff0c;能做到什么程度很多人都只是有一定的了解&#xff0c;今天就这案例给大家看看。 这是一个端子生产委托…

基于Java实现(MVC)图书管理系统

需求分析 系统用户分为&#xff1a;借阅者&#xff08;包括学生、教师及其他用户&#xff09;、管理员 借阅者的主要功能&#xff1a; 个人信息管理&#xff1a;查看、修改个人基本信息&#xff1b;查询图书、借书、还书、查询借阅记录、本人可借图书总数、目前在借的数量等&…

基于jetpackCompose实现最简单的悬浮窗效果

最近在研究使用compose框架实现悬浮窗效果&#xff0c;期间遇到很多问题&#xff0c;各种搜索结果琳琅满目&#xff0c;不是插件就是非常复杂的代码&#xff0c;只能潜心研究&#xff0c;最后得出了这个几行代码就能实现悬浮窗的方案。 为了技术人的脑力能得到应有的回报&#…

PTA - C语言接口题集

目录 6-1 计算两个复数之积&#xff08;结构体函数&#xff09;6-2 字符定位&#xff08;返回字符的地址&#xff0c;指针&#xff09;6-3 求结构体平均成绩&#xff08;变量名(数组名)用.;指针(带有*)用->&#xff09;6-4 删除字符串中数字字符6-5 使用函数找出数组中的最大…

系统更新报“更新失败“

系统更新报"更新失败" 本章只针对统信UOS系统 系统检查更新失败&#xff0c;或者系统更新的过程中失败&#xff0c;或者提示依赖错误&#xff0c;检测更新失败。 故障处理&#xff1a; 检查下网络是否正常&#xff0c;系统时间是否正常&#xff1b;开启开发者&…

MOS管驱动电路阻值如何选取?以及为什么要有下拉电阻

开通时&#xff0c;电源为高电平&#xff0c;会通过Rg1给MOS的Cgs充电&#xff0c;关断时&#xff0c;Cgs通过Rg2放电.实现慢开快关的过程 如果驱动阻值太大&#xff0c;开关会很慢&#xff0c;会让MOS管的损耗增加&#xff0c;降低了效率&#xff0c;dv/dt&#xff0c;di/dt也…

电路基础 ---- 运放里的虚短虚断

令人稀里糊涂的虚短虚断 想必好多人在学习硬件电路分析时&#xff0c;都会听到虚短虚断这个专业术语&#xff0c;但是对于新手玩家&#xff0c;这个术语不好理解&#xff0c;比如我自己&#xff0c;经常将这两个概念混淆。最近刷到大佬的视频&#xff0c;讲解的非常简洁易懂&a…

蓝卓与用友、中控签署全面战略合作协议

8月9日&#xff0c;蓝卓数字科技有限公司&#xff08;以下简称“蓝卓”&#xff09;与用友网络科技股份有限公司&#xff08;以下简称“用友网络”&#xff09;与中控技术股份有限公司&#xff08;以下简称“中控技术”&#xff09;签署全面战略合作协议。三方将在平台产品融合…

MySQL5.7版本实现数据库审计功能

一、基本介绍 MySQL 数据库审计&#xff08;MySQL Database Auditing&#xff09;主要将用户对数据库的各类操作行为记录审计日志&#xff0c;以便日后进行跟踪、查询、分析&#xff0c;以实现对用户操作的监控和审计。审计是一项非常重要的工作&#xff0c;也是企业数据安全体…

1412312

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

BugKu练习记录:你喜欢下棋吗

题目&#xff1a; 密码全为小写&#xff0c;格式bugku{} 解压密码&#xff1a; 你喜欢下棋吗&#xff1f; 解压密码为小写 4423244324433534315412244543棋盘密码解密&#xff1a; thisispolybius用这个密码解压&#xff0c;打开flag.txt文件 一种5bit的编码 bugku里面的内…

Transformer 动画揭秘:数据处理的四大关键技术

0背景 Transformer 大模型&#xff0c;一种基于自注意力机制的神经网络架构&#xff0c;已被广泛应用于各种自然语言处理任务&#xff0c;比如&#xff1a;机器翻译、文本摘要、生成问答等。 从端到端的角度来看&#xff0c;Transformer 大模型中数据的处理流程主要包括四个阶…

基于matlab的行人和车辆检测系统

基于matlab的行人和车辆检测系统 【目标检测】基于计算机视觉&#xff0c;含GUI界面 算法&#xff1a;二帧差分法&#xff0c;三帧差分法&#xff0c;混合高斯建模&#xff0c;ViBe算法。 功能&#xff1a;对视频中出现的动态目标进行逐帧作差分析或ViBe算法检测&#xff0c;使…