建设导航网站费用吗,华为云 wordpress,泉州共创科技,请写出网站建设前期需要做的准备hello#xff0c;这期给大家带来C语言实现静态通讯录,主要也是建立起创建大项目的思维#xff0c;与往期这两篇博客有点类似 C语言实现三子棋 C语言实现扫雷 文章目录#x1f913;通讯录介绍#x1f636;#x1f32b;️效果演示#x1f920;主题框架头文件测试文件函数… hello这期给大家带来C语言实现静态通讯录,主要也是建立起创建大项目的思维与往期这两篇博客有点类似 C语言实现三子棋 C语言实现扫雷 文章目录通讯录介绍️效果演示主题框架头文件测试文件函数实现初始化显示添加删除查找修改排序清空通讯录不足之处通讯录介绍
通讯录存放的是100个联系人的信息这些信息包括
姓名年龄性别电话地址
通讯录要实现的功能有
添加联系人删除联系人查找联系人修改联系人的信息给通讯录排序打印通讯录销毁通讯录(清空所有联系人)
️效果演示
在正式开始实现之前我们来看一下最终的完结通讯录是怎么样的
主题框架
大文件至少分3个文件 text.c-逻辑测试文件comtact.c-函数定义文件contact.h-函数声明结构体定义等文件 头文件
知道了通讯录需要实现的功能后我们就可以给出头文件
#pragma once
#include stdio.h
#include assert.h
#include stdlib.h
#include string.h
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 13
#define MAX_ADDRESS 20
typedef struct PerInfo
{char name[MAX_NAME];int age;char sex[MAX_SEX];char tele[MAX_TELE];char address[MAX_ADDRESS];
}PeoInfo;typedef struct Contact
{PeoInfo data[MAX];int sz;
}Contact;enum Opreation
{EXIT,ADD,DELETE,SEARCH,MODIFY,SHOW,SORT,DESTROY
};void InitContact(Contact* con);
void AddContact(Contact* con);
//这里传地址节省开销
void ShowContact(const Contact* con);void DeleteContact(Contact* con);void SearchContact(const Contact* con);void ModifyContact( Contact* con);void SortContact(Contact* con);void DestroyContact(Contact* con);给出几点说明 通讯录是静态的最大可以存放100个联系人的信息所以我们需要定义变量sz表示当前有效元素的个数所以通讯录类型应该是结构体结构体成员是数组和有效元素个数数组的每个元素都是联系人的信息联系人的信息有姓名、年龄、性别、地址、电话等所以数组元素也是一个结构体将通讯录的功能设置为枚举变量~提高程序的可读性数组元素定义为符号常量,方便后续统一同意更改函数的参数都是结构体指针 这样参数传递时可以只开辟一个指针的大小可以通过结构体指针改变结构体的内容 测试文件
#define _CRT_SECURE_NO_WARNINGS 1
#include contact.hvoid menu()
{printf(***********Contact***********\n);printf(****1. add 2. delete ****\n);printf(****3. search 4. modify ****\n);printf(****5. show 6. sort ****\n);printf(****7. destroy 0. exit ****\n);printf(***********Contact***********\n);
}
int main()
{Contact con;InitContact(con);int input 0;do{menu();printf(请输入需要进行的操作:);scanf(%d, input);switch (input){case ADD:AddContact(con);break;case DELETE:DeleteContact(con);break;case SEARCH:SearchContact(con);break;case MODIFY:ModifyContact(con);break;case SHOW:ShowContact(con);break;case SORT:SortContact(con);break;case DESTROY:DestroyContact(con);break;case EXIT:break;default :break;}} while (input);
}函数实现
初始化
由于我们申请的是一个Contact类型的变量并没有初始化所以我们需要将Contac变量的sz(有效联系人个数)成员初始化为0以及整个通讯录初始化为0
//初始化
void InitContact(Contact* con)
{con-sz 0;memset(con-data, 0, sizeof(con-data));
}显示
我们是通过成员sz来记录该通讯录有效联系人的个数所以打印通讯录时也只需要通过sz来判断打印结束条件(即只用打印sz个联系人的信息)
//显示
void ShowContact(const Contact* con)
{printf(%-10s%-10s%-10s%-20s%-20s\n, 姓名, 年龄, 性别, 电话, 地址);for (int i 0; i con-sz; i){printf(%-10s%-10d%-10s%-20s%-20s\n,con-data[i].name, con-data[i].age, con-data[i].sex, con-data[i].tele, con-data[i].address);}
}这里处于安全考虑形参用const修饰 添加
添加联系人需要完成2步
输入需要添加联系人的信息(姓名、年龄、性别、电话、地址)将通讯录的有效成员个数1
//添加
void AddContact(Contact* con)
{if (con-sz MAX){printf(通讯录容量已经满了无法添加\n);return;}printf(请输入你需要添加人的姓名:);scanf(%s, con-data[con-sz].name);
printf(请输出你需要添加人的年龄:);scanf(%d, (con-data[con-sz].age));printf(请输入你需要添加人的性别:);scanf(%s, con-data[con-sz].sex);printf(请输入你需要添加人的电话:);scanf(%s, con-data[con-sz].tele);printf(请输入你需要添加人的地址:);scanf(%s, con-data[con-sz].address);con-sz;printf(添加成功!\n通讯录还可以容纳%d人\n, MAX - con-sz);
} 添加的联系人存储在当前有效联系人的最后面 删除
删除需要两步
删除首先需要找到该联系人(由于后面查找功能也需要查找联系人所以将此时的查找定义为一个函数)用后面的联系人的信息覆盖以该联系人开始后面信息(即删除)
//查找联系人的下标
static int findContact(const Contact* con, const char* name)
{for (int i 0; i con-sz; i){if (strcmp(con-data[i].name, name) 0){return i;}}return -1;
}//删除
void DeleteContact(Contact* con)
{if (con-sz 0){printf(当前通讯录没有联系人无法删除\n);return;}char name[20];printf(请输出你需要删除联系人的姓名:);scanf(%s, name);//查找int pos findContact(con, name);if (pos -1){printf(没有找到该联系人\n);return;}//删除memmove((con-data[pos]), (con-data[pos]) 1, sizeof(con-data[0]) * (MAX - pos - 1));con-sz--;printf(删除成功!\n通讯录可容纳的人数%d\n, MAX - con-sz);
}给出几点注意 删除可以根据用户输入的姓名找到指定的联系人进行删除(不考虑删除)也可以根据用户输入的电话进行删除 这里实现根据用户输入的姓名进行删除删除可以将data数组后面的元素一个一个挪动到前面,我这里直接用memmove大同小异但是不能使用memcpy因为内存有重复的删除后通讯录有效人数的数量-1 查找
找到该联系人的下标打印该联系人的信息
//查找
void SearchContact(const Contact* con)
{printf(请输出你需要查找联系人的姓名:);char name[20];scanf(%s, name);int pos findContact(con, name);if (pos -1){printf(找不到该联系人\n);return;}printf(查找结果如下:\n);printf(%-10s%-10s%-10s%-20s%-20s\n,姓名, 年龄, 性别, 电话, 地址);printf(%-10s%-10d%-10s%-20s%-20s\n,con-data[pos].name, con-data[pos].age, con-data[pos].sex,con-data[pos].tele, con-data[pos].address);
}
修改
当联系人不小心信息输入错了之后我们需要对它进行修改 修改分两步
找到需要修改的联系人的下标录入修改后的信息
//修改
void ModifyContact(Contact* con)
{printf(请输出需要修改联系人的名字:);char name[20];scanf(%s, name);int pos findContact(con, name);if (pos -1){printf(找不到该联系人\n);return;}printf(请输入修改后的姓名:);scanf(%s, con-data[pos].name);printf(请输入修改后的年龄:);scanf(%d, (con-data[pos].age));printf(请输入修改后的性别:);scanf(%s, con-data[pos].sex);printf(请输入修改后的电话:);scanf(%s, con-data[pos].tele);printf(请输入修改后的地址:);scanf(%s, con-data[pos].address);
}
排序
排序主要为2中方式
按照名字从小到大排序按照年龄从小到大排序
//自定义名字比较函数
int CmpByName(const void* e1, const void* e2)
{return (strcmp(((PeoInfo*)e1)-name , ((PeoInfo*)e2)-name));
}
//自定义年龄比较函数
int CmpByAge(const void* e1, const void* e2)
{return ((PeoInfo*)e1)-age - ((PeoInfo*)e2)-age;
}
void SortContact(Contact* con)
{int input 0;do{printf(请选择排序方式\n1. 姓名 2.年龄\n);scanf(%d, input);if (input 1){qsort(con-data, con-sz, sizeof(con-data[0]), CmpByName);printf(排序成功\n);ShowContact(con);}else if (input 2){qsort(con-data, con-sz, sizeof(con-data[0]), CmpByAge);printf(排序成功\n);ShowContact(con);}else printf(选择错误\n);} while (input ! 1 input ! 2);
}由于待排序数组是结构体数组所以直接调用库函数qsort 注意比较函数是需要我们自己定义的 清空通讯录
比较简单将结构体数组所有元素赋值为0通讯录数组有效联系人置为0即可
void DestroyContact(Contact* con)
{printf(你确定要清空通讯录吗?(YES/NO)\n);char selection[MAX] { 0 };scanf(%s, selection);fflush(stdin);if (strcmp(selection, YES) ! 0) return;memset(con-data, 0, sizeof(con-data));con-sz 0;printf(清空成功!\n);
}不足之处
此通讯录总体来说实现比较简单类似于静态顺序表 次通讯录如下几方面不足可以改进
通讯录的大小是固定的通讯的内存存储是连续的(数组在空间中是连续存放的)通讯录的存储是存储在内存中的没有保存在文件中程序结束后通讯录销毁
本章内容到这结束了不足之处我们后续会逐渐改进在后续文章中随着更加系统的学习我们会逐渐优化
完整代码在静态通讯录