【C++】通讯录的基本实现,附有源码分享

news2024/11/16 3:40:24

目录

1、运行环境

2、系统实现功能

2.1菜单功能

2.2退出通讯录功能

2.3添加联系人功能

2.4显示联系人功能

2.5删除联系人功能

2.6查找联系人功能

2.7修改联系人功能

2.8清空联系人功能

2.9动态扩容功能

2.10选择优化功能

2.11文件操作

3、源码分享


1、运行环境

运行环境为:Visual Studio 2022

2、系统实现功能

  • 菜单功能:简单的人机交互菜单
  • 添加联系人:向通讯录中添加新人,信息包括(姓名、性别、年龄、联系电话、家庭住址)
  • 显示联系人:显示通讯录中所有联系人信息
  • 删除联系人:按照姓名进行删除指定联系人
  • 查找联系人:按照姓名查看指定联系人信息
  • 修改联系人:按照姓名重新修改指定联系人
  • 清空联系人:清空通讯录中所有信息
  • 退出通讯录:退出当前使用的通讯录
  • 动态扩容:动态扩容通讯录保存的上限人数
  • 选择优化:使用枚举常量优化switch
  • 文件操作:文件保存数据,读取文件数据

实现各种功能之前需要提供关于通讯录的结构体定义,该系统提出人的信息包括姓名,性别,年龄,联系电话和家庭住址,根据上述要求就可以定义出下面相关的结构体,数据大小使用宏定义定义,定义后的结构体用typedef关键字重命名,这样实现看起来更规范一点:

#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TELE 12
#define MAX_ADDR 30

typedef struct PeoInFo
{
	char name[MAX_NAME];
	char sex[MAX_SEX];
	int age;
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
}PeoInFo;

有了通讯录人的结构体之后,还需要一个管理结构体,这个管理结构体需要包含人的信息,通讯录当前的个数,通讯录的最大容量:

typedef struct Contact
{
	PeoInFo *data;		//指向动态申请的空间,用来存放联系人的信息
	int sz;				//记录的是当前通讯录中有效信息的个数
	int capacity;		//记录当前通讯录的最大容量
}Contact;

2.1菜单功能

百度百科的解释:

菜单最初指餐馆提供的列有各种菜肴的清单。现引申指电子计算机程序进行中出现在显示屏上的选项列表,也指各种服务项目的清单等,含义更为广泛。广义的菜单是指餐厅中一切与该餐饮企业产品、价格及服务有关的信息资料,它不仅包含各种文字图片资料、声像资料以及模型与实物资料,甚至还包括顾客点菜后服务员所写的点菜单。狭义的菜单则指的是餐饮企业为便于顾客点菜订餐而准备的介绍该企业产品、服务与价格等内容的各种印刷品。

菜单功能:为了方便人去选择功能使用

//1、显示菜单界面
void menu()
{
	cout << "***********************" << endl;
	cout << "*****1、添加联系人*****" << endl;
	cout << "*****2、显示联系人*****" << endl;
	cout << "*****3、删除联系人*****" << endl;
	cout << "*****4、查找联系人*****" << endl;
	cout << "*****5、修改联系人*****" << endl;
	cout << "*****6、清空联系人*****" << endl;
	cout << "*****0、退出通讯录*****" << endl;
	cout << "***********************" << endl;
}

2.2退出通讯录功能

功能描述:退出通讯录系统

思路:根据用户不同的选择,进入不同的功能,可以选择switch分支结构,将整个架构进行搭建

当用户选择0时候,执行退出,选择其他先不做操作,也不会退出程序

	int input = 0;

	do
	{
		menu();
		cout << "请输入:>";
		cin >> input;
		switch (input)
		{
		case 1:
			break;
		case 2:
			break;
		case 3:
			break;
		case 4:
			break;
		case 5:
			break;
		case 6:
			break;
		case 0:
			cout << "退出通讯录" << endl;
			break;
		default:
			cout << "选择错误, 重新选择" << endl;
			break;
		}
	} while (input);

2.3添加联系人功能

功能描述: 向通讯录中添加新人,信息包括(姓名、性别、年龄、联系电话、家庭地址)最多记录4人

实现步骤:设计初始化通讯录函数,主函数初始化通讯录,设计添加联系人功能,在循环中的对应case下使用该函数

//初始化通讯录功能
void InitContact(Contact* pc)
{
	pc->data = (PeoInFo*)malloc(DEFAULT_SZ * sizeof(PeoInFo));
	if (pc->data == NULL)
	{
		return;
	}
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;
}

//添加联系人功能
void AddContact(Contact* pc)
{
	if (pc->sz == MAX)
	{
		cout << "通讯录已满,无法添加" << endl;
		return;
	}
	//增加一个人的信息
	cout << "请输入名字:>" << endl;
	cin >> pc->data[pc->sz].name;
	cout << "请输入年龄:>" << endl;
	cin >> pc->data[pc->sz].age;
	cout << "请输入性别:>" << endl;
	cin >> pc->data[pc->sz].sex;
	cout <<  "请输入电话:>" << endl;
	cin >> pc->data[pc->sz].tele;
	cout <<  "请输入地址:>" << endl;
	cin >> pc->data[pc->sz].addr;

	pc->sz++;
	printf("增加成功\n");
}

 

2.4显示联系人功能

功能描述:显示通讯录中已有的联系人信息

在每个功能写完之后,我们都需要测试该功能是否实现,这个时候就需要写出显示函数来查看我们的执行操作和功能函数是否正确运行了:

//显示通讯录功能
void PrintContact(const Contact* pc)
{
	int i = 0;
	printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
	//打印数据
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-5d\t%-5s\t%-12s\t%-20s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr);
	}
}

2.5删除联系人功能

功能描述:按照姓名进行删除指定联系人

实现步骤:添加一些联系人后,删除指定联系人,利用显示联系人功能函数测试该功能是否正确实现

//删除通讯录信息功能
void DelectContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	if (pc->sz == 0)
	{
		printf("通讯录为空!\n");
		return;
	}

	cout << "请输入要删除的人的名字:>";
	cin >> name;
	int pos = -1;
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			pos = i;
			break;
		}
	}
	if (pos == -1)
	{
		cout << "要删除的人不存在!" << endl;
		return;
	}
	else
	{
		int i = 0;
		for (i = pos; i < pc->sz - 1; i++)
		{
			pc->data[i] = pc->data[i + 1];
		}
	}
	pc->sz--;
	cout << "删除成功!" << endl;
}

其中可以把查找名字的部分代码封装成找下标的函数:

//查找通讯录指定联系人下标功能
int FindByContact(Contact* pc, char name[])
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}

2.6查找联系人功能

功能描述:按照姓名查看指定联系人信息

实现步骤:设计查找联系人函数,然后测试该功能的作用是否正确实现

//查找通讯录联系人功能
void SeacherContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	cout << "请输入要查找的人的名字:>" << endl;
	cin >> name;
	int pos = FindByContact(pc, name);
	if (pos == -1)
	{
		cout << "要查找的人不存在!" << endl;
		return;
	}
	else
	{
		printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
		//打印数据
		printf("%-20s\t%-5d\t%-5s\t%-12s\t%-20s\n", pc->data[pos].name, pc->data[pos].age,
			pc->data[pos].sex, pc->data[pos].tele, pc->data[pos].addr);
	}
}

2.7修改联系人功能

功能描述:按照姓名重新修改指定联系人

实现步骤:查找用户输入的联系人,如果查找成功进行修改操作,查找失败提示查无此人

//更改通讯录联系人信息
void ModifyContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	cout << "请输入要修改的人的名字:>";
	cin >> name;
	int pos = FindByContact(pc, name);
	if (pos == -1)
	{
		cout << "要修改的人不存在!" << endl;
		return;
	}
	else
	{
		cout << "请输入名字:>" << endl;
		cin >>  pc->data[pos].name;
		cout << "请输入年龄:>" << endl;
		cin >> pc->data[pos].age;
		cout << "请输入性别:>" << endl;
		cin >> pc->data[pos].sex;
		cout << "请输入电话:>" << endl;
		cin >> pc->data[pos].tele;
		cout << "请输入地址:>" << endl;
		cin >> pc->data[pos].addr;
		cout << "修改成功!" << endl;
	}
}

2.8清空联系人功能

功能描述:销毁通讯录

//销毁通讯录
void DestoryContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->capacity = 0;
}

2.9动态扩容功能

由于,第一次初始化的时候规定了通讯录的上限人数,但这样有可能会出现人数超过的极端情况,而且在少数联系人的时候会浪费开辟的内存空间,不如改成动态开辟内存空间来的方便和有益:

void CheckContact(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		PeoInFo* ptr = (PeoInFo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInFo));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->capacity += INC_SZ;
			printf("增容成功!\n");
		}
		else
		{
			return;
		}
	}
}

//添加联系人功能
void AddContact(Contact* pc)
{
	//增容
	CheckContact(pc);

	if (pc->sz == MAX)
	{
		cout << "通讯录已满,无法添加" << endl;
		return;
	}
	//增加一个人的信息
	cout << "请输入名字:>" << endl;
	cin >> pc->data[pc->sz].name;
	cout << "请输入年龄:>" << endl;
	cin >> pc->data[pc->sz].age;
	cout << "请输入性别:>" << endl;
	cin >> pc->data[pc->sz].sex;
	cout << "请输入电话:>" << endl;
	cin >> pc->data[pc->sz].tele;
	cout << "请输入地址:>" << endl;
	cin >> pc->data[pc->sz].addr;

	pc->sz++;
	printf("增加成功\n");
}

2.10选择优化功能

学了枚举之后,枚举常量可以用在switch语句中

enum Option
{
	EXIT,
	ADD,
	PRINT,
	DEL,
	SEARCH,
	MODIFY,
	DESTORYAVE
};

switch (input)
		{
		case ADD:
			//增加人的信息
			AddContact(&con);
			break;
		case PRINT:
			//显示人的信息
			PrintContact(&con);
			break;
		case DEL:
			//删除人的信息
			DelectContact(&con);
			break;
		case SEARCH:
			//查找人的信息
			SeacherContact(&con);
			break;
		case MODIFY:
			//更改人的信息
			ModifyContact(&con);
			break;
		case DESTORY:
            //清空通讯录信息
			SaveContact(&con);
			break;
		case 0:
			cout << "退出通讯录" << endl;
			break;
		default:
			cout << "选择错误, 重新选择" << endl;
			break;
		}

2.11文件操作

如果没有文件操作,那么我们每次运行程序都需要重新输入数据,这未免太麻烦了。我们可以把我们输入的数据输出到文件里面保存起来,每次运行程序之后都从保存数据的文件读取出所有通讯录数据:

//保存通讯录到文件功能
void SaveContact(Contact* pc)
{
	FILE* pf;
	if (fopen_s(&pf, "contact.txt", "w"))
	{
		return;
	}
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		fwrite(pc->data + i, sizeof(PeoInFo), 1, pf);
	}
	fclose(pf);
	pf = NULL;
}

//读取通讯录文件内容
void LoadContact(Contact* pc)
{
	FILE* pf; 
	if (fopen_s(&pf, "contact.txt", "r"))
	{
		return;
	}
	PeoInFo tmp = { 0 };
	while (fread(&tmp, sizeof(PeoInFo), 1, pf))
	{
		//检测容量
		CheckContact(pc);
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}
	fclose(pf);
	pf = NULL;
}

3、源码分享

//test.cpp
#include "Contact.h"
int main(void)
{
	int input = 0;
	char name[1024] = { 0 };

	//创建通讯录
	Contact con;
	InitContact(&con);
	LoadContact(&con);

	do
	{
		menu();
		cout << "请输入:>";
		cin >> input;
		switch (input)
		{
		case ADD:
			//增加人的信息
			AddContact(&con);
			break;
		case PRINT:
			//显示人的信息
			PrintContact(&con);
			break;
		case DEL:
			//删除人的信息
			DelectContact(&con);
			break;
		case SEARCH:
			//查找人的信息
			SeacherContact(&con);
			break;
		case MODIFY:
			//更改人的信息
			ModifyContact(&con);
			break;
		case DESTORY:
			//清空通讯录信息
			SaveContact(&con);
			DestoryContact(&con);
			break;
		case 0:
			SaveContact(&con);
			cout << "退出通讯录" << endl;
			break;
		default:
			cout << "选择错误, 重新选择" << endl;
			break;
		}
	} while (input);
	SaveContact(&con);

	return 0;
}
#pragma once
#include <iostream>
#include <cstdio>
#include <fstream>
#include <string>
using namespace std;

#define DEFAULT_SZ 3
#define INC_SZ 2
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TELE 12
#define MAX_ADDR 30

typedef struct PeoInFo
{
	char name[MAX_NAME];
	char sex[MAX_SEX];
	int age;
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
}PeoInFo;

typedef struct Contact
{
	PeoInFo* data;		//指向动态申请的空间,用来存放联系人的信息
	int sz;				//记录的是当前通讯录中有效信息的个数
	int capacity;		//记录当前通讯录的最大容量
}Contact;

enum Option
{
	EXIT,
	ADD,
	PRINT,
	DEL,
	SEARCH,
	MODIFY,
	DESTORY
};

void menu();

void InitContact(Contact* pc);

void PrintContact(const Contact* pc);

void DelectContact(Contact* pc);

int FindByContact(Contact* pc, char name[]);

void SeacherContact(Contact* pc);

void ModifyContact(Contact* pc);

void DestoryContact(Contact* pc);

void CheckContact(Contact* pc);

void AddContact(Contact* pc);

void SaveContact(Contact* pc);

void LoadContact(Contact* pc);
#include "Contact.h"

//显示菜单界面
void menu()
{
	cout << "***********************" << endl;
	cout << "*****1、添加联系人*****" << endl;
	cout << "*****2、显示联系人*****" << endl;
	cout << "*****3、删除联系人*****" << endl;
	cout << "*****4、查找联系人*****" << endl;
	cout << "*****5、修改联系人*****" << endl;
	cout << "*****6、清空联系人*****" << endl;
	cout << "*****0、退出通讯录*****" << endl;
	cout << "***********************" << endl;
}

//初始化通讯录功能
void InitContact(Contact* pc)
{
	pc->data = (PeoInFo*)malloc(DEFAULT_SZ * sizeof(PeoInFo));
	if (pc->data == NULL)
	{
		return;
	}
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;
}

//添加联系人功能
//void AddContact(Contact* pc)
//{
//	if (pc->sz == MAX)
//	{
//		cout << "通讯录已满,无法添加" << endl;
//		return;
//	}
//	//增加一个人的信息
//	cout << "请输入名字:>" << endl;
//	cin >> pc->data[pc->sz].name;
//	cout << "请输入年龄:>" << endl;
//	cin >> pc->data[pc->sz].age;
//	cout << "请输入性别:>" << endl;
//	cin >> pc->data[pc->sz].sex;
//	cout <<  "请输入电话:>" << endl;
//	cin >> pc->data[pc->sz].tele;
//	cout <<  "请输入地址:>" << endl;
//	cin >> pc->data[pc->sz].addr;
//
//	pc->sz++;
//	printf("增加成功\n");
//}

//显示通讯录功能
void PrintContact(const Contact* pc)
{
	int i = 0;
	printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
	//打印数据
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-5d\t%-5s\t%-12s\t%-20s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr);
	}
}

//删除通讯录信息功能
void DelectContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	if (pc->sz == 0)
	{
		printf("通讯录为空!\n");
		return;
	}

	cout << "请输入要删除的人的名字:>";
	cin >> name;
	int pos = -1;
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			pos = i;
			break;
		}
	}
	if (pos == -1)
	{
		cout << "要删除的人不存在!" << endl;
		return;
	}
	else
	{
		int i = 0;
		for (i = pos; i < pc->sz - 1; i++)
		{
			pc->data[i] = pc->data[i + 1];
		}
	}
	pc->sz--;
	cout << "删除成功!" << endl;
}

//查找通讯录指定联系人下标功能
int FindByContact(Contact* pc, char name[])
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}

//查找通讯录联系人功能
void SeacherContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	cout << "请输入要查找的人的名字:>" << endl;
	cin >> name;
	int pos = FindByContact(pc, name);
	if (pos == -1)
	{
		cout << "要查找的人不存在!" << endl;
		return;
	}
	else
	{
		printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
		//打印数据
		printf("%-20s\t%-5d\t%-5s\t%-12s\t%-20s\n", pc->data[pos].name, pc->data[pos].age,
			pc->data[pos].sex, pc->data[pos].tele, pc->data[pos].addr);
	}
}

//更改通讯录联系人信息
void ModifyContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	cout << "请输入要修改的人的名字:>";
	cin >> name;
	int pos = FindByContact(pc, name);
	if (pos == -1)
	{
		cout << "要修改的人不存在!" << endl;
		return;
	}
	else
	{
		cout << "请输入名字:>" << endl;
		cin >> pc->data[pos].name;
		cout << "请输入年龄:>" << endl;
		cin >> pc->data[pos].age;
		cout << "请输入性别:>" << endl;
		cin >> pc->data[pos].sex;
		cout << "请输入电话:>" << endl;
		cin >> pc->data[pos].tele;
		cout << "请输入地址:>" << endl;
		cin >> pc->data[pos].addr;
		cout << "修改成功!" << endl;
	}
}

//销毁通讯录
void DestoryContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->capacity = 0;
}

void CheckContact(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		PeoInFo* ptr = (PeoInFo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInFo));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->capacity += INC_SZ;
			cout << "增容成功!" << endl;
		}
		else
		{
			return;
		}
	}
}

//添加联系人功能
void AddContact(Contact* pc)
{
	//增容
	CheckContact(pc);

	if (pc->sz == MAX)
	{
		cout << "通讯录已满,无法添加" << endl;
		return;
	}
	//增加一个人的信息
	cout << "请输入名字:>" << endl;
	cin >> pc->data[pc->sz].name;
	cout << "请输入年龄:>" << endl;
	cin >> pc->data[pc->sz].age;
	cout << "请输入性别:>" << endl;
	cin >> pc->data[pc->sz].sex;
	cout << "请输入电话:>" << endl;
	cin >> pc->data[pc->sz].tele;
	cout << "请输入地址:>" << endl;
	cin >> pc->data[pc->sz].addr;

	pc->sz++;
	printf("增加成功\n");
}

//保存通讯录到文件功能
void SaveContact(Contact* pc)
{
	FILE* pf;
	if (fopen_s(&pf, "contact.txt", "w"))
	{
		return;
	}
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		fwrite(pc->data + i, sizeof(PeoInFo), 1, pf);
	}
	fclose(pf);
	pf = NULL;
}

//读取通讯录文件内容
void LoadContact(Contact* pc)
{
	FILE* pf; 
	if (fopen_s(&pf, "contact.txt", "r"))
	{
		return;
	}
	PeoInFo tmp = { 0 };
	while (fread(&tmp, sizeof(PeoInFo), 1, pf))
	{
		//检测容量
		CheckContact(pc);
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}
	fclose(pf);
	pf = NULL;
}

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

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

相关文章

【备战秋招】每日一题:2023.04.26-华为OD机式-第三题-MC方块

在线评测链接:P1231 题目内容 MC最新版本更新了一种特殊的方块&#xff0c;幽匿催发体。这种方块能够吸收生物死亡掉落的经验并感染周围方块&#xff0c;使其变成幽匿块。Steve想要以此为基础尝试搭建一个经验仓库&#xff0c;他来到了创造超平坦模式&#xff0c;在只有草方块…

【微信小程序开发】第 7 课 - 小程序的常用组件

欢迎来到博主 Apeiron 的博客&#xff0c;祝您旅程愉快 &#xff01; 时止则止&#xff0c;时行则行。动静不失其时&#xff0c;其道光明。 目录 1、缘起 2、小程序中组件的分类 3、常用的视图容器类组件 3.1、view 组件 3.2、scroll - view 组件 3.3、swiper 和 swiper…

blfs:为lfs虚拟机增加桌面02

参考书籍&#xff1a; BLFS11.3 LFS11.3&#xff08;这里面有软件安装的详细说明&#xff09; 树莓派Linux操作系统移植&#xff08;这里面有桌面系统的脉络梳理&#xff09; 参考视频 https://www.youtube.com/watch?vcavxyXBgJ6Q&listPLyc5xVO2uDsBK_3VZOek8ICsxewOO4DU…

Vue3 网络请求——axios 高级用法之 axios 拦截器实战与并发请求

文章目录 &#x1f4cb;前言&#x1f3af;关于拦截器&#x1f3af;项目创建&#x1f3af;代码分析&#x1f3af;补充&#xff1a;并发请求&#x1f9e9;axios.all() 和 Promise.all() 的区别 &#x1f4dd;最后 &#x1f4cb;前言 Axios 是一个流行的基于 Promise 的 HTTP 客户…

机器学习中的多分类问题

文章标题&#xff1a;机器学习中的多分类问题 机器学习中的分类问题可以大致分为二分类和多分类两种。在二分类问题中&#xff0c;模型需要将输入数据分为两类&#xff1b;而在多分类问题中&#xff0c;模型需要将输入数据分为多个类别。本文将介绍机器学习中的多分类问题及其…

C语言指针类型,8个例子给你讲明白

0.问题 知乎上回答了一个粉丝问题&#xff0c; 结果这兄弟又连续问了几个问题&#xff1a; 好吧&#xff0c;帮人帮到底&#xff0c;送佛送到西&#xff01;给你讲彻底点吧&#xff01; 1. int va; 这是一个整型变量&#xff0c;32位CPU的话&#xff0c;占有32个bite 2. in…

Redis入门(1)

1.NOSQL概述 1.1.什么是NOSQL NoSQL&#xff0c;泛指非关系型的数据库。随着互联网web2.0网站的兴起&#xff0c;传统的关系数据库在处理web2.0网站&#xff0c;特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心&#xff0c;出现了很多难以克服的问题&…

设计模式之享元模式笔记

设计模式之享元模式笔记 说明Flyweight(享元)目录享元模式示例类图抽象图形类I图形类L图形类O图形类工厂类测试类 说明 记录下学习设计模式-享元模式的写法。JDK使用版本为1.8版本。 Flyweight(享元) 意图:运用共享技术有效地支持大量细粒度的对象。 结构: 其中&#xff1…

MCU(Cortex - M3/M4)启动加载过程和内存分配原理 笔记

最近发现对基础不太熟悉&#xff0c;写篇笔记记录一下MCU启动到用户C语言运行&#xff0c;之前做了那些工作&#xff0c;同时flash和Ram又分别保存了那个数据&#xff0c;每一段又是什么意义&#xff0c;方便后续自己忘记了&#xff0c;查阅。 一、 MCU启动 在MCU上电/复位之后…

WireShark常用协议抓包与原理分析

1.ARP协议(地址解析协议) nmap 发现网关nmap -sn 192.168.133.2wireshark 抓请求包和响应包 arp请求包内容 arp响应包内容 总结:请求包包含包类型(request),源IP地址,源MAC地址,目标IP地址,目标MAC地址(未知,此处为全0);响应包包含包类型(reply),源IP地址,源…

DAY28:回溯算法(三)组合总和Ⅲ+电话号码字母组合

文章目录 216.组合总和Ⅲ思路树形结构 完整版debug测试逻辑错误&#xff1a;没有输出 剪枝操作剪枝版本continue的用法剪枝最后是continue还是return的讨论 17.电话号码的字母组合思路树形结构 伪代码字符串中的字符2转化成int的方法字符串字符与int转换补充字符串与字符 完整版…

CTF-Show密码学【摩斯码、培根密码】

萌新 密码33 一、题目信息 题目名称&#xff1a;我想吃培根题目描述&#xff1a;-- — .-. … . …–.- … … …–.- -.-. — — .-… …–.- -… …- - …–.- -… .- -.-. — -. …–.- … … …–.- -.-. — — .-… . .-. …–.- – – -… -… – -… – -… – – – -…

ASP.NET Core MVC 从入门到精通之缓存

随着技术的发展&#xff0c;ASP.NET Core MVC也推出了好长时间&#xff0c;经过不断的版本更新迭代&#xff0c;已经越来越完善&#xff0c;本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容&#xff0c;适用于初学者&#xff0c;在校毕业生&#xff0c…

理解KMP

KMP 问题 字符串匹配问题&#xff0c;问字符串 str1中是否存在连续的子串与字符串str2相等,存在返回子串的起始位置&#xff0c;否则返回-1 思路 传统做法是依次遍历str1中的每个字符作为起始位置&#xff0c;看是否能凑出字符串str2. KMP算法就是对传统做法的一种加速&am…

【Linux】软件包管理器yum与环境开发工具vim

【Linux】系列文章目录 【Linux】基础常见指令&#xff1a;http://t.csdn.cn/hwLPb 【Linux】基本权限&#xff1a;http://t.csdn.cn/faFZg 目录 前言 一、软件包管理器yum 1.什么是软件包&#xff1f; 2. yum的使用 &#xff08;1&#xff09;包文件查询 &#xff08…

EMA:基于跨空间学习的高效多尺度注意力模块

文章目录 摘要1、 简介2、相关工作3、高效多尺度注意力机制3.1、回顾坐标注意力(CA)3.2、多尺度注意力(EMA)模块 4、实验4.1、CIFAR-100上的图像分类4.2、ImageNet-1k上的图像分类4.3、MS COCO上的目标检测4.4、基于VisDrone的目标检测 5、消融实验6、 结论 摘要 https://arxi…

MIT 6.S081 Lab Six

MIT 6.S081 Lab Six 引言Copy-on-Write Fork for xv6问题解决方案Implement copy-on write (hard)代码解析 可选的挑战练习 引言 本文为 MIT 6.S081 2020 操作系统 实验六解析。 MIT 6.S081课程前置基础参考: 基于RISC-V搭建操作系统系列 Copy-on-Write Fork for xv6 虚拟内…

开发之路,穷且益坚,不坠青云之志

引言 2023毕业季&#xff0c;距离笔者毕业已过2年有余。 互联网从业环境由盛转衰&#xff0c;互联网从业者数量剧增&#xff0c;市场竞争异常激烈&#xff0c;原本的利润空间被不断挤压&#xff0c;以至于很多开发者对互联网已经失去了信心与激情。 互联网的市场份额依旧是占…

vulntarget-j内网靶机write-up

文章目录 第一部分 获取边界服务器0x01 漏洞扫描0x02 漏洞利用第二部分 信息收集+代理0x01 连接工具0x02 进行信息收集0x03 sock代理设置第三部分 内网漫游0x01 通过代理获取服务器0x02 信息收集-获取账号信息0x03 上线CS0x04 远程访问免责声明摘抄第一部分 获取边界服务器 0x0…

JSP 在线药品管理系统用myeclipse定制开发sqlserver数据库网页模式java编程jdbc

一、源码特点 JAVA 在线药品管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 JSP 在线药品管理系统用myeclipse定制开发sqls 二、功能介绍 此次系统主要在JSP…