C语言实现八种功能的通讯录(添加、删除、查找、修改、显示、排序、退出、清空)
通讯录功能概要及前提说明
此通讯录利用C语言完成,可以实现八种功能的通讯录(添加、删除、查找、修改、显示、排序、退出、清空)
代码由三部分组成,为什么要写成三部分而不写成一部分可以参考我以前的博客,如下:
链接: link
文章目录
- 通讯录功能概要及前提说明
- 1.通信录具体功能
- 2.初始化菜单
- 3.通讯录存储的信息
- 4.通讯录基本框架
- 6.各个部分功能模块声明
- 7.初始化模块
- 8.增加联系人模块
- 9.显示通讯录模块
- 10.删除用户模块
- 11.查找用户模块
- 12.修改用户信息模块
- 13.排序用户信息模块
- 14.清除模块
- 15.完整源代码
1.通信录具体功能
通讯录可以用来存储100个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址
提供方法:
1.添加联系人信息
2.删除指定联系人信息
3.查找指定联系人信息
4.修改指定联系人信息
5.显示所有联系人信息
6.清空所有联系人
7.以名字/年龄/地址排序所有联系人
2.初始化菜单
void menu()
{printf("*********************************************\n");printf("*********************************************\n");printf("*********************************************\n");printf("*********1.添加 2.删除*************\n");printf("*********3.查找 4.修改*************\n");printf("*********5.显示 6.排序*************\n");printf("*********7.退出 8.清空*************\n");printf("*********************************************\n");printf("*********************************************\n");printf("*********************************************\n");
}
3.通讯录存储的信息
使用 typedef 将 struct peoinfo 类型自定义成 peoinfo 更加方边后续使用。
利用宏定义设定各个参数的值,后续不需要再重新定义。
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
#define MAX 100//最大人数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;
其中,创建存放联系人的通讯录Contact,存放MAX个联系人对应的信息。sz用于记录当前储存联系人的数量。
4.通讯录基本框架
enum option
{add=1, del=2,search=3,modify,show,sort,run,clc
};int main()
{int input = 0;contact con;//通讯录//初始化initcontact(&con);do{menu();printf("请输入功能:");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 run:printf("退出通讯录\n");break;case clc:clccontact(&con);break;default:printf("输入非法,请重新输入!\n");break;}} while (input != 7);return 0;
}
我们知道case后只能加整数,为了更加直观的看到每一种功能,我们可以创建枚举类型替换这些整数,枚举类型成员的值从0开始递增1,适用于代替case后的整数,因为我么的菜单选项是从1到8,所以这里我们定义枚举的第一个值为1,这样后面就会默认排序到8。
通讯录运行通过do-while实现,内部调用menu函数打印开始菜单,然后提示用户选择功能。
6.各个部分功能模块声明
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 clccontact(contact* pc);
代码的基本框架搭建完毕,我们就要实现每一个选项的功能。这里是定义每一个功能的头文件,声明后才能在别的原文件中使用。
7.初始化模块
void initcontact(contact* pc)
{assert(pc);pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));}
给定的代码是一个函数initcontact,它用于初始化一个名为contact的结构体指针pc。以下是对代码的分析:
①函数声明:void initcontact(contact* pc)
声明了一个名为initcontact的函数,它接受一个结构体指针pc作为参数,并且没有返回值(即返回类型为void)。
②断言:assert(pc) 断言确保pc指针不为空。如果pc为空,断言将失败,并导致程序终止。
③初始化:pc->sz = 0 将结构体指针pc的成员变量sz的值设置为0。这意味着将sz用作计数器或存储元素数量的变量。
④内存清零:memset(pc->data, 0, sizeof(pc->data))
使用memset函数将结构体指针pc的成员变量data的内存块清零。sizeof(pc->data)用于确定pc->data成员的大小,以确保清零操作覆盖整个内存块。
⑤通过这些操作,函数initcontact将结构体指针pc所指向的contact结构体进行初始化。初始化的结果是将sz设置为0,并将data的内存块清零。
8.增加联系人模块
void addcontact(contact* pc)
{assert(pc);if (pc->sz == MAX){printf("通讯录已满\n");return;}//增加信息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");Sleep(2000);
}
该代码定义了一个名为addcontact的函数,函数参数为一个指向contact结构体的指针pc。
①函数首先使用assert函数进行断言,确保指针pc不为空。
②然后判断通讯录的当前大小是否达到了最大值(MAX),如果达到了最大值则打印提示信息并返回。
③如果通讯录未满,则依次输入联系人的姓名、年龄、性别、电话和地址,并将这些信息保存到通讯录中。
④ 最后,将通讯录的大小加1,并打印添加成功的提示信息。使用Sleep函数暂停程序执行2秒后再弹出菜单继续选择。使使用者方便观察。
9.显示通讯录模块
void showcontact(contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空\n");return;}int i = 0;printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");for (i = 0; i < pc->sz; i++){printf("%-10s%-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);}Sleep(2000);
}
该代码定义了一个名为showcontact的函数,函数参数为一个指向contact结构体的指针pc。
①函数首先使用assert函数进行断言,确保指针pc不为空。
②然后判断通讯录的大小是否为0,如果为0则打印提示信息并返回。
③接下来,使用一个循环遍历通讯录中的每个联系人,并依次打印其姓名、年龄、性别、电话和地址。
④ 最后,使用Sleep函数暂停程序执行2秒。
需要注意的是,该代码依赖于一些未给出的头文件和结构体定义,例如contact结构体的定义。另外,该代码使用了格式化输出函数printf,其中使用了%-10s、%-5d等格式控制符,用于设置输出字段的宽度和对齐方式。
10.删除用户模块
int findname(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 1;}}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 = findname(pc,name);if (ret == -1){printf("要删除的人不存在\n");return;}int i = 0;for (i = ret; i <pc->sz-1 ; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");Sleep(2000);
}
该代码定义了两个函数:findname和delcontact。
findname函数用于在通讯录中查找指定姓名的联系人,函数参数为一个指向contact结构体的指针pc和一个字符数组name。
①函数首先使用assert函数进行断言,确保指针pc不为空。
②然后使用一个循环遍历通讯录中的每个联系人,通过strcmp函数比较联系人的姓名是否与指定的name相等。如果相等,则返回1表示找到了该联系人。
③如果遍历完整个通讯录都没有找到匹配的姓名,则返回-1表示未找到。
④delcontact函数用于从通讯录中删除指定姓名的联系人,函数参数为一个指向contact结构体的指针pc。
⑤函数首先使用assert函数进行断言,确保指针pc不为空。
⑥然后判断通讯录的大小是否为0,如果为0则打印提示信息并返回。
⑦接下来,依次输入要删除的联系人的姓名,并调用findname函数查找该联系人是否存在。如果不存在,则打印提示信息并返回。
⑧如果存在,使用一个循环从找到的位置开始,将后面的联系人逐个往前移动一位,实现删除该联系人的功能。
⑨最后,将通讯录的大小减1,并打印删除成功的提示信息。使用Sleep函数暂停程序执行2秒。
11.查找用户模块
void searchcontact(contact* pc)
{char name[NAME_MAX];assert(pc);printf("请输入要查找人的姓名:");scanf("%s", name);int ret = findname(pc, name);if (ret == -1){printf("要查找的人不存在\n");return;}printf("查询成功!!\n");printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");printf("%-10s%-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);Sleep(2000);
}
该代码定义了一个名为searchcontact的函数,函数参数为一个指向contact结构体的指针pc。
①函数首先使用assert函数进行断言,确保指针pc不为空。
②然后输入要查找的联系人的姓名。
③接下来,调用findname函数查找该姓名的联系人在通讯录中的位置。如果返回值为-1,则打印提示信息并返回。
④如果返回值不为-1,表示找到了该联系人,打印查询成功的提示信息。
⑤然后,使用printf函数按照一定的格式打印该联系人的姓名、年龄、性别、电话和地址。
⑥最后,使用Sleep函数暂停程序执行2秒。
12.修改用户信息模块
void modifycontact(contact* pc)
{char name[NAME_MAX];assert(pc);printf("请输入要查找人的姓名:");scanf("%s", name);int ret = findname(pc, name);if (ret == -1){printf("要修改的人不存在\n");return;}printf("请输入名字:");scanf("%s", pc->data[ret].name);printf("请输入年龄:");scanf("%d", &(pc->data[ret].age));printf("请输入性别:");scanf("%s", pc->data[ret].sex);printf("请输入电话:");scanf("%s", pc->data[ret].tele);printf("请输入地址:");scanf("%s", pc->data[ret].addr);printf("修改成功!\n");}
该代码定义了一个名为modifycontact的函数,函数参数为一个指向contact结构体的指针pc。
①函数首先使用assert函数进行断言,确保指针pc不为空。
②然后输入要修改的联系人的姓名。
③接下来,调用findname函数查找该姓名的联系人在通讯录中的位置。如果返回值为-1,则打印提示信息并返回。
④如果返回值不为-1,表示找到了该联系人,依次输入要修改的联系人的姓名、年龄、性别、电话和地址,并将这些信息更新到通讯录中。
⑤最后,打印修改成功的提示信息。
13.排序用户信息模块
int cmp_name(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}int cmp_age(const void* p1, const void* p2)
{return ((peoinfo*)p1)->age-((peoinfo*)p2)->age;
}int cmp_addr(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr);
}void sortcontact(contact* pc)
{int i = 0;char sort_choose[10];char sort_choose1[] = "name";char sort_choose2[] = "age";char sort_choose3[] = "addr";A:printf("请输入根据什么进行排序:");scanf("%s", sort_choose);if (strcmp(sort_choose,sort_choose1) == 0){//利用qsort 函数qsort(pc->data, pc->sz, sizeof((pc->data)[0]), cmp_name);}else if (strcmp(sort_choose,sort_choose2) == 0){qsort(pc->data, pc->sz, sizeof((pc->data)[1]), cmp_age);}else if (strcmp(sort_choose,sort_choose3) == 0){qsort(pc->data, pc->sz, sizeof((pc->data)[4]), cmp_addr);}else{printf("无此排序参数,请重新输入参数\n");goto A;}//打印列标题printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");//打印数据for (i = 0; i < pc->sz; i++){printf("%-10s%-5d%-5s%-12s%-30s\t\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);}Sleep(2000);
}
该代码定义了三个比较函数:cmp_name、cmp_age和cmp_addr。这些函数用于在排序通讯录时比较联系人信息的不同字段。
①cmp_name函数用于比较联系人姓名的大小,函数参数为指向两个联系人信息结构体的指针p1和p2。通过调用strcmp函数比较两个联系人的姓名,并返回比较结果。
② cmp_age函数用于比较联系人年龄的大小,函数参数为指向两个联系人信息结构体的指针p1和p2。通过将第一个联系人的年龄减去第二个联系人的年龄,并返回比较结果。
③cmp_addr函数用于比较联系人地址的大小,函数参数为指向两个联系人信息结构体的指针p1和p2。通过调用strcmp函数比较两个联系人的地址,并返回比较结果。
④sortcontact函数用于对通讯录中的联系人进行排序,函数参数为一个指向contact结构体的指针pc。
⑤函数首先定义一些变量和字符串数组用于接收用户输入的排序参数。
⑥然后,通过标签A实现一个循环,提示用户输入根据什么进行排序。根据用户的输入,分别调用qsort函数进行排序。排序时,根据用户的选择调用不同的比较函数。
⑦如果用户输入的排序参数无效,则打印提示信息并跳转回标签A,要求用户重新输入。
⑧排序完成后,先打印列标题,然后依次打印排序后的联系人信息。
⑨最后,使用Sleep函数暂停程序执行2秒。
14.清除模块
void clccontact(contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));printf("通讯录已经清空!!!\n");Sleep(2000);
}
此代码实现了一个清空通讯录的函数。(即和初始化模块一样)函数接收一个指向联系人结构体的指针,将通讯录结构体中的数据清空,包括sz(通讯录中已有联系人数量)和data(存放联系人信息的数组)。最后输出提示信息“通讯录已经清空!!!”并延时2秒。
此代码的功能比较简单,只是清空通讯录。可以作为通讯录管理系统的一个基本操作函数之一。
15.完整源代码
test.c如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include "adressbook.h"void menu()
{printf("*********************************************\n");printf("*********************************************\n");printf("*********************************************\n");printf("*********1.添加 2.删除*************\n");printf("*********3.查找 4.修改*************\n");printf("*********5.显示 6.排序*************\n");printf("*********7.退出 8.清空*************\n");printf("*********************************************\n");printf("*********************************************\n");printf("*********************************************\n");
}enum option
{add=1, del=2,search=3,modify,show,sort,run,clc
};int main()
{int input = 0;contact con;//通讯录//初始化initcontact(&con);do{menu();printf("请输入功能:");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 run:printf("退出通讯录\n");break;case clc:clccontact(&con);break;default:printf("输入非法,请重新输入!\n");break;}} while (input != 7);return 0;
}
addressbook.c如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include "adressbook.h"void initcontact(contact* pc)
{assert(pc);pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));}void addcontact(contact* pc)
{assert(pc);if (pc->sz == MAX){printf("通讯录已满\n");return;}//增加信息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");Sleep(2000);
}void showcontact(contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空\n");return;}int i = 0;printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");for (i = 0; i < pc->sz; i++){printf("%-10s%-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);}Sleep(2000);
}int findname(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 1;}}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 = findname(pc,name);if (ret == -1){printf("要删除的人不存在\n");return;}int i = 0;for (i = ret; i <pc->sz-1 ; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");Sleep(2000);
}void searchcontact(contact* pc)
{char name[NAME_MAX];assert(pc);printf("请输入要查找人的姓名:");scanf("%s", name);int ret = findname(pc, name);if (ret == -1){printf("要查找的人不存在\n");return;}printf("查询成功!!\n");printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");printf("%-10s%-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);Sleep(2000);
}void modifycontact(contact* pc)
{char name[NAME_MAX];assert(pc);printf("请输入要查找人的姓名:");scanf("%s", name);int ret = findname(pc, name);if (ret == -1){printf("要修改的人不存在\n");return;}printf("请输入名字:");scanf("%s", pc->data[ret].name);printf("请输入年龄:");scanf("%d", &(pc->data[ret].age));printf("请输入性别:");scanf("%s", pc->data[ret].sex);printf("请输入电话:");scanf("%s", pc->data[ret].tele);printf("请输入地址:");scanf("%s", pc->data[ret].addr);printf("修改成功!\n");}int cmp_name(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}int cmp_age(const void* p1, const void* p2)
{return ((peoinfo*)p1)->age-((peoinfo*)p2)->age;
}int cmp_addr(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr);
}void sortcontact(contact* pc)
{int i = 0;char sort_choose[10];char sort_choose1[] = "name";char sort_choose2[] = "age";char sort_choose3[] = "addr";A:printf("请输入根据什么进行排序:");scanf("%s", sort_choose);if (strcmp(sort_choose,sort_choose1) == 0){//利用qsort 函数qsort(pc->data, pc->sz, sizeof((pc->data)[0]), cmp_name);}else if (strcmp(sort_choose,sort_choose2) == 0){qsort(pc->data, pc->sz, sizeof((pc->data)[1]), cmp_age);}else if (strcmp(sort_choose,sort_choose3) == 0){qsort(pc->data, pc->sz, sizeof((pc->data)[4]), cmp_addr);}else{printf("无此排序参数,请重新输入参数\n");goto A;}//打印列标题printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");//打印数据for (i = 0; i < pc->sz; i++){printf("%-10s%-5d%-5s%-12s%-30s\t\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);}Sleep(2000);
}void clccontact(contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));printf("通讯录已经清空!!!\n");Sleep(2000);
}
addressbook.h如下:
#define _CRT_SECURE_NO_WARNINGS 1
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
#define MAX 100#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <Windows.h>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;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 clccontact(contact* pc);
大家只需要将此代码,按照文章开头设置为三部分,点击运行即可。
相关文章:

C语言实现八种功能的通讯录(添加、删除、查找、修改、显示、排序、退出、清空)
通讯录功能概要及前提说明 此通讯录利用C语言完成,可以实现八种功能的通讯录(添加、删除、查找、修改、显示、排序、退出、清空) 代码由三部分组成,为什么要写成三部分而不写成一部分可以参考我以前的博客,如下&…...

视频监控/视频汇聚/安防视频监控平台EasyCVR配置集群后有一台显示离线是什么原因?
开源EasyDarwin视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,在视频监控播放上,TSINGSEE青犀视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放,可同时播放多…...

【RabbitMQ实战】02 生产者和消费者示例
在上一节中,我们使用docker部署了RabbitMQ,这一节我们将写一段生产者和消费者的代码。将用到rabbitmq的原生API来进行生产和发送消息。 一、准备工作 开始前,我们先在RabbitMQ控制台建相好关的数据 本机的RabbitMQ部署机器是192.168.56.201…...

Linux下ThinkPHP5实现定时器任务 - 结合crontab
实例一: 1.在/application/command创建要配置的PHP类文件,需要继承Command类,并重写configure和execute两个方法,例如: <?php namespace app\command; use think\console\Command; use think\console\Input; use think\cons…...

3dsmax模型烘焙光照贴图并导入unity流程详解
目录 前言 软件环境 前置知识储备 一、模型场景搭建 二、模型材质处理 三、vray渲染准备 四、烘焙至贴图 五、unity场景准备 六、贴图与材质 前言 该流程针对某些固定场景(模型发布、无法使用实时渲染引擎等)情况下的展示,本文记录烘…...

安卓生成公钥和md5签名
安卓公钥和md5证书签名 大家好,最近需要备案app,用到了公钥和md5,MD5签名我倒是知道,然而对于公钥却一下子不知道了, 现在我讲一下我的流程。 首先是md5证书签名的查看, 生成了apk和签名.jks后&…...

pwndbg安装(gdb插件)
pwndbg安装(gdb插件) 源地址:https://github.com/pwndbg/pwndbg 手动安装 git clone https://github.com/pwndbg/pwndbg cd pwndbg ./setup.sh 没啥问题运行gdb的话就可以看到明显的不同了 如果安装成功了,但没有生效 如果有问…...

SpringBoot 学习(二)配置
2. SpringBoot 配置 2.1 配置文件类型 配置文件用于修改 SpringBoot 的默认配置。 2.1.1 properties 文件 **properties ** 是属性文件后缀。 文件名:application.properties 只能保存键值对。 基础语法:keyvalue namewhy注入配置类 Component //…...
西门子828d授权密钥破解经验分享 I7I54833762
操作数组的方法 Array.prototype.toSorted(compareFn) //返回一个新数组,其中元素按升序排序,而不改变原始数组。 Array.prototype.toReversed() //返回一个新数组,该数组的元素顺序被反转,但不改变原始数组。 Array.prototype.to…...
06贪心:跳跃游戏
06贪心:跳跃游戏 55. 跳跃游戏 刚看到本题一开始可能想:当前位置元素如果是 3,我究竟是跳一步呢,还是两步呢,还是三步呢,究竟跳几步才是最优呢? 其实跳几步无所谓,关键在于可跳的…...
鄙视测试,理解测试,成为测试
首先,其实题主的问题还是很实诚的,我刚开始做测试的时候其实也是这个心态,想转开发,也学习了很多的语言,个人觉得这是职业危机感的表现,挺好的,也相信题主不管去做开发和测试都会去不断的学习和…...

MySQL数据库基础知识要点总结
目录 前言 一.数据库构成 1.1 表 1.2 关系 1.3 索引 1.4 查询语言 1.5 数据库管理系统 二.数据类型 2.1 整数 2.2 浮点 2.3 日期与时间 2.4 字符串 三.约束条件 3.1 主键约束 3.2 唯一约束 3.3 外键约束 3.4 非空约束 3.5 默认值约束 总结 前言 数据库是…...

基础运维(一)YUM仓库
一 自定义YUM仓库 1 Yum仓库特点 作为yum源需要准备的内容 大量的rpm 软件安装包文件针对这些软件包的 repodata/ 仓库档案 repodata/ 仓库档案数据 filelists.xml.gz // 软件包的文件安装清单primary.xml.gz // 软件包的基本/主要信息other.xml.gz // 软件包…...

递归算法讲解,深度理解递归
首先最重要的就是要说明递归思想的作用,在后面学习的高级数据接口,树和图中,都需要用到递归,即深度优先搜索,如果递归掌握的不好,后面的数据结构将举步为艰。 加油 首先看下如何下面两个方法有什么区别&a…...

网络通信(套接字通信)(C/C++)
1.网络编程必知概念 1.广域网和局域网 广域网:又称外网、公网。是连接不同地区局域网或城域网进行计算机通信的远程公共网络。 局域网:在一定的通信范围内,有很个多计算机组成的私有网络就叫局域网。(这些计算机相互之间是可以通信的,但是不能直接访问外网(可以通过网线…...

anaconda navigator启动时一直卡在 loading applications 页面
anaconda navigator启动时一直卡在 loading applications 页面 方法1 在安装目录找到D:\anaconda\Lib\site-packages\anaconda_navigator\api 然后打开conda_api.py, 在1358行找到data yaml.load(f),将其改为data yaml.safeload(f) 猜测为保证代码…...

力扣刷题-链表-删除链表的倒数第N个节点
19.删除链表的倒数第N个节点 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head [1,2,3,4,5], n 2 输出:[1,2,3,5] 示例 2:输入:head [1], n 1 输出&…...

Blender DreamUV插件使用简明教程
DreamUV 是一个可让你在Blender的 3D 视口中操纵 UV的工具集合。 该工具集设计用于可重复使用的纹理,例如平铺纹理、装饰表和纹理图集。 其目的是让你无需退出 3D 视图即可对几何体进行纹理处理,从而节省时间并提高灵活性。 1、安装DreamUV 首先下载为…...

AI在线工具分享
1、ChatGPT ChatGPT是一种由OpenAI训练的大型语言模型。它的原理是基于Transformer架构,通过预训练大量文本数据来学习如何生成人类可读的文本,然后通过接受输入并生成输出来实现对话。 ChatGPT的用途非常广泛,可以用于自然语言处理…...
Matlab批量处理测试数据的方法:以VCO的调谐测试曲线处理为例
我们都知道得到的VCO调谐曲线是一根一根扫出来的,如果要手动对数据进行处理很麻烦。 (当然最好是搭建一个自动化测试平台,一边测试一边把数据抓取了,这个以后可以搞一下再更新) 目前还是手动测量的情况下,…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...