遵义新蓝外国语学校网站建设,什么网站容易收录,新闻热点事件2021(最新)10月,公司网站要备案么目录 静态简易通讯录
代码#xff1a;
功能模块展示#xff1a;
设计思路#xff1a;
动态简易通讯录#xff08;本质顺序表#xff09;
代码#xff1a;
扩容模块展示#xff1a;
设计思路#xff1a;
文件版本通讯录
代码#xff1a;
文件模块展示#x…目录 静态简易通讯录
代码
功能模块展示
设计思路
动态简易通讯录本质顺序表
代码
扩容模块展示
设计思路
文件版本通讯录
代码
文件模块展示
设计思路 静态简易通讯录
代码
//头文件内容#pragma once#include stdio.h
#include string.h
#include assert.h
#include stdlib.h//声明一个枚举类型增加主程序代码switch部分可读性
enum method
{EXIT,ADD,DELETE,FIND,MODIFY,SHOW,DESTROY,SORT
};//定义标识符常量便于对数据大小修改
#define MAX_NAME 20
#define MAX_SEX 6
#define MAX_TELEPHONE 12
#define MAX_ADDRESS 20
#define Max_PEOINFO 1000//定义一个联系人信息结构体类型
typedef struct PeoInfo
{char name[MAX_NAME];char sex[MAX_SEX];int age;char Telephone[MAX_TELEPHONE];char address[MAX_ADDRESS];
}PeoInfo;//创建一个联系人信息结构体数组和计数联系人个数的变量组成联系人结构体
typedef struct Contact
{PeoInfo data[Max_PEOINFO];int sz;
}Contact;//初始化通讯录
void InitContact(Contact* pc);//增加联系人函数
void AddContact(Contact* pc);//展示所有联系人函数
void ShowContact(Contact* pc);//删除联系人函数
void DeleteContact(Contact* pc);//查找联系人函数
void FindContact(Contact* pc);//修改联系人函数
void ModifyContact(Contact* pc);//清空联系人函数
void DestroyContact(Contact* pc);//对联系人排序函数
void SortContact(Contact* pc);//函数实现源文件内容//初始化函数
void InitContact(Contact* pc)
{assert(pc);//利用库函数将整个数组所有元素初始化为0memset(pc-data, 0, sizeof(pc-data));//通讯录没有联系人pc-sz 0;
}//增加联系人函数
void AddContact(Contact* pc)
{assert(pc);//通讯录已满情况if (pc-sz Max_PEOINFO){printf(通讯录已满\n);return;}//通讯录未满情况printf(请输入联系人的姓名:);scanf(%s, pc-data[pc-sz].name);printf(请输入联系人的性别:);scanf(%s, pc-data[pc-sz].sex);printf(请输入联系人的年龄:);scanf(%d, (pc-data[pc-sz].age));printf(请输入联系人的电话:);scanf(%s, pc-data[pc-sz].Telephone);printf(请输入联系人的地址:);scanf(%s, pc-data[pc-sz].address);//每增加一个联系人计数变量加1pc-sz pc-sz 1;printf(增加联系人成功\n);
}//为了便于局部调试程序先实现显示函数
//显示所有联系人
void ShowContact(Contact* pc)
{assert(pc);int i 0;//打印内容左对齐printf(%-20s\t%-6s\t%-4s\t%-12s\t%-20s\n, 姓名, 性别, 年龄, 电话, 地址);for (i 0; i pc-sz; i){printf(%-20s\t%-6s\t%-4d\t%-12s\t%-20s\n,pc-data[i].name,pc-data[i].sex,pc-data[i].age,pc-data[i].Telephone,pc-data[i].address);}
}//删除联系人时我们需要知道联系人在数组中的位置以名字删除联系人
//名字检索函数不需要在头文件中声明
//此函数无法在有同名联系人时精确找到联系人
int ModifyName(char* str, Contact* pc)
{assert(pc str);int i 0;//遍历已经存储了联系人的数组元素寻找第一个名字相符的联系人并返回下标for (i 0; i pc-sz; i){if (0 strcmp(str, pc-data[i].name))return i;}//找不到return -1;
}//删除指定联系人
//此函数无法在有同名联系人时精确删除联系人
void DeleteContact(Contact* pc)
{assert(pc);//以名字查找指定联系人char name[MAX_NAME] { 0 };printf(请输入要删除的联系人的名字\n);scanf(%s, name);int num ModifyName(name, pc);//找到了if (num ! -1){int i 0;for (i num; i pc-sz; i){memcpy(pc-data i, pc-data (i 1), sizeof(PeoInfo));}//删除后计数变量减1pc-sz pc-sz - 1;printf(删除成功\n);}//没找到elseprintf(删除失败找不到指定联系人\n);
}//查找指定联系人
//此函数无法在有同名联系人时精确查找联系人
void FindContact(Contact* pc)
{assert(pc);//以名字查找指定联系人char name[MAX_NAME] { 0 };printf(请输入要查找的联系人的名字\n);scanf(%s, name);//调用上面定义的名字检索函数int num ModifyName(name, pc);//找到了打印此联系人信息if (num ! -1){printf(%-20s\t%-6s\t%-4s\t%-12s\t%-20s\n, 姓名, 性别, 年龄, 电话, 地址);printf(%-20s\t%-6s\t%-4d\t%-12s\t%-20s\n,pc-data[num].name,pc-data[num].sex,pc-data[num].age,pc-data[num].Telephone,pc-data[num].address);}//找不到elseprintf(找不到指定联系人\n);
}//修改指定联系人
void ModifyContact(Contact* pc)
{assert(pc);//以名字查找指定联系人char name[MAX_NAME] { 0 };printf(请输入要修改的联系人的名字\n);scanf(%s, name);//调用名字检索函数int num ModifyName(name, pc);//找到后重新输入此联系人信息if (num ! -1){printf(请输入新的姓名\n);scanf(%s, pc-data[num].name);printf(请输入新的性别\n);scanf(%s, pc-data[num].sex);printf(请输入新的年龄\n);scanf(%d, (pc-data[num].age));printf(请输入新的电话\n);scanf(%s, pc-data[num].Telephone);printf(请输入新的地址\n);scanf(%s, pc-data[num].address);printf(修改联系人成功\n);}//找不到elseprintf(找不到指定联系人\n);
}//清空所有联系人
void DestroyContact(Contact* pc)
{assert(pc);//调用初始化函数将联系人结构体初始化InitContact(pc);printf(联系人已清空\n);
}//拓展功能
//以名字对所有联系人升序排序
void SortContact(Contact* pc)
{assert(pc);int i 0;//选择排序for (i 0; i pc-sz - 1; i){int j i;for (j i; j pc-sz; j){if (strcmp(pc-data[i].name, pc-data[j].name) 0){PeoInfo tmp;memcpy(tmp, pc-data[i].name, sizeof(PeoInfo));memcpy(pc-data[i].name, pc-data[j].name, sizeof(PeoInfo));memcpy(pc-data[j].name, tmp, sizeof(PeoInfo));}}}printf(排序完成\n);
}//主程序源文件内容//菜单
void menu()
{printf(****** 1.ADD 2.DELETE ********\n);printf(****** 3.FIND 4.MODIFY ********\n);printf(****** 5.SHOW 6.DESTROY********\n);printf(****** 7.SORT 0.EXIT ********\n);
}void test()
{//定义一个通讯录结构体变量Contact con;//初始化InitContact(con);enum method input 0;do{menu();printf(请选择你的操作\n);scanf(%d, input);switch (input){case ADD:AddContact(con);break;case DELETE:DeleteContact(con);break;case FIND:FindContact(con);break;case MODIFY:ModifyContact(con);break;case SHOW:ShowContact(con);break;case DESTROY:DestroyContact(con);break;case SORT:SortContact(con);break;case EXIT:printf(程序已退出\n);break;default:printf(输入错误请重新输入:\n);break;}} while (input);
}
int main()
{test();return 0;
}
功能模块展示
增加功能 删除功能 查找功能 修改功能 拓展功能 设计思路 要实现一个简易版静态通讯录无非是在实现增删查改的基础上进行进一步的功能拓展因此设计的重点是在增删查改的功能实现上静态版本存储通讯录内容的是定长数组因此要实现这些功能我们需要围绕数组下标和已经存储的联系人个数作为文章。 只要知道已经存储的联系人个数增加联系人就会变得轻而易举。而删除查找修改联系人时都必须先找到要操作的联系人因此我们需要先实现一个检索联系人接口供它们调用此接口实现的越精确删查改就会越精确。 为了方便对数组下标进行操作将计数联系人个数的变量和记录联系人信息的数组都作为通讯录结构体的成员计数变量从0开始每增加一个联系人就加1删除减1这样我们就会得到通讯录的实时大小从而可以非常容易的操作通讯录实现通讯录的功能也就变的非常简单。 动态简易通讯录本质顺序表
代码
动态版本的代码只需在静态版本上稍作修改即可。
//头文件增加和修改的内容//初始容量
#define INIT_SZ 3
//每次扩容增加容量
#define ADD_SZ 2//修改后通讯录结构体
typedef struct Contact
{//PeoInfo data[Max_PEOINFO];//用结构体指针代替结构体数组PeoInfo* data;int sz;//增加一个记录通讯录容量的变量int capacity;
}Contact;//函数实现源文件增加和修改的内容//动态版本初始化函数
void InitContact(Contact* pc)
{assert(pc);//先开辟INIT_SZ个空间pc-data (PeoInfo*)malloc(INIT_SZ * sizeof(PeoInfo));//开辟失败if (pc-data NULL){perror(InitContact);return;}pc-sz 0;//记录容量pc-capacity INIT_SZ;
}//增加联系人时需要先检查容量是否已满若满则增加容量
//空间动态增长无需在头文件中声明
int mallocContact(Contact* pc)
{assert(pc);//已满if (pc-sz pc-capacity){//扩容PeoInfo* ptr (PeoInfo*)realloc(pc-data, (pc-capacity ADD_SZ) * sizeof(PeoInfo));//扩容失败if (ptr NULL){perror(mallocContact);return 0;}//扩容成功else{pc-data ptr;pc-capacity ADD_SZ;printf(扩容成功\n);return 1;}}//未满return 1;
}//动态版本增加函数
void AddContact(Contact* pc)
{assert(pc);//扩容失败if (0 mallocContact(pc)){return;}//未满或扩容成功printf(请输入联系人的姓名\n);scanf(%s, pc-data[pc-sz].name);printf(请输入联系人的性别\n);scanf(%s, pc-data[pc-sz].sex);printf(请输入联系人的年龄\n);scanf(%d, (pc-data[pc-sz].age));printf(请输入联系人的电话\n);scanf(%s, pc-data[pc-sz].Telephone);printf(请输入联系人的地址\n);scanf(%s, pc-data[pc-sz].address);pc-sz pc-sz 1;printf(增加联系人成功\n);}//动态版本清空函数
void DestroyContact(Contact* pc)
{assert(pc);free(pc-data);pc-data NULL;pc-sz 0;pc-capacity 0;printf(联系人已清空\n);
}
扩容模块展示 设计思路 静态版本的通讯录十分死板需要存储的数据少了就会存在空间浪费多了又会不够因此衍生出动态版本来解决这一问题当存储空间不够时就向内存申请新的空间来增加容量更加灵活。 为了实现实时向内存申请空间需要一个变量用来记录通讯录结构体的容量当存储的联系人个数等于容量时就需要进行扩容同时由于通讯录的大小是动态变化的因此用结构体指针替代结构体数组来维护存储空间。 由于每次扩容后的存储空间依然是连续的因此在没有发生访问越界时可以像操作数组一样操作指针静态版本的大多数代码都无需修改。 文件版本通讯录
代码
在动态版本上稍作修改。
//函数实现源文件增加和修改的内容//容量检查函数声明
int mallocContact(Contact* pc);//初始化时需要先读取文件contact.dat的内容到data中去
void LoadContact(Contact* pc)
{//打开文件FILE* pf fopen(contact.dat, rb);//若路径下没有此文件则打开文件失败if (pf NULL){perror(LoadContact);return;}PeoInfo tmp { 0 };//读文件while (fread(tmp, sizeof(PeoInfo), 1, pf)){//扩容判断if (0 mallocContact(pc))return;pc-data[pc-sz] tmp;//每读取一个计数变量加1pc-sz;}//关闭文件fclose(pf);pf NULL;
}//动态版本初始化函数
void InitContact(Contact* pc)
{assert(pc);pc-data (PeoInfo*)malloc(INIT_SZ * sizeof(PeoInfo));if (pc-data NULL){perror(InitContact);return;}pc-sz 0;pc-capacity INIT_SZ;//载入文件内容LoadContact(pc);
}//将通讯录信息以二进制形式保存到contact.dat文件中
void SaveContact(Contact* pc)
{//打开文件若路径下没有此文件则新建一个此文件FILE* pf fopen(contact.dat, wb);if (pf NULL){perror(SaveContact);return;}int i 0;for (i 0; i pc-sz; i){//写入文件fwrite(pc-data i, sizeof(PeoInfo), 1, pf);}//关闭文件fclose(pf);pf NULL;printf(通讯录内容已保存到contact.dat文件中\n);
}//主程序源文件修改内容case EXIT://在退出程序时将内存中的信息保存到文件中去SaveContact(con);printf(程序已退出\n);break;
文件模块展示 设计思路 无论是静态版本还是动态版本联系人信息都是存储在内存中的一旦程序退出运行这些信息也会随之消失为了长久存储这些信息衍生出了文件版本的通讯录即利用文件操作函数将存储在内存中的信息存储到文件中长久保存。 我们只需要在动态版本的基础上增加一个读取文件函数和写入文件函数在程序开始时先将文件中的信息读取到内存中在程序退出时再将内存中的数据写回文件中即可。