通讯录项目实现

引言:通过顺序表的逻辑实现通讯录。这里就不讲关于顺序表的函数了。如果有不明白的可以看我写的顺序表的博客。

目录

顺序表与通讯录的比较

各源文件文件大榄

Contact.c中通讯录相关函数的定义

初始化和销毁通讯录

添加联系人:

删除联系人:

打印通讯录中存储的所有的联系人的信息

查找联系人(通过名字)

修改联系人的信息

保存顺序表的内容

将文件的内容读入顺序表

将通讯录中的联系人的信息写入文件

优化后的的通讯录初始化和销毁函数

test.c

SeqList.h

SeqList.c

Contact.h

Contact.c 

结语:


顺序表与通讯录的比较

通讯录的底层逻辑就是顺序表,与存储int数据的顺序表相比,通讯录这个结构体存储的每个元素的类型为结构体,并且这个结构体定义的是每个联系人的基本信息。

图解:


 

各源文件文件大榄

SeqList.h顺序表的结构的声明,顺序表相关函数的声明,#define定义的符号
SeqList.c顺序表函数的定义
Contact.h通讯录中每个联系人的结构的定义,通讯录相关函数的声明
Contact.c通讯录相关函数的定义
test.c可以测试,通讯录的流程实现

Contact.h

#pragma once
#define NAME_MAX 20
#define GENDER_MAX 20
#define TEL_MAX 20
#define ADRR_MAX 20

//联系人的信息的结构
typedef struct personInfo
{
	char name[NAME_MAX];//姓名
	char gender[GENDER_MAX];//性别
	int age;//年龄
	char tel[TEL_MAX];//电话
	char addr[ADRR_MAX];//家庭地址
}peoInfo;


typedef struct SeqList Contact;//前置声明,将顺组表中的struct SeqList 改为 Contact 增加代码的可读性
//初始化和销毁
void ContactInit(Contact* ps);
void ContactDestory(Contact* ps);

//添加和删除
void ContactAdd(Contact* ps);
void ContactDel(Contact* ps);

//打印通讯录中的联系人
void ContactPrint(Contact* ps);

//修改联系人的信息
void ContactModify(Contact* ps);

//查找想要查找的联系人
void ContactFind(Contact* ps);


//将文件的信息加载进通讯录
void ContactLoad(Contact* ps);
//销毁通讯录前将通讯录中的信息写入文件
void ContactSave(Contact* ps);

SeqList.h

#pragma once
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "Contact.h"

//顺序表中存储的元素的类型为定义的联系人的结构体
#define SLDataType peoInfo
typedef struct SeqList
{
	SLDataType* arr;
	int size;
	int capacity;
}SL;

//初始化
void SLInit(SL* ps);
void SLDestory(SL* ps);
//打印
//void SLPrint(SL ps);
//尾插,尾删
void SLPushBack(SL* ps, SLDataType x);
void SLPushFront(SL* ps, SLDataType x);
//尾删,头删
void SLPopFront(SL* ps);
void SLPopBack(SL* ps);
//任意插,任意删
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);

Contact.c中通讯录相关函数的定义

初始化和销毁通讯录

//初始化
void ContactInit(Contact* ps)
{
	SLInit(ps);
}
//销毁
void ContactDestory(Contact* ps)
{
	SLDestory(ps);
}

直接通过顺序表的初始化和销毁实现就可以了。

 

添加联系人:

void ContactAdd(Contact* ps)
{
	peoInfo s;//先定义一个联系人的变量存储要添加的联系人的信息
	printf("请输入要添加的联系人姓名:\n");
	scanf("%s", s.name);
	printf("请输入要添加联系人的性别:\n");
	scanf("%s", s.gender);
	printf("请输入要添加联系人的年龄:\n");
	scanf("%d", &s.age);
	printf("请输入要添加联系人的电话:\n");
	scanf("%s", s.tel);
	printf("请输入要添加联系人的地址:\n");
	scanf("%s", s.addr);
	SLPushFront(ps, s);//顺序表的头插,这里用尾插也可以
}

注意:用顺序表的头插或尾插将联系人的信息插入进通讯录.

删除联系人:

//通过名字在通讯录中找到要删除的人
int FindByName(Contact* ps, char* name)
{
	for (int i = 0; i < ps->size; i++)
	{
		if (strcmp(ps->arr[i].name, name) == 0)
			return i;
	}
	return -1;
}


//删除一个联系人
void ContactDel(Contact* ps)
{
	char name[NAME_MAX];
	printf("请输入你要删除的联系人的姓名:\n");
	scanf("%s",name);
    //如果通过名字找到联系人则返回存储该联系人的下标
	int find = FindByName(ps, name);
	if (find < 0)
	{
		printf("你的通讯录中没有您要删除的人\n");
		return;
	}
    //通过顺序表的任意删除函数删除
	SLErase(ps, find);
}

问题:如何删除一个联系人呢?

首先,你需要给出这个联系人的名字或手机号,或家庭地址,通过这些信息找到这个联系人在顺序表中存储的位置;然后,在通过下标,利用顺序表的任意删除顺序表中的数据,删除该联系人。

这里再讲一下FindByName 函数,如果顺序表中存储的联系人的结构体的名字中有这个名字,则返回在顺序表中存储该联系人的下标;若没找到,则返回一个比0小的数。

打印通讯录中存储的所有的联系人的信息

预期结果:

实现代码:

void ContactPrint(Contact* ps)
{
	printf("%-5s%-5s%-5s%-5s%-5s\n", 
			"姓名", "性别", "年龄", "电话", "家庭地址");
	for (int i = 0; i < ps->size; i++)
	{
		printf("%-5s%-5s%-5d%-5s%-5s\n",
				ps->arr[i].name,
				ps->arr[i].gender,
				ps->arr[i].age,
				ps->arr[i].tel,
				ps->arr[i].addr);
	}
	
}

这里代码比较简单,就不多说了。

查找联系人(通过名字)

//通过名字在顺序表中查询
int FindByName(Contact* ps, char* name)
{
	for (int i = 0; i < ps->size; i++)
	{
		if (strcmp(ps->arr[i].name, name) == 0)
			return i;
	}
	return -1;
}

//查找联系人
void ContactFind(Contact* ps)
{
	char name[NAME_MAX];
	printf("请输入想要查找的联系人的姓名:\n");
	scanf("%s", name);
	int find = FindByName(ps, name);//通过名字查找
	if (find < 0)
	{
		printf("你想要查找的联系人的姓名不在通讯录中\n");
		return;
	}
    //找到了该联系人则打印一下这个联系人的信息
	printf("%-5s%-5s%-5s%-5s%-5s\n",
		"姓名", "性别", "年龄", "电话", "家庭地址");
		printf("%-5s%-5s%-5d%-5s%-5s\n",
			ps->arr[find].name,
			ps->arr[find].gender,
			ps->arr[find].age,
			ps->arr[find].tel,
			ps->arr[find].addr);
}

这里的查找只是通过名字查找,你也可以通过电话,或家庭地址查找。

修改联系人的信息

void ContactModify(Contact* ps)
{
	char name[NAME_MAX];
	printf("请输入想要修改的联系人的姓名:\n");
	scanf("%s", name);
	int find = FindByName(ps, name);
	if (find < 0)
	{
		printf("你想要修改的联系人的姓名不在通讯录中\n");
		return;
	}
	printf("请输入要添加的联系人姓名:\n");
	scanf("%s", ps->arr[find].name);
	printf("请输入要添加联系人的性别:\n");
	scanf("%s", ps->arr[find].gender);
	printf("请输入要添加联系人的年龄:\n");
	scanf("%d", &ps->arr[find].age);
	printf("请输入要添加联系人的电话:\n");
	scanf("%s", ps->arr[find].tel);
	printf("请输入要添加联系人的地址:\n");
	scanf("%s", ps->arr[find].addr);
}

实现思路:通过名字找到你想要修改的联系人在顺序表中存储的下标,有了下标就可以直接对这个位置的数据进行修改。

保存顺序表的内容

每次程序运行完,通讯录中的数据就会丢失,如何在下次运行程序时,继续使用上次的程序呢?

在每次销毁顺序表之前将通讯录中联系人的信息写入一个文件,每次初始化通讯录后将文件的内容读入通讯录就可以了。

将文件的内容读入顺序表

void ContactLoad(Contact* ps)
{
	FILE* pf = fopen("test.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}
	peoInfo s;//定义一个联系人的变量存储每次从文件中读出的联系人的信息
	while (fread(&s, sizeof(peoInfo), 1, pf))//每次读一个联系人的信息直至没有联系人的信息可以读
	{
		SLPushFront(ps, s);//将联系人的信息写入通讯录
	}
	fclose(pf);
	pf = NULL;
}

将通讯录中的联系人的信息写入文件

void ContactSave(Contact* ps)
{
	assert(ps);
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}
	fwrite(ps->arr, sizeof(peoInfo), ps->size, pf);//将通讯录中size个联系人的数据,也就是所有联系人的数据写入文件
	fclose(pf);
	pf = NULL;
}

优化后的的通讯录初始化和销毁函数

void ContactInit(Contact* ps)
{
	SLInit(ps);
	ContactLoad(ps);
}

void ContactDestory(Contact* ps)
{
	ContactSave(ps);
	SLDestory(ps);
}

test.c

void menu()
{
	printf("************************************\n");
	printf("****1.添加联系人****2.删除联系人****\n"); 
	printf("****3.修改联系人****4.查找联系人****\n");
	printf("****5.展示联系人****0. 退出     ****\n");

}
int main()
{
	//ContactTest1();
	Contact s;
	ContactInit(&s);//初始化并载入文件中的联系人数据
	int op;
	do
	{
		menu();
		printf("请输入你的操作:\n");
		scanf("%d", &op);
		switch (op)
		{
			case 1:
				ContactAdd(&s);
				break;
			case 2:
				ContactDel(&s);
				break;
			case 3:
				ContactModify(&s);
				break;
			case 4:
				ContactFind(&s);
				break;
			case 5:
				ContactPrint(&s);
				break;
			case 0:
				printf("退出.....emo\n");
				break;
			default:
				printf("你在干什么?请输入正确的操作数:\n");
				break;
		}

	} while (op);
    //销毁并肩现在通讯录中联系人的信息写入文件
	ContactDestory(&s);
	return 0;
}

SeqList.h

#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "Contact.h"

#define SLDataType peoInfo
typedef struct SeqList
{
	SLDataType* arr;
	int size;
	int capacity;
}SL;

//初始化
void SLInit(SL* ps);
void SLDestory(SL* ps);
//打印
//void SLPrint(SL ps);
//尾插,尾删
void SLPushBack(SL* ps, SLDataType x);
void SLPushFront(SL* ps, SLDataType x);
//尾删,头删
void SLPopFront(SL* ps);
void SLPopBack(SL* ps);
//任意插,任意删
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);

SeqList.c

#include "SeqList.h"

void CheckSLCapacity(SL* ps)
{
	if (ps->capacity == ps->size)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("realloc");
			exit(-1);
		}
		//开辟成功
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
}

void SLInit(SL* ps)
{
	assert(ps);
	ps->arr = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

void SLDestory(SL* ps)
{
	assert(ps);
	free(ps->arr);
	ps->arr = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

//void SLPrint(SL s)
//{
//	for (int i = 0; i < s.size; i++)
//		printf("%d ", s.arr[i]);
//	printf("\n");
//}


void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps != NULL);
	CheckSLCapacity(ps);
	ps->arr[ps->size] = x;
	ps->size++;
}

void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps != NULL);
	CheckSLCapacity(ps);
	for (int i = ps->size; i>0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	ps->size++;
}


void SLPopBack(SL* ps)
{
	assert(ps != NULL);
	assert(ps->size > 0);
	ps->size--;
}

void SLPopFront(SL* ps)
{
	assert(ps != NULL);
	assert(ps->size > 0);
	for (int i = 0; i <ps->size-1 ; i++)
		ps->arr[i] = ps->arr[i + 1];
	ps->size--;
}

void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	CheckSLCapacity(ps);
	for (int i = ps->size; i>pos ; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;
	ps->size++;
}

void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	for (int i = pos; i < ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;

}

Contact.h

#pragma once
#define NAME_MAX 20
#define GENDER_MAX 20
#define TEL_MAX 20
#define ADRR_MAX 20

typedef struct personInfo
{
	char name[NAME_MAX];
	char gender[GENDER_MAX];
	int age;
	char tel[TEL_MAX];
	char addr[ADRR_MAX];
}peoInfo;


typedef struct SeqList Contact;
//初始化和销毁
void ContactInit(Contact* ps);
void ContactDestory(Contact* ps);

//添加和删除
void ContactAdd(Contact* ps);
void ContactDel(Contact* ps);

//打印通讯录中的联系人
void ContactPrint(Contact* ps);

//修改联系人的信息
void ContactModify(Contact* ps);

//查找想要查找的联系人
void ContactFind(Contact* ps);


//将文件的信息加载进通讯录
void ContactLoad(Contact* ps);
//销毁通讯录前将通讯录中的信息写入文件
void ContactSave(Contact* ps);

Contact.c 

#include "SeqList.h"//这个文件中有Contact的定义

void ContactInit(Contact* ps)
{
	SLInit(ps);
	ContactLoad(ps);
}

void ContactDestory(Contact* ps)
{
	ContactSave(ps);
	SLDestory(ps);
}

void ContactAdd(Contact* ps)
{
	peoInfo s;
	printf("请输入要添加的联系人姓名:\n");
	scanf("%s", s.name);
	printf("请输入要添加联系人的性别:\n");
	scanf("%s", s.gender);
	printf("请输入要添加联系人的年龄:\n");
	scanf("%d", &s.age);
	printf("请输入要添加联系人的电话:\n");
	scanf("%s", s.tel);
	printf("请输入要添加联系人的地址:\n");
	scanf("%s", s.addr);
	SLPushFront(ps, s);
}

int FindByName(Contact* ps, char* name)
{
	for (int i = 0; i < ps->size; i++)
	{
		if (strcmp(ps->arr[i].name, name) == 0)
			return i;
	}
	return -1;
}

void ContactDel(Contact* ps)
{
	char name[NAME_MAX];
	printf("请输入你要删除的联系人的姓名:\n");
	scanf("%s",name);
	int find = FindByName(ps, name);
	if (find < 0)
	{
		printf("你的通讯录中没有您要删除的人\n");
		return;
	}
	SLErase(ps, find);
}


void ContactPrint(Contact* ps)
{
	printf("%-5s%-5s%-5s%-5s%-5s\n", 
			"姓名", "性别", "年龄", "电话", "家庭地址");
	for (int i = 0; i < ps->size; i++)
	{
		printf("%-5s%-5s%-5d%-5s%-5s\n",
				ps->arr[i].name,
				ps->arr[i].gender,
				ps->arr[i].age,
				ps->arr[i].tel,
				ps->arr[i].addr);
	}
	
}

void ContactModify(Contact* ps)
{
	char name[NAME_MAX];
	printf("请输入想要修改的联系人的姓名:\n");
	scanf("%s", name);
	int find = FindByName(ps, name);
	if (find < 0)
	{
		printf("你想要修改的联系人的姓名不在通讯录中\n");
		return;
	}
	printf("请输入要添加的联系人姓名:\n");
	scanf("%s", ps->arr[find].name);
	printf("请输入要添加联系人的性别:\n");
	scanf("%s", ps->arr[find].gender);
	printf("请输入要添加联系人的年龄:\n");
	scanf("%d", &ps->arr[find].age);
	printf("请输入要添加联系人的电话:\n");
	scanf("%s", ps->arr[find].tel);
	printf("请输入要添加联系人的地址:\n");
	scanf("%s", ps->arr[find].addr);
}


void ContactFind(Contact* ps)
{
	char name[NAME_MAX];
	printf("请输入想要查找的联系人的姓名:\n");
	scanf("%s", name);
	int find = FindByName(ps, name);
	if (find < 0)
	{
		printf("你想要查找的联系人的姓名不在通讯录中\n");
		return;
	}
	printf("%-5s%-5s%-5s%-5s%-5s\n",
		"姓名", "性别", "年龄", "电话", "家庭地址");
		printf("%-5s%-5s%-5d%-5s%-5s\n",
			ps->arr[find].name,
			ps->arr[find].gender,
			ps->arr[find].age,
			ps->arr[find].tel,
			ps->arr[find].addr);
}


void ContactLoad(Contact* ps)
{
	FILE* pf = fopen("test.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}
	peoInfo s;
	while (fread(&s, sizeof(peoInfo), 1, pf))
	{
		SLPushFront(ps, s);
	}
	fclose(pf);
	pf = NULL;
}

void ContactSave(Contact* ps)
{
	assert(ps);
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}
	fwrite(ps->arr, sizeof(peoInfo), ps->size, pf);
	fclose(pf);
	pf = NULL;
}

最终结果展示:

第一次写:

写完之后文件中有一个联系人: 22  22  22  22   22   22 

文件的内容:

第二次使用程序:

 

结语:

总算写完了,现在脑袋还是昏昏的,哈哈哈哈.

下次的项目就是贪吃蛇了。

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

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

相关文章

欧拉角及其旋转矩阵,旋转顺序与内旋/外旋及其代码

目录 欧拉角介绍 旋转矩阵公式推导 旋转顺序 内旋/外旋 欧拉角介绍 欧拉角&#xff1a; 横滚&#xff1a;roll&#xff08;绕X轴旋转&#xff09;&#xff1b; 俯仰&#xff1a;pitch&#xff08;绕Y轴旋转&#xff09;&#xff1b; 偏航&#xff08;也称航向角&#x…

腾讯云服务器4核8g配置好不好?用它干啥使?

腾讯云4核8G服务器多少钱&#xff1f;腾讯云4核8G轻量应用服务器12M带宽租用价格646元15个月&#xff0c;活动页面 txybk.com/go/txy 活动链接打开如下图所示&#xff1a; 腾讯云4核8G服务器优惠价格 这台4核8G服务器是轻量应用服务器&#xff0c;详细配置为&#xff1a;轻量4核…

CSS简介

1. CSS简介 CSS(Cascading Style Sheets)层叠样式表&#xff0c;又叫级联样式表&#xff0c;简称样式表&#xff0c;文件后缀名为.css&#xff0c;用于HTML文档中元素样式的定义。CSS语法&#xff1a; <!DOCTYPE html> <html lang"en"> <head><…

C语言—用EasyX实现反弹球消砖块游戏

代码效果如下 #undef UNICODE #undef _UNICODE #include<graphics.h> #include<conio.h> #include<time.h> #include<stdio.h>#define width 640 #define high 480 #define brick_num 10int ball_x, ball_y; int ball_vx, ball_vy; int radius; int ba…

删除中间节点(狸猫换太子法)

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 每一个裂缝都是为透出光而努力&#…

香橙派OPI Airpro上的智能交通监管系统(保姆级代码)

首先&#xff0c;你需要安装必要的软件包和库&#xff0c;例如Python3和TensorFlow。然后&#xff0c;你可以编写脚本来处理数据采集、分析和报告生成等任务。以下是一个简单的示例&#xff1a; # 安装必要的软件包 sudo apt-get update sudo apt-get install -y python3 pyth…

腾讯云4核8G服务器性能怎么样?大明白来说说

腾讯云4核8G服务器价格&#xff1a;轻量4核8G12M优惠价格646元15个月、CVM S5服务器4核8G配置1437元买1年送3个月。腾讯云4核8G服务器支持多少人同时在线&#xff1f;支持30个并发数&#xff0c;可容纳日均1万IP人数访问。腾讯云百科txybk.com整理4核8G服务器支持多少人同时在线…

4月4号总结

java学习 一.接口 1.介绍 定义接口需要使用到关键字interface去定义接口。 格式如下&#xff1a; 类与接口的关系不是继承&#xff0c;而是实现&#xff0c;用关键字 implements &#xff0c;格式如下&#xff1a; 这个类去实现接口&#xff0c;其中的关系就相当于&#xf…

DFS(基础,回溯,剪枝,记忆化)搜索

DFS基础 DFS(深度优先搜索) 基于递归求解问题&#xff0c;而针对搜索的过程 对于问题的介入状态叫初始状态&#xff0c;要求的状态叫目标状态 这里的搜索就是对实时产生的状态进行分析检测&#xff0c;直到得到一个目标状态或符合要求的最佳状态为止。对于实时产生新的状态…

不到2000字,轻松带你搞懂STM32中GPIO的8种工作模式

大家好&#xff0c;我是知微&#xff01; 学习过单片机的小伙伴对GPIO肯定不陌生&#xff0c;GPIO &#xff08;general purpose input output&#xff09;是通用输入输出端口的简称&#xff0c;通俗来讲就是单片机上的引脚。 在STM32中&#xff0c;GPIO的工作模式被细分为8种…

gitcode 配置 SSH 公钥

在 gitcode 上配置SSH公钥后&#xff0c;可以通过SSH协议安全地访问远程仓库&#xff0c;无需每次都输入用户名和密码。以下是配置SSH公钥的步骤&#xff1a; 5分钟解决方案 用 OpenSSH公钥生成器 生成 公钥和私钥&#xff0c;私钥文件&#xff08;id_rsa&#xff09;下载&am…

算法设计与分析实验报告python实现(排序算法、三壶谜题、交替放置的碟子、带锁的门)

一、 实验目的 1&#xff0e;加深学生对算法设计方法的基本思想、基本步骤、基本方法的理解与掌握&#xff1b; 2&#xff0e;提高学生利用课堂所学知识解决实际问题的能力&#xff1b; 3&#xff0e;提高学生综合应用所学知识解决实际问题的能力。 二、实验任务 1、排序算法…

python中如何使用help()

help()函数帮助我们了解模块、类型、对象、方法、属性的详细信息。 1、帮助查看类型详细信息&#xff0c;包含类的创建方式、属性、方法 >>> help(list) Help on class list in module builtins: class list(object)| list() -> new empty list| list(iterable)…

EmpireCMS:帝国源码cms网站搬家/数据迁移方法教程

帝国cms迁移数据&#xff0c;从一台旧的服务器把网站文件都搬迁到新的服务器&#xff0c;会涉及到附件&#xff0c;数据库信息等&#xff0c;很多人在搬迁的时候也会遇到各种问题&#xff0c;下面是小编整理的关于如何搬迁帝国cms数据的解决方案和思路&#xff0c;方便新手站长…

957: 逆置单链表

学习版 【C语言】 #include<iostream> using namespace std; typedef struct LNode {char data;struct LNode* next;LNode(char x) :data(x), next(nullptr) {} }LNode; void creatlist(LNode *&L) {int n;char e;cin >> n;LNode* p1, * p2;p1 L;for (int i…

Kubernetes的基础概念

目录 一、概述 二、为什么要用Kubernetes 2.1 从技术层面分析 2.1.1 问题解答 2.1.2 Docker等“裸容器”的不足 2.1.2.1 宕机无法自动恢复 2.1.2.2 健康检查不到位 2.1.2.3 部署、回滚、扩容问题 2.1.2.4 运维难 2.1.3 总结 2.2 从开发人员层面分析 2.2.1 分析日志 …

关于首助编辑高手

首助编辑高手是一款专为现代办公场景设计的集合软件&#xff0c;致力于提升用户的办公效率和便利性。它集成了多种实用的办公辅助工具&#xff0c;包括但不限于文档编辑、图片处理、PDF编辑、文本批量操作等功能&#xff0c;帮助用户轻松应对各种办公挑战。 首助编辑高手主要功…

ChatGPT 在做什么,为什么有效?

原文&#xff1a;What Is ChatGPT Doing … and Why Does It Work? 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 序言 这本简短的书试图从第一原理解释 ChatGPT 是如何工作的。在某种程度上&#xff0c;这是关于技术的故事。但它也是关于科学的故事。以及关于哲学…

【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(五)- 向量加载和存储

1. 引言 以下是《riscv-v-spec-1.0.pdf》文档的关键内容&#xff1a; 这是一份关于向量扩展的详细技术文档&#xff0c;内容覆盖了向量指令集的多个关键方面&#xff0c;如向量寄存器状态映射、向量指令格式、向量加载和存储操作、向量内存对齐约束、向量内存一致性模型、向量…

七大开源基金会联合制定符合 CRA 法案的共同标准

欧洲议会上个月通过的《欧洲网络弹性法案》(CRA) 制定通用规范和标准 Apache 软件基金会、Blender 基金会、Eclipse 基金会、OpenSSL 软件基金会、PHP 基金会、Python 软件基金会 和 Rust 基金会 这项工作由 Eclipse 基金会牵头&#xff0c;旨在建立基于现有开源最佳实践的安全…