数据结构顺序表实现通讯录

目录

1. 前言:

2.通讯录项目的创建

3. 通讯录的实现

3.1 通讯录的初始化

3.2 通讯录的销毁

3.3 通讯录添加数据

3.4 通讯录查找数据

3.5 通讯录展示数据 

 3.6 通讯录删除数据

 3.7 通讯录修改数据

 4. 通讯录完整代码

4.1 test.c

4.2 SeqList.h

4.3 SeqList.c

 4.4 Contact.h

4.5 Contact.c


1. 前言:

想必大家也都用过手机上面的通讯录吧,手机上面的通讯录有着许多的功能,可以新建联系人,删除联系人,查找联系人,修改联系人等等一系列的功能,我们其实也可以使用数据结构中的顺序表来模拟实现一下这样功能。

本章主要讲述利用顺序表来实现一个简单的通讯录项目

2.通讯录项目的创建

通讯录项目在以顺序表的结构上面会多增加两个文件

通讯录头文件Contact.h和通讯录源文件Contact.h

我们之前使用顺序表数据是用的整型,但是我们想要实现一个通讯录,那么单单一个整型的数据肯定是不能完成的,通讯录里面的数据要有联系人姓名,联系人性别,联系人年龄,联系人电话,联系人住址,一想到需要这么多数据,我们不免就会用到结构体了。

Contact.h 创建结构体

//这里我们用#define来定义大小,方便后续修改
#define NAME_MAX  20
#define GENDER_MAX   20
#define TEL_MAX 20
#define ADDR_MAX 100

typedef struct SeqList son;//这里我们把顺序表重新命名为son

//创建一个存放联系人数据的结构体
typedef struct personinfo
{
	char name[NAME_MAX];//姓名
	char gender[GENDER_MAX];//性别
	int age;//年龄
	char tel[TEL_MAX];//电话
	char addr[ADDR_MAX];//住址
}person;

我们在SeqList.h里面包含通讯录头文件,并把int类型修改为struct类型

这里我们的test.c里面也包含通讯录头文件

 这里我们把int类型修改成struct类型之后,在SeqList.c里面我们的查找方法和打印方法就会报错,这时我们只需要注释掉这两个方法就好了。

最后在Contact.c里面包含通讯录头文件和顺序表头文件

3. 通讯录的实现

3.1 通讯录的初始化

思路:

我们在之前写顺序表的时候,写过初始化的方法,我们可以直接调用这个方法为我们的通讯录进行初始化

Contact.c

void ConInit(son* con)
{
	assert(con);//判断con是否为空指针
	//这里我们在顺序表里面就写过初始化的方法,我们直接调用,这个就是初始化方法的复用
	SLInit(con);
}

通讯录初始化的测试

3.2 通讯录的销毁

思路:

我们写顺序表时也写过销毁方法,我们这里直接调用方法就可以了

 Contact.c

void ConDestroy(son* con)
{
	assert(con);//判断con是否为空指针
	SLDestroy(con);//顺序表销毁方法复用
}

通讯录的销毁测试

3.3 通讯录添加数据

思路:

在我们对通讯录添加数据之前,我们需要检查一下空间大小是否足够,不够申请空间,调用我们之前顺序表的空间检查,增容函数,然后,我们创建一个结构体,把我们想要添加的联系人数据都写上,最后我们在写顺序表时有三种插入方法,我们这里选择尾插,调用尾插方法,将创建的结构体变量传过去,这样通讯录添加数据就完成了

Contact.h

void ConAdd(son* con)
{
	assert(con);//判断con是否为空指针
	//在我们添加联系人数据之前,我们需要检查空间大小
	SLCheckCapacity(con);
	//这里我们创建一个结构体变量
	person p;
	//我们在这里将我们添加联系人的数据写入到p结构体里面
    //这里姓名,性别,电话,住址都是数组,数组名是首元素的地址,所以不需要取地址符号
	printf("请输入你要添加联系人的姓名\n");
	scanf("%s", p.name);
	printf("请输入你要添加联系人的性别\n");
	scanf("%s", p.gender);
	printf("请输入你要添加联系人的年龄\n");
	scanf("%d", &(p.age));//age是整型,需要取地址
	printf("请输入你要添加联系人的电话\n");
	scanf("%s", p.tel);
	printf("请输入你要添加联系人的住址\n");
	scanf("%s", p.addr);
	//在这里我们写了3中插入数据的方法,随便调用一种即可,我们选择尾插
    printf("联系人新建成功!\n");
	SLPushBack(con, p);//我们将p结构体尾插进去
}

通讯录添加数据测试

3.4 通讯录查找数据

思路:

我们一般想要在通讯录里面查找联系人一般直接就是查找联系人的姓名,这里我们也是这样思考的,我们直接创建一个字符数组来接收要查找的联系人姓名,然后再通讯录里面利用循环的方法进行查找,然后找到联系人了,我们就把它的数据都打印出来,这样通讯录查找数据就完成了。

Contact.c

int Confind(son* con,char name[])
{
	int i = 0;
	//循环查找
	for (i = 0; i < con->size; i++)
	{
		if (strcmp(con->arr[i].name,name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void ConFind(son* con)
{
    assert(con);//判断con是否为空指针
	//在这里我们创建一个字符数组用来接收输入要查找的联系人姓名
	char name[NAME_MAX];
	printf("请输入你要查找的联系人姓名\n");
	scanf("%s",name);
	//写一个查找函数,在通讯录里面循环查找
	int find =Confind(con,name);
	//查找到了返回下标,如果没有查找到返回不是下标的数
	if (find < 0)
	{
		printf("你要查找的联系人不存在!\n");
	}
	else
	{   //当我们查找到了,就把它打印出来
		printf("姓名 性别 年龄 电话 住址\n");
		printf("%4s %4s %4d %4s %4s\n",
			con->arr[find].name,
			con->arr[find].gender,
			con->arr[find].age,
			con->arr[find].tel,
			con->arr[find].addr);
	}
}

 通讯录查找数据测试:

3.5 通讯录展示数据 

思路:

我们直接利用循环来打印通讯里里面的所有联系人数据

Contact.c

void ConShow(son* con)
{
	assert(con);//判断con是否为空指针
	printf("姓名 性别 年龄 电话 住址\n");
	int i = 0;
	for (i = 0; i < con->size; i++)
	{
		printf("%4s %4s %4d %4s %4s\n",
			con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].addr);
	}
}

通讯录展示数据测试

 3.6 通讯录删除数据

思路:

这个删除数据,首先我们肯定要考虑到通过联系人姓名进行删除联系人数据,我们要先创建一个字符数据来接收我们要删除的联系人姓名,然后利用前面写过的查找函数,来判断联系人是否在通讯录里面,最后,我们利用在前面顺序表里面写过的指定位置删除的方法进行删除,这样通讯录删除数据就完成了

Contact.c

void ConDel(son* con)
{
	assert(con);//判断con是否为空指针
	char name[NAME_MAX];//创建变量来接收要删除的联系人姓名
	printf("请输入你要删除的联系人姓名\n");
	scanf("%s", name);
	//这里先调用一下查找函数,看看联系人是否存在
	int find = Confind(con,name);
	if (find < 0)
	{
		printf("你要删除的联系人不存在\n");
	}
	else
	{
        printf("联系人删除成功!\n");
		//这里我们在前面顺序表里面写过在指定位置删除,进行复用
		SLEarse(con,find);
	}
}

通讯录删除数据测试

 

 3.7 通讯录修改数据

思路:

这里,我们是要对在通讯录里面的联系人数据进行修改,那我们肯定先查找要修改的联系人姓名在不在通讯录里面,利用查找函数,如果存在,直接进行修改

Contact.

void ConModify(son* con)
{
	assert(con);//判断con是否为空指针
	char name[NAME_MAX];//创建变量来接收要修改的联系人姓名
	printf("请输入你要修改的联系人姓名\n");
	scanf("%s",name);
	//这里先调用一下查找函数,看看联系人是否存在
	int find = Confind(con, name);
	if (find < 0)
	{
		printf("你要修改的联系人不存在\n");
	}
	else
	{   //我们直接在这里进行修改
		printf("请输入你要新建联系人的姓名\n");
		scanf("%s", con->arr[find].name);
		printf("请输入你要新建联系人的性别\n");
		scanf("%s", con->arr[find].gender);
		printf("请输入你要新建联系人的年龄\n");
		scanf("%d", &(con->arr[find].age));//age是整型,需要取地址
		printf("请输入你要新建联系人的电话\n");
		scanf("%s", con->arr[find].tel);
		printf("请输入你要新建联系人的住址\n");
		scanf("%s", con->arr[find].addr);
	}
    printf("联系人修改成功!\n");
}

通讯录修改数据测试

 

 4. 通讯录完整代码

4.1 test.c

#include"SeqList.h"//包含顺序表头文件
#include"Contact.h"//包含通讯录头文件

void menu()
{
	printf("----------通讯录----------\n");
	printf("-------1.新建联系人-------\n");
	printf("-------2.删除联系人-------\n");
	printf("-------3.展示联系人-------\n");
	printf("-------4.查找联系人-------\n");
	printf("-------5.修改联系人-------\n");
	printf("-------0.退出通讯录-------\n");

}
int main()
{
	int input = 0;
	son con;
	ConInit(&con);
	do
	{
		menu();
		printf("请选择你的操作!\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			ConAdd(&con);
			break;
		case 2:
			ConDel(&con);
			break;
		case 3:
			ConShow(&con);
			break;
		case 4:
			ConFind(&con);
			break;
		case 5:
			ConModify(&con);
			break;
		default:
			printf("选择错误,请重新选择!\n");
			break;
		}
	} while (input);
	return 0;
}

4.2 SeqList.h

#include"Contact.h"

//下面是需要使用到的库函数的头文件
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>

//typedef int SLData;//类型重命名,为了方便后续替换类型
//我们把int类型替换成strcut 类型
typedef person SLData;

typedef struct SeqList //类型重命名
{
	SLData *arr;//定长数组
	int size;//顺序表当前有效的数据个数
	int capacity;//容量大小
}sl;

//顺序表增容
void SLCheckCapacity(sl* ps);
//顺序表初始化
void SLInit(sl* ps);
//顺序表打印
void SLPaint(sl* ps);
//顺序表尾插
void SLPushBack(sl* ps, SLData x);
//顺序表头插
void SLPushFront(sl* ps, SLData x);
//顺序表尾删
void SLPopBack(sl* ps);
//顺序表头删
void SLPopFront(sl* ps);
//顺序表指定位置之前插入
void SLInsert(sl* ps, int pos, SLData x);
//顺序表指定位置删除
void SLEarse(sl* ps, int pos);
//顺序表修改指定位置数据
void SLModify(sl* ps,int pos, SLData x);
//顺序表数据查找
int SLFind(sl* ps, SLData x);
//顺序表销毁
void SLDestroy(sl* ps);

4.3 SeqList.c

#include"SeqList.h"//包含顺序表的头文件

void SLInit(sl* ps)
{
	assert(ps);//判断ps是否为空指针
	//这里我们不知道这个顺序表需求的大小
	ps->arr = NULL;//我们就先把指针置为空
	ps->size = ps->capacity = 0;//这里有效数据个数和可存储数据个数都置为0;
}

void SLDestroy(sl* ps)
{
	assert(ps);//判断ps是否为空指针
	free(ps->arr);//释放动态内存开辟的空间
	ps->arr = NULL;//防止ps->arr变成野指针
	ps->size = ps->capacity = 0;//将有效数据和空间大小置0
}

void SLCheckCapacity(sl* ps)
{
	assert(ps);//判断ps是否为空指针
	if (ps->size == ps->capacity)//判断有效数据个数和可存储数据个数,这里如果有效数据个数==可存储数据个数,说明空间不够了,需要增容
	{
		//这里利用三目操作符,判断可用数据个数的大小,并创建相同变量来接收
		int tmp = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		//这里我们用于同类型指针来接收realloc开辟空间返回的地址
		SLData* ptr = (SLData*)realloc(ps->arr, tmp * sizeof(SLData));
		//判断是否开辟成功
		if (ptr == NULL)
		{
			//开辟失败,报错
			perror("realloc");
			exit(1);//退出程序
		}
		//开辟成功,接收
		ps->arr = ptr;
		ps->capacity = tmp;//接收可用空间数据
	}
}

void SLPushBack(sl* ps, SLData x)
{
	assert(ps);//断言ps是否为空指针
	//检查空间大小,不够进行增容
	SLCheckCapacity(ps);
	//这里我们在size位置进行尾插,之后让size++(后置++,先使用在++),用来记录顺序表中有效数据的个数
	ps->arr[ps->size++] = x;
}

//void SLPaint(sl* ps)
//{
//	assert(ps);//判断ps是否为空指针
//	int i = 0;
//	//循环打印
//	for (i = 0; i < ps->size; i++)
//	{
//		printf("%d ", ps->arr[i]);
//	}
//	//换行
//	printf("\n");
//}

void SLPushFront(sl* ps, SLData x)
{
	assert(ps);//判断ps是否为空指针
	//判断空间大小
	SLCheckCapacity(ps);
	int i = 0;
	//循环移动数据
	for (i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];//将前面的数据复制到后一位
	}
	//这里i == 0,跳出循环
	ps->arr[i] = x;
	//让顺序表有效数据个数++
	ps->size++;
}

void SLPopBack(sl* ps)
{
	assert(ps);//判断ps是否为空指针
	assert(ps->size);//判断顺序表里面的有效数据个数
	ps->size--;
}

void SLPopFront(sl* ps)
{
	assert(ps);//判断ps是否为空指针
	assert(ps->size);//判断顺序表里面的有效数据个数
	int i = 0;
	//循环移动
	for (i = 0; i < ps->size; i++)
	{
		ps->arr[i] = ps->arr[i + 1];//将后面值赋值给前一位
	}
	ps->size--;
}

void SLInsert(sl* ps, int pos, SLData x)
{
	assert(ps);//判断ps是否为空指针
	assert(pos >= 0 && pos < ps->size);//判断删除数据的范围
	SLCheckCapacity(ps);//判断空间大小
	int i = 0;
	for (i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];//将数据整体往后移动一位
	}
	//i == pos 跳出循环
	ps->arr[i] = x;
	ps->size++;
}

void SLEarse(sl* ps, int pos)
{
	assert(ps);//判断ps是否为空指针
	assert(pos >= 0 && pos < ps->size);//判断指定位置的范围
	int i = 0;
	for (i = pos; i < ps->size; i++)
	{
		ps->arr[i] = ps->arr[i + 1];//将指定位置之后的数据整体往前移动一位
	}
	ps->size--;
}

void SLModify(sl* ps, int pos, SLData x)
{
	assert(ps);//判断ps是否为空指针
	assert(pos >= 0 && pos < ps->size);//判断指定位置是否合法
	ps->arr[pos] = x;
}

 4.4 Contact.h

//这里我们用#define来定义大小,方便后续修改
#define NAME_MAX  20
#define GENDER_MAX   20
#define TEL_MAX 20
#define ADDR_MAX 100

typedef struct SeqList son;//这里我们把顺序表重新命名为son

//创建一个存放联系人数据的结构体
typedef struct personinfo
{
	char name[NAME_MAX];//姓名
	char gender[GENDER_MAX];//性别
	int age;//年龄
	char tel[TEL_MAX];//电话
	char addr[ADDR_MAX];//住址
}person;

//通讯录初始化
void ConInit(son* con);
//通讯录销毁
void ConDestroy(son* con);
//通讯录添加数据
void ConAdd(son* con);
//通讯录查找数据
void ConFind(son* con);
//通讯录展示数据
void ConShow(son* con);
//通讯录删除数据
void ConDel(son* con);
//通讯录修改数据
void ConModify(son* con);

4.5 Contact.c

#include"Contact.h"
#include"SeqList.h"

void ConInit(son* con)
{
	assert(con);//判断con是否为空指针
	//这里我们在顺序表里面就写过初始化的方法,我们直接调用,这个就是初始化方法的复用
	SLInit(con);
}

void ConDestroy(son* con)
{
	assert(con);//判断con是否为空指针
	SLDestroy(con);//顺序表销毁方法复用
}

void ConAdd(son* con)
{
	assert(con);//判断con是否为空指针
	//在我们添加联系人数据之前,我们需要检查空间大小
	SLCheckCapacity(con);
	//这里我们创建一个结构体变量
	person p;
	//我们在这里将我们添加联系人的数据写入到p结构体里面
    //这里姓名,性别,电话,住址都是数组,数组名是首元素的地址,所以不需要取地址符号
	printf("请输入你要添加联系人的姓名\n");
	scanf("%s", p.name);
	printf("请输入你要添加联系人的性别\n");
	scanf("%s", p.gender);
	printf("请输入你要添加联系人的年龄\n");
	scanf("%d", &(p.age));//age是整型,需要取地址
	printf("请输入你要添加联系人的电话\n");
	scanf("%s", p.tel);
	printf("请输入你要添加联系人的住址\n");
	scanf("%s", p.addr);
	printf("联系人新建成功!\n");
	printf("--------------------------\n");
	//在这里我们写了3中插入数据的方法,随便调用一种即可,我们选择尾插
	SLPushBack(con, p);//我们将p结构体尾插进去
}


int Confind(son* con,char name[])
{
	int i = 0;
	//循环查找
	for (i = 0; i < con->size; i++)
	{
		if (strcmp(con->arr[i].name,name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void ConFind(son* con)
{
	assert(con);//判断con是否为空指针
	//在这里我们创建一个字符数组用来接收输入要查找的联系人姓名
	char name[NAME_MAX];
	printf("请输入你要查找的联系人姓名\n");
	scanf("%s",name);
	//写一个查找函数,在通讯录里面循环查找
	int find =Confind(con,name);
	//查找到了返回下标,如果没有查找到返回不是下标的数
	if (find < 0)
	{
		printf("你要查找的联系人不存在!\n");
		return;//提前返回
	}
	else
	{   //当我们查找到了,就把它打印出来
		printf("姓名 性别 年龄 电话 住址\n");
		printf("%4s %4s %4d %4s %4s\n",
			con->arr[find].name,
			con->arr[find].gender,
			con->arr[find].age,
			con->arr[find].tel,
			con->arr[find].addr);
	}
}

void ConShow(son* con)
{
	assert(con);//判断con是否为空指针
	printf("姓名 性别 年龄 电话 住址\n");
	int i = 0;
	for (i = 0; i < con->size; i++)
	{
		printf("%4s %4s %4d %4s %4s\n",
			con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].addr);
	}
}

void ConDel(son* con)
{
	assert(con);//判断con是否为空指针
	char name[NAME_MAX];//创建变量来接收要删除的联系人姓名
	printf("请输入你要删除的联系人姓名\n");
	scanf("%s", name);
	//这里先调用一下查找函数,看看联系人是否存在
	int find = Confind(con,name);
	if (find < 0)
	{
		printf("你要删除的联系人不存在\n");
		return;//提前返回
	}
	else
	{
		//这里我们在前面顺序表里面写过在指定位置删除,进行复用
		printf("联系人删除成功!\n");
		SLEarse(con,find);
	}
}

void ConModify(son* con)
{
	assert(con);//判断con是否为空指针
	char name[NAME_MAX];//创建变量来接收要修改的联系人姓名
	printf("请输入你要修改的联系人姓名\n");
	scanf("%s",name);
	//这里先调用一下查找函数,看看联系人是否存在
	int find = Confind(con, name);
	if (find < 0)
	{
		printf("你要修改的联系人不存在\n");
	}
	else
	{   //我们直接在这里进行修改
		printf("请输入你要新建联系人的姓名\n");
		scanf("%s", con->arr[find].name);
		printf("请输入你要新建联系人的性别\n");
		scanf("%s", con->arr[find].gender);
		printf("请输入你要新建联系人的年龄\n");
		scanf("%d", &(con->arr[find].age));//age是整型,需要取地址
		printf("请输入你要新建联系人的电话\n");
		scanf("%s", con->arr[find].tel);
		printf("请输入你要新建联系人的住址\n");
		scanf("%s", con->arr[find].addr);
	}
	printf("联系人修改成功!\n");
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OneAPI接入本地大模型+FastGPT调用本地大模型

将Ollama下载的本地大模型配置到OneAPI中&#xff0c;并通过FastGPT调用本地大模型完成对话。 OneAPI配置 新建令牌 新建渠道 FastGPT配置 配置docker-compose 配置令牌和OneAPI部署地址 配置config.json 配置调用的渠道名称和大模型名称 {"systemEnv": {&qu…

【虚拟机软件】 VMware Workstation Pro 17 新建 Linux 虚拟机教程(CentOS 7 版本)

文章目录 下载安装 VMware Workstation Pro 17 软件下载 Linux 的 ISO 映像文件Linux版本选择 新建虚拟机准备配置新建安装 后续设置文章导航 我是一名立志把细节说清楚的博主&#xff0c;欢迎【关注】&#x1f389; ~ 原创不易&#xff0c; 如果有帮助 &#xff0c;记得【点赞…

【全开源】填表统计预约打卡表单系统FastAdmin+ThinkPHP+UniApp

简化流程&#xff0c;提升效率 一、引言&#xff1a;传统表单处理的局限性 在日常工作和生活中&#xff0c;我们经常会遇到需要填写表单、统计数据和预约打卡等场景。然而&#xff0c;传统的处理方式往往效率低下、易出错&#xff0c;且不利于数据的统计和分析。为了解决这些…

报名倒计时两周|2024 OpenTiny 开源之夏项目直播解读回顾

5月16日&#xff0c;OpenTiny 开源社区成功举办了以《OpenTiny 开源之夏项目解读直播》为主题的直播活动。此次直播中&#xff0c;华为云的高级前端工程师曾令卡、华为云的高级前端工程师伍其和与10位开源之夏技术专家携手组成项目导师团&#xff0c;面向广大开发者一同深入探讨…

如何在go语言中调用c语言代码

1.安装c语言编译器 要使用cgo&#xff0c;需要安装c语言编译器 gcc 2.检查CGO_ENABLED时候开启 使用以下命令查看&#xff1a; go env CGO_ENABLED 如果go env CGO_ENABLED被禁用(为0),需要将其设置为开启(为1) 3.编写c语言程序&#xff0c;并用go语言调用c语言程序 1&#xff…

Design to code(2)

【碎碎念】从七点到十一点&#xff0c;累计用时4个小时完成的代码翻译Σ(&#xffe3;。&#xffe3;ノ)ノ DCDS图 顺序图&#xff08;支付过程&#xff09; 交互图&#xff08;订单&#xff09; 我的代码 Payment public class Payment { //定义支付订单金额 private…

k8s集群部署成功后某个节点突然出现notready状态解决办法

通过&#xff1a; kubectl get nodes 查看master1节点为not ready 通过查看日志&#xff1a; journalctl -f -u kubelet.service 看到这里 查看状态&#xff1a; systemctl status kubelet.service 重启一样会报错 执行&#xff1a; swapoff -a 执行后&#xff0c;重启…

以及Spring中为什么会出现IOC容器?@Autowired和@Resource注解?

以及Spring中为什么会出现IOC容器&#xff1f;Autowired和Resource注解&#xff1f; IOC容器发展史 没有IOC容器之前 首先说一下在Spring之前&#xff0c;我们的程序里面是没有IOC容器的&#xff0c;这个时候我们如果想要得到一个事先已经定义的对象该怎么得到呢&#xff1f;…

HCIP-Datacom-ARST自选题库__ISIS判断【23道题】

1.IS-1S快速收敛是为了提高路由的收敛速度而做的扩展特性&#xff0c;包含PRC和I-SPF&#xff0c;其中PRC只对发生变化的路由进行重新计算&#xff0c;而I-SPF只对受影响的节点进行路由计算。√ 2.在I5-S协议视图下配置ipv6 preference&#xff0c;该命令的作用是配置|5-IS协议…

『哈哥赠书 - 53期』-『深入浅出 Spring Boot 3.x』

⭐️ 《深入浅出 Spring Boot 3.x》 ⭐️ 学习Spring Boot的必读之书 在 Java 后端开发领域&#xff0c;功能强大的 Spring 开源框架不仅是首选&#xff0c;也是事实上的标准。但由于 Spring 存在配置烦琐、部署不易、依赖管理困难等问题&#xff0c;因此基于 Spring 的快速开…

【IDEA软件应用篇】IDEA基础开发设置和开发快捷键

IDEA是一种集成开发环境&#xff0c;可以运行java代码。 本篇文章你将收获到下面的知识&#xff1a; &#xff08;1&#xff09;IDEA如何设置字体大小快捷键 &#xff08;2&#xff09;如何解决每次进IDEA时&#xff0c;进去的页面都是上次使用完时的那个页面 &#xff08;3&am…

【学习笔记】Windows GDI绘图(四)矩阵Matrix详解

矩阵Matrix 基于矩阵在GDI绘图的重要性&#xff0c;所以想深入了学习矩阵的相关属性与方法。 先上个本文中所有的函数图例演示吧。 原型&#xff1a; namespace System.Drawing.Drawing2D;public sealed unsafe class Matrix : MarshalByRefObject, IDisposableMatrix类封装…

(Java企业 / 公司项目)配置Linux网络-导入虚拟机

公司给了我一个IP地址 &#xff0c;提供了一个虚拟机或者自己搭建虚拟机&#xff0c;还有提供登录的账号密码 可以查看我之前的文章 VMware Workstation Pro 17虚拟机超级详细搭建&#xff08;含redis&#xff0c;nacos&#xff0c;docker, rabbitmq&#xff0c;sentinel&…

民国漫画杂志《时代漫画》第16期.PDF

时代漫画16.PDF: https://url03.ctfile.com/f/1779803-1248612470-6a05f0?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps:资源来源网络&#xff01;

EMQX 的初始IP改为自己的实际IP

分类 EMQX Dashboard&#xff08;控制台&#xff09;: Dashboard提供了一个Web界面&#xff0c;用于管理和监控EMQX的运行状态。您可以通过配置dashboard.listeners.http.bind来设置Dashboard的监听地址和端口。例如&#xff0c;如果您想要Dashboard在所有网络接口上监听&#…

【oracle004】oracle内置函数手册总结(已更新)

1.熟悉、梳理、总结下oracle相关知识体系。 2.日常研发过程中使用较少&#xff0c;随着时间的推移&#xff0c;很快就忘得一干二净&#xff0c;所以梳理总结下&#xff0c;以备日常使用参考 3.欢迎批评指正&#xff0c;跪谢一键三连&#xff01; 总结源文件资源下载地址&#x…

Scala的简单学习一

一 相关知识 1.1 scala的安装 1.在idea中导入依赖&#xff0c;并在Idea下载scala插件 1.2 scala基础知识点 1.scala代码中一行语句的结束是以换行符为标准&#xff0c;可以不用写分号 2.class是一个普通的类&#xff0c;object相当于一个单例对象&#xff0c;object类中的…

基于GA遗传优化的CNN-GRU的时间序列回归预测matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 CNN-GRU模型架构 4.2 GA优化CNN-GRU流程 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 ...........................................…

类和对象的基本概念

类和对象的基本概念 C和C中struct区别类的封装封装访问权限总结struct和class的区别 将成员变量设置为private C和C中struct区别 C语言struct只有变量C语言struct 既有变量&#xff0c;也有函数 类的封装 封装 把变量&#xff08;属性&#xff09;和函数&#xff08;操作&a…