线性表之顺序表(C语言实现)

news2024/12/24 9:04:17

在这里插入图片描述

前言

🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨
🐻推荐专栏: 🍔🍟🌯 c语言初阶
🔑个人信条: 🌵知行合一
🍉本篇简介:>:讲解数据结构的入门知识,线性结构之顺序表.
金句分享:
✨人最高级的炫耀,是你这一生拒绝过什么.✨

目录

  • 前言
  • 一、线性表
  • 二、顺序表
    • 2.1 静态顺序表简单介绍:
    • 2.2 动态顺序表:
  • 三、顺序表的常见操作(接口)
    • 3.1 顺序表的类型声明:
    • 3.2 顺序表的初始化
    • 3.3 "增容"函数
    • 3.4 顺序表的"插入"操作:
      • 顺序表的"尾插"
      • 顺序表的"头插"
    • 3.5 顺序表的"判空"
    • 3.6 顺序表的删除操作
      • 顺序表的"尾删"
      • 顺序表的"头删"
    • 3.7 顺序表的指定位置"插入"
    • 3.8 顺序表的指定位置"删除"
    • 3.9 顺序表的"打印"
    • 3.10 顺序表的"查找"
    • 3.11 顺序表的"销毁"
  • 四.总代码:
    • 函数声明区(SQList.h)
    • 函数实现区(SQList.c)
    • 主测试区(test.c)

一、线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串等…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储.

二、顺序表

概念:
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

顺序表一般分为;两种:1.静态顺序表 2.动态顺序表

静态顺序表实际作用不大,本篇主要讲解动态顺序表.

2.1 静态顺序表简单介绍:

在这里插入图片描述

静态顺表是指顺序表的容量是固定的,如果看过c语言实现通讯录的友友们,对于静态顺序表可以轻松拿捏.

2.2 动态顺序表:

在这里插入图片描述

三、顺序表的常见操作(接口)

3.1 顺序表的类型声明:

//动态版
typedef int DataType;
#define  MAX 10
typedef struct SQList
{
	DataType* data;//指向一段连续的内存空间
	int size;//代表当前顺序表的长度
	int capacity;//表示最大容量
}SQL;

3.2 顺序表的初始化

动态顺序表虽然容量没有限制,会自动扩容,但是也要设置初始值,当达到初始值的最大限制时,才会去动态扩容.

	SQL SL;//用顺序表类型创建一个SL顺序表
	InitSQL(&SL);

顺序表的初始化是需要修改顺序表中的成员的,所以需要传址调用,否则形参不会影响实参.

void InitSQL(SQL* SL)
{
	assert(SL);//防止传入空指针
	SL->capacity = MAX;
	SL->size = 0;//顺序表初始状态,当前数据量为0
	SL->data = (DataType*)malloc(sizeof(DataType) * MAX);//初始化顺序表大小
	if (SL->data == NULL)
	{
		printf("初始化申请空间失败.\n");
	}
}

3.3 "增容"函数

当顺序表需要增容时,increase函数利用realloc函数对data指针指向的空间,重新分配合适大小.

DataType* increase(SQL* SL)
{
	assert(SL);
	SL->capacity *= 2;//增容扩大为原来的两倍,这里根据情况,可自由选择每次扩容的增量
	DataType* ret=(DataType*)realloc(SL->data,sizeof(DataType) * SL->capacity);//重新申请一段增容后大小的空间.
	assert(ret);//如果增容失败,则报错.
	return ret;
}

3.4 顺序表的"插入"操作:

顺序表的"尾插"

顺序表的尾插很简单,size为当前顺序表的数据个数,将其作为下标,刚好可以指向新的位置(尾部的下一个位置),将新元素插入后,size自增1,可完成顺序表的尾插操作.
在这里插入图片描述
尾插:

  1. 插入操作之前都需要先判断顺序表是否已满.
  2. 以size作为下标,将新元素插入进数组.
  3. size++,顺序表长度+1.

注意:

执行插入操作之前,要先判断目前的顺序表是否已经达到最大容量(capacity),如果顺序表已满,则需要调用增容函数(increase),对函数进行增容.

代码:

//顺序表的尾插
void PushBack(SQL* SL, DataType x)
{
	assert(SL);
	if (SL->size == SL->capacity)//
	{
		SL->data = increase(SL);//调用增容函数,进行动态扩容
	}
	SL->data[SL->size] = x;
	SL->size++;
}

顺序表的"头插"

顺序表的头插就显得稍微复杂一些,效率不高,需要移动数据.
在这里插入图片描述

头插:

  1. 插入操作之前都需要先判断顺序表是否已满.
  2. 将所有的原有数据向后移动一个位置. (这里只能从最后一个位置开始往后移,如果从前面开始移动数据,会将后面的数据覆盖,导致数据出错.)
  3. 将新数据插入进数组首位置.
  4. size+1,表示顺序表长度+1
//顺序表的头插
void PushFront(SQL* SL, DataType x)
{
	assert(SL);
	//同样在进行插入操作之前,要先判断是否.
	if (SL->size == SL->capacity)
	{
		SL->data = increase(SL);
	}
	for (int i = SL->size; i > 0; i--)//将原来数据往后移
	{
		SL->data[i] = SL->data[i - 1];
	}
	//将新的数据插入到数组首位置
	SL->data[0] = x;
	SL->size++;
}

3.5 顺序表的"判空"

size=0时,表示顺序表中没有元素,即顺序表为空.

顺序表如果为空,则返回"真"
顺序表不为空,则返回"假".

//判断是否为空顺序表
bool Empty(SQL* SL)
{
	assert(SL);
	if (SL->size == 0)
	{
		return true;
	}
	else 
		return false;
}

3.6 顺序表的删除操作

顺序表的"尾删"

顺序表的尾删也是很舒服的.

尾删:

  1. 判空:进行删除元素的操作之前,我们应当先对顺序表进行"判空"操作,如果顺序表为空,则不能删除
  2. .size–,即长度-1.

顺序表的尾删操作没有必要真的将最后一个数据删除,只需要调整size的值,那样我们就不能访问到已经删除的元素,这也就等于删除了.

代码:

void PopBack(SQL* SL)
{
	assert(SL);
	assert(!Empty(SL));
	SL->size--;
}

顺序表的"头删"

  顺序表的头删效率不高,需要将数据从第二个元素开始,往后的所有元素(包括第二个元素)向前移动一个位置.

在这里插入图片描述

//顺序表的头删
void PopFront(SQL* SL)
{
	assert(SL);
	assert(!Empty(SL));
	for (int i = 0; i < SL->size-1; i++)//将后面的数据向前覆盖
	{
		SL->data[i] = SL->data[i + 1];
	}
	SL->size--;
}

3.7 顺序表的指定位置"插入"

//函数声明.h

//指定位置插入元素,位置是下标+1
void SLInsert(SQL* SL, int pos, DataType x);

提供给该函数要插入的元素及其要被插入的位置.

步骤:

  1. 判断插入的位置是否合法.
  2. 插入操作之前都需要先判断顺序表是否已满.
  3. 将数据从最后一个元素开始到pos位置结束(包括pos处的元素),向后移动一个元素.
  4. 将数据插入到pos位置处.
  5. size++,顺序表的长度+1

该函数主要注意点有两个:

  1. pos位置的合法判断.

pos的取值范围应该是,[1,size+1].
不理解时可以举个例子:
在这里插入图片描述

  1. 需要移动的元素的下标的确定.
    在这里插入图片描述

理解完这两点,代码就不难写了.

代码:

//指定位置的插入
void SLInsert(SQL* SL, int pos, DataType x)
{
	assert(SL);
	assert(!(pos < 0 || pos > SL->size+1));//这里可以在最后一个位置的后面插入,例如:size=5时,可以在6号位置插入
	
	//老样子,插入之前先检查顺序表是否已满
	if (SL->size == SL->capacity)
	{
		SL->data = increase(SL);
	}
	int i = 0;
	//移动数据
	for ( i = SL->size; i > pos - 1; i--)
	{
		SL->data[i] = SL->data[i - 1];
	}
	SL->data[pos-1] = x;
	SL->size++;
}

图解:

在这里插入图片描述

此时我们不妨可以利用SLInsert函数来简写尾插和头插.

尾插:
之所以是size+1,是因为位置是坐标+1

void PushBack(SQL* SL, DataType x)
{
	SLInsert(SL, SL->size+1, x);
}

头插:
之所以是0+1,也是因为位置是坐标+1

//顺序表的头插
void PushFront(SQL* SL, DataType x)
{
	SLInsert(SL, 0 + 1, x);
}

3.8 顺序表的指定位置"删除"

看到这里,相信对于pos的位置范围应该不难判断了吧.

/指定位置删除
void SLErase(SQL* SL, int pos)
{
	assert(SL);
	assert(!Empty(SL));
	assert(!(pos<0 || pos>SL->size));//删除只能在[1-size]范围
	for (int i = pos - 1; i < SL->size-1; i++)
	{
		SL->data[i] = SL->data[i + 1];
	}
	SL->size--;
}

修改后的头删:

//顺序表的头删
void PopFront(SQL* SL)
{
	SLErase(SL, 0 + 1);
}

修改后的尾删:

void PopBack(SQL* SL)
{
	SLErase(SL, SL->size);
}

3.9 顺序表的"打印"

void PrintSQL(SQL* SL)//最好是传指针,保证接口的统一性,传指针的时候记得断言
{
	if (SL->size == 0)
	{
		printf("该顺序表为空.\n");
		return;
	}
	for (int i = 0; i < SL->size; i++)
	{
		printf("%d ", SL->data[i]);
	}
	printf("\n");
}

3.10 顺序表的"查找"

要查找顺序表中的某个值,只需要遍历这个顺序表,依次比较即可.(如果数据有重复,该函数只返回第一次遇到的目标值)

//查找函数
//查找成功返回元素的下标.
//查找失败,返回-1.(因为下标不可能为负数).
int Find(SQL SL, DataType x)
{
	for (int i = 0; i < SL.size; i++)
	{
		if (SL.data[i] == x)
		{
			return i;
		}
	}
	//遍历完顺序表都没找到时.
	return -1;
}

3.11 顺序表的"销毁"

顺序表的销毁及其简单.

1.将data指针释放并置空.
2.将capacity和size设置为0.

//顺序表的销毁后记得要将顺序表置空,该函数不会置空操作.
void DestorySQL(SQL* SL)
{
	assert(SL);
	free(SL->data);
	SL->data = NULL;
	SL->size = 0;
	SL->capacity = 0;

}

好了,关于顺序表牛牛就讲到这里了.如果文章有帮助的话,记得三连支持一波哦!💗💗💗

如果文章中有部分错误之处,可以私信牛牛,互相讨论哦!!!

在这里插入图片描述

四.总代码:

函数声明区(SQList.h)

//SQList.h
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
//动态版
typedef int DataType;
#define  MAX 10
typedef struct SQList
{
	DataType* data;//指向一段连续的内存空间
	int size;//代表当前顺序表的长度
	int capacity;//表示最大容量
}SQL;

/*
//静态版
#define  MAX 10
typedef int DataType;
typedef struct SQList
{
	DataType data[MAX];//大小固定的数组
	int size;//代表当前顺序表的长度
}SQL;
*/

void InitSQL(SQL* SL);
//顺序表的尾插
void PushBack(SQL* SL, DataType x);
//顺序表的头插
void PushFront(SQL* SL, DataType x);

//顺序表的尾删
void PopBack(SQL* SL);
//顺序表的头删
void PopFront(SQL* SL);

int Find(SQL SL, DataType x);//顺序表的查找,输入元素,返回下标,找不到返回-1;


//指定位置删除,位置是下标+1
void SLErase(SQL* SL, int pos);

//指定位置插入元素,位置是下标+1
void SLInsert(SQL* SL, int pos, DataType x);

DataType* increase(SQL* SL);//用于增容
//打印顺序表
//void PrintSQL(SQL SL);
void PrintSQL(SQL* SL);

//顺序表的销毁
void DestorySQL(SQL SL);

函数实现区(SQList.c)

#define _CRT_SECURE_NO_WARNINGS 1
#include "SQList.h"
void InitSQL(SQL* SL)
{
	assert(SL);
	SL->capacity = MAX;
	SL->size = 0;
	SL->data = (DataType*)malloc(sizeof(DataType) * SL->capacity);//初始化顺序表大小
	if (SL->data == NULL)
	{
		printf("初始化申请空间失败.\n");
	}
}
//动态扩容函数
DataType* increase(SQL* SL)
{
	assert(SL);
	SL->capacity *= 2;//增容扩大为原来的两倍
	DataType* ret=(DataType*)realloc(SL->data,sizeof(DataType) * SL->capacity);//重新申请一段增容后大小的空间.
	assert(ret);
	return ret;
}
//顺序表的尾插
void PushBack(SQL* SL, DataType x)
{
	/*assert(SL);
	if (SL->size == SL->capacity)
	{
		SL->data = increase(SL);
	}
	SL->data[SL->size] = x;
	SL->size++;*/
	//上面是不调用SLInsert之前
	SLInsert(SL, SL->size+1, x);
}

//顺序表的头插
void PushFront(SQL* SL, DataType x)
{
	//assert(SL);
	//if (SL->size == SL->capacity)
	//{
	//	SL->data = increase(SL);
	//}
	//for (int i = SL->size; i > 0; i--)//将原来数据往后移
	//{
	//	SL->data[i] = SL->data[i - 1];
	//}
	//SL->data[0] = x;
	//SL->size++;
	//上面是不调用SLInsert之前
	SLInsert(SL, 0 + 1, x);
}

//判断是否为空顺序表
bool Empty(SQL* SL)
{
	assert(SL);
	if (SL->size == 0)
	{
		return true;
	}
	else 
		return false;
}

//顺序表的尾删
void PopBack(SQL* SL)
{
	/*assert(SL);
	assert(!Empty(SL));
	SL->size--;*/
	//上面是不调用SLErase函数之前
	SLErase(SL, SL->size);
}


//顺序表的头删
void PopFront(SQL* SL)
{
	//assert(SL);
	//assert(!Empty(SL));
	//for (int i = 0; i < SL->size-1; i++)//将后面的数据向前覆盖
	//{
	//	SL->data[i] = SL->data[i + 1];
	//}
	//SL->size--;
	//上面是不调用SLErase函数之前
	SLErase(SL, 0 + 1);
}

//void PrintSQL(SQL SL)//这是不传指针版本
//{
//	if (SL.size == 0)
//	{
//		printf("该顺序表为空.\n");
//		return;
//	}
//	for (int i = 0; i < SL.size; i++)
//	{
//		printf("%d ", SL.data[i]);
//	}
//	printf("\n");
//}

void PrintSQL(SQL* SL)//最好是传指针,保证接口的统一性,传指针的时候记得断言
{
	if (SL->size == 0)
	{
		printf("该顺序表为空.\n");
		return;
	}
	for (int i = 0; i < SL->size; i++)
	{
		printf("%d ", SL->data[i]);
	}
	printf("\n");
}

//查找函数
int Find(SQL SL, DataType x)
{
	for (int i = 0; i < SL.size; i++)
	{
		if (SL.data[i] == x)
		{
			return i;
		}
	}
	//遍历完顺序表都没找到时.
	return -1;
}

//指定位置删除操作
void SLErase(SQL* SL, int pos)
{
	assert(SL);
	assert(!Empty(SL));
	//这里当时忘了pos的位置检查
	assert(!(pos<0 || pos>SL->size));//删除只能在[1-size]范围
	for (int i = pos - 1; i < SL->size-1; i++)
	{
		SL->data[i] = SL->data[i + 1];
	}
	SL->size--;
}


//指定位置插入操作.
void SLInsert(SQL* SL, int pos, DataType x)
{
	assert(SL);
	assert(!(pos < 0 || pos > SL->size+1));//这里可以在最后一个位置的后面插入,例如:size=5时,可以在6号位置插入
	
	//老样子,插入之前先检查顺序表是否已满
	if (SL->size == SL->capacity)
	{
		SL->data = increase(SL);
	}
	int i = 0;
	for ( i = SL->size; i > pos - 1; i--)
	{
		SL->data[i] = SL->data[i - 1];
	}
	SL->data[pos-1] = x;
	SL->size++;
}


//顺序表的销毁后记得要将顺序表置空,该函数不会对SL指针置空操作.
void DestorySQL(SQL* SL)
{
	assert(SL);
	free(SL->data);
	SL->data = NULL;
	SL->size = 0;
	SL->capacity = 0;

}

主测试区(test.c)

#define _CRT_SECURE_NO_WARNINGS 1
#include"函数声明区.h"
void test1()
{
	SQL SL;
	InitSQL(&SL);
	printf("判断是否为空顺序表的打印.\n");
	PrintSQL(&SL);

	printf("尾插1,2,3,4,5,6,7,8后:\n");
	PushBack(&SL, 1);
	PushBack(&SL, 2);
	PushBack(&SL, 3);
	PushBack(&SL, 4);
	PushBack(&SL, 5);
	PushBack(&SL, 6);
	PushBack(&SL, 7);
	PushBack(&SL, 8);
	PrintSQL(&SL);

	printf("头插-1,-2,-3后:\n");
	PushFront(&SL, -1);
	PushFront(&SL, -2);
	PushFront(&SL, -3);
	PrintSQL(&SL);
	printf("尾删两次后\n");
	PopBack(&SL);
	PopBack(&SL);
	PrintSQL(&SL);

	printf("头删2次后:\n");
	//printf("头删到空\n");
	PopFront(&SL);
	PopFront(&SL);
	//PopFront(&SL);
	//PopFront(&SL);
	//PopFront(&SL);
	//PopFront(&SL);
	//PopFront(&SL);
	//PopFront(&SL);
	//PopFront(&SL);
	//PopFront(&SL);
	PrintSQL(&SL);
int main()
{
	test1();
	return 0;
}

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

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

相关文章

机器学习笔记 基于深度学习的边缘检测

一、Holistically-Nested Edge Detection 边缘检测是视觉工作中十分常用的技术,传统边缘检测已经包含了很多经典的诸如Canny、Robert等等,都是各有擅场,不过有一点问题,就是很多参数需要人工调试,所以深度学习研究人员提出了基于卷积神经网络的边缘检测算法。 即HED,该算…

uniapp拍照离线定位,获取图片信息,经纬度解析地址

✅作者简介&#xff1a; 我是痴心阿文&#xff0c;你们的学友哥&#xff0c;今天给大家分享uniapp拍照离线定位&#xff0c;获取图片信息&#xff0c;经纬度解析地址 &#x1f4c3;个人主页:痴心阿文的博客_CSDN博客-Vue.js,数组方法,前端领域博主 &#x1f525;本文前言&#…

【数据结构】超详细之顺序表(利用C语言实现)

文章目录 前言一、顺序表是什么&#xff1f;二、顺序表的实现步骤 1.顺序表的初始化以及开辟空间2.实现顺序表的头插、尾插以及打印3.实现顺序表的头删、尾删以及打印4.实现顺序表的查找5.实现顺序表指定位置插入6.实现顺序表指定位置删除7.释放内存总结 前言 数据结构是一个程…

离散数学_九章:关系(3)

9.3 关系的表示 1、用集合表示关系2、用矩阵表示关系矩阵表示关系⭐集合上的关系矩阵 R 自反时 R 对称时 R 反对称时 ⭐确定关系合成的矩阵 3、用有向图表示关系有向图⭐从有向图中 确定关系具有的属性 自反性对称性反对称性传递性 本节及本章的剩余部分研究的所有关系均为二…

函数(详解)——C语言

Hello&#xff0c;友友们前段时间忙拖更了这么久&#xff0c;趁着五一假期好好卷上一波哈哈哈。好的&#xff0c;我们本期主要对C语言中的函数进行讲解。 1.什么是函数 在数学中也常常用到函数&#xff0c;但你对C语言中的函数有了解吗&#xff1f; 在C语言中函数是一段可重…

数据结构学习分享之单链表详解

数据结构第三课 1. 前言2. 链表的概念以及结构3. 链表的分类4.链表的实现4.1 初始化结构4.2 尾插函数4.3 尾删函数4.4 头插函数4.5 头删函数4.6 开辟新节点4.7 销毁链表 5. 单链表OJ题目6. 顺序表和链表的区别7. 总结 1. 前言 &#x1f493;博主CSDN:杭电码农-NEO&#x1f493;…

五年开发经验前端程序员,刚入职一个月就要离职,我来聊聊看法

最近有一个新来的同事&#xff0c;估计又要离职了吧。从他的工作经历来看&#xff0c;大概有5年的前端工作经验&#xff0c;但是头发看起来挺少的&#xff0c;不知道是工作加班导致的&#xff0c;看他的性格不太像是经常加班的。 他这个人就是我们公司人事面试的&#xff0c;虽…

操作系统——进程管理

0.关注博主有更多知识 操作系统入门知识合集 目录 0.关注博主有更多知识 4.1进程概念 4.1.1进程基本概念 思考题&#xff1a; 4.1.2进程状态 思考题&#xff1a; 4.1.3进程控制块PCB 4.2进程控制 思考题&#xff1a; 4.3线程 思考题&#xff1a; 4.4临界资源与临…

躺平减脂减重法补充篇——无需控制碳水摄入的有效方法,另推一种健康的运动和防止老年慢性病的方式...

本文此前已经连续发表了六篇相关文章&#xff0c;内容确实比较多&#xff0c;最近又做了一组实验&#xff0c;进食了大量的锅巴&#xff0c;看看是否会带来体重的增加&#xff0c;每天进食量都不少于200克锅巴&#xff0c;对&#xff0c;4两重&#xff0c;而且是在每天正常进食…

SAPUI5 之XML Views (视图) 笔记

文章目录 官网 Walkthrough学习-XML Views视图案例要求&#xff1a;我们把上面通过index.html body的展示放在XML中展示1.0.1 新增view文件夹1.0.2 在xml文件中新增一个Text 文本1.0.3 在index.js中实例化view视图1.0.4 执行刷新浏览器1.0.5 调试界面分析结果 官网 Walkthrough…

假期给朋友介绍如何学习java和找工作的建议?

Java学习 一、学习Java的建议1. 学习Java基础知识2. 学习Java框架3. 学习Java Web开发4. 学习Java数据库编程5. 学习Java工具6.学习Java中的多线程技术6. 练习编程 二、找工作的建议1. 准备好简历2. 寻找工作机会3. 准备面试4. 提高自己的技能5. 关注行业动态 学习Java和找工作…

第十九章 观察者模式

文章目录 前言普通方式解决问题CurrentConditions 显示当前天气情况WeatherData 管理第三方Clint 测试 一、观察者模式(Observer)原理完整代码SubjectObserverWeatherData implements SubjectCurrentConditions implements ObserverBaiduSite implements ObserverClint 前言 普…

《软件工程教程》(第2版) 主编:吴迪 马宏茹 丁万宁 第十章课后习题参考答案

第十章 面向对象设计 课后习题参考答案 一、单项选择题 &#xff08;1&#xff09;A &#xff08;2&#xff09;B &#xff08;3&#xff09;B &#xff08;4&#xff09;D &#xff08;5&#xff09;A &#xff08;6&#xff09;C&#xff08;7&#xff09;D &#xff0…

【学习心得】Python多版本控制

问题描述&#xff1a;本文主要解决Windows系统下的多个Python版本共存问题。 &#xff08;一&#xff09;安装不同版本Python 官方下载链接&#xff1a;Python Releases for Windows | Python.org 下载如图中所示的版本&#xff08;64位Windows系统可执行安装包版本&#xff0…

赞!数字中国建设峰会上的金仓风采

4月30日&#xff0c;第六届数字中国建设成果展览会圆满落幕。人大金仓深度参与本届峰会&#xff0c;在会上发布产品新版本&#xff0c;展出国产数据库前沿的行业解决方案和创新应用成果&#xff0c;出席国资央企SaaS应用服务共享平台伙伴签约仪式&#xff0c;吸引众多用户、伙伴…

面试官:你知道 Spring lazy-init 懒加载的原理吗?

普通的bean的初始化是在容器启动初始化阶段执行的&#xff0c;而被lazy-init修饰的bean 则是在从容器里第一次进行context.getBean(“”)时进行触发。 Spring 启动的时候会把所有bean信息(包括XML和注解)解析转化成Spring能够识别的BeanDefinition并存到Hashmap里供下面的初始…

k210单片机定时器的应用

定时器应该是一个单片机的标准配置&#xff0c;所以k210也是有的&#xff0c;拥有3个定时器&#xff0c;具体的使用方法我们往下看&#xff1a; 分步介绍&#xff1a; 首先是相关模块的使用 构造函数&#xff1a; machine.Timer(id,channel,modeTimer.MODE_ONE_SHOT,period100…

【7. ROS 中的 IMU 惯性测量单元消息包】

欢迎大家阅读2345VOR的博客【6. 激光雷达接入ROS】&#x1f973;&#x1f973;&#x1f973; 2345VOR鹏鹏主页&#xff1a; 已获得CSDN《嵌入式领域优质创作者》称号&#x1f47b;&#x1f47b;&#x1f47b;&#xff0c;座右铭&#xff1a;脚踏实地&#xff0c;仰望星空&#…

vue3回到上一个路由页面

学习链接 Vue Router获取当前页面由哪个路由跳转 在Vue3的setup中如何使用this beforeRouteEnter 在这个路由方法中不能访问到组件实例this&#xff0c;但是可以使用next里面的vm访问到组件实例&#xff0c;并通过vm.$data获取组件实例上的data数据getCurrentInstance 是vue3提…

Java --- springboot2请求参数处理

目录 一、请求参数处理 1.1、请求映射 1.2、自定义请求规则 1.3、请求处理 1.4、普通参数与基本注解 1.4.1、注解 1.5、参数处理原则 1.6、复杂参数 1.7、自定义参数对象 1.8、自定义Converter 一、请求参数处理 1.1、请求映射 // RequestMapping(value "…