C语言之通讯录的实现篇优化版

news2024/11/20 19:37:40

目录

动态内存管理

通讯录声明

静态版本 

 动态版本

 ​初始化通讯录

静态版本

动态版本

Add增加通讯录

静态版本

动态版本

 Checkcapacity增容

DestroyContact释放动态空间 

文件操作

SaveContact保存信息到文件中 

初始化通讯录

旧版本

文件版本

LoadContact加载文件信息到通讯录

test.c

contact.h

contact.c


我们前面已经学习完 动态内存管理 和 C语言操作文件,相信你对内存的管理和操作有了更加深入的了解。那我们今天接着来优化一下前面我们写过的通讯录。

  • 特别提醒:函数如果放在后面,在使用函数前面必须声明!!

动态内存管理

使用动态内存相关的知识优化通讯录。主要是从增加内存的方面去优化。我们设置为以下规则,注意这种设置仅仅为了方便讲解和测试仅此而已。后期大家可以设置为自己想要的规则。

  • 通讯录刚刚开始可以存放3个人的信息。
  • 通讯录放满,可以增加容量,每次增加2个人的信息的空间。

通讯录声明

静态版本 

//通讯录---存放结构体的数组--每个结构体就是一个人的信息
typedef struct Contact
{
	PeoInfo data[MAX];//存放数据
	int sz;//记录当前通讯录中存放的人的信息个数
}Contact;

 动态版本

//动态版本
typedef struct Contact
{
	PeoInfo* data;//存放数据,可修改数组内存的空间了
//🆗PeoInfo结构体类型的指针
	int sz;//记录当前通讯录中存放的人的信息个数
	int capacity;//记录的是通讯录的当前容量
}Contact;
  • 当通讯录中存放的人的信息个数 sz == 通讯录当前容量 capacity就可以考虑增加容量问题。
  • 目前的data是没有空间的,需要在初始化的时候在堆区开辟3个人的信息空间。
  • PeoInfo* data  存放数据,可修改数组内存的空间了,🆗PeoInfo结构体类型的指针
  • PeoInfo* data  指针维护开辟的空间

 ​初始化通讯录

静态版本

void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));
}

动态版本

#define DEFAULT_SZ 3 //后期容易修改
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;
	pc->data = calloc(pc->capacity ,sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact->calloc");
		return;
	}
}
  •  PeoInfo* data  指针维护开辟的空间

Add增加通讯录

静态版本

void AddContact(Contact* pc)
{
	assert(pc);
	printf("请输入名字\n");
	scanf("%s", pc->data[pc->sz].name);//name是数组名,不用&
	printf("请输入年龄\n");
	scanf("%d", &(pc->data[pc->sz].age));//
	printf("请输入性别\n");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入电话\n");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入地址\n");
	scanf("%s", pc->data[pc->sz].addr);
	//
	pc->sz++;
	printf("增加成功\n");
}

动态版本

#define DEFAULT_INC 2//后期容易修改
//动态版本
void AddContact(Contact* pc)
{
	assert(pc);
	//满了增加容量
	if (pc->sz == pc->capacity)
	{
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + DEFAULT_INC) * sizeof(PeoInfo));
		if (ptr != NULL)
		{
			pc->data = ptr;
		}
		else
		{
			perror("AddContact->realloc");
			return;
		}
	}
	//不需要增容填写人信息
	printf("请输入名字\n");
	scanf("%s", pc->data[pc->sz].name);//name是数组名,不用&
	printf("请输入年龄\n");
	scanf("%d", &(pc->data[pc->sz].age));//
	printf("请输入性别\n");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入电话\n");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入地址\n");
	scanf("%s", pc->data[pc->sz].addr);
	//
	pc->sz++;
	printf("增加成功\n");
}
  • 当通讯录中存放的人的信息个数 sz == 通讯录当前容量 capacity就可以考虑增加容量问题。

当然也可以封装成函数Checkcapacity 

 Checkcapacity增容

Checkcapacity(pc);
void Checkcapacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + DEFAULT_INC) * sizeof(PeoInfo));
		if (ptr != NULL)
		{
			pc->data = ptr;
		}
		else
		{
			perror("AddContact->realloc");
			return;
		}
	}
}

 当然我们使用了动态内存的空间,我们必须手动释放和销毁,我们封装一个函数去销毁。

DestroyContact释放动态空间 

void DestroyContact(Contact* pc);
case EXIT:
	DestroyContact(&con);
	printf("退出通讯录\n");
	break;
void DestroyContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->capacity = 0;
}

文件操作

程序退出之后,输入的信息都丢了。所以在通讯录之前最好把我们输入的信息全部保存到文件里。

SaveContact保存信息到文件中 

//保存信息到文件
void SaveContact(Contact* pc);
case EXIT:
	//保存通讯录中的数据到文件中
	SaveContact(&con);
	DestroyContact(&con);
	printf("退出通讯录\n");
	break;
void SaveContact(Contact* pc)
{
	//打开文件
	FILE* pf = fopen("contact.txt", "wb");//wb以二进制的方式写数据到文件
	if (pf == NULL)
	{
		perror("SaveContact");
		return;
	}
	//写信息到文件
	int i = 0;//一个数据一个数据写
	for (i = 0; i < pc->sz; i++)
	{
		fwrite(&(pc->data[i]), sizeof(PeoInfo), 1, pf);
		fwrite(pc->data+i, sizeof(PeoInfo), 1, pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
}
  • 字符以ASCII码和二进制的存储的方式相同
  • 整型以ASCII码和二进制的存储的方式不同

初始化通讯录

但是当程序再次跑起来的时候,还是看不到信息??所以我们需要在执行通讯录等一系列的功能之前我们就要从文件里读取到数据信息。我们去修改初始化部分

旧版本

void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;
	pc->data = calloc(pc->capacity * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact->calloc");
		return;
	}
}

文件版本

//文件版本
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;
	pc->data = calloc(pc->capacity * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact->calloc");
		return;
	}
	LoadContact(pc);
}

LoadContact加载文件信息到通讯录

//加载文件信息到通讯录
void LoadContact(Contact* pc);
void Checkcapacity(Contact* pc);//声明

void LoadContact(Contact* pc)
{
	//打开文件
	FILE* pf = fopen("contact.txt", "rb");//以二进制的形式读
	if (pf == NULL)
	{
		perror("LoadContact");
		return;
	}
	//读文件
	PeoInfo tmp = { 0 };//创建临时变量,结构体PeoInfo类型
	while (fread(&tmp, sizeof(PeoInfo), 1, pf))//读到就返回1,没有读到就返回0,一个一个读直到没有读到为0跳出循环
	{
		Checkcapacity(pc);//若文件中有5个人,但是这里只有3个人的容量,首先判断需不需要增容
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
void menu()
{
	printf("************************************\n");
	printf("********1.add      2.del************\n");
	printf("********3.search   4.modify*********\n");
	printf("********5.show     6.sort***********\n");
	printf("********0.exit           ***********\n");
	printf("************************************\n");
}
enum Option
{
	EXIT,//0
	ADD,//1
	DEL,//2
	SEARCH,//3
	MODIFY,//4
	SHOW,//5
	SORT,//6	
};
int main()
{
	int input = 0;
	//创建通讯录
	Contact con;
	//初始化通讯录
	InitContact(&con);
	do
	{
		menu();
		printf("请输入你的选择:>\n");
		scanf("%d", &input);
		switch (input)//这里为了代码更加清晰用枚举常量
		{
		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DelContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			break;
		case SHOW:
			ShowContact(&con);
			break;
		case SORT:
			//SortContact(&con);
			break;
		case EXIT:
			//保存通讯录中的数据到文件中
			SaveContact(&con);
			DestroyContact(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择:>\n");
			break;
		}
	} while (input);
	return 0;
}

contact.h

#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#define NAME_MAX 20
#define SEX_MAX 20
#define TELE_MAX 20
#define ADDR_MAX 30
#define MAX 100
#define DEFAULT_SZ 3
#define DEFAULT_INC 2
typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}PeoInfo;

//静态版本
//typedef struct Contact
//{
//	PeoInfo data[MAX];//存放数据
//	int sz;//记录当前通讯录中存放的人的信息个数
//}Contact;

//动态版本
typedef struct Contact
{
	PeoInfo* data;//存放数据
	int sz;//记录当前通讯录中存放的人的信息个数
	int capacity;//记录的是通讯录的当前容量
}Contact;

//初始化通讯录
void InitContact(Contact* pc);
//增加个人信息
void AddContact(Contact* pc);
//展示个人信息
void ShowContact(Contact* pc);
//删除个人信息
void DelContact(Contact *pc);
//查找个人信息
void SearchContact(Contact* pc);
//修改个人信息
void ModifyContact(Contact* pc);
//排序
//void SortContact(Contact* pc);
//释放空间
void DestroyContact(Contact* pc);
//保存信息到文件
void SaveContact(Contact* pc);
//加载文件信息到通讯录
void LoadContact(Contact* pc);

contact.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"

//初始化静态版本
//void InitContact(Contact* pc)
//{
//	assert(pc);
//	pc->sz = 0;
//	memset(pc->data, 0, sizeof(pc->data));
//}

//动态版本
//void InitContact(Contact* pc)
//{
//	assert(pc);
//	pc->sz = 0;
//	pc->capacity = DEFAULT_SZ;
//	pc->data = calloc(pc->capacity * sizeof(PeoInfo));
//	if (pc->data == NULL)
//	{
//		perror("InitContact->calloc");
//		return;
//	}
//}

//文件版本
void Checkcapacity(Contact* pc);//声明
void LoadContact(Contact* pc)
{
	//打开文件
	FILE* pf = fopen("contact.txt", "rb");//以二进制的形式读
	if (pf == NULL)
	{
		perror("LoadContact");
		return;
	}
	//读文件
	PeoInfo tmp = { 0 };
	while (fread(&tmp, sizeof(PeoInfo), 1, pf))
	{
		Checkcapacity(pc);
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
}
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;
	pc->data = calloc(pc->capacity * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact->calloc");
		return;
	}
	LoadContact(pc);
}

//增加静态版本
//void AddContact(Contact* pc)
//{
//	assert(pc);
//	printf("请输入名字\n");
//	scanf("%s", pc->data[pc->sz].name);//name是数组名,不用&
//	printf("请输入年龄\n");
//	scanf("%d", &(pc->data[pc->sz].age));//
//	printf("请输入性别\n");
//	scanf("%s", pc->data[pc->sz].sex);
//	printf("请输入电话\n");
//	scanf("%s", pc->data[pc->sz].tele);
//	printf("请输入地址\n");
//	scanf("%s", pc->data[pc->sz].addr);
//	//
//	pc->sz++;
//	printf("增加成功\n");
//}

//动态版本
void Checkcapacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));
		if (ptr != NULL)
		{
			pc->data = ptr;
		}
		else
		{
			perror("AddContact->realloc");
			return;
		}
	}
}

void AddContact(Contact* pc)
{
	assert(pc);
	//满了增加容量
	Checkcapacity(pc);
	//不需要增容填写人信息
	printf("请输入名字\n");
	scanf("%s", pc->data[pc->sz].name);//name是数组名,不用&
	printf("请输入年龄\n");
	scanf("%d", &(pc->data[pc->sz].age));//
	printf("请输入性别\n");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入电话\n");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入地址\n");
	scanf("%s", pc->data[pc->sz].addr);
	//
	pc->sz++;
	printf("增加成功\n");
}

//展示
void ShowContact(const Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无需打印\n");
		return 0;
	}
	int i = 0;
	//名字 年龄 性别 电话 地址
	//-左对齐
	//20是需要20字符的位置来放名字 
	printf("%-20s%-5s%-5s%-12s%-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s%-5d%-5s%-12s%-30s\n",
			pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
	}
}


//删除,查找,修改都需要使用
int FindByName(const Contact* pc, char name[])
{
	assert(pc);
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}

//删除
void DelContact(Contact* pc)
{
	char name[NAME_MAX];//
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}
	printf("输入要删除的名字:>");
	scanf("%s", name);
	int ret = FindByName(pc, name);
	if (ret == -1)
	{
		printf("要删除的人不存在\n");
		return;
	}
	//存在返回这个人的所在data的下标放入ret
	int i = 0;

	for (i = ret; i < pc -> sz - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("删除成功\n");
}



//查找
void SearchContact(Contact* pc)
{
	char name[NAME_MAX];
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法查找\n");
		return;
	}
	//查找
	printf("输入要查找的名字:>");
	scanf("%s", name);
	int ret = FindByName(pc, name);
	if (ret == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}
	//返回下标显示这个的信息🆗
	printf("%-20s%-5s%-5s%-12s%-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	printf("%-20s%-5d%-5s%-12s%-30s\n",
			pc->data[ret].name, pc->data[ret].age, pc->data[ret].sex, pc->data[ret].tele, pc->data[ret].addr);
}


//修改
void ModifyContact(Contact* pc)
{
	char name[NAME_MAX];
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法修改\n");
		return;
	}
	//查找
	printf("输入要修改的名字:>");
	scanf("%s", name);
	int ret = FindByName(pc, name);
	if (ret == -1)
	{
		printf("要修改的人不存在\n");
		return;
	}
	//修改
	assert(pc);
	printf("请输入名字\n");
	scanf("%s", pc->data[ret].name);//name是数组名,不用&
	printf("请输入年龄\n");
	scanf("%d", &(pc->data[ret].age));//
	printf("请输入性别\n");
	scanf("%s", pc->data[ret].sex);
	printf("请输入电话\n");
	scanf("%s", pc->data[ret].tele);
	printf("请输入地址\n");
	scanf("%s", pc->data[ret].addr);
	printf("修改成功\n");
}

//释放动态空间
void DestroyContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->capacity = 0;
}

//写函数到文件中
void SaveContact(Contact* pc)
{
	//打开文件
	FILE* pf = fopen("contact.txt", "wb");//wb以二进制的方式写数据到文件
	if (pf == NULL)
	{
		perror("SaveContact");
		return;
	}
	//写信息到文件
	int i = 0;//一个数据一个数据写
	for (i = 0; i < pc->sz; i++)
	{
		fwrite(&(pc->data[i]), sizeof(PeoInfo), 1, pf);
		fwrite(pc->data+i, sizeof(PeoInfo), 1, pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
}

✔✔✔✔✔最后,感谢大家的阅读,若有错误和不足,欢迎指正!

接下来的博文会更新一些练习题,到实践中去加深对知识的理解。C语言的基本学习就快结束了,还是要多加练习。🆗

代码----------→【gitee:唐棣棣 (TSQXG) - Gitee.com】

联系----------→ 【邮箱:2784139418@qq.com】

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

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

相关文章

Hudi-源码-索引-bloom 索引

文章目录 前言问题原理TagLocation流程入口LookupIndexfindMatchingFilesForRecordKeysHoodieKeyLookupHandle 如何优化问题一 如何避免大量 IO问题二 如何减少计算 Hash问题三 使用什么结构优化比对结果如何初始化树查询 总结 前言 Hudi 系列文章在这个这里查看 https://gith…

图论与网络优化

2.概念与计算 2.1 图的定义 2.1.1 定义 图(graph) G G G 是一个有序的三元组&#xff0c;记作 G < V ( G ) , E ( G ) , ψ ( G ) > G<V(G),E(G),\psi (G)> G<V(G),E(G),ψ(G)>。 V ( G ) V(G) V(G) 是顶点集。 E ( G ) E(G) E(G) 是边集。 ψ ( G ) \…

【合集】Redis——Redis的入门到进阶 结合实际场景的Redis的应用

前言 Redis是一个开源的内存数据结构存储系统&#xff0c;也被称为键值存储系统。它支持多种数据结构&#xff0c;如字符串、哈希表、列表、集合、有序集合等&#xff0c;并提供了丰富的操作命令&#xff0c;可以对这些数据结构进行快速的读写操作。Redis具有高性能、高可用性…

驱动:驱动相关概念,内核模块编程,内核消息打印printk函数的使用

一、驱动相关概念 1.操作系统的功能 向下管理硬件&#xff0c;向上提供接口 操作系统向上提供的接口类型&#xff1a; 内存管理&#xff1a;内存申请&#xff08;malloc&#xff09; 内存释放&#xff08;free&#xff09;等 文件管理&#xff1a; 通过文件系统格式对文件ext2…

this指向详解

目录 一&#xff1a;严格模式与非严格模式 1.严格模式的开启 2.this指向的一些情况&#xff1a; 二&#xff1a;如何指定this的值&#xff1f; 1.在调用时指定this的值 2.在创建时指定this的值 ​编辑三&#xff1a; 结尾 一&#xff1a;严格模式与非严格模式 在非严格模…

项目管理之分析项目特点的方法

在管理项目时&#xff0c;了解项目的目标和实现方法可以帮助我们更好地规划和执行项目。根据项目的目标和实现方法的不同&#xff0c;可以将项目分为四种类型&#xff1a;地、水、火和气。 对于工程项目&#xff0c;采用基于活动任务的计划管理方法&#xff0c;使用活动网络图…

聊聊分布式架构08——SpringBoot开启微服务时代

目录 微服务架构时代 快速入门 入门详解 SpringBoot的自动配置 石器时代&#xff1a;XML配置bean 青铜时代&#xff1a;SpringConfig 铁器时代&#xff1a;AutoConfigurationImportSelector 手写简单Starter SpringApplication启动原理 微服务架构时代 Spring Boot的…

LabVIEW中将枚举与条件结构一起使用

LabVIEW中将枚举与条件结构一起使用 枚举是一个具有相应数值的字符串标签型列表。在LabVIEW&#xff08;U8 &#xff0c; U16-默认值和U32&#xff09;中以无符号整数形式应用。 例如&#xff0c;可以有一个枚举保存四个季节&#xff0c;在这种情况下&#xff0c;每个字符串都…

2022最新版-李宏毅机器学习深度学习课程-P26RNN-2

一、RNN网络结构 与时间有关的反向传播&#xff08;每次不同&#xff09; 损失函数 实验其实不容易跑&#xff0c;因为他的损失函数曲线幅度很大 画出来差不多是这个样子。突然一下升高是因为从右到左碰到陡峭的地方梯度一下变大了&#xff0c;所以弹回去了。 原作者在训练时…

JAVA反射(原理+使用)

引言 反射是一种机制&#xff0c;能够使java程序在运行过程中&#xff0c;检查&#xff0c;获取类的基本信息&#xff08;包&#xff0c;属性&#xff0c;方法等&#xff09;&#xff0c;并且可以操作对象的属性和方法 反射是框架实现的基础 反射的原理 讲述反射的原理之前&a…

covfefe 靶机/缓冲区溢出

covfefe 信息搜集 存活检测 详细扫描 后台网页扫描 80 端口 31337 端口 网页信息搜集 分别访问扫描出的网页 说有三个不允许看的内容 尝试访问 第一个 flag 访问 .ssh 文件 继续根据提示访问 获取了三个 ssh 文件 ssh 登录 在下载的 id_rsa_pub 公钥文件中发现了…

leetCode 11. 盛最多水的容器 + 双指针

11. 盛最多水的容器 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/container-with-most-water/description/?envTypestudy-plan-v2&envIdtop-interview-150 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是…

【Java基础面试三十三】、接口和抽象类有什么区别?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;接口和抽象类有什么区别…

大同小异!如何在苹果不同类型设备上更改AirDrop的名称

你可以更改你的AirDrop ID&#xff0c;让其他人看到你名字之外的东西。本文介绍了如何在iPhone、iPad和Mac上更改AirDrop名称。 如何在iPhone上更改AirDrop名称 在iPhone上更改AirDrop名称涉及到你可能不想做的更改。幸运的是&#xff0c;这在iPad和Mac上不是真的&#xff0c…

【408数据结构】第一章 绪论

第一章 绪论 1.数据结构基本概念及三要素 一.数据结构基本概念 1.数据 信息的载体&#xff0c;能被客观事物描述的数字&#xff0c;字符以及能被计算机程序识别和处理的符号的集合 2.数据元素 数据的基本单位&#xff0c;一个数据元素可由若干个数据项&#xff08;构成数…

Unity Animation--动画剪辑(创建动画)

创建一个新的动画编辑 创建新的动画剪辑 &#xff0c;在场景中选择一个GameObject&#xff0c;然后打开“ 动画”窗口&#xff08;顶部菜单&#xff1a;&#xff09;“ 窗口” >“ 动画” >“ 动画”。 如果GameObject 中尚未分配任何动画剪辑&#xff0c;“创建”按钮…

pytorch nn.Embedding 读取gensim训练好的词/字向量(有例子)

最近在跑深度学习模型&#xff0c;发现Embedding随机性太强导致模型结果有出入&#xff0c;因此考虑固定初始随机向量&#xff0c;既提前训练好词/字向量&#xff0c;不多说上代码&#xff01;&#xff01; 1、利用gensim训练字向量&#xff08;词向量自行修改&#xff09; #…

YCSB on MySQL(避免重复load)

一、编译安装MySQL 下载mysql5.7.28源码 https://downloads.mysql.com/archives/community/ Select Operating System 选择 Source Code Select OS version 选择 All Operating Systems 选择带有boost的版本 安装系统包 apt -y install make cmake gcc g perl bison libai…

AAOS CarMediaService 服务框架

文章目录 前言MediaSessionCarMediaService作用是什么&#xff1f;提供了哪些接口&#xff1f;如何使用&#xff1f;CarMediaService的实现总结 前言 CarMediaService 是AAOS中统一管理媒体播放控制、信息显示和用户交互等功能的服务。这一服务依赖于android MediaSession框架…

JVM第十五讲:调试排错 - Java 内存分析之堆外内存

调试排错 - Java 内存分析之堆外内存 本文是JVM第十五讲&#xff0c;Java 内存分析之堆外内存调试排错。Java 堆外内存分析相对来说是复杂的&#xff0c;美团技术团队的Spring Boot引起的“堆外内存泄漏”排查及经验总结可以为很多Native Code内存泄漏/占用提供方向性指引。 文…