C语言——自定义类型:结构体

news2024/11/24 14:50:48

前言

本篇博客位大家介绍C语言中一块儿重要的内容,那就是结构体,关于结构体的内容,大家需要深入掌握,在后面的学习中依然会用到,如果你对本文感兴趣,麻烦点进来的老铁一键三连。多多支持,下面我们进入正文部分。

1. 结构体类型的声明

1.1 什么是结构体

C语言已经提供了内置类型,如:char、short、int、long、float、double等,但是只有这些内置类 型还是不够的,假设我想描述学生,描述⼀本书,这时单⼀的内置类型是不行的。

描述⼀个学生需要名字、年龄、学号、身高、体重等;

描述一本书需要作者、出版社、定价等。C语言为了解决这个问 题,增加了结构体这种自定义的数据类型,让程序员可以自己创造适合的类型。

结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量,如: 标量、数组、指针,甚至是其他结构体。

上面为大家介绍了结构体的概念,大家需要进行理解;结构体就是用于一些比较复杂的对象,这也给了程序员一定的自由发挥的空间;

1.2 结构体的声明方法

关于结构体的声明方法其实挺简单的,大家来看下面的代码;

struct Stu
{
	char name[20];//名字 
	int age;//年龄 
	char sex[5];//性别 
	char id[20];//学号 
}; //分号不能丢 

这里大家可以看到,上面就是结构体的声明方法,这里要提醒大家一下,结尾的分号一定不能丢,否则程序将报错;

1.3 结构体的特殊声明 

上面说了结构体的一般声明方法,然而还存在一类特殊的声明方法,大家请看下面的代码;

struct
{
	int a;
	char b;
	double c;

}s = { 10,'a',3.14 };
int main()
{
	printf("%d %c %lf", s.a, s.b, s.c);
	return 0;
}

这里大家可以发现,我将结构体的名字省略掉了,这种声明方法声明的结构体叫做匿名结构体;这种声明方法声明的结构体在创建变量的时候,必须和声明同时进行,不能单独拿出来进行创建;

这里建议大家不要去使用匿名结构体类型,这种写法是容易出现问题的;

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

2.1 结构体变量的定义/创建

//代码1:变量的定义 
struct Point
{
 int x;
 int y;
}p1; //声明类型的同时定义变量p1 
struct Point p2; //定义结构体变量p2

大家可以看到,上面给出了两种创建方式,一种是在声明类型的同时进行定义;还有一种是单独进行定义;这两种方法都是正确的,大家根据自己的习惯进行选择。

2.2 结构体变量的初始化

//代码2:初始化。 
struct Point p3 = {10, 20};
struct Stu //类型声明
{
 char name[15];//名字 
 int age; //年龄 
};
struct Stu s1 = {"zhangsan", 20};//初始化 
struct Stu s2 = {.age=20, .name="lisi"};//指定顺序初始化
//代码3
#include<stdio.h>
struct s 
{
	int a;
	char b;
}; 
struct b
{
	struct s a;
	int* p;
	char arr[10];
	float sc;
};
int main()
{
	struct b c = { {10,'w'},NULL,"hehe",85.5f };
}

这里大家仔细观察上面的代码,在代码2中,展示了两种初始化的方法,一种是常规的初始化方法,按照声明时的顺序进行初始化;第二种初始化方法是按照指定顺序进行初始化,这里大家需要注意其写法,用到了“.”操作符,这是结构体成员访问操作符,这个后面还会为大家介绍;

下面来说说代码3,前面说过,结构体的成员可以是不同类型的变量,这里当然就包括结构体了;那么大家来看代码3,这里大家可以看到,我声明了两个不同的结构体,并且用第一个结构体定义了一个变量将其放到第二个结构体中,当我对第二个变量进行初始化的时候,大家注意嵌套结构体初始化的方法,对于嵌套的结构体,我们需要使用{}进行初始化,这里希望大家可以根据上面的代码理解嵌套结构体初始化的方法。

3. 结构体成员访问操作符

3.1 结构体成员的直接访问

结构体成员的直接访问是通过点操作符(.)访问的;点操作符接受两个操作数;如下所示:

#include <stdio.h>
struct Point
{
 int x;
 int y;
}p = {1,2};
int main()
{
 printf("x: %d y: %d\n", p.x, p.y);
 return 0;
}

 

上面大家看到,使同方式:结构体变量.成员名,这就是对结构体成员直接访问的方法;

那么这里就有一个问题,如果是嵌套结构体呢?我们应该如何进行访问,大家来看下面的代码;

#include<stdio.h>
struct s 
{
	int a;
	char b;
}; 
struct b
{
	struct s a;
	int* p;
	char arr[10];
	float sc;
};
int main()
{
	struct b c = { {10,'w'},NULL,"hehe",85.5f };
	printf("%c\n", c.a.b);
}

 

大家注意在访问嵌套结构体的时候,我们是按照顺序依次访问的,大家可以通过上面的代码进行理解,相信大家可以掌握。

3.2 结构体成员的间接访问 

有时候我们得到的不是⼀个结构体变量,而是得到了⼀个指向结构体的指针。如下所示:

#include <stdio.h>
struct Point
{
 int x;
 int y;
};
int main()
{
 struct Point p = {3, 4};
 struct Point *ptr = &p;
 ptr->x = 10;
 ptr->y = 20;
 printf("x = %d y = %d\n", ptr->x, ptr->y);
 return 0;
}

这里大家注意,间接访问的方法:使用方式:结构体指针->成员名;

这里创建了一个结构体指针接受了我们创建了结构体变量p,我们将p的地址传给结构体指针,通过结构体指针来间接访问结构体的内容;这种访问方法大家也需要理解并且掌握。

4. 结构体的内存对齐

前面我们了解了结构体的基本内容,下面我们要讨论一个问题:计算结构体的大小;这就是我们接下来要说到的内容——结构体的内存对齐

4.1 对齐规则

首先为大家展示结构体的内存对齐规则,下面用一个例子来为大家解释;

struct S1
{
	char c1;
	int i;
	char c2;
};
int main()
{
	struct S1 s;
	printf("%zd\n", sizeof(s));
}

大家来看这段代码,这里我想要求出代码中的结构体的大小,那么就需要遵循上面说的对齐规则;

 

大家仔细来看上面的图,右边的数字就是偏移量。根据第一条规则,第一个成员对齐到结构体变量起始位置偏移量为0的地址处,如上图所示;

下面轮到第二个成员,这里大家要理解对齐数的概念,在VS里默认对齐数为8,而最终的对齐数是在默认对齐数和成员变量大小中取较小的那一个,比如这里的第二个成员,是int类型。大小为4字节,而VS默认值为8,所以结果就是4,也就是说第二个成员要对齐到4的整数倍的地址处,那么最近的就是从偏移量为4的地方开始存储,向后存4个字节;

第三个成员,和第二个同理,char类型的大小是1字节,VS默认值是8,所以对于第三个成员来说,对齐数就为1,那么第三个成员就需要对齐到1的整数倍的地址处,看一下图,就是偏移量为8的位置,在这里存储第三个成员,占1字节;

综上,可能有的同学就认为这个结构体的大小是9字节了,那么这里大家要注意第三条规则,结构体的总大小为最大对齐数的整数倍,那么在这个结构体中,第一个成员的对齐数为1,第二个成员的对齐数为4,第三个成员的对齐数为1,那么最大对齐数就为4了,所以整个结构体的大小就必须为4的整数倍,那么我们看图,占内存最小的就是12,那么这个结构体的大小就为12字节;

大家可以看到,上面是在VS2022环境下算出的结构体的大小,与我们上面的推理结果一致;希望大家可以通过这个例子理解对齐规则;

为了让大家更好地掌握对齐规则,下面有几道例题,大家一起来看一下;

​//例题1
#include<stdio.h>
struct S2
{
	char c1;
	char c2;
	int i;
};
int main()
{
	struct S2 s;
	printf("%zd\n", sizeof(s));
}

​

大家来看一下这道题,和前面的分析方法一样,首先来对齐第一个成员,第一个成员是char类型,占1字节;

第二个成员,依然是char类型,VS默认值为8,char为1字节,所以其对齐数就是1,那么第二个成员将对齐到偏移量为1的地址处;

第三个成员,为int类型,大小4字节,VS默认值是8,所以其对齐数为4,那么第三个成员就需要对齐到4的整数倍的地址处,那么最近的就是偏移量为4的地址处,从那里往后占4字节;

综上,我们将三个成员都存进去了,下面我们要确定整个结构体的大小,很容易知道,最大对齐数为4,那么整个结构体的大小就必须为4的倍数,我们可以发现,前面我们刚好占用了8个字节,8又刚好是4的整数倍,所以整个结构体的大小就是8字节。

//例题2
#include<stdio.h>
struct S3
{
	double d;
	char c;
	int i;
};
int main()
{
	struct S3 s;
	printf("%zd\n", sizeof(s));
}

这道题还是同样的分析方法;

首先来看第一个成员,double类型,我们知道它占8字节;

第二个成员,char类型,大小为1字节,默认值是8,那么其对齐数就是1,那么第二个成员就要对齐在1的整数倍的地址处,前面已经存过了第一个成员,那么第二个成员就可以放在偏移量为8的地址处;

第三个成员,int类型,大小4字节,默认值为8,其对齐数就为4,那么就应该对齐在偏移量为12的地址处,占4字节;

那么最终大家可以发现,我们一共占用了16个字节,我们知道最大对齐数为8,那么16是8的整数倍,所以这个结构体的大小就为16字节。

//例题3
#include<stdio.h>
struct S3
{
	double d;
	char c;
	int i;
};
struct S4
{
	char c1;
	struct S3 s3;
	double d;
};
int main()
{
	struct S4 s;
	printf("%zd\n", sizeof(s));
}

这道题大家要注意它和前两道是不一样的,它出现了嵌套结构体的情况,那么这个时候大家就要注意上面对齐规则中的第四条规则了;

第一个成员,char类型。大小1字节,直接存到起始位置;

第二个成员,这是一个结构体,那么第四条规则告诉我们:结构体成员对齐到自己的成员中最大对齐数的整数倍处,那么从例题2我们知道,S3结构体中最大对齐数是8,所以S3必须对齐到8的整数倍的地址处,在这里就需要对齐到偏移量为8的地址处,占16字节;

第三个成员,double类型,大小8字节,VS默认值为8,所以其对齐数为8,那么成员三就需要对齐到8的整数倍的地址处,大家自己画图会发现,就是偏移量为24的地址处,占8字节;

综上,我们一共占用了32个字节,那么整个结构体的大小是多少呢?再来看一下第四条规则,整个结构体的大小必须为所有最大对齐数的整数倍,那么我们知道,在S4结构体中,最大的对齐数为8,所以整个S4结构体的大小就要为8的整数倍,刚才说一共占用了32字节,32刚好是8的整数倍,那么S4结构体的大小就是32字节。

 

OK,上面我们讨论了几道关于结构体内存对齐的例题,希望大家通过这些例题能够更好地掌握内存对齐的规则;

不知道大家是否注意到,在内存对齐的过程中,其实造成了空间的浪费,那么我们为什么还要遵循内存对齐规则呢?下面我们继续来讨论为什么会有内存对齐?

4.2 为什么存在内存对齐 

4.2.1 平台原因(移植原因)

不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

4.2.2 性能原因

数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要⼀次访问。假设⼀个处理器总是从内存中取8个字节,则地址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对齐成8的倍数,那么就可以用⼀个内存操作来读或者写值了。否则,我们可能需要执行两次内存访问,因为对象可能被分放在两个8字节内存块中。

总体来说:结构体的内存对齐是拿空间来换取时间的做法

那么,我们有没有一种方式,既满足对齐,又能节省空间呢?
大家来看下面的代码;

struct S1
{
 char c1;
 int i;
 char c2;
};
struct S2
{
 char c1;
 char c2;
 int i;
};

大家观察这段代码,并且取计算一下这两个结构体的大小;

这里大家发现,两个结构体虽然成员一样,但是最终大小却不一样;这里大家就要注意一点,在创建结构体的过程中我们要让占有空间小的成员尽量集中在一起,这样我们就可以在满足对齐的情况下尽量节省空间。

4.3 修改默认对齐数

#pragma 这个预处理指令,可以改变编译器的默认对齐数。

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

5. 结构体传参 

#include<stdio.h>
struct S
{
	int data[1000];
	int num;
};
struct S s = { {1,2,3,4}, 1000 };
//结构体传参 
void print1(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;
}

大家看看上面的代码,一个是传结构体本身;还有一个是传结构体的地址;那么哪种方式更好呢?答案是print2;

为什么呢?

结论: 结构体传参的时候,要传结构体的地址。 

6.结构体实现位段

6.1 位段的概念

位段的声明和结构是类似的,有两个不同:

1. 位段的成员必须是 int、unsigned int 或signed int ,在C99中位段成员的类型也可以选择其他类型。

2. 位段的成员名后边有⼀个冒号和⼀个数字。

struct A
{
 int _a:2;
 int _b:5;
 int _c:10;
 int _d:30;
};

大家可以发现,位段是专门用来节省内存的;

这里还有一个问题,位段A的大小的多少呢? 

大家可以自己去测试一下,相信很多同学的第一反应是6(因为有一共47个bit);

大家发现,这个结果并不是6,那这是什么原因呢?咱们继续看下面的内容;

6.2 位段的内存分配 

1. 位段的成员可以是 int unsigned int signed int 或者是 char 等类型

 2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。

 3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段

这里给大家举个例子,咱们来看下面的代码;

#include<stdio.h>
struct S
{
	char a : 3;
	char b : 4;
	char c : 5;
	char d : 4;
};
int main()
{
	struct S s = { 0 };
	s.a = 10;
	s.b = 12;
	s.c = 3;
	s.d = 4;
	printf("%zd", sizeof(s));
	return 0;
}

 这里大家可以思考一下结果;​​​​​​​

 大家仔细看上面这张图,它描述了位段申请空间的过程;这里大家注意,每一个小格子代表一个bit;

这里一次开辟一个字节(8bit),在VS 中,在一个字节内部空间是从右向左进行使用的;那么剩余的空间是继续使用,还是浪费掉呢?在VS中,答案是浪费掉。最终我们可以发现,一共申请了3个字节的空间。

每个方块儿中存放的是对应数据的二进制,由于空间有限,所以数据并不能完整地存放到空间中,就会发生截断的现象;所以最终我们通过调试就可以看见位段s中的数据;

大家注意这里是十六进制的形式进行表示的;OK,到这里,关于位段内存分配的内容就为大家介绍完了;

6.3 位段的跨平台问题

1. int位段被当成有符号数还是无符号数是不确定的。

2. 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题。

3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。

4. 当⼀个结构包含两个位段,第⼆个位段成员⽐较大,无法容纳于第⼀个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。

总结: 跟结构相比,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在。

6.4 位段的应用

这里的内容大家作了解即可,在这里不需要深入研究,后面在学习网络的相关知识的时候,

6.5 位段使用的注意事项

位段的几个成员共有同⼀个字节,这样有些成员的起始位置并不是某个字节的起始位置,那么这些位 置处是没有地址的。内存中每个字节分配⼀个地址,⼀个字节内部的bit位是没有地址的。

所以不能对位段的成员使⽤&操作符,这样就不能使用scanf直接给位段的成员输入值,只能是先输入放在⼀个变量中,然后赋值给位段的成员。

int main()
{
 struct A sa = {0};
 scanf("%d", &sa._b);//这是错误的 
 
 //正确的⽰范 
 int b = 0;
 scanf("%d", &b);
 sa._b = b;
 return 0;
}

大家看一下上面的一段代码,我们是不能对位段的成员进行取地址操作的。

7. 总结 

本篇文章为大家介绍了结构体的相关内容,结构体在C语言中也是一种重要的自定义类型,在后面的学习中大家会经常使用,所以本篇内容,建议大家认真阅读,注意其中的细节,掌握结构体的使用方法以及关于结构体的对齐规则;最后,希望本篇博客可以为大家带来帮助,谢谢!

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

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

相关文章

WPS JS宏获取自动筛选后的行数

//WPS JS宏获取自动筛选后的行数 function getFilterRowCnt(shtRng)//shtRng表示筛选目标工作表范围 {let lngRowCnt 0;for(let rngCell of shtRng.SpecialCells(xlCellTypeVisible).Areas)//获取自动筛选后的单元格行数{lngRowCnt lngRowCnt rngCell.Rows.Count;}return ln…

Metes and Bounds Pro for Mac——开启智能地产测量新时代

在数字化时代&#xff0c;Metes and Bounds Pro for Mac以其智能化和高效性引领了地产测量领域的新潮流。这款软件采用了先进的人工智能技术&#xff0c;能够自动识别和提取地块信息&#xff0c;极大地提高了测量工作的速度和准确性。此外&#xff0c;Metes and Bounds Pro还支…

【GreenHills】如何使用GHS对于不同的文件进行文档内容对比

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 利用GHS对于不同的文件进行对比。 2、 问题场景 在项目开发过程中&#xff0c;会对于工程进行版本管理&#xff0c;对于没有项目管理工具的客户&#xff0c;想要对于当前版本的源文件和上一版或其他版本的源文件进行…

Anzo Capital昂首资本总结斐波纳契指标7个特点

斐波纳契指标是一种强大的技术分析工具&#xff0c;被誉为交易者的“神秘武器”&#xff0c;用于预测金融市场中的价格走势和潜在反转点。下面是Anzo Capital昂首资本总结的斐波纳契指标的7个特点&#xff1a; 1. 识别趋势&#xff1a;首先&#xff0c;斐波纳契指标可以快速确…

旅游行业电商平台:数字化转型的引擎与未来发展趋势

引言 旅游行业数字化转型的背景和重要性 随着信息技术的飞速发展&#xff0c;数字化转型成为各行业发展的必然趋势。旅游行业&#xff0c;作为一个高度依赖信息和服务的领域&#xff0c;数字化转型尤为重要。通过数字化手段&#xff0c;旅游行业能够实现资源的高效配置、服务的…

tvm实战踩坑

今天玩了一下tvm的安装 我要安装v0.14.0的版本 所以按照官网的方法 https://tvm.apache.org/docs/install/from_source.html#python-package-installation git clone --recursive https://github.com/apache/tvm tvmgit checkout v0.14.0recursive是很重要的 这一步可以替换成…

蓝桥杯软件测试第十五届蓝桥杯模拟赛1期题目解析

PS 需要第十五界蓝桥杯模拟赛1期功能测试模板、单元测试被测代码、自动化测试被测代码请加&#x1f427;:1940787338 备注&#xff1a;15界蓝桥杯省赛软件测试模拟赛1期 题目1 功能测试用例1&#xff08;测试用例&#xff09;&#xff08;15分&#xff09; 【前期准备】 按步…

优化查询性能:DolphinDB 时间类型数据比较规则详解

在数据库中&#xff0c;时间是一种常见的数据类型。在处理时间数据时&#xff0c;比较操作是非常常见的需求。然而&#xff0c;在不同的场景下&#xff0c;对时间类型数据进行比较时应用的规则不同。本文将从 DolphinDB 支持的时间类型开始&#xff0c;由浅入深分别介绍时间类型…

鸿蒙轻内核A核源码分析系列六 MMU协处理器(2)

3、MMU汇编代码 在arch\arm\arm\include\arm.h文件中&#xff0c;封装了CP15协处理器相关的寄存器操作汇编函数。我们主要看下MMU相关的部分。 3.1 CP15 C2 TTBR转换表基地址寄存器 代码比较简单&#xff0c;结合下图&#xff0c;自行查看即可。该图来自《ARM Cortex-A9 Tec…

minIo ubuntu单节点部署

资源准备 minio二进制包 下载地址:https://dl.min.io/server/minio/release/linux-amd64/minio ubuntu-单节点部署 选择一台ubuntu18.04机器10.253.9.41、intel 或者 amd 64位处理器 上传minio到~目录 sudo cp minio /usr/local/bin/ sudo chmod x /usr/local/bin/minio 设…

python pip下载镜像

官网&#xff1a;python https://pypi.python.org/simple 阿里&#xff1a; pip install -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com packagename 腾讯&#xff1a; pip install -i https://mirrors.cloud.tencent.com/pypi/simple --tr…

CC攻击的有效应对方案

随着互联网的发展&#xff0c;网络安全问题愈发突出。CC攻击&#xff08;Challenge Collapsar Attack&#xff09;&#xff0c;一种针对Web应用程序的分布式拒绝服务&#xff08;DDoS&#xff09;攻击方式&#xff0c;已经成为许多网络管理员和网站拥有者不得不面对的重大挑战。…

reGeorg隐秘隧道搭建

reGeorg隐秘隧道搭建 【实验目的】 通过学习reGeorg与Proxifier工具使用&#xff0c;实现外网攻击端连接内网主机远程桌面。 【知识点】 python、reGeorg、proxifier。 【实验原理】 在内网渗透中&#xff0c;由于防火墙的存在&#xff0c;导致无法对内网直接发起连接&#xff…

Java中List流式转换为Map的终极指南

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 在Java编程中&#xff0c;经常需要将一个List对象转换为另一个Map对象。这可能是因为需要根据List中的元素的某些属性来创建一个新的键值对集合。在本文中&#xff0c;我将向您展示如何使用Java 中的流式API轻松地实…

机器学习:数据分布的漂移问题及应对方案

首先&#xff0c;让我们从一位高管告诉我的一个故事开始&#xff0c;很多读者可能对此感同身受。 大约两年前&#xff0c;他的公司聘请了一家咨询公司开发一个机器学习模型&#xff0c;帮助他们预测下周每种食品杂货需要多少&#xff0c;以便他们可以相应地补货。这家咨询公司…

【SQL边干边学系列】08高级问题-4

文章目录 前言回顾高级问题48.客户分组49.客户分组-修复null50.使用百分比的客户分组51.灵活的客户分组 答案48.客户分组49.客户分组-修复null50.使用百分比的客户分组51.灵活的客户分组 未完待续 前言 该系列教程&#xff0c;将会从实际问题出发&#xff0c;边干边学&#xff…

qmt量化交易策略小白学习笔记第29期【qmt编程之获取行业概念数据--如何下载板块分类信息及历史板块分类信息】

qmt编程之获取行业概念数据 qmt更加详细的教程方法&#xff0c;会持续慢慢梳理。 也可找寻博主的历史文章&#xff0c;搜索关键词查看解决方案 &#xff01; 感谢关注&#xff0c;咨询免费开通量化回测与获取实盘权限&#xff0c;欢迎和博主联系&#xff01; 获取行业概念数…

在typora中利用正则表达式,批量处理图片

一&#xff0c;png格式 在 Typora 中批量将 HTML 图片标签转换为简化的 Markdown 图片链接&#xff0c;且忽略 alt 和 style 属性&#xff0c;可以按照以下步骤操作&#xff1a; 打开 Typora 并加载你的文档。按下 Ctrl H&#xff08;在 Windows/Linux 上&#xff09;或 Cmd…

【NOI-题解】1389 - 数据分析1750 - 有0的数1457 - 子数整除1121 - “倒”数1962. 数值计算

文章目录 一、前言二、问题问题&#xff1a;1389 - 数据分析问题&#xff1a;1750 - 有0的数问题&#xff1a;1457 - 子数整除问题&#xff1a;1121 - “倒”数问题&#xff1a;1962. 数值计算 三、感谢 一、前言 本章节主要对循环中带余除法部分题目进行讲解&#xff0c;包括…

CV预测:快速使用LeNet-5卷积神经网络

AI预测相关目录 AI预测流程&#xff0c;包括ETL、算法策略、算法模型、模型评估、可视化等相关内容 最好有基础的python算法预测经验 EEMD策略及踩坑VMD-CNN-LSTM时序预测对双向LSTM等模型添加自注意力机制K折叠交叉验证optuna超参数优化框架多任务学习-模型融合策略Transform…