通讯录的实现

  • 一.静态版本
    • 1.所需要的功能
    • 2.大致菜单
    • 3.创建通讯录
    • 4.增加联系人
    • 5.显示联系人
    • 6.查找联系人
    • 7.删除联系人
    • 8.修改联系人
    • 9.按名字排序
    • 10.源代码
  • 二.动态版本
    • 1.修改data数组
    • 2.修改初始化
    • 3.修改增加函数
    • 4.完善通讯录
    • 5.源代码
  • 三.文件版本
    • 1.退出前保存
    • 2.进入后读取
    • 3.源代码

一.静态版本

1.所需要的功能

对于通讯录来说,我们需要它实现以下几个功能。

1.人的信息:姓名+年龄+性别+电话+地址。
2.可以存放100个人的信息。
功能:
1>增加联系人。
2>删除联系人。
3>查找指定联系人信息。
4>修改指定联系人信息。
5>显示所有联系人信息。
6>按名字排序。

接下来分为三个模块,test.c->用来测试通讯录;contact.c->通讯录主体部分;contact.h->用于函数的声明。

2.大致菜单

#include"contact.h"void menu()
{printf("********************************\n");printf("****** 1.增加      2.删除 ******\n");printf("****** 3.查找      4.修改 ******\n");printf("****** 5.展示      6.排序 ******\n");printf("*******0.退出             ******\n");printf("********************************\n");}
int main()
{int input = 0;do{menu();scanf("%d", &input);switch (input){case 1:break;case 2:break;case 3:break;case 4:break;case 5:break;case 6:break;   case 0:printf("退出通讯录。\n");break;default:printf("输入无效,请重新输入。\n");break;}} while (input);return 0;
}

这一块很简单,就不再多说。菜单是属于测试部分,所以我将它放入test.c文件里。

3.创建通讯录

对于一个人,肯定有多方面的因数,所以将其封装在一个结构体内。这里使用到typedef,如果不太熟悉可以看看这篇博客typedef的使用

接下来,再封装一个结构体里面存放100个人的信息和当前人的个数。

接着在主函数里使用该结构体创建通讯录。然后进行初始化。

初始化函数在contact.h里声明。

在contact.c里实现,需要使用到memset,如果不太明白可以看看这篇博客memset如何使用

4.增加联系人

在contact.h里声明。

在contact.c里面实现。

5.显示联系人

在contact.h里声明。

在contact.c里实现。这里使用到\t,向后隔开8个字节,用于分隔。同时例如%-20s是右边隔开20个字节,也就是进行左对齐。

6.查找联系人

我们发现无论是查找,删除还是修改都需要先找到这个人。所以我们干脆将寻找封装成一个函数来使用。我们通过名字来查找(需要使用strcmp,如果不熟悉可以看看这篇博客strcmp的使用)

完成后正式进行查找。

老规矩,现在contact.h里进行声明。ps:前面的find不用声明是因为find只在contact.c里使用。

在contact.c里实现。

7.删除联系人

这里采用一种最简单的方法,就是从后往前依次覆盖。首先找到该名字的位置,然后依次将后面的往前挪。

在contact.h里声明。

在contact.c里实现。

8.修改联系人

老规矩在contact.h里进行声明。

在contact.c里实现。修改其实就是重新录入,找到位置,重新写一遍就好了。

9.按名字排序

下面排序需要使用到qsort函数。如果不太熟悉可以看看这篇博客qsort函数

老规矩在contact.h里声明。

在contact.c里实现。

好了,以上就是通讯录静态版本的实现功能啦,下面是源代码。

10.源代码

test.c

#include"contact.h"
void menu()
{printf("********************************\n");printf("****** 1.增加      2.删除 ******\n");printf("****** 3.查找      4.修改 ******\n");printf("****** 5.展示      6.排序 ******\n");printf("*******0.退出             ******\n");printf("********************************\n");}
int main()
{int input = 0;//创建通讯录Contact con;//该结构体包含100个人的信息和已填充人的个数//初始化通讯录InitContact(&con);//结构体传参do{menu();printf("请选择:");scanf("%d", &input);switch (input){case 1:AddContact(&con);break;case 2:Dlete(&con);break;case 3:Search(&con);break;case 4:Modify(&con);break;case 5:ShowContact(&con);break;case 6:Order(&con);break;case 0:printf("退出通讯录。\n");break;default:printf("输入无效,请重新输入。\n");break;}} while (input);return 0;
}

contact.h

#include<stdio.h>
#include<string.h>
#include<assert.h>//人的信息
typedef struct PeoInfo
{char name[20];int age;char sex[5];char addr[30];char tele[12];
}PeoInfo;typedef struct Contact
{PeoInfo data[100];//存放人的信息int sz;//当前已经放的信息个数
}Contact;//同理,这里也进行了重命名//声明初始化函数
void InitContact(Contact* pc);//声明增加联系人函数
void AddContact(Contact*pc);//声明显示联系人函数
void ShowContact(const Contact*pc);//声明查找函数
void Search(const Contact*pc);//查找依然不会改变,所以加上const//声明删除函数
void Dlete(Contact*pc);//声明修改函数
void Modify(Contact*pc);//声明排序函数
void Order(Contact*pc);

contact.c

#include"contact.h"//初始化函数的实现
void InitContact(Contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}//增加联系人
void AddContact(Contact* pc)
{assert(pc);//一个好的习惯判断是否为空指针(当然不加也没影响)if (pc->sz == 100){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].addr);printf("请输入电话:");scanf("%s", pc->data[pc->sz].tele);pc->sz++;//别忘了添加完一个人后向后走一步}//显示联系人
void ShowContact(const Contact* pc)//因为显示不会改变元素,所以最好加上const
{assert(pc);printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");//提示for (int i = 0; i < pc->sz; i++){printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].addr,pc->data[i].tele);}
}//找到特定联系人的位置
int FindByName(const Contact* pc, char name[])//两个参数,一个是通讯录里存的名字,一个是你要查找的名字
{for (int i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;//找到返回下标}}return -1;//没找到,返回-1
}//查找
void Search(const Contact* pc)
{assert(pc);char name[20] = { 0 };printf("请输入要查找的名字:");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("查无此人。\n");return;}//找到了,打印信息printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].addr,pc->data[pos].tele);
}//删除
void Dlete(Contact* pc)
{assert(pc);char name[20] = { 0 };printf("请输入要删除的名字:");scanf("%s", name);int dle = FindByName(pc, name);//找到位置if (dle == -1){printf("查无此人。\n");return;}for (int i = dle; i < pc->sz-1; i++)//从后往前覆盖,同时-1避免越界{pc->data[i] = pc->data[i + 1];}pc->sz--;//删除完成后别忘了个数-1printf("删除成功\n");
}//修改
void Modify(Contact* pc)
{assert(pc);char name[20] = { 0 };printf("请输入要修改的名字:");scanf("%s", name);int ret = FindByName(pc, name);if (-1 == ret){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].addr);printf("请输入电话:");scanf("%s", pc->data[ret].tele);printf("修改成功\n");
}//排序
int cmp(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void Order(Contact* pc)
{assert(pc);qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp);printf("排序成功\n");
}

二.动态版本

动态版本主要在静态版本的基础上加入扩容功能,如果通讯录已存满,那么会自动扩大通讯录,下面设置初始容量为三个人,如果不满足每次扩容两个人。需要的前置知识是动态内存,如果不太了解,可以看看这篇博客动态内存

1.修改data数组

上面的静态版本是直接开辟了一个100人的数组,很明显已经固定。所以应当将这100个人改为动态的。

静态版本

动态版本

2.修改初始化

在静态版本的初始化里直接使用的memset指定具体的字节数来初始化。在动态版本里不知道具体的大小,很明显不能这么暴力。下面使用calloc对data进行开辟空间的同时完成初始化。

静态版本

动态版本

3.修改增加函数

在静态版本中,如果一直增加联系人到通讯录满后直接给提升:通讯录已满,不能再加入。在动态版本里需要修改,当放满通讯录后自动扩容。

静态版本

动态版本

4.完善通讯录

上面的修改大致功能没有问题了,但还有个缺陷是在开辟空间时我们在堆区上开辟的,所以在程序结束时应当主动free,避免内存泄漏。

在test.c里


在contact.h里

在contact.c里

演示

5.源代码

test.c

#include"contact.h"
void menu()
{printf("********************************\n");printf("****** 1.增加      2.删除 ******\n");printf("****** 3.查找      4.修改 ******\n");printf("****** 5.展示      6.排序 ******\n");printf("*******0.退出             ******\n");printf("********************************\n");}
int main()
{int input = 0;//创建通讯录Contact con;//该结构体包含100个人的信息和已填充人的个数//初始化通讯录InitContact(&con);//结构体传参do{menu();printf("请选择:");scanf("%d", &input);switch (input){case 1:AddContact(&con);break;case 2:Dlete(&con);break;case 3:Search(&con);break;case 4:Modify(&con);break;case 5:ShowContact(&con);break;case 6:Order(&con);break;case 0:Destroy(&con);printf("退出通讯录。\n");break;default:printf("输入无效,请重新输入。\n");break;}} while (input);return 0;
}

contact.h

#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>#define DEFAULT_SZ 3 //初始大小
#define INC_SZ 2 //每次扩容//人的信息
typedef struct PeoInfo
{char name[20];int age;char sex[5];char addr[30];char tele[12];
}PeoInfo;//动态版本
typedef struct Contact
{PeoInfo *data;//指向存放人信息的空间int sz;//当前已经放的信息个数int capacity;//当前通讯录的最大容量
}Contact;//声明初始化函数
void InitContact(Contact* pc);//声明销毁函数
void Destroy(Contact* pc);//声明增加联系人函数
void AddContact(Contact*pc);//声明显示联系人函数
void ShowContact(const Contact*pc);//声明查找函数
void Search(const Contact*pc);//查找依然不会改变,所以加上const//声明删除函数
void Dlete(Contact*pc);//声明修改函数
void Modify(Contact*pc);//声明排序函数
void Order(Contact*pc);

contact.c

#include"contact.h"//初始化函数的实现,动态版本
void InitContact(Contact* pc)
{pc->sz = 0;PeoInfo* ptr = (PeoInfo*)calloc(DEFAULT_SZ,sizeof(PeoInfo));//开辟初始空间if (ptr == NULL){printf("%s", strerror(errno));return;}//判断是否空间开辟成功pc->data = ptr;pc->capacity = DEFAULT_SZ;//初始容量为3
}//销毁
void Destroy(Contact* pc)
{free(pc->data);//由于整个data都是在堆区上开辟的,所以直接freepc->data = NULL;pc->capacity = 0;pc->sz = 0;pc = NULL;
}void check_capacity(Contact* pc)
{if (pc->sz == pc->capacity)//如果容量已满{//增加容量PeoInfo* ptr =(PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));//调整空间大小if (ptr == NULL){printf("%s", strerror(errno));}pc->data = ptr;//把新空间的起始位置传给datapc->capacity += INC_SZ;//最大容量加INC_SZprintf("增容成功\n");}
}
//增加联系人
void AddContact(Contact* pc)
{assert(pc);check_capacity(pc);//检查容量,判断是否需要增容//开始添加信息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].addr);printf("请输入电话:");scanf("%s", pc->data[pc->sz].tele);pc->sz++;//别忘了添加完一个人后向后走一步}//显示联系人
void ShowContact(const Contact* pc)//因为显示不会改变元素,所以最好加上const
{assert(pc);printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");//提示for (int i = 0; i < pc->sz; i++){printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].addr,pc->data[i].tele);}
}//找到特定联系人的位置
int FindByName(const Contact* pc, char name[])//两个参数,一个是通讯录里存的名字,一个是你要查找的名字
{for (int i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;//找到返回下标}}return -1;//没找到,返回-1
}//查找
void Search(const Contact* pc)
{assert(pc);char name[20] = { 0 };printf("请输入要查找的名字:");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("查无此人。\n");return;}//找到了,打印信息printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].addr,pc->data[pos].tele);
}//删除
void Dlete(Contact* pc)
{assert(pc);char name[20] = { 0 };printf("请输入要删除的名字:");scanf("%s", name);int dle = FindByName(pc, name);//找到位置if (dle == -1){printf("查无此人。\n");return;}for (int i = dle; i < pc->sz-1; i++)//从后往前覆盖,同时-1避免越界{pc->data[i] = pc->data[i + 1];}pc->sz--;//删除完成后别忘了个数-1printf("删除成功\n");
}//修改
void Modify(Contact* pc)
{assert(pc);char name[20] = { 0 };printf("请输入要修改的名字:");scanf("%s", name);int ret = FindByName(pc, name);if (-1 == ret){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].addr);printf("请输入电话:");scanf("%s", pc->data[ret].tele);printf("修改成功\n");
}//排序
int cmp(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void Order(Contact* pc)
{assert(pc);qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp);printf("排序成功\n");
}

三.文件版本

我们可以发现前面两个版本在运行结束后通讯录里的信息就自动删除了,很明显是不符合我们的预期的。这是因为上面的数据都储存在内存中,而内存在一次程序运行结束后会重置,所以我们需要将其写在硬盘上(文件里),才能保证信息的存储。(需要的前置知识是文件操作,如果不太熟悉可以看看这篇博客文件操作)

1.退出前保存

test.c里

contact.h里


contact.c里

注意文件可以建在任意位置,但如果不是在当前路径下,在fopen时记得将该文件的绝对路径写上(也就是几盘,第几文件夹…)

2.进入后读取

原来初始化通讯录时是直接初始化为0,现在初始化时将文件里的信息加载到通讯录里。



3.源代码

test.c

#include"contact.h"
void menu()
{printf("********************************\n");printf("****** 1.增加      2.删除 ******\n");printf("****** 3.查找      4.修改 ******\n");printf("****** 5.展示      6.排序 ******\n");printf("*******0.退出             ******\n");printf("********************************\n");}
int main()
{int input = 0;//创建通讯录Contact con;//该结构体包含100个人的信息和已填充人的个数//初始化通讯录InitContact(&con);//结构体传参do{menu();printf("请选择:");scanf("%d", &input);switch (input){case 1:AddContact(&con);break;case 2:Dlete(&con);break;case 3:Search(&con);break;case 4:Modify(&con);break;case 5:ShowContact(&con);break;case 6:Order(&con);break;case 0:SaveContact(&con);Destroy(&con);printf("退出通讯录。\n");break;default:printf("输入无效,请重新输入。\n");break;}} while (input);return 0;
}

contact.h

#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>#define DEFAULT_SZ 3 //初始大小
#define INC_SZ 2 //每次扩容//人的信息
typedef struct PeoInfo
{char name[20];int age;char sex[5];char addr[30];char tele[12];
}PeoInfo;//动态版本
typedef struct Contact
{PeoInfo *data;//指向存放人信息的空间int sz;//当前已经放的信息个数int capacity;//当前通讯录的最大容量
}Contact;//声明初始化函数
void InitContact(Contact* pc);//声明销毁函数
void Destroy(Contact* pc);//声明增加联系人函数
void AddContact(Contact*pc);//声明显示联系人函数
void ShowContact(const Contact*pc);//声明查找函数
void Search(const Contact*pc);//查找依然不会改变,所以加上const//声明删除函数
void Dlete(Contact*pc);//声明修改函数
void Modify(Contact*pc);//声明排序函数
void Order(Contact*pc);//声明保存函数
void SaveContact(Contact*pc);//声明加载通讯录函数
void LoadContact(Contact*pc);

contact.c

#include"contact.h"//初始化函数的实现
void InitContact(Contact* pc)
{pc->sz = 0;PeoInfo* ptr = (PeoInfo*)calloc(DEFAULT_SZ,sizeof(PeoInfo));//开辟初始空间if (ptr == NULL){printf("%s", strerror(errno));return;}//判断是否空间开辟成功pc->data = ptr;pc->capacity = DEFAULT_SZ;//初始容量为3//加载数据到通讯录LoadContact(pc);
}//销毁
void Destroy(Contact* pc)
{free(pc->data);//由于整个data都是在堆区上开辟的,所以直接freepc->data = NULL;pc->capacity = 0;pc->sz = 0;pc = NULL;
}void check_capacity(Contact* pc)
{if (pc->sz == pc->capacity)//如果容量已满{//增加容量PeoInfo* ptr =(PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));//调整空间大小if (ptr == NULL){printf("%s", strerror(errno));}pc->data = ptr;//把新空间的起始位置传给datapc->capacity += INC_SZ;//最大容量加INC_SZprintf("增容成功\n");}
}
//增加联系人
void AddContact(Contact* pc)
{assert(pc);check_capacity(pc);//检查容量,判断是否需要增容//开始添加信息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].addr);printf("请输入电话:");scanf("%s", pc->data[pc->sz].tele);pc->sz++;//别忘了添加完一个人后向后走一步}//显示联系人
void ShowContact(const Contact* pc)//因为显示不会改变元素,所以最好加上const
{assert(pc);printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");//提示for (int i = 0; i < pc->sz; i++){printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].addr,pc->data[i].tele);}
}//找到特定联系人的位置
int FindByName(const Contact* pc, char name[])//两个参数,一个是通讯录里存的名字,一个是你要查找的名字
{for (int i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;//找到返回下标}}return -1;//没找到,返回-1
}//查找
void Search(const Contact* pc)
{assert(pc);char name[20] = { 0 };printf("请输入要查找的名字:");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("查无此人。\n");return;}//找到了,打印信息printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].addr,pc->data[pos].tele);
}//删除
void Dlete(Contact* pc)
{assert(pc);char name[20] = { 0 };printf("请输入要删除的名字:");scanf("%s", name);int dle = FindByName(pc, name);//找到位置if (dle == -1){printf("查无此人。\n");return;}for (int i = dle; i < pc->sz-1; i++)//从后往前覆盖,同时-1避免越界{pc->data[i] = pc->data[i + 1];}pc->sz--;//删除完成后别忘了个数-1printf("删除成功\n");
}//修改
void Modify(Contact* pc)
{assert(pc);char name[20] = { 0 };printf("请输入要修改的名字:");scanf("%s", name);int ret = FindByName(pc, name);if (-1 == ret){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].addr);printf("请输入电话:");scanf("%s", pc->data[ret].tele);printf("修改成功\n");
}//排序
int cmp(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void Order(Contact* pc)
{assert(pc);qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp);printf("排序成功\n");
}//保存
void SaveContact(Contact* pc)
{//第一步打开文件FILE* pf = fopen("contact.txt", "wb");if (pf == NULL){perror("fopen:");}else{//写数据,一个人一个人的写//data数组里一个元素就是一个结构体,也就是一个人for (int i = 0; i < pc->sz; i++){fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);}fclose(pf);pf = NULL;printf("保存成功\n");}
}//加载通讯录
void LoadContact(Contact* pc)
{//打开文件FILE*pf=fopen("contact.txt", "rb");if (pf == NULL){perror("LoadCContact:");}else{//读取文件PeoInfo tmp = { 0 };int i = 0;while (fread(&tmp, sizeof(PeoInfo), 1, pf))//一次读一个人,如果读取完毕返回0{//写数据//由于在退出时销毁了通讯录,所以回到初始大小,如果存储的数据打于初始容量,需要扩容check_capacity(pc);//检查是否需要扩容,如果需要就扩容pc->data[i] = tmp;pc->sz++;i++;}fclose(pf);pf = NULL;}
}

通讯录的实现(静态版本,动态版本,文件版本)(后附完整源代码)相关推荐

  1. FFmpeg:进行qsv加速转码,以及如何动态更改编码器的选项(附完整源代码)

    FFmpeg:进行qsv加速转码,以及如何动态更改编码器的选项 #include <stdio.h> #include <errno.h> #include <libav ...

  2. JavaScript实现截留雨水问题的动态编程方法算法(附完整源码)

    JavaScript实现截留雨水问题的动态编程方法算法(附完整源码) dpRainTerraces.js完整源代码 dpRainTerraces.tset.js完整源代码 dpRainTerraces ...

  3. Silverlight 2动态创建矩形对象(附完整源代码)

    Silverlight 2动态创建矩形对象(附完整源代码)[转] 使用Silverlight 2的Canvas,写了一个动态创建Rectangle的示例,由于时间的原因所以难免有些不足之处,但程序功能 ...

  4. C语言小项目 -- 通讯录(静态版+动态版+文件版)

    文章目录 一.总体设计思路 1.设计背景 2.设计框架 3.功能概述 二.通讯录(静态版) 1.结构体设计 2.初始化通讯录 3.添加联系人信息 4.删除联系人信息 5.查找联系人(按姓名) 6.查找 ...

  5. MP3制作之LRC歌词文件解析(附:源代码)

    LRC 歌词同步 一.准备工作   既然要制作歌词同步程序,首先要准备一首歌,我们就以"周杰伦-青花瓷"为例.首先要下载这首"青花瓷.mp3",保存为" ...

  6. (静态,动态,文件)三个版本的通讯录

  7. 【C】信息管理系统/通讯录通用模板(介绍静态、动态、文件三个版本)

    ✨博客主页: XIN-XIANG荣 ✨系列专栏:[从0到1,C语言学习] ✨一句短话:你若盛开,蝴蝶自来! ✨博客说明:尽己所能,把每一篇博客写好,帮助自己熟悉所学知识,也希望自己的这些内容可以帮助到 ...

  8. OpenCV输出版本和构建配置的实例(附完整代码)

    OpenCV输出版本和构建配置的实例 OpenCV输出版本和构建配置的实例 OpenCV输出版本和构建配置的实例 #include <opencv2/core/utility.hpp> # ...

  9. 简易通讯录的实现(c语言,后附完整代码)

    今天我要介绍的是通讯录的实现(c语言) 首先先简单说一下思路吧. 一共需要三个文件分别为test.c(测试通讯录),contact.h(所需函数及头文件),contact.c(通讯录功能实现).因为通 ...

最新文章

  1. Hadoop集群搭建(七:MySQL的安装配置)
  2. 3D视觉应用开发--机器人3D互动四大技术难点分析
  3. Bootstrap——优秀的开源前端框架
  4. UA MATH564 概率论 QE练习题1
  5. elk 第二篇 , 为elk加入redis, 替换下beats(个人感觉不错2)
  6. 【C语言基础】C语言异常捕获机制 - assert
  7. POJ 1804 Brainman (归并排序 -- 求逆序对数)
  8. 汇编语言比C51需要效率高,汇编语言与C51语言实现跑马灯实验的比较 -
  9. matlab imagesc参数设置,[转载]matlab 中imagesc的用法
  10. js 正则练习之语法高亮
  11. mybatis mysql merge_Spring Boot + Mybatis 整合Mysql ,SQLServer数据源以及整合druid,动态调整数据源切换。...
  12. BoneCP主要配置参数
  13. 计算机应用基础第四版答案周南岳,计算机应用基础周南岳答案.docx
  14. 怎样在命令行下检测和清除恶意软件
  15. 2100 年的世界会怎样?用遥感数据预测未来城市
  16. 物流学哪方面计算机知识,物流说丨物流专业的毕业生应该具备的6大技能
  17. Typora超级纯净免费记笔记软件分享给大家
  18. linux中uboot作用,uboot的作用和启动方式
  19. 永不止步,南卡新品Runner Pro3上市,刷新最高配置
  20. 计算机入门基础知识大全

热门文章

  1. autocad不能画图_说说基本的画图软件—AutoCAD(一)
  2. 小题目——给出n阶方阵里所有的数,求方阵里所有数的和
  3. Android 10 系统屏蔽底部按键 禁止锁屏 禁用横屏
  4. 3_Semantic Pitfalls 语义错误
  5. Spring学习之旅(二) AOP(面向切面编程)的使用
  6. 女生适合学数据分析吗
  7. java学习之JDO
  8. 两个对象数组去重的3种方法
  9. c语言编程斐波那契前n项,c语言:写一个函数,输入n,求斐波拉契数列的第n项(5种方法,层层优化)...
  10. 1990-2021年汇率年平均价数据