C语言小程序:通讯录(静态版)
哈喽各位老铁们,今天给大家带来一期通讯录的静态版本的实现,何为静态版本后面会做解释,话不多说,直接开始!
关于通讯录,其实也就是类似于我们手机上的通讯录一样,有着各种各样的功能,小编来带大家实现一部分功能就好啦(1.添加联系人 2. 删除指定联系人 3.查找指定联系人 4.修改指定联系人 5.显示全部联系人 6.排序通讯录 7.清空通讯录)要实现这些功能,首先得要有一个可以存放联系人的一块空间,而要存放的联系人的个人信息有:名字、性别、年龄、电话、家庭地址。这些个人信息类型不同,大小也不同,那该如何去存放,如何查找,又该如何去修改?我们一步一步来通过代码的方式实现这些功能
1.文件的划分
在前面发布的博客中就提到过划分文件进行编写,在之前的三子棋、扫雷的代码中就是通过划分文件,每一个文件实现相对应的功能,互不干扰,那么通讯录也要使用同样的方法
头文件:Contact.h
在头文件里面主要实现函数的声明,变量的定义、头文件的包含
源文件:Contact.c
在这个源文件里面实现通讯录的实现模块
源文件:test.c
这个源文件里面实现测试通讯录相关的功能
2.通讯录
实现一个通讯录:
1.这个通讯录可以存放100个人的信息
2.每个人的信息:
名字、性别、年龄、电话、地址
3.通讯录所包含的功能
添加联系人、删除联系人、查找联系人、修改联系人、显示通讯录、排序通讯录、清空通讯录
首先我们先搭出通讯录的基本框架:
头文件:Contact.h
//头文件的包含#include <stdio.h>
源文件:test.c
#include "Contact.h"//测试通讯录相关的功能
void menu()
{printf("**************************************\n");printf("**** 1.Add ***** 2.Del ****\n");printf("**** 3.Search ***** 4.Modify ****\n");printf("**** 5.Show ***** 6.Sort ****\n");printf("**** 7.Clear ***** 0.Exit ****\n");printf("**************************************\n");
}int main()
{int input = 0;do{menu();printf("请选择通讯录的功能:>");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);return 0;
}
但是如果这样字写,在代码可读性不高,为什么呢?当代码走到switch case 语句中,这里的case1、case2...里面的1、2..都代表什么呢?就得返回到最上面重新查看,因此这里需要完善一下,我们可以使用枚举,将我们选择的全部可能型都一一列举出来,然后进行选择,就比较方便。
优化代码:
enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT,CLEAR
};
//枚举的可能取值默认是从0开始,在这里刚好对应菜单里面的选项
int main()
{int input = 0;do{menu();printf("请选择通讯录的功能:>");scanf("%d", &input);switch (input){case ADD://添加联系人break;case DEL://删除联系人break;case SEARCH://查找联系人break;case MODIFY://修改联系人break;case SHOW://展示break;case SORT://排序联系人break;case CLEAR://清空break;case EXIT:printf("退出通讯录!\n");break;default:printf("选择错误,请重新选择:>\n");break;}} while (input);return 0;
}
基本框架搭建好了之后,就得有一个块空间来存放我们的联系人了,而联系人的信息又有多种,因此就需要一个结构体来存放联系人的信息,这里还存在一个问题,我们存放的联系人从哪里开始存放呢?所以我们还需要一个变量来确定联系人该存放在哪里,而且每当我们存放一个联系人,这个变量就要+1,以便下一个联系人存放在上一个联系人的后面。
注:如果我们将这个结构体创建在源文件中,就得在两个源文件中都要创建,因此为了节省空间,可以直接将结构体变量创建在头文件中
头文件:Contact.h
//表示一个联系人的各种信息
typedef struct PeoInfo
{char name[20];int age;char sex[5];char tele[12];char addr[20];
}PeoInfo;//通讯录
typedef struct Contact
{PeoInfo data[100]; //用来存放100个人的信息int sz; //记录通讯录中有效信息的个数
}Contact;
如果这样子写还是有一个弊端,如果后期要修改通讯录中存放联系人的个数和每一个联系人信息中存放的大小,所有有关的数组都得一一修改,因此我们可以直接用#define来定义大小
代码优化:
//大小的定义
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 20//表示一个联系人的各种信息
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]; //用来存放100个人的信息int sz; //记录通讯录中有效信息的个数
}Contact;
这样子写在后期需要修改的时候就比较方便
存放联系人的空间也搭建好了,但是创建好的空间里面刚刚开始放的是什么东西呢?我们也不知道,因此我们先得给通讯录进行初始化,让里面一个联系人也没有,让标记的变量也变为0
2.1初始化通讯录
初始化通讯录我们分装一个函数:InitContact
源文件:test.c
int main()
{int input = 0;Contact con; //创建通讯录变量//初始化通讯录InitContact(&con); //要修改通讯录里面的内容要传递指针do{menu();printf("请选择通讯录的功能:>");scanf("%d", &input);switch (input){case ADD://添加联系人break;case DEL://删除联系人break;case SEARCH://查找联系人break;case MODIFY://修改联系人break;case SHOW://展示break;case SORT://排序联系人break;case CLEAR://清空break;case EXIT:printf("退出通讯录!\n");break;default:printf("选择错误,请重新选择:>\n");break;}} while (input);return 0;
}
头文件Contact.h
#include <string.h>
//函数的声明
//初始化通讯录
void InitContact(Contact* pc);
源文件:Contact.c
//初始化通讯录
void InitContact(Contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));//memset函数在使用时要包含头文件<string.h>
}
2.2添加联系人
初始化好通讯录的内容之后,接下来就到了我们进行通讯录功能的实现了,首先我们实现添加联系人功能,要添加联系人,我们要确定sz的大小,如果sz等于MAX了,那不就证明通讯录以及满了嘛,就再不能添加联系人了,只有sz小于MAX的时候才可以添加联系人
源文件:test.c
case ADD://添加联系人printf("添加联系人\n");AddContact(&con); //传址调用break;
头文件:Contact.h
//添加联系人
void AddContact(Contact* pc);
源文件:Contact.c
//添加联系人
void AddContact(Contact* 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++; //每一次添加完之后sz都要++printf("添加成功\n");
}
2.3展示通讯录
要展示通讯录,可以先打印一行标题,有助于展示,打印整个通讯录就可以使用循环,设置一个循环,循环条件只要小于sz的大小就可以
源文件:test.c
case SHOW://展示ShowContact(&con);//显示通讯录不需要修改通讯录其实传值调用也可以,但是为了节省空间使用传值调用break;
头文件:Contact.h
//显示通讯录
void ShowContact(Contact* pc);
源文件:Contact.c
//显示通讯录
void ShowContact(Contact* pc)
{//先打印标题printf("%-10s %-2d %-5s %-10s %-15s\n", "名字", "年龄", "性别", "电话", "地址");int i = 0;for (i = 0; i < pc->sz; i++){printf("%-10s %-2d %-5s %-10s %-15s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);}
}
2.4删除联系人
要删除联系人,首先得判断这个通讯录里面有没有联系人呀,所以要先判断sz是否为0,如果为0就证明没有联系人,判断完之后,需要删除联系人,那么首先得找到所想删除的联系人的位置,然后将这个位置记录下来,通过下标的形式访问,然后进行删除,这里还要注意,如果找完了整个通讯录,没有找到与之匹配的名字,那么就没有这个人,在删除的时候就是将记录的那个位置上的人,用后面一个人的信息进行覆盖,依次类推,然后整个通讯录的总人数减1就行了
源文件:test.c
case DEL://删除联系人printf("删除联系人\n");DelContact(&con);
头文件:Contact.h
//删除联系人
void DelContact(Contact* pc);
源文件:Contact.c
//删除联系人
void DelContact(Contact* pc)
{char name[MAX_NAME] = { 0 };//判断通讯录是否为空if (0 == pc->sz){printf("通讯录为空,无法删除!\n");return;}printf("请输入你要删除联系人的姓名:>");scanf("%s", name);int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){//找到所要删除的联系人所在的位置if (0 == strcmp(pc->data[i].name, name)){pos = i;break;}}if (i == pc->sz){printf("找不到所要删除的联系人\n");return;}//进行删除for (i = pos; i < pc->sz - 1; i++) //判断条件这里所要交换的比总数少一个{pc->data[i] = pc->data[i + 1];}//删除完之后sz减一pc->sz--;printf("删除成功\n");
}
2.5查找联系人
查找联系人和删除练习人的基本步骤一样,先判断是否为空通讯录,然后进行查找,记录位置,然后打印
源文件:test.c
case SEARCH://查找联系人printf("查找联系人\n");SearchContact(&con);break;
头文件:Contact.h
//查找联系人
void SearchContact(Contact* pc);
源文件:Contact.c
//查找联系人
void SearchContact(Contact* pc)
{char name[MAX_NAME] = { 0 };if (pc->sz == 0){printf("通讯录为空,查找不到!");return;}printf("请输入你要查找联系人的姓名:>");scanf("%s", name);int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){//找到所要查找的联系人所在的位置if (0 == strcmp(pc->data[i].name, name)){pos = i;break;}}if (i == pc->sz){printf("找不到所要查找的联系人\n");return;}//打印导航栏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);
}
写到这里,我们不难发现这个查找联系人的过程重复了两次,在删除联系人和查找的时候都出现了,因此我们可以简化一下代码,直接将查找的过程分装一个查找函数,然后在使用的时候代码就不显得那么冗余,每次使用查找就直接调用这个函数
代码优化:
static int FindByName(const Contact* pc, char name[]) //使用static修饰, //只在本源文件中使用
{int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){//找到所要删除的联系人所在的位置if (0 == strcmp(pc->data[i].name, name)){return i;}}return -1;
}//删除联系人
void DelContact(Contact* pc)
{char name[MAX_NAME] = { 0 };//判断通讯录是否为空if (0 == pc->sz){printf("通讯录为空,无法删除!\n");return;}printf("请输入你要删除联系人的姓名:>");scanf("%s", name);int pos = FindByName(pc, name);int i = 0;if (pos == -1){printf("找不到所要删除的联系人\n");return;}//进行删除for (i = pos; i < pc->sz - 1; i++) //判断条件这里所要交换的比总数少一个{pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}//查找联系人
void SearchContact(const Contact* pc) //使用const修饰更安全
{char name[MAX_NAME] = { 0 };if (pc->sz == 0){printf("通讯录为空,查找不到!");return;}printf("请输入你要查找联系人的姓名:>");scanf("%s", name);int pos = FindByName(pc, name);int i = 0;if (pos == -1){printf("找不到所要查找的联系人\n");return;}//打印导航栏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);
}
2.6修改联系人
要修改联系人,首先的找到联系人的位置,然后输入信息将其修改
源文件:test.c
case MODIFY://修改联系人printf("修改联系人\n");ModifyContact(&con);break;
头文件:Contact.h
//修改联系人
void ModifyContact(Contact* pc);
源文件:Contact.c
//修改联系人
void menu1()
{printf("**********************************\n");printf("******1.姓名*********2.年龄*******\n");printf("******3.性别*********4.电话*******\n");printf("*************5.地址***************\n");printf("**********************************\n");
}
void ModifyContact(Contact* pc)
{int input = 0;char name[MAX_NAME] = { 0 };printf("请输入你要修改的联系人姓名:>");scanf("%s", name);//查找int pos = FindByName(pc, name);int i = 0;if (pos == -1){printf("找不到所要查找的联系人\n");return;}//修改printf("请输入要修改的具体信息:>\n");menu1();scanf("%d", &input);switch (input){case 1:printf("请输入新的姓名:>");scanf("%s", pc->data[pos].name);break;case 2:printf("请输入新的年龄:>");scanf("%d", &pc->data[pos].age);break;case 3:printf("请输入新的性别:>");scanf("%s", pc->data[pos].sex);break;case 4:printf("请输入新的电话:>");scanf("%s", pc->data[pos].tele);break;case 5:printf("请输入新的地址:>");scanf("%s", pc->data[pos].addr);break;default:printf("输入有误,修改失败\n");return;}printf("修改成功\n");
}
2.7排序联系人
要排序联系人,也就意味着要排序结构体成员,就需要用到qsort排序,如果不清楚可以点击查看->qsort排序详解
源文件:test.c
case SORT://排序联系人SortContact(&con);break;
头文件:Contcat.h
#include <stdlib.h>
//排序联系人
void SortContact(Contact* pc);
源文件:Contact.c
void menu2()
{printf("***************************\n");printf("******** 1.NAME **********\n");printf("******** 2.AGE **********\n");printf("***************************\n");
}//按照名字排序
int cmp_byname(const void* p1, const void* p2)
{return strcmp(((PeoInfo*)p1)->name, ((PeoInfo*)p2)->name);
}//按照年龄来排序
int cmp_byage(const void* p1, const void* p2)
{return ((PeoInfo*)p1)->age - ((PeoInfo*)p2)->age;
}//排序联系人
void SqrtContact(Contact* pc)
{int input = 0;if (pc->sz == 0){printf("通讯录没有联系人,无法排序!\n");return;}menu2();printf("请选择排序的对象:>");scanf("%d", &input);switch (input){case 1:qsort(pc, pc->sz, sizeof(PeoInfo), cmp_byname);break;case 2:qsort(pc, pc->sz, sizeof(PeoInfo), cmp_byage);break;}printf("排序成功\n");//排序成功之后打印一下ShowContact(pc);
}
2.8清空联系人
清空联系人本质上就是再将通讯录初始化,我们只需要再进行调用初始化函数就可以了
源文件:test.c
case CLEAR://清空联系人ClearContact(&con);break;
头文件:Contact.h
//清空联系人
void ClearContact(Contact* pc);
源文件:Contact.c
//清空联系人
void ClearContact(Contact* pc)
{//初始化通讯录InitContact(pc);printf("清空成功\n");//初始完之后再打印ShowContact(pc);
}
3.完整代码
头文件:Contact.h
#pragma once//头文件的包含#include <stdio.h>
#include <string.h>
#include <stdlib.h>//大小的定义
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 20//表示一个联系人的各种信息
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]; //用来存放100个人的信息int sz; //记录通讯录中有效信息的个数
}Contact;//函数的声明
//初始化通讯录
void InitContact(Contact* pc);//添加联系人
void AddContact(Contact* pc);//显示通讯录
void ShowContact(const Contact* pc);//删除联系人
void DelContact(Contact* pc);//查找联系人
void SearchContact(const Contact* pc);//修改联系人
void ModifyContact(Contact* pc);//排序联系人
void SqrtContact(Contact* pc);//清空联系人
void ClearContact(Contact* pc);
源文件:test.c
#define _CRT_SECURE_NO_WARNINGS 1#include "Contact.h"//测试通讯录相关的功能void menu()
{printf("**************************************\n");printf("**** 1.Add ***** 2.Del ****\n");printf("**** 3.Search ***** 4.Modify ****\n");printf("**** 5.Show ***** 6.Sqrt ****\n");printf("**** 7.Clear ***** 0.Exit ****\n");printf("**************************************\n");
}enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SQRT,CLEAR
};int main()
{int input = 0;Contact con; //创建通讯录变量//初始化通讯录InitContact(&con); //要修改通讯录里面的内容要传递指针do{menu();printf("请选择通讯录的功能:>");scanf("%d", &input);switch (input){case ADD://添加联系人printf("添加联系人\n");AddContact(&con); //传址调用break;case DEL://删除联系人printf("删除联系人\n");DelContact(&con);break;case SEARCH://查找联系人printf("查找联系人\n");SearchContact(&con);break;case MODIFY://修改联系人printf("修改联系人\n");ModifyContact(&con);break;case SHOW://展示ShowContact(&con);//显示通讯录不需要修改通讯录其实传值调用也可以,但是为了节省空间使用传值调用break;case SQRT://排序联系人SqrtContact(&con);break;case CLEAR://清空联系人ClearContact(&con);break;case EXIT:printf("退出通讯录!\n");break;default:printf("选择错误,请重新选择:>\n");break;}} while (input);return 0;
}
源文件:Contact.c
#define _CRT_SECURE_NO_WARNINGS 1#include "Contact.h"
//通讯录的实现模块//初始化通讯录
void InitContact(Contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}//添加联系人
void AddContact(Contact* 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++; //每一次添加完之后sz都要++printf("添加成功\n");
}//显示通讯录
void ShowContact(const Contact* pc)
{printf("%-10s %-4s %-5s %-12s %-15s\n", "名字", "年龄", "性别", "电话", "地址");int i = 0;for (i = 0; i < pc->sz; i++){printf("%-10s %-4d %-5s %-12s %-15s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);}
}//查找
static int FindByName(const Contact* pc, char name[])
{int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){//找到所要联系人所在的位置if (0 == strcmp(pc->data[i].name, name)){return i;}}return -1;
}
//删除联系人
void DelContact(Contact* pc)
{char name[MAX_NAME] = { 0 };//判断通讯录是否为空if (0 == pc->sz){printf("通讯录为空,无法删除!\n");return;}printf("请输入你要删除联系人的姓名:>");scanf("%s", name);int pos = FindByName(pc, name);int i = 0;if (pos == -1){printf("找不到所要删除的联系人\n");return;}//进行删除for (i = pos; i < pc->sz - 1; i++) //判断条件这里所要交换的比总数少一个{pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}//查找联系人
void SearchContact(const Contact* pc)
{char name[MAX_NAME] = { 0 };if (pc->sz == 0){printf("通讯录为空,查找不到!");return;}printf("请输入你要查找联系人的姓名:>");scanf("%s", name);int pos = FindByName(pc, name);int i = 0;if (pos == -1){printf("找不到所要查找的联系人\n");return;}//打印导航栏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 menu1()
{printf("*********************************\n");printf("******1.姓名*********2.年龄*******\n");printf("******3.性别*********4.电话*******\n");printf("*************5.地址**************\n");printf("*********************************\n");
}
void ModifyContact(Contact* pc)
{int input = 0;char name[MAX_NAME] = { 0 };printf("请输入你要修改的联系人姓名:>");scanf("%s", name);//查找int pos = FindByName(pc, name);int i = 0;if (pos == -1){printf("找不到所要查找的联系人\n");return;}//修改printf("请输入要修改的具体信息:>\n");menu1();scanf("%d", &input);switch (input){case 1:printf("请输入新的姓名:>");scanf("%s", pc->data[pos].name);break;case 2:printf("请输入新的年龄:>");scanf("%d", &pc->data[pos].age);break;case 3:printf("请输入新的性别:>");scanf("%s", pc->data[pos].sex);break;case 4:printf("请输入新的电话:>");scanf("%s", pc->data[pos].tele);break;case 5:printf("请输入新的地址:>");scanf("%s", pc->data[pos].addr);break;default:printf("输入有误,修改失败\n");return;}printf("修改成功\n");
}void menu2()
{printf("***************************\n");printf("******** 1.NAME **********\n");printf("******** 2.AGE **********\n");printf("***************************\n");
}//按照名字排序
int cmp_byname(const void* p1, const void* p2)
{return strcmp(((PeoInfo*)p1)->name, ((PeoInfo*)p2)->name);
}//按照年龄来排序
int cmp_byage(const void* p1, const void* p2)
{return ((PeoInfo*)p1)->age - ((PeoInfo*)p2)->age;
}//排序联系人
void SqrtContact(Contact* pc)
{int input = 0;if (pc->sz == 0){printf("通讯录没有联系人,无法排序!\n");return;}menu2();printf("请选择排序的对象:>");scanf("%d", &input);switch (input){case 1:qsort(pc, pc->sz, sizeof(PeoInfo), cmp_byname);break;case 2:qsort(pc, pc->sz, sizeof(PeoInfo), cmp_byage);break;}printf("排序成功\n");//排序成功之后打印一下ShowContact(pc);
}//清空联系人
void ClearContact(Contact* pc)
{//初始化通讯录InitContact(pc);printf("清空成功\n");//初始完之后再打印ShowContact(pc);
}
关于通讯录的代码就展现在这里了,但是这只是静态版本,还有很多的不足,当退出程序后下一次再进入程序我们之前的信息就回收了,还有各个数组的大小都是固定的,没办法随时随地的变化,在后面也会补发上关于通讯录的动态版本的代码,最后感谢大家的支持!谢谢
相关文章:
C语言小程序:通讯录(静态版)
哈喽各位老铁们,今天给大家带来一期通讯录的静态版本的实现,何为静态版本后面会做解释,话不多说,直接开始!关于通讯录,其实也就是类似于我们手机上的通讯录一样,有着各种各样的功能,…...
写CSDN博客两年半的收获--总结篇
👨💻作者简介:练习时长两年半的java博主 🎟️个人主页:君临๑ ps:点赞是免费的,却可以让写博客的作者开心好几天😎 不知不觉间,在csdn写博客也有两年半的时间了&#x…...
中科亿海微FPGA应用(一、点灯)
1.软件: https://download.csdn.net/download/weixin_41784968/87564071 需要申请license才能使用:软件试用申请_软件试用申请_中科亿海微电子科技(苏州)有限公司 2.开发板: 芯片EQ6HL45,42.5k LUT。 3…...
ElasticSearch - SpringBoot整合ES:实现搜索结果排序 sort
文章目录00. 数据准备01. Elasticsearch 默认的排序方式是什么?02. Elasticsearch 支持哪些排序方式?03. ElasticSearch 如何指定排序方式?04. ElasticSearch 如何按照相关性排序?05. ElasticSearch 查询结果如何不按照相关性排序…...
IDEA的全新UI可以在配置里启用了,快来试试吧!
刚看到IDEA官方昨天发了这样一条推:IDEA的新UI可以在2022.3版本上直接使用了!开启方法如下:打开IDEA的Setting界面,在Appearance & Behavior下有个被标注为Beta标签的New UI菜单,具体如下图:勾选Enable…...
第九章 镜像架构和规划 - 备份处于活动状态时自动进行故障转移
文章目录第九章 镜像架构和规划 - 备份处于活动状态时自动进行故障转移备份处于活动状态时自动进行故障转移备份不活动时的自动故障转移对各种中断场景的镜像响应响应主要中断场景的自动故障转移第九章 镜像架构和规划 - 备份处于活动状态时自动进行故障转移 备份处于活动状态…...
Barra模型因子的构建及应用系列七之Liquidity因子
一、摘要 在前期的Barra模型系列文章中,我们构建了Size因子、Beta因子、Momentum因子、Residual Volatility因子、NonLinear Size因子和Book-to-Price因子,并分别创建了对应的单因子策略,其中Size因子和NonLinear Siz因子具有很强的收益能力…...
走进二叉树的世界 ———性质讲解
二叉树的性质和证明前言1.二叉树的概念和结构特殊的二叉树:二叉树的性质前言 本篇博客主要讲述的是有关二叉树的一些概念,性质以及部分性质的相关证明,如果大伙发现了啥错误,可以在评论区指出😘😘 1.二叉树…...
【SSM】Spring + SpringMVC +MyBatis 框架整合
个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ SSM框架整合一、导入相关依赖二、配置web.xml文…...
【算法基础】一篇文章彻底弄懂Dijkstra算法|多图解+代码详解
博主简介:努力学习的大一在校计算机专业学生,热爱学习和创作。目前在学习和分享:算法、数据结构、Java等相关知识。博主主页: 是瑶瑶子啦所属专栏: 算法 ;该专栏专注于蓝桥杯和ACM等算法竞赛🔥近期目标&…...
第二十三天01MySQL多表查询与事务
目录 1. 多表查询 1.1 概述 1.1.1 数据准备 1.1.2 介绍 1.1.3 分类 1.2 内连接 1.2.1 语法 1.2.2 案例演示 1.3 外连接 1.3.1 语法 1.3.2 案例演示 1.4 子查询 1.4.1 介绍 1.4.2 标量子查询 1.4.3 列子查询 1.4.4 行子查询 1.4.5 表子查询 1.5 案例 1.5.1 介…...
TCP协议详解
1.TCP的准备条件在古代的时候,古人们经常写书信进行交流,写书信的前提是你要知道这份信是要寄给谁在网络中,我们通过ip端口号找对目标对象,但是现在网站一般会对ip端口注册一个域名,所以我们一般就是对域名进行查找&am…...
Activiti7与Spring、Spring Boot整合开发
Activiti整合Spring 一、Activiti与Spring整合开发 1.1 Activiti与Spring整合的配置 1)、在pom.xml文件引入坐标 如下 <properties><slf4j.version>1.6.6</slf4j.version><log4j.version>1.2.12</log4j.version> </properties> <d…...
基于SpringBoot实现冬奥会运动会科普平台【源码+论文】
基于SpringBoot实现冬奥会科普平台演示开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包&#…...
一文吃透SpringBoot整合mybatis-plus(保姆式教程)
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
C++ primer plus(第六版)编程练习答案 第4章 复合类型
一、程序清单 arrayone.cpp // arrayone.cpp -- small arrays of integers #include <iostream> int main() {using namespace std;int yams[3]; // creates array with three elementsyams[0] = 7; // assign value to first elementyams[1] = 8;yams[2] = 6;i…...
Kafka源码分析之Producer(一)
总览 根据kafka的3.1.0的源码example模块进行分析,如下图所示,一般实例代码就是我们分析源码的入口。 可以将produce的发送主要流程概述如下: 拦截器对发送的消息拦截处理; 获取元数据信息; 序列化处理;…...
springboot校友社交系统
050-springboot校友社交系统演示录像开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:e…...
python flask项目部署
flask上传服务器pyhon安装下载Anacondasudo wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.3.1-Linux-x86_64.sh可根据需要安装对应的版本https://repo.anaconda.com/archive/解压anaconda压缩包bash Anaconda3-5.3.1-Linux-x86_64.sh解压过程中会…...
常见排序算法(C语言实现)
文章目录排序介绍插入排序直接插入排序希尔排序选择排序选择排序堆排序交换排序冒泡排序快速排序递归实现Hoare版本挖坑法前后指针版本非递归实现Hoare版本挖坑法前后指针版本快排的优化三值取中小区间优化归并排序递归实现非递归实现计数排序排序算法复杂度及稳定性分析不同算…...
基于jsp+ssm+springboot的小区物业管理系统【设计+论文+源码】
摘 要随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于小区物业管理系统当然也不能排除在外,随着网络技术的不断成熟,带动了小区物业管理系统,它彻底改变了过去…...
Elasticsearch 学习+SpringBoot实战教程(三)
需要学习基础的可参照这两文章 Elasticsearch 学习SpringBoot实战教程(一) Elasticsearch 学习SpringBoot实战教程(一)_桂亭亭的博客-CSDN博客 Elasticsearch 学习SpringBoot实战教程(二) Elasticsearch …...
try-with-resource
try-with-resource是Java 7中引入的新特性,它可以方便地管理资源,自动关闭资源,从而避免了资源泄漏的问题。 作用 使用try-with-resource语句可以简化代码,避免了手动关闭资源的繁琐操作,同时还可以保证资源的正确关闭…...
leetcode148_排序链表的3种解法
1. 题目2. 解答 2.1. 解法12.2. 解法22.3. 解法3 1. 题目 给你链表的头结点head,请将其按升序排列并返回排序后的链表。 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullp…...
使用stm32实现电机的PID控制
使用stm32实现电机的PID控制 PID控制应该算是非常古老而且应用非常广泛的控制算法了,小到热水壶温度控制,大到控制无人机的飞行姿态和飞行速度等等。在电机控制中,PID算法用的尤为常见。 文章目录使用stm32实现电机的PID控制一、位置式PID1.计…...
数学原理—嵌入矩阵
目录 1.嵌入矩阵的基本作用 2.嵌入矩阵的数学解释 3.嵌入矩阵在联合分布适应中的数学推导主要包括以下几个步骤 4.在JDA中,怎么得到嵌入矩阵 5.联合分布自适应中如何得到嵌入矩阵 (另一种解释) 1.嵌入矩阵的基本作用 在机器学习中&a…...
English Learning - L2 语音作业打卡 辅音翘舌音 [ʃ] [ʒ] 空气摩擦音 [h] Day31 2023.3.23 周四
English Learning - L2 语音作业打卡 辅音翘舌音 [ʃ] [ʒ] 空气摩擦音 [h] Day31 2023.3.23 周四💌发音小贴士:💌当日目标音发音规则/技巧:翘舌音 [ʃ] [ʒ]空气摩擦音 [h]🍭 Part 1【热身练习】🍭 Part2【练习内容】…...
记录springboot+vue+fastdfs实现简易的文件(上传、下载、删除、预览)操作
前言说明:springboot vue FastDFS实现文件上传(支持预览)升级版 FASTDFS部分 FASTDFS安装过程:基于centos 7安装FastDFS文件服务器 SpringBoot部分 springboot源码实现 package com.core.doc.controller;import com.baomid…...
Java中循环使用Stream应用场景
在JAVA中,涉及到对数组、Collection等集合类中的元素进行操作的时候,通常会通过循环的方式进行逐个处理,或者使用Stream的方式进行处理。例如,现在有这么一个需求:从给定句子中返回单词长度大于5的单词列表,…...
中国蚁剑AntSword实战
中国蚁剑AntSword实战1.基本使用方法2.绕过安全狗连接3.请求包修改UA特征伪造RSA流量加密4.插件使用1.基本使用方法 打开蚂蚁宝剑,右键添加数据: 输入已经上传马的路径和连接密码: 测试连接,连接成功! GetShell了&…...
谷歌上怎样做网站/郑州网站建设
thinkphp和wordpress区别ThinkPHPThinkPHP是一个快速、兼容而且简单的轻量级国产PHP开发框架,诞生于2006年初,原名FCS,2007年元旦正式更名为ThinkPHP,遵循Apache2开源协议发布,从Struts结构移植过来并做了改进和完善&a…...
精神文明建设委员会网站/关键词排名查询工具
state 和 props 主要的区别: 在于 props 是不可变的,而 state 可以根据与用户交互来改变。 组件需要定义 state 来更新和修改数据,子组件只能通过 props 来传递数据。 1.如何在组件中使用 props: <body> <div id&quo…...
邳州做网站的公司/b2b网站免费推广
于戴尔笔记本怎么重装系统呢?其实关于戴尔笔记本怎么重装系统的方法小编也是说过的了,但是还是有不少的用户不知道戴尔笔记本电脑怎么重装系统,接下来是小编为大家收集的dell2900如何重装系统,欢迎大家阅读。dell2900如何重装系统第一步、设…...
企业内部网站打不开/网络营销的职能是什么
文件夹 Directory类 静态类,无需实例化,引用 System.IO 命名空间即可使用 常用方法 //创建文件夹 Directory.CreateDirectory("D:\DownLoad");//判断文件夹是否存在 Directory.Exists("D:\DownLoad");//删除文件夹 空文件夹 Dir…...
网站怎么建立视频/百度网盘官网登陆入口
以前也想这个问题,程序还没有写如何测试呢?看下泥瓦匠如何工作的吧:工匠一:先拉一跟水平线,砌每一块砖时,都与这根水平线进行比较,使得每一块砖都保持水平;工匠二:先将一排砖砌完,然后拉一跟水平线,看看哪些砖有问题,然后进行调整.看过这则类比之后直想笑,第二个工匠真的很笨,…...
成都免费招聘网站/常州百度搜索优化
,之前看<<PostgreSQL数据库内核分析>>这本书,提到了postmaster进程,于是在我安装的PG 9.6.0中,ps -ef了一把,结果没找到,如下:[postgresrhel73 global]$ pwd /usr/local/pgsql/data/global [postgresrhel73 global]$ ps -ef | grep -i post root 2220 1 …...