静态通讯录

news2024/11/16 12:31:32

文章目录

  • 前言
  • 🌟一、明确通讯录信息/步骤
    • 🌏1.1.通讯录信息
    • 🌏1.2.通讯录多文件写法的好处
    • 🌏1.3.通讯录多文件写法
  • 🌟二、通讯录的实现
    • 🌏2.1.通讯录的菜单部分
    • 🌏2.2.通讯录的框架部分
    • 🌏2.3.通讯录的系列操作
      • 📒(1).初始化
      • 📒(2).增加联系人
      • 📒(3).显示联系人
      • 📒(4).运行结果
      • 📒(5).查找联系人
      • 📒(6).修改联系人信息
      • 📒(7).排序联系人
  • 🌟三、通讯录的全部代码
  • 😽总结


前言

👧个人主页:@小沈熬夜秃头中୧⍤⃝❅
😚小编介绍:欢迎来到我的乱七八糟小星球🌝
📋专栏:C语言学习
🔑本章内容:用自定义类型写一个静态通讯录小程序
送给各位💌:听闻少年二字应与平庸相斥 不要因为没有掌声而丢掉梦想
记得 评论📝 +点赞👍 +收藏😽 +关注💞哦~


提示:以下是本篇文章正文内容,下面案例可供参考

🌟一、明确通讯录信息/步骤

🌏1.1.通讯录信息

  • 要写一个通讯录首先我们应该明确通讯录信息,然后才可以根据信息来写一个通讯录。
    实现一个通讯录:

1.可以存放100个人的信息;
2.每个人的信息:
姓名;
性别;
年龄;
电话;
地址;
3.对信息的操作:
增加联系人;
删除指定联系人;
查找指定联系人;
修改指定联系人;
显示联系人信息;
排序联系人(按名字/年龄);

🌏1.2.通讯录多文件写法的好处

  • 其次我们应该使用多文件的写法,避免写在一个文件里。
    其好处至少可以说出以下几点:

1、方便代码复用
2、方便分工合作
3、方便后续维护
4、保证了库支持

🌏1.3.通讯录多文件写法

  • 所以我们创建三个文件夹分别是:

test.c — 测试通讯录的相关功能
contact.c — 通讯录的实现模块
contact.h — 声明

🌟二、通讯录的实现

🌏2.1.通讯录的菜单部分

看过之前三子棋的都知道,通讯录也需要菜单供用户使用查看
因为我们需要按照上面规定的信息进行操作,所以我们菜单也要写上上面的信息。
分别是增加,删除,查找,修改,显示,排序,最后加上一个退出

void meau()
{
	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");
}

🌏2.2.通讯录的框架部分

对于用户使用通讯录应该是一个循环部分,所以我们可以使用do…while循环,然后采用switch语句来完善循环,以便用户选择,按照平常对switch的了解和使用,我们一般会采用,case1:,case2:等等来完成选择,但是这样会使代码的可读性不高,为什么呢?试想一下,用户选择1时候,还要查看上面的add del等产生不必要的麻烦,这就需要用到我们上章节学到的枚举类型了,大家不要忘了它会自己设定值这样我们在switch语句中,直接使用case ADD等

enum Option//结构体
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT
};
int main()
{
	int input = 0;
	InitContact(&con);
	do
	{
		meau();
		printf("请选择:>\n");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			break;
		case DEL:
			break;
		case SEARCH:
			break;
		case MODIFY:
			break;
		case SHOW:
			break;
		case SORT:
			break;
		case EXIT:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
	return 0;
}

然后我们需要定义一个关于人的结构体的信息把它放到头文件里,这样别人使用或者我们使用的时候只需要包含头文件就可以了,为简便我们可以使用 (typedef)为自定义数据类型(结构体、共用体和枚举类型)定义简洁的类型名称,为PeoInfo

typedef struct PeoInfo
{
	char name[20];
	int age;
	char sex[5];
	char tele[12];
	char addr[30];
}PeoInfo;

我们希望我们的main函数运行起来显示一个通讯录,通讯录中可以存放100个人的信息,所以我们应该在test.c的测试部分的main函数中创建一个数组来存放
在这里插入图片描述
可以看到我们这里显示错误,错误信息为未定义标识符,所以我们一定要记得在test.c文件中包含#include"contact.h";

我们这个数组可以存放100个人的信息,我们可能对里面增加信息修改信息等一系列操作,所以我们应该知道这个通讯录中有几个人的信息 (注意哦100只是最大存放值是100我们增加信息时可能到达不了100所以需要操作时记录当时的人的信息数量),这就需要我们创建一个变量来记录
在这里插入图片描述
随着我们增加通讯录中的人的数量或者删除,这个sz也随之变化,所以我们增加一个到通讯录时,既要改变数组PeoInfo date[100]数组,也要改变sz,我们可以试想而知当我们使用函数操作时,既要传数组也要传sz有点麻烦那我们有没有更好的方法呢?
我们知道数组中存放的是信息,sz存放是数量,整合在一起刚好是一个通讯录,所以我们再次创建一个结构体放在contact.h中,里面是我们的这两个数据

typedef struct Contact
{
	PeoInfo data[100];//存放数据
	int sz;//记录通讯录中有效信息个数
}Contact;

然后我们再在text.c中实现一下:
在这里插入图片描述
到目前为止我们的通讯录整体结构写的差不多了,你有没有发现我们的数组中存放数据多是数字,当我们某一天想改变通讯录中的数量时,比如改为1000,那是不是需要在代码中找到数字然后更改有点麻烦这时就需要用到我们的定义(#define)了放在头文件中以便其他文件使用。

#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30
typedef struct PeoInfo
{
	char name[MAX_NAME];
	int age;
	char sex[MAX_SEX];
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
}PeoInfo;
typedef struct Contact
{
	PeoInfo data[MAX];
	int sz;
}Contact;

🌏2.3.通讯录的系列操作

📒(1).初始化

在这里插入图片描述
首先我们需要对通讯录初始化 (在contact.c中实现)注意也要在contact.x中包含#include"contact.h"头文件,保证里面的数据是从0开始的,所以我们需要分装一个函数,这样我们才可以正常的实行系列操作。
说的函数我们就会想起传值;传址两种操作,那我们传值可不可以呢?

在这里插入图片描述
很显然答案是不行的:传值调试时我们可以看到里面的值并没有改变;当我们传值的时候会有一份con的临时拷贝在里面进行相应操作修改时,是不会影响这里的con;所以我们最终采用的是传址。
注意:
data是一个连续的空间,不能直接pc->data的data是一个数组是一块连续的空间,数组名是地址不可以改成0所以应该把pc所指向通讯录的data数组里的值改成0,这里我们还需要用到之前学到的一个函数memset.

void InitContact(Contact* pc)
{
	pc->sz=0;
	//pc->date;//date是一个数组是一块连续的空间,数组名是地址不可以改成0
	//所以应该把pc所指向通讯录的date数组里的值改成0
	memset(pc->data, 0, sizeof(pc->data));
}

📒(2).增加联系人

首先在contact.h中声明一下,然后再contact.c中实现
在这里插入图片描述

在这里插入图片描述
在contact.c中实现的时候这里有一点容易忽略:通讯录如果满了怎么办还需要增加吗?所以我们应该判断一下:
还需要注意什么时候需要&操作,数组名本来就是一个地址所以不需要进行&操作;年龄是一个变量所以需要&操作;还要注意
结构体对象用 .
结构体指针用 ->

在这里插入图片描述

void AddContact(Contact* pc)
{
	if (pc->sz == MAX)
	{
		printf("通讯录已满,无法增加\n");
		return;//在函数里面遇见return就返回了,因为是void所以不需要返回值
	}
	printf("请输入名字>:");
	//结构体对象用 . 
	//结构体指针用 ->
	scanf("%s", pc->data[pc->sz].name);//数组名本来就是一个地址所以不需要进行&操作
	printf("请输入年龄>:");
	scanf("%d", &(pc->data[pc->sz].age));//年龄是一个变量所以需要&操作
	printf("请输入性别>:");
	scanf("%s", pc->data[pc->sz].sex );
	printf("请输入电话>:");
	scanf("%s", pc->data[pc->sz].tele );
	printf("请输入地址>:");
	scanf("%s", pc->data[pc->sz].addr );
	pc->sz++;
	printf("输入完成\n");
}

📒(3).显示联系人

我们添加完成后打印出来看看是否成功输入所以需要运用show操作;然后我们设置一个函数ShowContact(&con),同样传址操作,打印时不是不可以传值,传值也是可以的哦~
然后在contact.h中声明,在contact.c中实现

在这里插入图片描述

我们希望打印出来是下面格式:
姓名 年龄 性别 电话 地址
zhangsan 20 男 1234567890 北京
打印要根据里面的人物信息的输入个数所以i< pc->sz;打印时我们可以设置长度,例如%5s;
%5s是把变量的值保持长度5位(不足5位时),不足5位在前面用空格补齐,超过5位就不用补空格,直接显示全部,以字符串方式输出。也就是所谓的右对齐
%-5s 是把变量的值保持长度5位(不足5位时),不足5位在后面用空格补齐,超过5位就不用补空格,直接显示全部,以字符串方式输出。也就是所谓的左对齐
为了美观我们采用左对齐所以前面要加负号,打印时标题和数据要保持一致这样才能更美观

void ShowContact(Contact* pc)
{
	
	int i = 0;
	//printf("%10s %4s %5s %12s %30s\n", "姓名" "年龄" "性别" "电话" "地址");
	//打印标题
	printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	//打印数据
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-10s %-4d %-5s %-12s %-30s\n", 
			pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
	}

📒(4).运行结果

在这里插入图片描述

📒(5).查找联系人

这里可以向各位在提供一种写法

typedef struct Contact
{
	PeoInfo data[MAX];
	int sz;
}* pContact;//这里是一种指针
void DelContact(pContact pc);//我们这样写也可以哦~

在这里插入图片描述
首先在contact.h中声明一下:
在这里插入图片描述
然后在contact.c中实现:
我们怎么实现呢?首先输入指定联系人姓名,然后遍历数组用strcmp进行比较如果==0时就找到了我们就用一个变量来记录这个位置找到就退出,如果没有也就退出

void DelContact(Contact* pc)
{
	char name[MAX_NAME]={0};
	int pos = 0;
	printf("请输入要删除指定联系人的名字\n");
	scanf("%s", &name);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
	}
	//删除
	//1.找到删除的指定联系人 - 位置 (下标)
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if(strcmp(pc->data [i].name ,name)==0)
		{
			pos = i;//记录所删除联系人所在位置的下标
			break;
		}
	}
	if (i==pc->sz )//这里如果判断pos==0时可能是第一个元素因为i是从0开始了所以可以把pos开始赋值为-1
	{
		printf("要删除的人不存在\n");
		return;
	}
	//2.删除 - 删除pos位置上的数据
	for (i = pos;i<pc->sz -1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;//元素个数减少
	printf("删除成功\n");
}

我们发现下面的查找也需要遍历删除也需要所以为了简洁我们可以把这个遍历的数组分装成一个函数

int FindByName(Contact*pc,char name[])
{
	int pos = FindByName(pc, name);
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
			break;
		}
	}
	if (i == pc->sz)
	{
		return -1;
	}
}
void DelContact(Contact* pc)
{
	char name[MAX_NAME]={0};
	int i = 0;
	int pos = 0;
	printf("请输入要删除指定联系人的名字\n");
	scanf("%s", &name);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
	}
	//删除
	//1.找到删除的指定联系人 - 位置 (下标)
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要删除的人不存在\n");
	}
	//2.删除 - 删除pos位置上的数据
	for (i = pos;i<pc->sz -1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;//元素个数减少
	printf("删除成功\n");
}

📒(6).修改联系人信息

首先在contact.h中声明一下:
在这里插入图片描述
然后在contact.c中实现:

void ModifyContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	printf("请输入修改指定联系人的名字\n");
	scanf("%s", &name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要修改的人不存在\n");
	}
	//存在就修改
	printf("请输入名字>:");
	scanf("%s", pc->data[pos].name);
	printf("请输入年龄>:");
	scanf("%d", &(pc->data[pos].age));
	printf("请输入性别>:");
	scanf("%s", pc->data[pos].sex);
	printf("请输入电话>:");
	scanf("%s", pc->data[pos].tele);
	printf("请输入地址>:");
	scanf("%s", pc->data[pos].addr);
	printf("修改成功\n");
}

📒(7).排序联系人

假设根据联系人姓名排序我们就需要用到之前学过的一个库函数(qsort)
首先在contact.h中声明一下:
在这里插入图片描述
然后在contact.c中实现:

int cmp_by_name(const void* e1, const void* e2)
{
	return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(PeoInfo),cmp_by_name);
	printf("排序成功\n");
}

如果对qsort函数不太了解的话可以看C语言学习第十八弹:
在这里插入图片描述

🌟三、通讯录的全部代码

contact.h中的全部代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30
//表示一个人信息
typedef struct PeoInfo
{
	char name[MAX_NAME];
	int age;
	char sex[MAX_SEX];
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
}PeoInfo;
typedef struct Contact
{
	PeoInfo data[MAX];
	int sz;
}Contact;
//typedef struct Contact
//{
//	PeoInfo data[MAX];
//	int sz;
//}* pContact;
//初始化通讯录
void InitContact(Contact* pc);
//增加指定联系人
void AddContact(Contact* pc);
//显示联系人信息
void ShowContact(Contact* pc);
//删除联系人信息
//void DelContact(pContact pc);
void DelContact(Contact* pc);
//查找指定联系人
void SearchContact(Contact* pc);
//修改指定联系人信息
void ModifyContact(Contact* pc);
//排序联系人
void SortContact(Contact* pc);

contact.c中的全部代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
#include<string.h>
//void InitContact(Contact c)
//{
//	c.az;
//}

void InitContact(Contact* pc)
{
	pc->sz=0;
	//pc->date;//date是一个数组是一块连续的空间,数组名是地址不可以改成0
	//所以应该把pc所指向通讯录的date数组里的值改成0
	memset(pc->data, 0, sizeof(pc->data));
}
void AddContact(Contact* pc)
{
	if (pc->sz == MAX)
	{
		printf("通讯录已满,无法增加\n");
		return;//在函数里面遇见return就返回了,因为是void所以不需要返回值
	}
	printf("请输入名字>:");
	//结构体对象用 . 
	//结构体指针用 ->
	scanf("%s", pc->data[pc->sz].name);//数组名本来就是一个地址所以不需要进行&操作
	printf("请输入年龄>:");
	scanf("%d", &(pc->data[pc->sz].age));//年龄是一个变量所以需要&操作
	printf("请输入性别>:");
	scanf("%s", pc->data[pc->sz].sex );
	printf("请输入电话>:");
	scanf("%s", pc->data[pc->sz].tele );
	printf("请输入地址>:");
	scanf("%s", pc->data[pc->sz].addr );
	pc->sz++;
	printf("输入完成\n");
}
void ShowContact(const Contact* pc)
{
	//姓名        年龄        性别        电话            地址
	//zhangsan    20          男         1234567890     北京
	int i = 0;
	//printf("%10s %4s %5s %12s %30s\n", "姓名" "年龄" "性别" "电话" "地址");
	//打印标题
	printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	//打印数据
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-10s %-4d %-5s %-12s %-30s\n", 
			pc->data [i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
	}
}
static int FindByName(Contact*pc,char name[])//加上static这个函数只能在所在.c文件中使用
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;//记录所删除联系人所在位置的下标
			break;
		}
	}
	if (i == pc->sz)//这里如果判断pos==0时可能是第一个元素因为i是从0开始了所以可以把pos开始赋值为-1
	{
		return -1;
	}
}
void DelContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	int i = 0;
	printf("请输入要删除指定联系人的名字\n");
	scanf("%s", &name);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
	}
	//删除
	//1.找到删除的指定联系人 - 位置 (下标)
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要删除的人不存在\n");
	}
	//2.删除 - 删除pos位置上的数据
	for (i = pos;i<pc->sz -1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;//元素个数减少
	printf("删除成功\n");
}
void SearchContact(Contact* pc)
{
	//我们发现查找也需要遍历删除也需要所以为了简洁我们可以把这个遍历的数组分装成一个函数
	char name[MAX_NAME] = { 0 };
	printf("请输入要查找人的名字\n");
	scanf("%s", &name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
	}
	//找到就打印
	printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	printf("%-10s %-4d %-5s %-12s %-30s\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 };
	printf("请输入修改指定联系人的名字\n");
	scanf("%s", &name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要修改的人不存在\n");
	}
	//存在就修改
	printf("请输入名字>:");
	scanf("%s", pc->data[pos].name);
	printf("请输入年龄>:");
	scanf("%d", &(pc->data[pos].age));
	printf("请输入性别>:");
	scanf("%s", pc->data[pos].sex);
	printf("请输入电话>:");
	scanf("%s", pc->data[pos].tele);
	printf("请输入地址>:");
	scanf("%s", pc->data[pos].addr);
	printf("修改成功\n");
}
//按照名字排序
int cmp_by_name(const void* e1, const void* e2)
{
	return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(PeoInfo),cmp_by_name);
	printf("排序成功\n");
}

test.c中的全部代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void meau()
{
	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,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT
};
int main()
{
	int input = 0;
	//PeoInfo date[100];
	//int sz = 0;//记录通讯录中有几个人的信息
	Contact con;
	//初始化信息
	//传值调试时我们可以看到里面的值并没有改变
	//InitContact(con);//当我们传值的时候会有一份con的临时拷贝在里面进行相应操作修改时,是不会影响这里的con
	InitContact(&con);
	do
	{
		meau();
		printf("请选择:>\n");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&con);//输入信息,所输入的信息最终还是要放入通讯录所以要传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:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
	return 0;
}

😽总结

请添加图片描述
😽Ending,今天的实现静态通讯录内容就到此结束啦~如果后续想了解更多,就请关注我吧,一键三连哦 ~

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

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

相关文章

centos卸载mysql5.7安装mysql8.0

一、参考 CentOS7安装MySQL8的超级详细教程(无坑!)_Mysql_脚本之家 云服务器Centos7.9卸载 MySQL5.7.x 或 MySQL8.x 教程_centos 卸载mysql_大白有点菜的博客-CSDN博客 二、centos卸载mysql5.7 1、查看MySQL的依赖安装组件 rpm -qa|grep -i mysql 2、 依次移除&#xff08…

Canvas实现缩放+涂鸦改进

几个月以前&#xff0c;有人问了我一个canvass怎么实现缩放和涂鸦的问题&#xff0c;我基于当时的想法写了一篇博客&#xff0c;但是后来发现当时做的不完善&#xff0c;所以实现上其实还是有一些其他问题的。但是因为前段时间太忙了&#xff0c;也就一直没有机会去改进它。现在…

超详细:实现 Swift 与 汇编(Asm)代码混编并在真机或模拟器上运行

功能需求 虽然现在  开发的绝对主角是 Swift 语言&#xff0c;不过我们也希望有时 Swift 能够调用小段汇编代码以完成特殊功能。 在本篇博文中&#xff0c;您将学到如下内容&#xff1a; Swift 与 汇编语言混编的基本原理&#xff1b;如何在模拟器中使用 Swift x64 汇编指…

小黑带领阿黄中老黑一起跑步完成了小怪兽,晚上一起吃烤肠西瓜,买了帐篷准备一起露营的leetcode之旅:438. 找到字符串中所有字母异位词

小黑代码 class Solution:def findAnagrams(self, s: str, p: str) -> List[int]:# 串p长度n_p len(p)# 串s长度n_s len(s)# 计数字典flags collections.Counter(p)# 统计字典map_ dict((k, 0) for k in p)# 匹配到的字符个数count 0# 头尾指针left right 0# 目标数…

Python给一个exe执行文件注册持续性的快捷键(热键)的代码实例

本篇文章主要讲解通过python给一个exe文件绑定一个快捷键、并取消快捷键(热键)的实操方法。 日期:2023年6月11日 作者:任聪聪 实现按下快捷键即可启动软件的效果说明 启动软件注册热键呼出其他软件或本体的效果说明: 演示材料说明:在download文件目录下存放一个可执行的…

数据结构与算法之美 | 栈

栈结构&#xff1a;后进者先出&#xff0c;先进者后出 栈是一种“操作受限”的线性表 当某个数据集合只涉及在一端插入和删除数据&#xff0c;并且满足后进先出、先进后出的特性&#xff0c;这时我们就应该首选“栈”这种数据结构 栈的实现 使用数组实现&#xff1a;顺序栈…

【数据结构】二叉树(一)

目录 一、树的概念及结构 1、树的概念 2、树的相关概念 3、树的表示 二、二叉树概念及结构 1、二叉树的概念 2、特殊二叉树 3、二叉树的性质 4、二叉树的存储结构 4.1 顺序存储结构 4.2 链式存储结构 三、二叉树顺序结构及实现 1、二叉树的顺序结构 2、堆的概念及结构 3、堆…

OMG--RTPS(Real Time Publish Subscribe Protocol)

OMG--RTPS&#xff08;Real Time Publish Subscribe Protocol&#xff09; 1 概述2 内容缩写DDS 有线协议的要求RTPS 有线协议The RTPS Platform Independent Model (PIM)The Structure ModuleThe Messages ModuleThe Behavior ModuleThe Discovery Module The RTPS Platform S…

Xuperchain多节点网络搭建+加节点+测试

环境准备 创建网络部署环境 # 在xuperchain目录执行 make testnet 种子节点 # 查看node1节点连接地址netURL cd node1 ./bin/xchain-cli netURL preview # 得到如下结果,实际使用时,需要将ip配置节点的真实ip,port配置成 /ip4/{{ip}}/tcp/{{port}}/p2p/Qmf2HeHe4sspGkfR…

深度学习应用篇-计算机视觉-OCR光学字符识别[7]:OCR综述、常用CRNN识别方法、DBNet、CTPN检测方法等、评估指标、应用场景

【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍&#xff1a;【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化…

上课补充的知识

题目 char类型的默认值是\u0000 数组的创建方式 数组的遍历 遍历:从头到尾,依次访问数组每一个位置,获取每一个位置的元素.形式如下: 我们通过数组的下标操作数组,所以for循环变量操作的也是数组下标 开始:开始下标0 结束:结束下标length-1 如何变化: 语法&#xff1a; for…

大学结束啦!!!

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

神舟笔记本“性能、娱乐、省电、安静”模式之间的区别

前言&#xff1a;主要是对比神舟笔记本电脑“性能、娱乐、省电、安静”模式之间的区别 工具及硬件 名称版本号电脑Z8D6 2.5k屏鲁大师6.1023.xxx 之所以使用鲁大师&#xff0c;主要是为了节省时间.另外仅仅只是为了做横向对比&#xff0c;不需要太专业的工具。 实验中有两个变…

六级备考6天|CET-6|听力第一二三四讲|复习回顾|长对话篇章|14:00~16:30

长对话 篇章 目录 听写笔记 练习讲义 听写笔记 1. 听力策略 听前&#xff1a;读题——分析文章——预测题目 听中&#xff1a;划出听到的内容——对应程度高为正确选项 听后&#xff1a;不听题目——往下读题 2. 重点词汇 proofread / ˈpruːfriːd / …

CodeWhisperer插件使用体验

官方教程点击跳转 使用工具 1.vscode 2.插件(AWS Toolkit),免费使用 安装以后如何使用 1.首先要有一个aws账号 2.插件下载好以后登录aws账号&#xff0c;我们主要用这款插件的CodeWhisperer这个功能&#xff0c;其它的自行看官方教程了解。 注意事项&#xff1a;我们在从vs…

杭州互联网医疗Java实习一面

目录 1.java集合知道哪些2.ArrayList和LinkedList插入效率对比3.HashMap的底层结构4.HashMap怎么实现线程安全4.介绍下reentrantlock5.Redis分布式锁的实现原理7.知道哪些排序算法8.快排的原理9.Spring的AOP作用和原理10.MySQL的InnoDB索引结构11.网络中TCP和UDP的区别12.JVM的…

delphi 调用youtube-dl命令,下载youtube视频,原理及源代码

一、概要 1、Youtube-dl工具 强大的视频下载命令行工具Youtube-dl项目由Ricardo Garcia创建于2008年&#xff0c;源代码由Python编写&#xff0c;托管在GitHub上&#xff0c; 最初仅支持YouTube&#xff0c;但随着项目的发展&#xff0c;也开始支持其他视频网站&#xff0c;优势…

如何优化selenium webdriver的执行速度

目录 前言 在page_source中断言text比直接使用text属性断言要快 元素越具体&#xff0c;获取text的速度越快 使用变量去缓存没有变化的元素 快速在文本框中输入大文本 使用动态等待进行动态/AJAX 操作而不是固定睡眠 最后 前言 让自动化测试脚本正常工作只是自动化测试的…

微信小程序的自动化测试框架Minium详解,10分钟掌握

目录 前言 minium 是为小程序专门开发的自动化框架 文档使用 框架依赖运行环境部署 使用 打开工具 特别说明&#xff1a; 总结&#xff1a; 前言 微信发布了小程序的自动化测试框架Minium&#xff0c;提供了多种运行验证方式&#xff0c;其特点&#xff1a; 支持一套脚…

Alloy Tutorial(2)LastPass; cacheMemory

文章目录 LastPass整体 solution 代码&#xff1a; cacheMemory LastPass module LastPass/** LastPass password map** A simple example to explain basics of Alloy. ** The PassBook keeps track of a set of users passwords for a set of URLs. * For each User/URL pai…