C语言实现通讯录静态版本

news2024/11/18 18:37:21

通讯录中首先要有人的信息,然后是存放多少个人的信息

再丰富一下通讯录的功能,例如增删查改、显示、排序。

我们分三个文件来实现。

1、实现简易的菜单,通讯录的整体逻辑 

#include"contact.h"

void menu()
{
	printf("***********通讯录contact**************\n");
	printf("*****1、add      2、del   3、search***\n");
	printf("*****4、update   5、show  6、sort1 ** \n");
	printf("*****7、sort2    0、exit**************\n");
	printf("**************************************\n");
}
int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择要使用的功能\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			break;
		case 2:
			break;
		case 3:
			break;
		case 4:
			break;
		case 5:
			break;
		case 6:
			break;
		case 7:
			break;
		case 0:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
}

case的不同情况对应菜单中的不同功能。考虑到枚举常量的知识点,可以将上面的功能对应枚举常量的数字,用来代替单一的case+数字,从而更加直观。

enum
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	UPDATE,
	SHOW,
	SORT1,
	SORT2,
};

优化后的菜单代码

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择要使用的功能\n");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			break;
		case DEL:
			break;
		case SEARCH:
			break;
		case UPDATE:
			break;
		case SHOW:
			break;
		case SORT1:
			break;
		case SORT2:
			break;
		case EXIT:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
}

2、实现每个人信息包含的内容

一个人的信息包含姓名、年龄、电话等不同类型的数据,因此对于每个人的信息,我们可以选择使用结构体类型的数据。

struct peopleinfo
{
	char name[20];
	int age;
	char sex[5];
	char tel[12];
	char dres[10];
};

这里我们暂时规定  姓名  年龄   性别   电话   地址  五个元素。除年龄外,均为字符数组。

为了我们代码灵活性的考虑,我们在实现某个功能时尽量不要把数字写死(逻辑功能除外),相反,我们可以采用#define定义的标识符常量来替换它。

#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TEL 12
#define MAX_DRES 10

替换后的人员信息

struct peopleinfo
{
	char name[MAX_NAME];
	int age;
	char sex[MAX_SEX];
	char tel[MAX_TEL];
	char dres[MAX_DRES];
};

3、通讯录N个人的包含

定义完每个人的个人信息,我们就需要将N个人的信息统一起来。

这里我们可以用创建一个结构体数组,其中包含N个元素。

在这之前,我们可以用typedef使结构体的名字简化一些。

typedef struct peopleinfo
{
	char name[MAX_NAME];
	int age;
	char sex[MAX_SEX];
	char tel[MAX_TEL];
	char dres[MAX_DRES];
}peopleinfo;
#define N 1000


peopleinfo date[N];

这里我们定义数组有1000个元素,即可以存储1000个人的信息。

为了方便实现后续增删查改时确定我们操作数组的范围,这里我们可以定义一个变量sz,用来标记接下来要操作的元素的下标。

然后我们可以将date数组和sz再封装为一个结构体类型contact。(并用typedef简化) 

typedef struct contact
{
	peopleinfo date[1000];
	int sz;
}contact;

4、通讯录的初始化

得到contact这个结构体后,我们可以对它进行初始化。

sz可初始化为0,date数组可按需初始化,这里我们统一初始化为0,但为了代码灵活性考虑,我们将其封装为一个函数。

contact con;
contact_init(&con);
void contact_init(contact* pc)
{
	pc->sz = 0;
	//初始化可以才用循环遍历,这里我使用memset直接设置
	//   设置的起始地址  要设置成的内容   设置的字节数
	memset(pc->date, 0, sizeof(pc->date));
	//这里用结构体指针直接指向其中的数组,即数组名表示找到这个数组
	//  sizeof内部单独放数组名,求的是整个数组的大小
}

这里因为是结构体传参,为了保证性能,我们才用传址调用,用一个结构体指针pc接收,然后再函数内部用pc操作结构体。

5、增加人员信息功能

//增加人员信息
void contact_add(contact* pc)
{
	//增加前确保通讯没满
	if (pc->sz == N)
	{
		printf("通讯录已满,无法添加\n");
		return;  //直接返回,不进行后续功能
	}
	//通讯录没满,添加信息
	printf("请输入姓名\n");
	scanf("%s", pc->date[pc->sz].name);
	printf("请输入年龄\n");
	scanf("%d", &pc->date[pc->sz].age);
	//由于其它的都是字符数组,数组名就是地址,不用再加&,int的年龄需要&
	printf("请输入性别\n");
	scanf("%s", pc->date[pc->sz].sex);
	printf("请输入电话\n");
	scanf("%s", pc->date[pc->sz].tel);
	printf("请输入地址\n");
	scanf("%s", pc->date[pc->sz].dres);
	//输入后再到下一个元素
	pc->sz++;
}

 6、显示通讯录

//显示通讯录已有信息
void contact_show(const contact* pc)
{
	//先打印一个目录
	printf("%-20s\t%-10s\t%-10s\t%-12s\t%-10s\n", "姓名", "年龄", "性别", "电话", "地址");
	//各个信息分别打印
	int i = 0;
	for (i=0;i<pc->sz;i++)
	{
		printf("%-20s\t%-10d\t%-10s\t%-12s\t%-10s\n",   pc->date[i].name,
														pc->date[i].age,
														pc->date[i].sex,
														pc->date[i].tel,
														pc->date[i].dres);
	}
}

用i遍历数组,挨个结构体,挨个成员打印。 

输入两个人的信息后显示。

 7、查找某个人的信息是否存在

在删除,查找,更新,等功能中,都需要先找到某个人的信息是否存在,因此我们封装一个查找函数,用来反复使用。

//按名字查找某个人是否存在
int seek_by_name(contact* pc,char name[])
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->date[i].name, name) == 0)
		{
			int pos = i;
			return i;//找到后返回数组下标
		}
	}
	//遍历完扔没有返回,即没有找到
	return -1;
}

8、删除指定人的信息

删除时有多种方式

1、找到后直接从后往前覆盖。然后sz--,使访问权限-1,完成删除。

2、将最后一个元素直接覆盖到要删除的位置,但是会改变元素的顺序。

这里我们选择往前覆盖的方法。

//删除指定人员信息
void contact_del(contact* pc)
{
	assert(pc);
	//先判断通讯录内是否还有人员信息
	if (pc->sz == 0)
	{
		printf("通讯录内已无信息,无法删除\n");
		return;  //直接返回,不进行后续
	}
	//可以删除时
	//先查找要删除的人(例如按照名字)
	char name[20];
	printf("请输入要删除的人的名字\n");
	scanf("%s", name);
	//查找要删除的人的名字
	int del=seek_by_name(pc,name);
	if (del == -1)
	{
		printf("没有找到要删除人的信息\n");
		return;//没找到直接返回,不进行后续操作
	}
	//找到要删除的元素,进行删除操作
	int i = 0;
	for (i = del; i < pc->sz - 1; i++)
	{
		pc->date[i] = pc->date[i + 1];//结构体的两个元素直接覆盖即可
	}
	//完成删除后sz--,缩小访问权限
	pc->sz--;
}

 9、查找指定人的信息

//查找指定人员的信息
void contact_search(const contact* pc)
{
	printf("请输入要查找的人的名字\n");
	char name[20];
	scanf("%s", name);
	int pos=seek_by_name(pc, name);
	if (pos == -1)
	{
		printf("查无此人\n");
		return;//找不到直接返回
	}
	//找到后打印出来
	printf("查找成功,信息为\n");
	int i = 0;
	printf("%-20s\t%-10s\t%-10s\t%-12s\t%-10s\n", "姓名", "年龄", "性别", "电话", "地址");
	for (i = pos; i < pc->sz; i++)
	{
		printf("%-20s\t%-10d\t%-10s\t%-12s\t%-10s\n", 
			pc->date[pos].name,
			pc->date[pos].age,
			pc->date[pos].sex,
			pc->date[pos].tel,
			pc->date[pos].dres);
	}
	
}

 10、更改/更新指定人的信息

//更改指定人员信息
void contact_update(contact* pc)
{
	printf("请输入要更改的人的姓名\n");
	char name[20];
	scanf("%s", name);
	int pos=seek_by_name(pc, name);
	if (pos == -1)
	{
		printf("查无此人,无法更改\n");
		return;
	}
	printf("开始更改\n");
	printf("请输入姓名\n");
	scanf("%s", pc->date[pos].name);
	printf("请输入年龄\n");
	scanf("%d", &pc->date[pos].age);
	printf("请输入性别\n");
	scanf("%s", pc->date[pos].sex);
	printf("请输入电话\n");
	scanf("%s", pc->date[pos].tel);
	printf("请输入地址\n");
	scanf("%s", pc->date[pos].dres);
	printf("信息更新成功\n");
}

 11、按照年龄排序(升序)

12、按照名字排序

排序函数可以使用我们之前讲解的bubble_qsort函数来实现

下面附上源码

头文件contact.c

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TEL 12
#define MAX_DRES 10
#define N 1000
enum
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	UPDATE,
	SHOW,
	SORT1,
	SORT2,
};
typedef struct peopleinfo
{
	char name[MAX_NAME];
	int age;
	char sex[MAX_SEX];
	char tel[MAX_TEL];
	char dres[MAX_DRES];
}peopleinfo;

typedef struct contact
{
	peopleinfo date[1000];
	int sz;
}contact;

//初始化通讯录
void contact_init(contact* pc);
//增加人员信息
void contact_add(contact* pc);
//显示通讯录已有信息
void contact_show(const contact* pc);
//删除指定人员信息
void contact_del(contact* pc);
//查找指定人员信息
void contact_search(const contact* pc);
//更改指定人员信息
void contact_update(contact* pc);
//按年龄升序
void contact_sort_byage(contact* pc);
//按名字升序
void contact_sort_byname(contact* pc);

test.c

#include"contact.h"

void menu()
{
	printf("***********通讯录contact**************\n");
	printf("*****1、add      2、del   3、search***\n");
	printf("*****4、update   5、show  6、sort1 ** \n");
	printf("*****7、sort2    0、exit**************\n");
	printf("**************************************\n");
}
int main()
{
	contact con;
	contact_init(&con);
	int input = 0;
	do
	{
		menu();
		printf("请选择要使用的功能\n");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			contact_add(&con);
			break;
		case DEL:
			contact_del(&con);
			break;
		case SEARCH:
			contact_search(&con);
			break;
		case UPDATE:
			contact_update(&con);
			break;
		case SHOW:
			contact_show(&con);
			break;
		case SORT1:
			contact_sort_byage(&con);
			break;
		case SORT2:
			contact_sort_byname(&con);
			break;
		case EXIT:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
}

contact.c

#include"contact.h"
//通讯录初始化
void contact_init(contact* pc)
{
	assert(pc);
	pc->sz = 0;
	//初始化可以才用循环便利,这里我使用memset直接设置
	//   设置的起始地址  要设置成的内容   设置的字节数
	memset(pc->date, 0, sizeof(pc->date));
	//这里用结构体指针直接指向其中的数组,即数组名表示找到这个数组
	//  sizeof内部单独放数组名,求的是整个数组的大小
}

//增加人员信息
void contact_add(contact* pc)
{
	assert(pc);
	//增加前确保通讯没满
	if (pc->sz == N)
	{
		printf("通讯录已满,无法添加\n");
		return;  //直接返回,不进行后续功能
	}
	//通讯录没满,添加信息
	printf("请输入姓名\n");
	scanf("%s", pc->date[pc->sz].name);
	printf("请输入年龄\n");
	scanf("%d", &pc->date[pc->sz].age);
	//由于其它的都是字符数组,数组名就是地址,不用再加&,int的年龄需要&
	printf("请输入性别\n");
	scanf("%s", pc->date[pc->sz].sex);
	printf("请输入电话\n");
	scanf("%s", pc->date[pc->sz].tel);
	printf("请输入地址\n");
	scanf("%s", pc->date[pc->sz].dres);
	//输入后再到下一个元素
	pc->sz++;
}


//显示通讯录已有信息
void contact_show(const contact* pc)
{
	assert(pc);
	//先打印一个目录
	printf("%-20s\t%-10s\t%-10s\t%-12s\t%-10s\n", "姓名", "年龄", "性别", "电话", "地址");
	//各个信息分别打印
	int i = 0;
	for (i=0;i<pc->sz;i++)
	{
		printf("%-20s\t%-10d\t%-10s\t%-12s\t%-10s\n",   pc->date[i].name,
														pc->date[i].age,
														pc->date[i].sex,
														pc->date[i].tel,
														pc->date[i].dres);
	}
}

//按名字查找某个人是否存在
int seek_by_name(const contact* pc,char name[])
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->date[i].name, name) == 0)
		{
			int pos = i;
			return i;//找到后返回数组下标
		}
	}
	//遍历完扔没有返回,即没有找到
	return -1;
}


//删除指定人员信息
void contact_del(contact* pc)
{
	assert(pc);
	//先判断通讯录内是否还有人员信息
	if (pc->sz == 0)
	{
		printf("通讯录内已无信息,无法删除\n");
		return;  //直接返回,不进行后续
	}
	//可以删除时
	//先查找要删除的人(例如按照名字)
	char name[20];
	printf("请输入要删除的人的名字\n");
	scanf("%s", name);
	//查找要删除的人的名字
	int del=seek_by_name(pc,name);
	if (del == -1)
	{
		printf("没有找到要删除人的信息\n");
		return;//没找到直接返回,不进行后续操作
	}
	//找到要删除的元素,进行删除操作
	int i = 0;
	for (i = del; i < pc->sz - 1; i++)
	{
		pc->date[i] = pc->date[i + 1];//结构体的两个元素直接覆盖即可
	}
	//完成删除后sz--,缩小访问权限
	pc->sz--;
}

//查找指定人员的信息
void contact_search(const contact* pc)
{
	printf("请输入要查找的人的名字\n");
	char name[20];
	scanf("%s", name);
	int pos=seek_by_name(pc, name);
	if (pos == -1)
	{
		printf("查无此人\n");
		return;//找不到直接返回
	}
	//找到后打印出来
	printf("查找成功,信息为\n");
	int i = 0;
	printf("%-20s\t%-10s\t%-10s\t%-12s\t%-10s\n", "姓名", "年龄", "性别", "电话", "地址");
	for (i = pos; i < pc->sz; i++)
	{
		printf("%-20s\t%-10d\t%-10s\t%-12s\t%-10s\n", 
			pc->date[pos].name,
			pc->date[pos].age,
			pc->date[pos].sex,
			pc->date[pos].tel,
			pc->date[pos].dres);
	}
	
}

//更改指定人员信息
void contact_update(contact* pc)
{
	printf("请输入要更改的人的姓名\n");
	char name[20];
	scanf("%s", name);
	int pos=seek_by_name(pc, name);
	if (pos == -1)
	{
		printf("查无此人,无法更改\n");
		return;
	}
	printf("开始更改\n");
	printf("请输入姓名\n");
	scanf("%s", pc->date[pos].name);
	printf("请输入年龄\n");
	scanf("%d", &pc->date[pos].age);
	printf("请输入性别\n");
	scanf("%s", pc->date[pos].sex);
	printf("请输入电话\n");
	scanf("%s", pc->date[pos].tel);
	printf("请输入地址\n");
	scanf("%s", pc->date[pos].dres);
	printf("信息更新成功\n");
}
//按照   结构体   年龄大小判断是否交换的函数
int exchange_by_age(const void* e1, const void* e2)
{
	return ((peopleinfo*)e1)->age - ((peopleinfo*)e2)->age;
}
//按照  结构体    字符串大小比较判断是否交换的函数
int exchange_by_name(const void* e1, const void* e2)
{
	return strcmp(((peopleinfo*)e1)->name, ((peopleinfo*)e2)->name);
}


//逐字节交换函数
void swap_by_byte(char* low, char* high, size_t width)
{
	int i = 0;
	for (i = 0; i < width; i++)
	{
		char tmp = *low;
		*low = *high;
		*high = tmp;
		low++;
		high++;
	}
}
//排序函数
void bubble_sort(void* base, size_t num, size_t width, int (*pf)(const void*, const void*))
{
	int i = 0;
	//冒泡排序的躺数
	for (i = 0; i < num - 1; i++)
	{
		//每一趟冒泡排序
		int j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
			//判断是否需要交换
			int ret = pf((char*)base + j * width, (char*)base + (j + 1) * width);
			if (ret > 0)
			{
				//交换相邻的两个元素
				swap_by_byte((char*)base + j * width, (char*)base + (j + 1) * width, width);
			}
		}
	}


}

//按年龄升序排列
void contact_sort_byage(contact* pc)
{
	bubble_sort(pc->date, pc->sz, sizeof(peopleinfo), exchange_by_age);
	printf("按照年龄排序成功\n");
}
//按名字升序排列
void contact_sort_byname(contact* pc)
{
	bubble_sort(pc->date, pc->sz, sizeof(peopleinfo), exchange_by_name);
	printf("按名字排序成功\n");
}

大家可以动手敲一敲,遇到困难就去解决一下。

目录

1、实现简易的菜单,通讯录的整体逻辑 

2、实现每个人信息包含的内容

3、通讯录N个人的包含

4、通讯录的初始化

5、增加人员信息功能

​编辑

 6、显示通讯录

 7、查找某个人的信息是否存在

8、删除指定人的信息

 9、查找指定人的信息

 10、更改/更新指定人的信息

 11、按照年龄排序(升序)

12、按照名字排序


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

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

相关文章

900页文档比对只需5分钟?鸿翼InWise文档比对,以人工智能撬动办公效率杠杆

在日常办公中&#xff0c;多份文件间的检查、纠错、复核工作不可避免&#xff0c;这类工作往往具有很强的重复性&#xff0c;占用了大量的工作时间。鸿翼InWise平台文档比对能够赋能企业极速完成海量文档、图片的高精度比对&#xff0c;以人工智能撬动企业生产力提升。 随着数字…

MySQL调优-MySQL索引深入总结

目录 MySQL索引深入总结 InnoDB中的索引复习 聚集索引/聚簇索引 问题&#xff1a;如果我们没有定义主键呢&#xff1f; 问题&#xff1a;分析一下B树三层和四层的性能差异&#xff1f; 辅助索引/二级索引 回表 问题&#xff1a;为什么我们还需要一次回表操作呢?直接把完…

亚马逊云科技:小鹏汽车拓展全球市场,跑出“加速度”

汽车产业变革走向下半场&#xff0c;智能汽车的市场份额之争也从国内走向国际&#xff0c;出海之战讲求速战速决&#xff0c;小鹏汽车携手亚马逊云科技拓展海外市场&#xff0c;完成海外布局。 扩大“鹏”友圈&#xff0c;迈进欧洲市场 近年来&#xff0c;小鹏汽车不断推进全…

数字人民币年度总结:支付变革未停、试点之风再起

文/尹宁出品/陀螺研究院数字人民币&#xff0c;无疑是近年来热度最高的词汇之一&#xff0c;作为我国法币的数字形式&#xff0c;至其出世伊始&#xff0c;不论是资金溯源的透明追踪、零售更新的消费用途&#xff0c;还是跨境结算的雄图大略&#xff0c;围绕其推广与意义的讨论…

关于 国产麒麟系统上长时间运行Qt程序根目录/下磁盘空间占用100%导致无法写入 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/128671382 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软…

LeetCode 129. 求根节点到叶节点数字之和

&#x1f308;&#x1f308;&#x1f604;&#x1f604; 欢迎来到茶色岛独家岛屿&#xff0c;本期将为大家揭晓LeetCode 129. 求根节点到叶节点数字之和&#xff0c;做好准备了么&#xff0c;那么开始吧。 &#x1f332;&#x1f332;&#x1f434;&#x1f434; 一、题目名…

4.6 集成运放的使用

一、使用时必做的工作 1、集成运放的外引线&#xff08;管脚&#xff09; 目前集成运放的常见封装方式有金属壳封装和双列直插式封装&#xff0c;外形如图4.6.1所示&#xff0c;以后者居多。双列直插式有 8、10、12、14、16 管脚等种类&#xff0c;虽然它们的外引线排列日趋标…

laravel JWT 用户认证 实现API认证

JWT 是 JSON Web Token 的缩写&#xff0c;它是一个规范&#xff0c;让用户和服务器之间传递安全可靠的信息。 JWT介绍 JWT 由头部&#xff08;header&#xff09;、载荷&#xff08;payload&#xff09;与签名&#xff08;signature&#xff09;组成 { “typ”:“JWT”, “a…

python的8大核心语句,你确定不来看看嘛,那格局就小啦

Python 是一种代表简单思想的语言&#xff0c;其语法相对简单&#xff0c;很容易上手。不过&#xff0c;如果就此小视 Python 语法的精妙和深邃&#xff0c;那就大错特错了。本文精心筛选了最能展现 Python 语法之精妙的十个知识点&#xff0c;并附上详细的实例代码。如能在实战…

学习使用 Clion 第一次使用Clion开发Qt的hello world

为什么使用Clion之前在window上开发软件基本上是使用VS2022,使用Clion在windows上开发并不是嫌弃VS2022不好用,相反我依然觉得VS是世界上最好用的IDE没有之一.没有其他的理由,这是我第一款使用的IDE,而且已经很使用的熟练.那为什么还要学习使用Clion了,其实是考虑到跨平台.VS有…

【C进阶】 字符串函数和字符分类函数

家人们欢迎来到小姜的世界&#xff0c;<<点此>>传送门 这里有详细的关于C/C/Linux等的解析课程&#xff0c;家人们赶紧冲鸭&#xff01;&#xff01;&#xff01; 客官&#xff0c;码字不易&#xff0c;来个三连支持一下吧&#xff01;&#xff01;&#xff01;关注…

Linux操作系统-信号

信号的基本认识&#xff1a;Linux信号机制&#xff1a;它是一种异步的通知机制&#xff0c;用来提醒进程一个事件已经发生。如上图&#xff0c;Linux操作系统中&#xff0c;共有编号为1~31的31个普通信号&#xff0c;编号为34~64的31个实时信号。日常中只会涉及和使用到普通信号…

说说你对Spring三级缓存的理解

这个问题或者换个问法&#xff1a;Spring是如何解决循环依赖的&#xff1f;答案即是Spring的三级缓存 什么是循环依赖&#xff1f; 简单说&#xff0c;就是A对象依赖B对象&#xff0c;B对象⼜依赖A对象&#xff0c;类似的代码如下&#xff1a; 其他还有很多种⽅式&#xff0…

内核解读之内存管理(12)进程虚拟内存管理 vm_area_struct 与反向映射

在32位的系统上&#xff0c;线性地址空间可达到4GB&#xff0c;这4GB一般按照3:1的比例进行分配&#xff0c;也就是说用户进程享有前3GB线性地址空间&#xff0c;而内核独享最后1GB线性地址空间。由于虚拟内存的引入&#xff0c;每个进程都可拥有3GB的虚拟内存&#xff0c;并且…

靶机测试ReconForce笔记

靶机地址https://www.vulnhub.com/entry/hacknos-reconforce,416/靶机测试信息收集nmap扫描端口nmap扫描结果└─$ nmap -sC -sV 192.168.1.100 -oA hack …

结合NWR,让Paxos拥有的动态的Quorum,以及在Klein中的实践

Paxos Quorum面临的困境在原生的Basic-Paxos或者Multi-Paxos中&#xff0c;Quorum的数量要求的是多数派&#xff0c;例如&#xff1a;一个5成员组成的Paxos集群&#xff0c;Prepare和Accept阶段需要获得3个Acceptor的支持。Quorum3的条件&#xff0c;在原生的Paxos中是硬性条件…

NTP服务器(GPS北斗授时服务器)的市场需求及性能分析

NTP服务器&#xff08;GPS北斗授时服务器&#xff09;的市场需求及性能分析 NTP服务器&#xff08;GPS北斗授时服务器&#xff09;的市场需求及性能分析 目前国内NTP时间服务器时间精度已达到毫秒级&#xff0c;能够满足各个行业对时间同步运转的要求&#xff1b;有些企业需要…

QtitanComponents Solution 2022.4.0 Crack

2022-12-29 开始开发基于Adobe XD文件的Qt样式创建工具 包括&#xff1a; QtitanDataGrid QtitanRibbon QtitanNavigationDesignUI QtitanChart QtitanDocking QtitanFastInfoset 不要问我源码&#xff0c;没有&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#x…

Spring Boot 加载外部配置文件

Spring Boot 允许你从外部加载配置&#xff0c;这样的话&#xff0c;就可以在不同的环境中使用相同的代码。支持的外部配置源包括&#xff1a;Java属性文件、YAML文件、环境变量、命令行参数。用Value注解可以将属性值直接注入到beans中。命令行参数以 -- 开头配置文件加载的顺…

数据结构学习

数据结构 单值二叉树 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时&#xff0c;才返回 true&#xff1b;否则返回 false。 类似上述图中&#xff0c;所有结点都为1&#xff0c;那么返回true&#xff0c;只要有一个结…