C语言:数组-学习笔记(万字笔记)——翻新版

news2024/11/16 0:20:56

目录

前言:

1、 数组的概念

1.1 什么是数组

1.2 为什么学习数组?

2. ⼀维数组的创建和初始化

2.1 数组创建

2.2 数组的初始化

 2.3 数组的类型

2.3.1 什么是数组类型?

2.3.2 数组类型的作用

3、 一维数组的使用

3.1 数组下标

 3.2 数组元素的打印

​编辑

 3.3 数组元素的输入

4 一维数组在内存中的存储

4.1 内存单元地址

4.2 数组在内存中的存储

5、sizeof计算数组元素个数

6、二维数组的创建

6.1 二维数组的概念

6.2 ⼆维数组的创建

7、二维数组的初始化

7.1 完全初始化

7.2 不完全初始化

7.3 按行初始化

8. ⼆维数组的使用

8.1 ⼆维数组的下标 

8.2 ⼆维数组的输入和输出

9、二维数组在内存中的存储

9.1 二维数组的存储

9.2 二维数组的实际应用

结语:

前言:

本篇文章将会介绍C语言中数组的相关知识,

1、 数组的概念

1.1 什么是数组

数组是一组相同类型元素的集合

你可以这么理解什么是数组:想象一个书架,上面整齐地排列着同一类书籍,这就类似于一个数组。每本书的位置都是固定的,而且它们都属于同一类型(比如都是小说或者都是传记)。

特点: 

•数组中存放的是1个或者多个数据,但是数组元素个数不能为0 

• 数组中存放的多个数据,类型是相同的。

1.2 为什么学习数组?

在了解了什么是数组的情况下,我们又会产生一个疑问,为什么要引入数组这个概念呢?我们学习数组的目的是什么呢?

我们拿一个例子来说明:

存放一串整数,我们用代码可以怎么表示?

#include <stdio.h>
int main()
{
	int a = 1;
	int b = 2;
	int c = 3;
	//如果我们要存1~100个数字呢?
    //数组是一组相同类型的元素的集合
	return 0;
}

如果我们要存1~100的数字,难道我们就这样写下去吗?那也太麻烦了,这时数组就应运而生了!

人类的进步有一部分就来自与人类的懒惰,因为我们想要更加方便的记录我们想要的东西,所以数组便被创造出来了,学习数组就是为了方便我们写代码。

当我们了解了为什么学习数组后,我们还需要知道该怎么使用它。

数组分为⼀维数组和多维数组,多维数组⼀般⽐较多⻅的是⼆维数组。

2. ⼀维数组的创建和初始化

2.1 数组创建

⼀维数组创建的基本语法如下:

1 type arr_name[ 常量值 ];

存放在数组的值被称为数组的元素,数组在创建的时候可以指定数组的大小数组的元素类型

  • type 指定的是数组中存放数据的类型,可以是: char 、 short 、 int 、 float 等,也可以自定义的类型。
  •  arr_name 指的是数组名的名字,这个名字根据实际情况,起的有意义就⾏。
  •  [] 中的常量值是⽤来指定数组的大小的,这个数组的大小是根据实际的需求指定就⾏。

比如说:

int arr[10];//整型数组,名为arr [10]指存放了10个元素
double data[20];
char ch[5];//字符数组,名为ch [5]指存放五个字符

也可以同时创建多个相同类型的数组

int arr 1 [10];
int arr 2 [2+8];

这里你或许还会有新的疑问, [ ] 这里面只能用常量或常量表达式吗? 

但是呢,并不是所有情况下都可以使用变量,比如

补充知识点:

在C99标准之前,数组的大小必须是常量或者常量表达式;

在C99之后,数组的大小可以是变量,这是为了支持变长数组;

变长数组的意思是 数组的大小是通过变量来指定的。

上图中的代码想要实现该怎么办呢?

#include <stdio.h>
int main()
{	
    int n = 10;
    scanf("%d",&n);
	int arr[n];	
	return 0;
}

但是呢,这里还有一个限制条件,就是只能在支持C99标准的编译器上编译

支持C99的编译器:

  • GCC:GNU Compiler Collection 的缩写,它在其编译器集合中提供了 C 编译器,支持 C99 标准。GCC 是一款广泛使用的开源编译器。
  • Clang:基于 LLVM 的 C 编译器,支持 C11 标准,同时也对 C99 有较好的支持。
  • Intel C++ Compiler:英特尔的 C++编译器,也支持 C99 标准。
  • Keil:在 Keil 编译器中,可通过相关设置使其支持 C99(变量声明在执行语句之后)。具体操作是在“Options for Target”中的“C/C++”选项卡下,勾选“C99 Mode”。

2.2 数组的初始化

数组的初始化:在创建数组的同时给数组的内容一些合理初始值(初始化)。

 方式:数组的初始化一般使用大括号,将数据放在大括号中。

直接代码演示:

//完全初始化
int arr1[3] = { 1,2,3 };
char arr2[3] = { 'a',98,'c' };

//不完全初始化,剩余的元素,默认初始化为0
int arr3[10] = { 1,2,3 };

//[]括号里面也是可以不指定大小的
char arr4[] = { 'a','b','c'};
char arr5[] = { "abcdef" };

//错误初始化,初始化的值多于元素个数
int arr6[4] = { 1,2,3,4,5};

 我们可以调试来辅助理解不完全初始化:

//不完全初始化,剩余的元素,默认初始化为0
int arr3[10] = { 1,2,3 };

 我们可以看到 1 2 3是我们输入的初始值,剩下的全为 0 

字符串也默认是 0 

char arr[6] = { 'a','b','c'};

这里\0的 ASVLL 为 就为0,0就是\0。

注意:

1. 不完全初始化(所给元素比指定元素要少),剩余的元素,默认初始化为 0;

2. 数组如果初始化了,就可以省略掉数组的大小,那么编译器就会根据初始化的内容来自动推算数组的元素的个数;

3.初始化的值不能比数组的元素更多 { 初始值} <= [ 元素值 ]。

对于下面的代码要会区分在内存中是如何分配。

char arr1[10] = { 'a','b','c'};
char arr2[10] = { "abc" };

对于arr1,里面的字符为:a b c 0 0 0 0 0 0 0

对于arr2,里面的字符为:a b c \0 0 0 0 0 0 0

 2.3 数组的类型

2.3.1 什么是数组类型?

数组也是有类型的,数组算是⼀种⾃定义类型,去掉数组名留下的就是数组的类型。如下: 

1 int arr1[10];

2 int arr2[12];

3 char ch[5];

1 arr1数组的类型是 int [10]

2 arr2数组的类型是 int [12] 

3 ch数组的类型是 char[5]

注意区分数组元素类型和数组类型:

拿第一个举例:

int arr1[10];

int 是数组元素的类型

int [10]是数组的类型  //10不能省略,10也是类型的一部分

刷题过程中要看清楚问的是数组元素类型还是数组类型。

问题:int [10]和 int [5] 这两个数组类型是否相同?

答案:不一样

2.3.2 数组类型的作用

int main()
{
	int arr[10] = { 0 };
	printf("%zd\n", sizeof(arr));//数组名
	printf("%zd\n", sizeof(int[10]));//数组类型
    printf("%zd\n", sizeof(int[5]))
	return 0;
}

 我们用数组名算数组大小,这里是 结果是40 的原因是 10个整型,一个整型 4 个字节。

而我们使用数组类型计算也能得到相同结果。可以更加确定数组类型是 int[10] 

从打印结果我们也可以证明int [10]和 int [5] 这两个数组类型是把不同的。

sizeof函数C 语言和 C++语言中的一个运算符,用于计算数据类型或变量占用的内存字节数。

不知道大家有没有对 %zd\n" 有所疑惑,为什么这里要使用%zd 呢?

sizeof的返回值的类型是 size_t 对于该类型的打印占位符用%zd。就只有这个作用

3、 一维数组的使用

学习了⼀维数组的基本语法,⼀维数组可以存放数据,存放数据的⽬的是对数据的操作,那我们如何 使⽤⼀维数组呢?

3.1 数组下标

C语⾔规定数组是有下标的,下标是从 0 开始的,假设数组有 n 个元素,最后⼀个元素的下标是      n-1,下标就相当于数组元素的编号,如下:

 
int arr[10] = {1,2,3,4,5,6,7,8,9,10}; 

下标的作用:准确、快速找到数组中特定位置的元素,从而对其进行操作和使用

辅助理解:

假设我们把 C 语言中的数组想象成一个书架。 这个书架上一格一格地摆放着很多书,每一格就相当于数组中的一个元素。 而下标呢,就像是每一格的编号。

比如说,我们有一个数组 int arr[5] = {10, 20, 30, 40, 50}; 这里的数字 0、1、2、3、4 就是下标。 如果我们想要找到并使用第三本书(也就是数字 30 ),我们就通过下标 2 来找到它(因为数组下标从 0 开始,所以第三格对应的下标是 2 )。 再比如,你想要从这个书架上取走最后一本书(数字 50 ),你就通过下标 4 来找到它。

所以,下标就是帮助我们准确、快速找到数组中特定位置的元素,从而对其进行操作和使用。

 那我们应该怎么找呢?

在C语⾔中数组的访问提供了⼀个操作符 [ ] ,这个操作符叫:下标引⽤操作符

有了下标访问操作符,我们就可以轻松的访问到数组的元素了,⽐如我们访问下标为7的元素,我们就 可以使⽤ arr[7] ,想要访问下标是3的元素,就可以使⽤ arr[3] ,如下代码:

#include <stdio.h>
 int main()
 {
  int arr[10] = {1,2,3,4,5,6,7,8,9,10}; 
  printf("%d\n", arr[7]);// 打印结果8
  printf("%d\n", arr[3]);// 打印结果4
}

注意:使用下标引用操作符时,一定要确保索引值在有效范围内,否则可能导致访问越界错误。

总结:

1.数组是使用下标来访问的,下标是从0开始的。

2.数组的大小可以通过计算得到。                                                    

int sz = sizeof(arr) / sizeof(arr[0]);//计算公式

 3.2 数组元素的打印

接下来,如果想要访问整个数组的内容,那怎么办呢?

只要我们产⽣数组所有元素的下标就可以了,那我们使⽤for循环产⽣0~9的下标,接下来使⽤下标访 问就⾏了。 如下代码:

#include <stdio.h>
 int main()
 {
   int arr[10] = {1,2,3,4,5,6,7,8,9,10}; 
   int i = 0;
   for(i=0; i<10; i++)
   {
     printf("%d ", arr[i]);
   }
   return 0;
 }

打印结果:

 3.3 数组元素的输入

如果我们想要自己输入值,该怎么做?
如下代码:

#include <stdio.h>
 int main()
 {
    int arr[10] = {0}; 
    int i = 0;
     //输入
    for(i=0; i<10; i++)
    {
     scanf("%d", &arr[i]);。//这里需要去地址,arr[i]是数组的一个元素,而不是数组名
    }//输出
    for(i=0; i<10; i++)
    {
     printf("%d ", arr[i]);//这里不要写成了arr,这样无法打印数组的内容
    }
     return 0;
 }

注意:

  1. 数组名是地址,但数组元素不是地址。
  2. arr是数组名,数组名是数组的起始地址 printf("%d ", arr[i])不要写成了printf("%d ", arr)
  3. 输入的值超过循环的值时不会报错,只会取你循环的值,比如说你要循环10个值,而你输入了11个值,那么第11个元素就不打印。

结果演示:

4 一维数组在内存中的存储

4.1 内存单元地址

内存内存会被划分为一个个的内存单元,一个单元的大小是1个字节,每个内存单元都有一个编号,这个编号就是地址。

辅助理解:

我们可以把 C 语言中的内存想象成一个超级大的停车场。

这个停车场被划分成了一个个的停车位,每个停车位就相当于一个内存单元,而每个停车位的大小是 1 个字节。

每一个停车位都有一个独特的编号,就像我们在现实中的停车场,每个车位都有一个标识号码一样。在 C 语言中,这个编号就是内存单元的地址。

比如说,我们要把一辆红色的车(代表一个数据)停到停车场里。我们需要知道哪个停车位是空的,这个空的停车位的编号(地址)就是我们要找的地方。

又比如,我们想要找到之前停在停车场里的那辆红色的车,就需要通过之前记住的那个停车位的编号(地址)去找到它。

所以,内存单元的地址就像是停车场里停车位的编号,帮助我们准确找到存储数据的位置

4.2 数组在内存中的存储

数组在内存中是连续存储的,这意味着数组中的元素在内存中是一个紧挨着一个排列的。

 比如说,有一个整数类型的一维数组 int arr[5] = {1, 2, 3, 4, 5} 。

注:地址是16进制的(后面会讲怎么计算的)

在 C 语言中,一个整数通常占用 4 个字节的内存空间。 

假设这段连续存储空间的起始地址为 0*1000 ,由于在 C 语言中,一个整数通常占用 4 个字节的存储空间。那么,数组中的第一个元素将被存储在地址 0*1000 ,第二个元素紧接着存储在地址 0*1004 ,第三个元素在 0*1008 ,第四个元素在 0*100C ,第五个元素则在 0*1010 。

这种连续存储有两个重要的特点和影响:

一方面,它使得随机访问数组元素的速度非常快。比如说,如果想要获取第三个元素,只需要通过简单的计算 起始地址 + 元素大小 * 索引 (也就是 1000 + 4 * 2 = 1008 ),就能直接找到并访问到第三个元素 3 ,几乎不需要额外的时间去查找。

另一方面,它也带来了一些不便。比如说,如果要在数组中间插入一个新元素,那就需要把插入位置后面的所有元素都向后移动,以腾出空间插入新元素。这是一个比较耗时的操作。同样,删除数组中间的元素时,也需要把后面的元素向前移动来填补空缺。

为了更加直观的解释,我们来用表格辅助理解:

假设有一个整数数组int num[3] = {10,20,30 } ,其在内存中的存储情况如下:

内存地址存储的值
0 * 200010
0 * 200420
0 * 200830

如果现在要在第二个位置插入一个新元素 15 ,那么原有的 20 和 30 都需要向后移动 4 个字节,变成:

内存地址存储的值
0 * 200010
0 * 200415
0 * 200820
0 * 200C30

同样,如果要删除第二个元素 15 ,则 20 和 30 需要向前移动:

内存地址存储的值
0 * 200010
0 * 200420
0 * 200830

综上所述,C 语言中一维数组在内存中的连续存储方式在提供快速随机访问的同时,也在插入和删除操作上带来了一定的复杂性。

当我们知道这一特点后,有助于我们在编程实践中根据具体需求合理地选择和使用数组,或者考虑其他更适合特定操作的数据结构。

所以,理解 C 语言中一维数组在内存中的连续存储方式,对于我们有效地使用数组、优化程序性能以及避免一些常见的错误(比如内存越界访问)都非常重要。

 代码展示:

int main()
{
	int arr[] = { 1, 2, 3 ,4 ,5 ,6, 7,8 ,9,10 };	
	//下标范围    0                        9         
	//printf("%d\n", arr[4]);
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	//打印数组的每个元素的地址
	for (i = 0; i < sz; i++)
	{
		printf("&arr[%d] = %p\n",i, &arr[i]);
	}
	return 0;
}

结果展示:

我们发现这里打印的地址比较长,不方便我们进行观察。

当我们使用x64的环境时,所打印的地址较长

当我们使用x86的环境时,所打印的地址较短。

从上面结果我们可以发现地址打印出来的时候,是按照16进制的形式显示的。(16进制计算)

随着下标的增加,地址是由小到大变化的 。

5、sizeof计算数组元素个数

在遍历数组的时候,我们经常想知道数组的元素个数,那C语⾔中有办法使⽤程序计算数组元素个数 吗?

答案是有的,可以使⽤sizeof。

sizeof可以计算数组的大小


 #include <stido.h>
 int main()
 {
    int arr[10] = {0};
    printf("%d\n", sizeof(arr));   //40 
    return 0;
 }

   //sizeof(arr)  计算的是数组的总大小

 这⾥sizeof(arr) 输出的结果是40,计算的是数组所占内存空间的总大小,单位是字节

一个int 是4个字节,这里有 10 个整型,所以最后打印出来的结果是40。 

我们⼜知道数组中所有元素的类型都是相同的,那只要计算出⼀个元素所占字节的个数,数组的元素 个数就能算出来。这⾥我们选择第⼀个元素算⼤⼩就可以。


 #include <stido.h>
 int main()
 {
    int arr[10] = {0};
    printf("%d\n", sizeof(arr[0]));   //4 
    return 0;
 }

   //sizeof(arr[0])  计算的是数组中一个元素的大小

接下来就能计算出数组的元素个数:

#include <stido.h>
 int main()
 {
 int arr[10] = {0};
 int sz = sizeof(arr)/sizeof(arr[0]);//元素总大小/单个元素大小
 printf("%d\n", sz);
 return 0;
 }

这里的结果是:10,表⽰数组有10个元素。 以后在代码中需要数组元素个数的地方就不用固定写死了,使⽤上面的计算,不管数组怎么变化,计算出的大小也就随着变化了。 

6、二维数组的创建

6.1 二维数组的概念

前⾯学习的数组被称为⼀维数组,数组的元素都是内置类型的,如果我们把⼀维数组做为数组的元 素,这时候就是⼆维数组,⼆维数组作为数组元素的数组被称为三维数组,⼆维数组以上的数组统称 为多维数组。

辅助理解:

想象一个围棋棋盘,它有横纵的线条划分出行和列,每个交叉点就可以看作是二维数组中的一个元素 

6.2 ⼆维数组的创建

那我们如何定义二维数组呢?语法如下:

type arr_name[常量值1][常量值2];

例如:
int arr[3][5];
double data[2][8];

解释:上述代码中出现的信息

  • 3表⽰数组有3⾏
  •  5表⽰每⼀⾏有5个元素
  •  int表⽰数组的每个元素是整型类型
  •  arr是数组名,可以根据⾃⼰的需要指定名字 data数组意思基本⼀致。

7、二维数组的初始化

二维数组的初始化和以为数组一样,也是使用大括号初始话的。

7.1 完全初始化

1 int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};

2 int arr[3][5] = {{1,2,3,4,5},{ 2,3,4,5,6}, {3,4,5,6,7}};//向这样使用{}分开也是可以的

向第一种这样排列元素,会先找前5个放在第一行,再找5个放在第二行,最后5个放在第三行。也就是会按顺序放 

我们可以通过调试来理解

7.2 不完全初始化

如果所给的元素不够怎么办?

所给数组元素不够就是不完全初始化

1 int arr1[3][5] = {1,2};

2 int arr2[3][5] = {0};

调试结果

7.3 按行初始化

我们还有另一种方法排放元素

int main()
{
 int arr[3][3] = { { 3,2},{1,1},{2,3} };//不完全初始化
 return 0;
}

如果数据不够的时候,我们可以按照分区间的方法,把想要的数据放在适当的位置。

二维数组如果有初始化,行可以省略,列不能省略。

int arr[ ][4] = {{1,2},{3,4}};

8. ⼆维数组的使用

8.1 ⼆维数组的下标 

当我们掌握了⼆维数组的创建和初始化,那我们怎么使⽤二维数组呢?

其实⼆维数组访问也是使⽤下标的形式的,⼆维数组是有行和列的,只要锁定了行和列就能唯⼀锁定 数组中的⼀个元素。

 C语⾔规定,二维数组的行是从0开始的,列也是从0开始的,如下所示:

1 int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};

图中最右侧绿⾊的数字表示行号,第⼀行蓝色的数字表示列号,都是从0开始的,比如,我们说:第2行,第4列,快速就能定位出7。

 #include <stdio.h>
 int main()
 {
  int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
  printf("%d\n", arr[2][4]);
  return 0;
 }

8.2 ⼆维数组的输入和输出

访问⼆维数组的单个元素我们知道了,那如何访问整个⼆维数组呢?

其实我们只要能够按照⼀定的规律产⽣所有的⾏和列的数字就行;以上⼀段代码中的arr数组为例,行的选择范围是0~2,列的取值范围是0~4,所以我们可以借助循环实现⽣成所有的下标。

#include <stdio.h>
int main()
{
	int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };
	int i = 0;//遍历⾏ 
	//输⼊
	for (i = 0; i < 3; i++)//产生行号
	{
		int j = 0;
		for (j = 0; j < 5; j++)//产生列号
		{
			scanf("%d", &arr[i][j]);//输入数据
		}
	}
	//输出
	for (i = 0; i < 3; i++)//产生行号
	{
		int j = 0;
		for (j = 0; j < 5; j++)//产生列号
		{
			printf(("%d ", arr[i][j]);//输出数据
		}
		printf("\n");
	}
	return 0;
}

输入和输出的结果

9、二维数组在内存中的存储

9.1 二维数组的存储

二维数组可以理解为:一维数组的数组

在 C 语言中,二维数组在内存中是按照行优先(row-major order)的方式连续存储的。

假设我们有一个二维数组 int arr[2][3] ,其在内存中的存储方式类似于将其看作一个一维数组。 先存储第一行的所有元素,然后再存储第二行的元素。

也就是说,内存中元素的排列顺序是 arr[0][0] 、 arr[0][1] 、 arr[0][2] 、 arr[1][0] 、 arr[1][1] 、 arr[1][2] 。

以具体的内存地址为例,如果 arr[0][0] 的地址为 1000 ,且每个 int 类型占用 4 个字节,那么 arr[0][1] 的地址就是 1004 , arr[0][2] 的地址是 1008 , arr[1][0] 的地址是 1012 ,依此类推。

这种连续存储的方式使得可以通过简单的地址计算来快速访问二维数组中的元素。

但需要注意的是,在处理二维数组时,要确保索引不越界,以免访问到非法的内存地址导致程序出错。

代码展示:

#include<stdio.h>
int main()
{
    int arr[3][5] = { 0 };
    int i = 0;
    int j = 0;
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 5; j++)
        {
            printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);
        }
    }
    return 0;
}

输出结果:

从输出的结果来看,每⼀⾏内部的每个元素都是相邻的,地址之间相差4个字节,跨⾏位置处的两个元 素(如:arr[0][4]和arr[1][0])之间也是差4个字节,所以⼆维数组中的每个元素都是连续存放的 

9.2 二维数组的实际应用

二维数组在实际编程中有许多应用场景,以下是一些常见的例子:

1. 图像处理:可以用来存储图像的像素信息,其中行和列分别对应图像的高度和宽度。 - 例如,灰度图像可以用二维数组存储每个像素的灰度值。

2. 矩阵运算:如线性代数中的矩阵相加、相乘等操作。 - 在科学计算、机器学习和数值分析中经常用到。

3. 电子表格:类似于 Excel 中的表格数据,可以用二维数组表示行和列的数据。

4. 地图表示:将地图划分为网格,用二维数组存储每个网格的相关信息,如地形、资源等。

5. 游戏开发: - 表示游戏中的棋盘、地图布局。 - 存储游戏中多个角色的位置和状态。

6. 座位安排:例如在会议室、教室等场景中安排座位。

 7. 文本处理:分析文本的二维结构,如表格形式的文本。

这些只是二维数组的一些常见应用场景,实际上,只要数据具有二维的特性并且需要进行批量处理,都可以考虑使用二维数组来进行存储和操作。


结语:

本篇文章到这里就结束了,该篇文章讲了C语言中数组的相关知识,希望能够对大家有所帮助,后面后讲解数组相关例题,敬请期待!!!
 

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

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

相关文章

ZYNQ 入门笔记(零):概述

文章目录 引言产品线Zynq™ 7000 SoCZynq UltraScale™ MPSoCZynq UltraScale RFSoCVersal™ Adaptive SoC 开发环境 引言 Xilinx FPGA 产品线从经济型的 Spartan、Artix 系列到高性能的 Kintex、Virtex、Versal 系列&#xff0c;可以说涵盖了 FPGA 的绝大部分应用场景&#x…

SpringBoot 最大连接数及最大并发数是多少

SpringBoot 最大连接数及最大并发数 Spring Boot 是一个基于 Spring 框架的快速开发框架&#xff0c;它本身并不直接管理数据库连接或网络连接的最大连接数和最大并发数。这些参数通常由底层的基础设施和组件来控制&#xff0c;例如&#xff1a; 数据库连接池&#xff1a;Spri…

Web 3.0革新:社交金融与边玩边赚开启用户数据主权时代

目录 Web 3.0与社交商业模式 传统社交平台的问题 去中心化社交创新 Mirror&#xff1a;去中心化内容发布平台 Lens Protocol&#xff1a;去中心化社交图谱 Maskbook&#xff1a;隐私保护的社交方式 Web 3.0与与边玩边赚模式 经济模型解析 新商业模式的探索 Axie Infi…

C++——模板初阶 | STL简介

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

maven私服上传jar包 400 Bad Request 错误

文章目录 前言一、直接看报错二、问题处理三 maven 私服配置说明总结 前言 maven仓库的私服,一般会存放公司或者个人封装的jar包,用来共享给二次开发和协作伙伴用,很方便 第一次发布没有问题,但是我第二次发布,开始报错了 一、直接看报错 [外链图片转存失败,源站可能有防盗链…

十五届蓝桥杯JAVA B组题目详解(持续更新中)

试题 B: 类斐波那契循环数 我发现蓝桥杯的题目现在就是要费时间去理解&#xff0c;所以还是审题很重要&#xff0c;这道题的思路就是&#xff0c;一个n位数的前n个数&#xff0c;都是对应的位数上的值&#xff0c;比如说12345&#xff0c;五位数是吧&#xff0c;那数列S的前五位…

自主巡航,目标射击

中国机器人及人工智能大赛 参赛经验&#xff1a; 自主巡航赛道 【机器人和人工智能——自主巡航赛项】动手实践篇-CSDN博客 主要逻辑代码 #!/usr/bin/env python #coding: utf-8import rospy from geometry_msgs.msg import Point import threading import actionlib impor…

数据结构(Java):七大排序算法【多方法、多优化、多细节】

目录 1、排序的概念 1.1 排序 1.2 排序的稳定性 1.3 内部排序&外部排序 1.4 各排序算法总结对比 2、 插入排序 2.1 &#x1f338;直接插入排序 2.2 &#x1f338;希尔排序 3、 选择排序 3.1 &#x1f338;直接选择排序 3.2 直接选择排序优化 3.3 &#x1f338;…

【PyTorch】图像多分类项目

【PyTorch】图像二分类项目 【PyTorch】图像二分类项目-部署 【PyTorch】图像多分类项目 【PyTorch】图像多分类项目部署 多类图像分类的目标是为一组固定类别中的图像分配标签。 目录 加载和处理数据 搭建模型 定义损失函数 定义优化器 训练和迁移学习 用随机权重进行训…

HC-SR04超声波测距模块使用方法和例程(STM32快速移植)

基于STM32和HC-SR04模块实现超声波测距功能 HC-SR04硬件概述HC-SR04超声波距离传感器的核心是两个超声波传感器。一个用作发射器&#xff0c;将电信号转换为40 KHz超声波脉冲。接收器监听发射的脉冲。如果接收到它们&#xff0c;它将产生一个输出脉冲&#xff0c;其宽度可用于…

磁盘作业1

新添加一块硬盘&#xff0c;大小为5g&#xff0c;给这块硬盘分一个mbr格式的主分区&#xff08;大小为3g&#xff09;&#xff0c;给此主分区创建ext2的文件系统&#xff0c;挂载到/guazai1目录&#xff0c;并写入文件内容为 "this is fist disk" 文件名为1.txt的文件…

五分钟学会 Docker Registry 搭建私有镜像仓库

在上一篇文章《前端不懂 Docker &#xff1f;先用它换掉常规的 Vue 项目部署方式》中&#xff0c;我们学习了如何使用 aliyun 私有镜像仓库&#xff0c;也了解到可以使用 Docker Registry 搭建私有镜像仓库。这篇文章就分享下实操过程。 registry 是官方提供的 registry 镜像&…

【数据结构--查找】

目录 一、查找&#xff08;Searching&#xff09;的概念1.1、基本概念1.2、算法的评价指标 二、顺序查找2.1、算法思想2.2、算法实现2.2.1、常规顺序查找2.2.2、带哨兵的顺序查找 2.3、效率分析2.4、优化2.4.1、针对有序表2.4.2、被查效率不相等 三、折半查找3.1、算法思想3.2、…

<数据集>学生课堂行为识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;13899张 标注数量(xml文件个数)&#xff1a;13899 标注数量(txt文件个数)&#xff1a;13899 标注类别数&#xff1a;8 标注类别名称&#xff1a;[js, tt, dk, zt, dx, zl, jz, xt] # 举手 js # 抬头听课 …

新版GPT-4omini上线!快!真TM快!

大半夜&#xff0c;OpenAI突然推出了GPT-4o mini版本。 当我看到这条消息时&#xff0c;正准备去睡觉。mini版本质上是GPT-4o模型的精简版本&#xff0c;没有什么革命性的创新&#xff0c;因此我并没有太在意。 结果今天早上一觉醒来发现伴随GPT-4o mini上线&#xff0c;官网和…

Vue3+ element plus 前后分离admin项目安装教程

前后分离admin项目安装 前后分离admin项目安装基于 vue3.x CompositionAPI typescript vite element plus vue-router-next pinia&#xff0c;适配手机、平板、pc 的后台开源免费模板&#xff0c;希望减少工作量&#xff0c;帮助大家实现快速开发。 下载源码 前往gite…

Flink SQL 实时读取 kafka 数据写入 Clickhouse —— 日志处理(三)

文章目录 前言Clickhouse 表设计adlp_log_local 本地表adlp_log 分布式表 Flink SQL 说明创建 Source Table (Kafka) 连接器表创建 Sink Table (Clickhouse) 连接器解析 Message 写入 Sink 日志查询演示总结 前言 在之前的文章中&#xff0c;我们总结了如何在 Django 项目中进…

甄选范文“论系统安全架构设计及其应用”,软考高级论文,系统架构设计师论文

论文真题 随着社会信息化进程的加快,计算机及网络已经被各行各业广泛应用,信息安全问题也变得愈来愈重要。它具有机密性、完整性、可用性、可控性和不可抵赖性等特征。信息系统的安全保障是以风险和策略为基础,在信息系统的整个生命周期中提供包括技术、管理、人员和工程过…

Noah-MP陆面生态水文模拟与多源遥感数据同化技术

了解陆表过程的主要研究内容以及陆面模型在生态水文研究中的地位和作用&#xff1b;熟悉模型的发展历程&#xff0c;常见模型及各自特点&#xff1b;理解Noah-MP模型的原理&#xff0c;掌握Noah-MP模型在单站和区域的模拟、模拟结果的输出和后续分析及可视化等方法&#xff1b;…

【Spring Boot】网页五子棋项目实现,手把手带你全盘解析(长达两万3千字的干货,坐好了,要发车了......)

目录 网页五子棋项目一、项目核心流程二、 登录模块2.1 前端输入用户信息2.2 后端进行数据库查询用户信息 三、 游戏大厅模块3.1 前端通过Ajax请求用户数据&#xff0c;后端从Session中拿取并从数据库中查询后返回3.2 前后端建立WebSocket连接&#xff0c;并进行判断&#xff0…