自定义类型——结构体,枚举,联合(详,真的太详了)

news2024/11/15 14:20:28

一.结构体

1.1什么是结构体,结构体如何声明和定义变量?

结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
struct 变量名
{
     不同类型的成员变量;
};   一定要记得在花括号的后面加上分号

声明结构体: 

首先声明结构体用到的关键字是struct,当我们要描述一个对象时,需要多个不同类型的变量,比如说声明一个学生的结构体变量,需要多种不同类型的成员变量,定义一个名字需要的是字符串,定义年龄身高之类的需要的是单精度浮点数,定义学生的学号需要的是数组等,这些都算是关于学生的成员变量,这些就是我们声明的结构体。

#include<stdio.h>

struct student    //定义结构体时是在主函数外部定义的
{
	char name[10];//学生姓名;
	int id[15];   //学生学号
	int age;      //年龄
	float hight;  //身高
};


 
int main()
{
	return 0;
}

定义结构体变量: 

已上代码结构体定义完成后,上面的是struct student 相当于是类型,我们在主函数创建变量时就可以直接使用这个类型。给结构体对象赋初始值时,我们用的方式是(对象名 +  . )比如说我们定义A变量来表示A同学,定义B变量来表示B同学等,同时创建的对象的方式有两种。


第一种:

在主函数定义变量并初始化

#include<stdio.h>

struct student
{
	char name[10];
	int id[8];
	int age;
	float hight;
};


 
int main()
{
	int i = 0;
	struct student A = { "LiHua",{2,0,2,3,0,7,1,3},18,175.5 };
	printf("名字是%s 年龄是%d 身高是%.2f ", A.name, A.age, A.hight);
	printf("学号是");
	for (i = 0; i < 8; i++)
	{
		printf("%d", A.id[i]);//因为学生学号是整型数组,所以在打印时要用for循环遍历输出
	}

	return 0;
}

运行代码如下:

第二种:

在声明结构体时同时定义变量

#include<stdio.h>

struct student
{
	char name[10];
	int id[8];
	int age;
	float hight;
}B = { "XiaoMing",{2,0,2,3,0,7,1,3},20,180.7};


 
int main()
{
	int i = 0;
	printf("名字是%s 年龄是%d 身高是%.2f ", B.name, B.age, B.hight);
	printf("学号是");
	for (i = 0; i < 8; i++)
	{
		printf("%d", B.id[i]);//同理,因为学号是整型数组,打印整型数组要用for循环
	}
	
	return 0;
}

运行代码如下:

1.2结构体的特殊声明(匿名结构体类型)

在声明结构的时候,可以不完全的声明,相当于就是没有标签名,如下代码:

匿名结构体有两处限制的地方。


第一,因为没有标签名,即使两个匿名结构体的成员变量是相同的,编译器也会认为这是两种不同的类型。所以一般情况下,匿名结构体我们只能使用一次。

如下面代码:


#include<stdio.h>

struct
{
	char name[10];
	int id[8];
	int age;
	float hight;
}A;                  //声明匿名结构体
struct
{
	char name[10];
	int id[8];
	int age;
	float hight;
}*B;                 //声明匿名结构体指针
  
int  main()
{
	B = &A;          //成员变量相同,试图讲A的地址赋给指针B
	return 0;
}

能正常运行,但是发现有警告,即使两个结构体的成员都是相同的,编译器依然会把上面的两个声明当成完全不同的两个类型,所以是非法的。

第二,因为匿名结构体没有标签名,所以无法在主函数定义变量;

#include<stdio.h>

struct
{
	char name[10];
	int id[8];
	int age;
	float hight;
};


int  main()
{
	struct  A = { "LHY",{2,0,2,3,0,7,1,3},19,180.6 };
         //注意是没有标签名的
	return 0;
}

 运行报错,原因总的来说就是匿名结构体没有标签名,所以无法在主函数定义变量

1.3结构体自引用

在结构体里面的成员变量存放的是自己的结构体类型变量 


当我们直接在结构体中放入自己结构体类型的成员变量,可以吗?

struct Node
{
 int data;
 struct Node next;
};

int main()
{
	int sz = sizeof(struct Node);
	printf("%d", sz);
	return 0;
}

当我们尝试运行代码时,发现报错了。对代码进行调整 ,放入的是自己的结构体类型指针

#include<stdio.h>

struct Node
{
	int data;
	struct Node* next;
};
int main()
{
	int sz = sizeof(struct Node);
	printf("%d", sz);
	return 0;
}

运行代码如下:

 所以结构体的自引用是需要放入自己结构体类型指针的,这是为什么呢?

这就涉及到数据结构了, 数据结构描述的是数据在内存中的组织结构,相关的有线性数据结构和树形数据结构,这里要讲线性数据结构。


有顺序的,那自然有乱序的,当数据在内存中的位置是互相是乱序时,我们得想办法让数据之间发生关联,相当于是知道一个,就可以知道全部。

存储一个数据的结构相当于一个是一个节点,,比如我们有存储数据的五个节点,节点不仅存放数据,还存放下一个节点的地址(既然是地址,当然是用指针存放),这样就可以通过一个节点,可以访问到下一个节点了。这样的结构,我们称为链表。而在结构体中存放数据的,成为数据域,存放指针的,成为指针域。

 1.3结构体嵌套

在结构体中成员嵌套放入另外一个结构体。

比如我在声明“老师”的结构体里面,放入”学生“的结构体变量;注意在引用Student的结构体成员时是要用两次 ” . "



struct Student
{
	char name[20];
	int age;
};
struct Teacher
{
	char name[20];
	int age;
	struct Student stu;
};

int main()
{
	struct Teacher C = { "zhangsan",29,{"Lihua",18} };
	printf("老师名字是%s年龄是%d\n学生名字是%s年龄是%d", C.name,C.age ,C.stu.name, C.stu.age);
	return 0;
	
}

运行代码如下:

1.4结构体传参

结构体是一种类型,在函数调用,传参可以是直接传入结构体,也可以传入结构体的地址,但是又区别:

传入结构体时,函数内的任何操作都是对拷贝结构体的修改,不会影响到原本的结构体变化。

传入结构体地址时,该在函数用结构体指针接收,指针指向的是结构体起始地址,函数里的操作会改变结构体里面的内容,如果想要不被改变,可以加 const 修饰符。

如下面的代码:

#include <stdio.h>
struct S
{
	int data[1000];
	int num;
};
struct S s = { {1,2,3,4}, 1000 };
//结构体传参
void print1(const struct S s)
{
	printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
	printf("%d\n", ps->num);
}
int main()
{
	print1(s);  //传结构体
	print2(&s); //传地址
	return 0;
}

 一般情况,函数调用时是传结构体好呢,还是传结构体地址好呢?

答案:传结构体地址好。

原因:
函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销。
如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。
结论:结构体传参的时候,要传结构体的地址。

 *1.5结构体内存对齐

我们已经掌握了结构体的基本使用了。 现在我们深入讨论一个问题:计算结构体的大小。
请看下面的代码,并尝试计算结构体的大小。
//代码1;
struct S1
{
	char c1;
	int i;
	char c2;
};

//代码2;
struct S2
{
	char c1;
	char c2;
	int i;
};

int main()
{
	printf("%d\n", sizeof(struct S1));
	printf("%d\n", sizeof(struct S2));
	return 0;
}

代码1和代码2都是结构体,里面的成员内容也是一样的,那它们的大小是否相同呢?

运行代码如下:

 结果发现代码1和代码2的结构体大小是不一样的,为什么呢?因为结构体有对齐规则(四点)

结构体的对齐规则:(同时以第一个代码为例)
1. 第一个成员在与结构体变量偏移量为0的地址处。
通俗点讲就是结构体的第一个成员占据的是内存的起始位置(从0开始)
比如:
struct S1
{
	char c1;
	int i;
	char c2;
};

char c1 是结构体的第一个成员,字符类型,大小是一个字节。


2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。(VS默认对齐数是8,gcc没有默认对齐数)(我用的是VS)
第一个成员 char c1位置已经放好了,如上图。
第二个成员 int i ,字节大小是4个字节,比默认对齐数小,又需要整数倍,所以位置对应是4的(1*4,整数倍是1);

第三个成员是 char c2,字节是一个大小,比默认对齐数小,位置对应整数倍,其实就是下一个位置。


3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
根据上面的成员占据的内存大小,应该是9个字节才对(0~8),但是结构体大小是最大对齐数的整数倍,上面的代码最大的对齐数是 4 (因为是 int ),所以应该是12个字节。


4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
S3的最大对齐数是8,S4的最大对齐数也是8,在对其过程中是32是8的整数倍
所以结构体大小是32个字节。
 


#include<stdio.h>

struct S3
{
	double d;
	char c;
	int i;
};

struct S4
{
	char c1;
	struct S3 s3;
	double d;
};
int main()
{

    printf("S3的结构体大小为%d\n", sizeof(struct S3));
	printf("S4嵌套S3的结构体大小为%d\n", sizeof(struct S4));
	return 0;
}

 

上面的结构体内存对齐,有时候会浪费空间,那 为什么存在内存对齐 ?
大部分的参考资料都是如是说的:
1.平台原因 ( 移植原因 )
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特 定类型的数据,否则抛出硬件异常。
2. 性能原因
数据结构 ( 尤其是栈 ) 应该尽可能地在自然边界上对齐。 原因在于为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
总体来说:
结构体的内存对齐是拿空间来换取时间的做法。
那在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到:
让占用空间小的成员尽量集中在一起。
举一个简单的例子:
示例代码:
struct S1
{
 char c1;
 int i;
 char c2;
};
struct S2
{
 char c1;
 char c2;
 int i;
};

运行代码: 

 1.6修改默认对齐数

使用  #pragma 这个预处理指令,可以改变我们的默认对齐数。

#include <stdio.h>
#pragma pack(8)//设置默认对齐数为8
struct S1
{
	char c1;
	int i;
	char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
#pragma pack(1)//设置默认对齐数为1
struct S2
{
	char c1;
	int i;
	char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
int main()
{
	//输出的结果是什么?
	printf("%d\n", sizeof(struct S1));
	printf("%d\n", sizeof(struct S2));
	return 0;
}

运行代码:

结论: 结构在对齐方式不合适的时候,我么可以自己更改默认对齐数。

二.位段

2.1什么是位段

位段的声明和结构是类似的,有两个不同:
1.位段的成员必须是 intunsigned int signed int
2.位段的成员名后边有一个冒号和一个数字。
如下代码, A 就是一个位段类型。
#include <stdio.h>
struct A
{
	int _a : 2;
	int _b : 5;
	int _c : 10;
	int _d : 30;
};
int main()
{
	printf("%d\n", sizeof(struct A));
	return 0;

}
那位段 A 的大小是多少?
这是怎么得来的呢?这就要看 位段的内存分配了

2.1位段的内存分配

1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
2. 位段的空间上是按照需要以 4个字节( int )或者1个字节( char )的方式来开辟的
3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

struct S
{
 char a:3;
 char b:4;
 char c:5;
 char d:4;
};
struct S s = {0};
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;

int main()
{
   printf("%d",sizeof(struct S);
   return 0;
}

位段上的空间根据四个字节(int)或一个字节(char)开辟空间,一个字节就是8个比特位,位段上的数字,单位就是比特位,,存储顺序我按照的是小端存储比如 char a:3 的意思就是在一个字节中的8个比特位占据3个比特

 占3个比特位后剩余5个比特位,如果下一个成员占据的空间不超过5比特位,就会在同一块空间中放入,否则就自己重新开辟一块空间。

在给结构体赋初始值时,初始值十进制转化成二进制,再从低位对应的位段开辟的数位,比如char a:3,就取后面3位,再放入内存中。如下图。

观察数据在内存中的改变:如下图

 2.2位段的跨平台问题 

1. int 位段被当成有符号数还是无符号数是不确定的。
2. 位段中最大位的数目不能确定。( 16 位机器最大 16 32 位机器最大 32 ,写成 27 ,在 16
器会出问题。
3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是 舍弃剩余的位还是利用,这是不确定的。
总结:
跟结构相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题存在。

2.3 位段的应用

1.可以使数据单元节省储存空间,当程序需要成千上万个数据单元时,这种方法就显得尤为重要。

2.位段可以很方便的访问一个整数值的部分内容从而可以简化程序源代码。

常用于数据包的传送 

三.枚举

 3.1什么是枚举

枚举顾名思义就是列举,把可能的取值一 一列举。枚举的关键字是 enum
比如以下代码:

列举一周的星期:
enum Day//星期
{
 Mon,
 Tues,
 Wed,
 Thur,
 Fri,
 Sat,
 Sun
};

列举颜色:

enum Color//颜色
{
 RED,
 GREEN,
 BLUE
};

以上定义的 enum Day   enum Color 都是枚举类型。 { }中的内容是枚举类型的可能取值,也叫 枚举常量
这些可能取值都是有值的,默认从 0 开始,一次递增 1
#include <stdio.h>
enum Day
{
		Mon,
		Tues,
		Wed,
		Thur,
		Fri,
		Sat,
		Sun
};
int main()
{
	printf("%d\n",Mon);
	printf("%d\n", Tues);
	printf("%d\n", Wed);
	printf("%d\n", Thur);
	printf("%d\n", Fri);
	printf("%d\n", Sat);
	printf("%d\n", Sun);



	return 0;

}

运行代码如下:


当然,我们也可以赋初始值,赋初始值后,后面的值也会跟着递增1。

#include <stdio.h>
enum Day
{
		Mon = 1,
		Tues,
		Wed,
		Thur,
		Fri,
		Sat,
		Sun
};
int main()
{
	printf("%d\n",Mon);
	printf("%d\n", Tues);
	printf("%d\n", Wed);
	printf("%d\n", Thur);
	printf("%d\n", Fri);
	printf("%d\n", Sat);
	printf("%d\n", Sun);



	return 0;

}


#include <stdio.h>
enum Color//颜色
{
	RED = 1,
	GREEN,
	BLUE = 4,
	Black= 256
};
int main()
{
	printf("%d\n", RED);
	printf("%d\n", GREEN);
	printf("%d\n",BLUE);
	printf("%d\n", Black);


	
	return 0;

}

运行代码如下: 


3.2枚举的使用 

只能拿枚举常量给枚举变量赋值

#include <stdio.h>
enum Color//颜色
{
	RED = 1,
	GREEN = 2,
	BLUE = 4
};

int main()
{
	enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
	printf("%d\n", clr);
	clr = 15;               
	printf("%d\n", clr);
	return 0;
}


运行代码如下:


3.3枚举的优点

我们可以使用 #define 定义常量,为什么非要使用枚举? 枚举的优点:
1. 增加代码的可读性和可维护性
2. #define定义的标识符比较枚举有类型检查,更加严谨。
3. 防止了命名污染(封装)
4. 便于调试
5. 使用方便,一次可以定义多个常量

四. 联合(共用体)

4.1什么是联合体 

联合也是一种特殊的自定义类型.
这种类型定义的变量也包含一系列的成员,特征是这些成员共用同一块空间(所以联合也叫共用体)。
比如以下代码:
#include<stdio.h>

union Un
{
	char c;
	int i;
};
int main()
{
	printf("%d\n", sizeof(union Un));//打印联合体大小
	union Un un = { 0 };
	un.i = 0x11223344;
	un.c = 0x55;

	printf("%p\n", &un);            //打印联合体的地址
	printf("%p\n", &(un.i));        //打印成员 i 的地址
	printf("%p\n", &(un.c));        //打印成员 c 的地址

	return 0;
}

 联合体的空间是根据最大成员的大小来开辟的,然后所有的成员共用这一块空间,比如在上面的代码中,int i 的大小最大,开辟4个字节空间,然后char c成员共用这块空间。

 运行代码:


因为共用同一块空间,所以“动一发而动全身”,改变任意成员的内容,都会改变其他成员内容

#include<stdio.h>

union Un
{
	char c;
	int i;
};
int main()
{
	union Un un = { 0 };
	un.i = 0x11223344;
	un.c = 0x55;

	return 0;
}

我们可以根据上面代码执行顺序查看内存 的变化

union Un un = { 0 };

1.给结构体初始值赋为0;


 2.给结构体成员 i 赋十六进制的值


3.给结构体成员c也赋值一个十六进制数,改动了成员 i 的内容;

 

 4.2联合体的计算

1.联合的大小至少是最大成员的大小。
举个简单例子:
union Un
{
	char c;
	int i;
    double x;
};
则联合的大小是x,8个字节的空间;

2.当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
举个简单例子:
#include<stdio.h>

union Un2
{
	char c[7];
	int i;
};
//下面输出的结果是什么?

int main()
{
	printf("%d\n", sizeof(union Un2));

	return 0;
}

联合的大小要对齐到最大对齐数的整数倍,上面代码,联合开辟的空间应该是7个字节,要对齐最大数是4(int i)的整数倍。所以联合空间应是8个字节。

 4.3用联合判断当前计算机的大小端存储

我们取一个整型,初始值为1,根据机器的大小端存储的位置不同,取出起始地址,如果是1,就是小端存储,如果是0,就是大端存储。

 举个简单例子:

union Un1
{
	int i;      //设置一个整型
};


int main()
{
	union Un1 un = {0};
	un.i = 1; 赋初始值为1

	printf("%d\n", (*(char *)&un.i)); 强制转换char*,并取出第一个字节的内容。

	return 0;
}

好了,今天的内容就到这里,制作不易,如果对您有帮助,就给个赞赞支持一下吧!如果有错误的地方,敬请在评论区批评指出,谢谢。

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

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

相关文章

5.4 python内置高阶函数之--map、reduce、filter、sorted

高阶函数满足条件&#xff1a;1、 函数名被作为参数传给另外一个函数2、 函数返回值为另外一个函数&#xff08;返回为自己&#xff0c;则为递归&#xff09;一、 高阶函数&#xff1a;map 【 map函数】说明可以去查看源码&#xff0c; 会发现&#xff1a;map的__init__中有两个…

deeplabv3+源码之慢慢解析 第二章datasets文件夹(3)cityscapes.py--Cityscapes类

系列文章目录&#xff08;更新中&#xff09; 第一章deeplabv3源码之慢慢解析 根目录(1)main.py–get_argparser函数 第一章deeplabv3源码之慢慢解析 根目录(2)main.py–get_dataset函数 第一章deeplabv3源码之慢慢解析 根目录(3)main.py–validate函数 第一章deeplabv3源码之…

MyBatis-Plus学习总结

目录 1.MyBatis-Plus介绍 2.第一个MyBatis-Plus程序 3.配置日志输出 4. 主键生成策略 4.1 ID_WORKER -- 雪花算法 4.2 主键生成策略 -- 详情 5. 自动填充 6.MyBatis-Plus的CRUD 6.1 insert -- 插入 6.2 delete -- 删除 6.3 update -- 更新 6.4 select -- 查询 7. …

Nacos报错Could not resolve placeholder ‘order.name‘ in value “${order.name}“怎么解决?

出现这个原因有两个&#xff1a; 1.首先在Nacos配置中心&#xff0c;写入yml配置文件的数据和后端服务在取数据的时候名称不一致 如下图&#xff0c;现在我的配置中心为order-service 看看其中的文件内容信息&#xff1a; 再看看后端是怎么取的&#xff1a; 看出上面错误了吗…

Windows Cluster 投票权问题

在日常运维中&#xff0c;如果你的 Windows Cluster 需要升级、重启、意外宕机、网络中断等&#xff0c;你知道该怎么操作才能保证集群的可用性吗&#xff1f;按什么样的顺序怎样关闭或启动集群节点吗&#xff1f;怎么快速恢复你的集群呢&#xff1f; 接下来&#xff0c;我们就…

【C++ 重要知识点总结】STL字符串向量

字符串、向量和数组 这里讲的是 C中的处理&#xff0c;置于 C 中的字符串向量和数组&#xff0c;可以自己去复习。 1 命名空间的 using 声明 基本使用 //独立使用名字 using namespace::name; //声明空间 using namespace使用规则 头文件中不应包含 using 声明。因为会破坏包…

组合数学相关知识总结(适合复习用)

全排列 例子&#xff1a; n n n 个数取 m m m 个数有序排放 通项公式&#xff1a; A n m ( P n m ) n ∗ ( n − 1 ) ∗ ( n − 2 ) ∗ ⋅ ⋅ ⋅ ∗ ( n − m 1 ) n ! ( n − m ) ! A_n^m(P_n^m)n*(n-1)*(n-2)**(n-m1) \frac{n!}{(n-m)!} Anm​(Pnm​)n∗(n−1)∗(n−2)∗…

[QT编程系列-12]:QT快速学习 - 0 - 主要内容

第0章 主要内容 0.1 QT的主要内容 附录&#xff1a; Qt 是一个功能强大的应用程序开发框架&#xff0c;涵盖了广泛的知识点。以下是一些常见的 Qt 知识点&#xff1a; 基本概念和特性&#xff1a;了解 Qt 的基本概念&#xff0c;如信号和槽、事件处理、对象模型、元对象系统等…

Python基础合集 练习27 (turtle函数使用)

import turtle as t 画笔控制工具 t.penup() 表示画笔抬起 海龟在天上飞 不能直接形成图形 t.pendown() 画笔落下 海龟降下来 t.pensize(15) 也可以用 t.width() 画笔宽度 t.pencolor(“red”) 画笔颜色 为颜色字符串或rgb值 运动控制函数 控制行进方向、走曲线或…

二进制文件的Python写入

二进制文件的Python编写 这么基础的东西&#xff0c;必然用内置的就好 二进制文件的Python读写 重要提示 p.s. 1 >>> bHello World.decode() "Hello World" True >>> example import struct with open(binary_file.bin, wb) as file:data b…

【cfengDB】自己实现数据库第0节 ---整体介绍及事务管理层实现

LearnProj 内容管理 MySQL系统结构一条SQL执行流程 cfengDB整体结构事务管理TM模块TID文件规则定义文件读写 -- NIORandomAccessFile、FileChannel、ByteBuffer接口实现文件合法检测begin()commit(tid)rollback(tid)tid文件创建 本文作为数工底层的项目CfengDB开始篇章&#xf…

vue 升级3 +vite+antdv4

目录 一、安装包相关升级 二、vite.config 三、 入口文件修改 四、App.vue 及相关升级 五、路由 六、状态管理VUEX 一、安装包相关升级 升级pakage.json相关安装包 vue2插件vue3替换插件vue2使用vue3使用vue-ls vuex-persistedstate或vuex-persistVue.ls.get() Vue.ls.…

C++ 多线程学习总结

C 多线程 创建线程 thread jion与detach方式的区别 jion方式&#xff1a;必须等待创建并启动的子线程任务执行完毕&#xff0c;才会继续往下执行。 示例&#xff1a; #include <stdio.h> #include <unistd.h> #include <iostream> #include <string&g…

【企业架构实践】要避免的 7 个企业架构错误

颠覆性时代需要有弹性、前瞻性的企业架构。不要让错误的框架破坏您的组织实现当前和未来目标的能力。 企业架构为成功的业务 IT 计划奠定了基础。如果设计和实施得当&#xff0c;企业架构将帮助业务领导者实现他们的目标&#xff0c;使组织变得更具响应性、效率和竞争力。 不幸…

matlab使用教程(2)—数组索引、工作区与字符

1数组索引 MATLAB 中的每个变量都是一个可包含许多数字的数组。如果要访问数组的选定元素&#xff0c;请使用索引。 例如&#xff0c;假设有 44 矩阵 A &#xff1a; A [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16] A 44 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 引…

python selenium.webdriver 爬取政策文件

文章目录 获取文章链接批量爬取政策文件应用selenium爬取文件信息数据处理导出为excel 获取文章链接 获取中央人民政府网站链接&#xff0c;进入国务院政策文件库&#xff0c;分为国务院文件和部门文件&#xff08;发改委、工信部、交通运输部、市场监督局、商务部等&#xff…

JavaScript 中 五种迭代数组的方法 every some map filter forEach

JavaScript 中 五种迭代数组的方法 every some map filter forEach 1.every 和 some2.filter (重点常用)3.map (灵活常用&#xff09;4.forEach (重点常用) ECMAScript 提供了 5个对数组的迭代方法 1.every() 2.some() 3.filter() 4.forEach() 5.map() 1.every 和 some every…

串联型PI和并联型PI调节器的比较

一、PI调节器的种类 图3-4 仿真波形变化情况&#xff08;串联型PI调节器&#xff0c;1500r/min&#xff09; 从图3-1到3-4比较可知&#xff0c;与并联型PI调节器相比&#xff0c;串联型PI调节器的超调量很小&#xff08;速度环&#xff09;&#xff0c;且动态过程时间短&…

从新的角度看待大模型微调

一、前言 一切要从最近大火的Lora(《LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS》&#xff09;说起&#xff0c;该文章在ICLR2022中提出。说的是利用低秩适配(low-rank adaptation)的方法&#xff0c;可以在使用大模型适配下游任务时只需要训练少量的参数即可达到一…

【SQL应知应会】表分区(二)• MySQL版

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习&#xff0c;有基础也有进阶&#xff0c;有MySQL也有Oracle 分区表 • MySQL版 前言一、分区表1.非分区表2.分区…