C系列文章目录
目录
前言
通过使用C语言来创建一个通讯录的管理系统,管理人员可对成员信息进行管理。成员信息包括姓名、年龄、电话、性别以及住址,执行操作有增删改查这四项基本操作以及成员信息全览和信息排序。
一,模块化编程
可维护性:模块化编程将代码划分为独立的模块,每个模块负责特定的任务或功能。这样,在需要修改或调试某个功能时,只需关注相关的模块,而不需要涉及整个程序。这大大简化了维护和调试的工作,使得代码更易于理解和修改。
重用性:模块化编程鼓励开发人员将一些常用的功能封装成模块,然后在不同的项目中重复使用。这样可以避免重复编写相同的代码,减少了开发工作量,提高了开发效率。同时,通过不断重用经过测试和验证的模块,可以提高代码的可靠性和稳定性。
可扩展性:当需要添加新的功能或修改现有功能时,模块化编程能够提供更好的可扩展性。由于模块之间的依赖关系明确定义和管理,可以单独修改或替换某个模块,而不会影响到其他模块。这种灵活性使得系统更容易适应变化和演化。
并行开发:模块化编程允许多个开发人员并行工作,每个人负责开发和测试不同的模块。这样可以提高开发效率,缩短项目的开发周期。同时,模块化编程也方便团队协作和沟通,降低了开发过程中的冲突和合并的风险。
可测试性:模块化编程使得单元测试更容易进行。每个模块都是相对独立的,可以单独测试其功能和性能。这样可以更容易地发现和修复问题,提高软件的质量和稳定性。
总之,模块化编程的优势包括可维护性、重用性、可扩展性、并行开发和可测试性。这些优势使得代码更易于理解、修改和维护,提高了开发效率和软件质量。
在学习通讯录管理系统前,我们先了解模块化编程,模块化编程的思想可以让我们更好的进行编程,让我们更好的理解接下来的通讯录管理系统过程。
二,系统框架构建
1.成员信息的创建
因为我们要输入成员信息较多,所有我们可以选择通过创建结构体来创建一个通讯录结构体和一个成员信息结构体。
通讯录结构体内部会嵌套一个成员信息结构体和一个表示成员数量的变量。
typedef struct PeoInfo//创建成员信息结构体 { char name[FILENAME_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;
2.菜单实现
首先对于我们要创建的通讯录管理系统来说,建立一个菜单让人们选择功能是非常重要的,这就好比在一个餐厅里,只有提供了一份菜单,顾客就可以根据自己的意愿的点菜,在操作界面显示一个完整简明的菜单,才能更好地管理通讯录系统。
void nume() { printf("*******************************\n"); printf("***** 通讯录管理系统 ******\n"); printf("*** 1.add 2.del ****\n");//增加和删除指定联系人 printf("*** 3.search 4.modify***\n");//查找和修改指定联系人 printf("*** 5.show 6.sort ****\n");//显示和排序所有联系人 printf("*** 7.empty 0.exit ****\n");//清除所有联系人,和退出程序 printf("*******************************\n"); }
3.系统功能声明
//对通讯录进行初始化 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 QingContact(Contact* pc); //排序联系人 void PaiContact(Contact* pc);
三、系统功能实现
1.初始化通讯录
为什么要对通讯录进行初始化呢,因为在创建了通讯录之后,里边的所有信息的以随机值的形式存在,不知道的还以为这个通讯录里已经存放了成员信息,所以要进行初始化。
//初始化通讯录 void InitContact(Contact* pc) { assert(pc);//防止空指针 pc->sz = 0;//将sz初始化为0 memset(pc->data, 0, sizeof(pc->data));//数组名,替换,替换数 }
2.增加联系人
//增加联系人 void AddContact(Contact* pc) { assert(pc);//防止空指针 if (pc->sz == MAX)//表示通讯录结构体的开辟的空间满了 { printf("通讯录已满,无法增加\n"); return; } //通讯录没有满就输入 else { 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"); } }
3.显示所有联系人
//打印所有联系人 void ShowContact(Contact* pc) { assert(pc);//防止空指针 if (pc->sz == 0)//检查sz是否是指向开头 { printf("通讯录为空,无需打印\n"); return; } int i = 0; printf("%-20s%-5s%-5s%-12s%-30s%\n", "名字", "年龄", "性别", "电话", "地址"); for (i = 0; i < pc->sz; i++) { printf("%-20s%-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); } }
4.根据姓名查找位置
这个函数的存在就是为了通讯录管理人员通过成员姓名来查找该成员信息所处的位置。
static int FindByName(Contact* pc, char name[]) { assert(pc);//防止空指针 int i = 0; for (i = 0; i < pc->sz; i++) { if (strcmp(pc->data[i].name, name) == 0)//对比数据是否相同,如果相同就返回该指针的指向数据,不相同就返回-1 { return i; } } return -1; }
5.删除指定联系人
//删除指定联系人 void DelContact(Contact* pc) { char name[NAME_MAX]; assert(pc); if (pc->sz == 0)//先要看通讯录是否为空 { printf("通讯录为空,无法删除\n"); return; } printf("请输入要删除人的名字:"); scanf("%s", name); int ret = FindByName(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"); }
6.查找指定联系人
void SearchContact(Contact* pc) { char name[NAME_MAX]; assert(pc); printf("请输入要查找人的名字:"); scanf("%s", name); int ret = FindByName(pc, name); if (ret == -1) { printf("要查找的人不存在\n"); return; } printf("%-20s%-5s%-5s%-12s%-30s%\n", "名字", "年龄", "性别", "电话", "地址"); printf("%-20s%-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); }
7.修改指定联系人
//修改联系人 void ModifyContact(Contact* pc) { char name[NAME_MAX]; assert(pc); printf("请输入要修改人的名字:"); scanf("%s", name); int ret = FindByName(pc, name); if (ret == -1) { printf("要修改的人不存在\n"); return; } printf("请输入名字:"); scanf("%s", pc->data[ret].name); printf("请输入年龄:"); scanf("%d", &(pc->data[pc->sz].age)); printf("请输入性别:"); scanf("%s", pc->data[ret].sex); printf("请输入电话:"); scanf("%s", pc->data[ret].tele); printf("请输入地址:"); scanf("%s", pc->data[ret].addr); printf("修改成功\n"); }
8.清空所有联系人
//清空所有联系人 void QingContact(Contact* pc) { char name[NAME_MAX]; assert(pc); if (pc->sz == 0) { printf("通讯录为空,无法删除\n"); return; } pc->sz = 0; memset(pc->data, 0, sizeof(pc->data)); printf("删除成功\n"); }
9.按照名字排序所有联系人
使用qsort函数经行排序
//排序所有人 int cmp_s(const void* elem1, const void* elem2) { return strcmp((char*)elem1, (char*)elem2); } void PaiContact(Contact* pc) { assert(pc); qsort(pc, pc->sz, sizeof(pc->data[0]), cmp_s); int i = 0; printf("%-20s%-5s%-5s%-12s%-30s%\n", "名字", "年龄", "性别", "电话", "地址"); for (i = 0; i < pc->sz; i++) { printf("%-20s%-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); } }
四,源文件展示
1.test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" void nume() { printf("*******************************\n"); printf("***** 通讯录管理系统 ******\n"); printf("*** 1.add 2.del ****\n");//增加和删除指定联系人 printf("*** 3.search 4.modify***\n");//查找和修改指定联系人 printf("*** 5.show 6.sort ****\n");//显示和排序所有联系人 printf("*** 7.empty 0.exit ****\n");//清除所有联系人,和退出程序 printf("*******************************\n"); } enum Option { EXIT, ADD, DEL, SEARCH, MODIFY, SHOW, SORT, EMPTY, }; int main() { int input = 0; Contact con; InitContact(&con); do { nume(); 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: PaiContact(&con); break; case EMPTY: QingContact(&con); break; default: break; } } while(input); return 0; }
2.game.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" //初始化通讯录 void InitContact(Contact* pc) { assert(pc);//防止空指针 pc->sz = 0;//将sz初始化为0 memset(pc->data, 0, sizeof(pc->data));//数组名,替换,替换数 } //增加联系人 void AddContact(Contact* pc) { assert(pc);//防止空指针 if (pc->sz == MAX)//表示通讯录结构体的开辟的空间满了 { printf("通讯录已满,无法增加\n"); return; } //通讯录没有满就输入 else { 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"); } } //打印所有联系人 void ShowContact(Contact* pc) { assert(pc);//防止空指针 if (pc->sz == 0)//检查sz是否是指向开头 { printf("通讯录为空,无需打印\n"); return; } int i = 0; printf("%-20s%-5s%-5s%-12s%-30s%\n", "名字", "年龄", "性别", "电话", "地址"); for (i = 0; i < pc->sz; i++) { printf("%-20s%-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); } } static int FindByName(Contact* pc, char name[]) { assert(pc);//防止空指针 int i = 0; for (i = 0; i < pc->sz; i++) { if (strcmp(pc->data[i].name, name) == 0)//对比数据是否相同,如果相同就返回该指针的指向数据,不相同就返回-1 { return i; } } 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 = FindByName(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"); } //查找联系人 void SearchContact(Contact* pc) { char name[NAME_MAX]; assert(pc); printf("请输入要查找人的名字:"); scanf("%s", name); int ret = FindByName(pc, name); if (ret == -1) { printf("要查找的人不存在\n"); return; } printf("%-20s%-5s%-5s%-12s%-30s%\n", "名字", "年龄", "性别", "电话", "地址"); printf("%-20s%-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); } //修改联系人 void ModifyContact(Contact* pc) { char name[NAME_MAX]; assert(pc); printf("请输入要修改人的名字:"); scanf("%s", name); int ret = FindByName(pc, name); if (ret == -1) { printf("要修改的人不存在\n"); return; } printf("请输入名字:"); scanf("%s", pc->data[ret].name); printf("请输入年龄:"); scanf("%d", &(pc->data[pc->sz].age)); printf("请输入性别:"); scanf("%s", pc->data[ret].sex); printf("请输入电话:"); scanf("%s", pc->data[ret].tele); printf("请输入地址:"); scanf("%s", pc->data[ret].addr); printf("修改成功\n"); } //清空所有联系人 void QingContact(Contact* pc) { char name[NAME_MAX]; assert(pc); if (pc->sz == 0) { printf("通讯录为空,无法删除\n"); return; } pc->sz = 0; memset(pc->data, 0, sizeof(pc->data)); printf("删除成功\n"); } //排序所有人 int cmp_s(const void* elem1, const void* elem2) { return strcmp((char*)elem1, (char*)elem2); } void PaiContact(Contact* pc) { assert(pc); qsort(pc, pc->sz, sizeof(pc->data[0]), cmp_s); int i = 0; printf("%-20s%-5s%-5s%-12s%-30s%\n", "名字", "年龄", "性别", "电话", "地址"); for (i = 0; i < pc->sz; i++) { printf("%-20s%-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); } }
3.game.h
#pragma once #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #define NAME_MAX 20 #define SEX_MAX 5 #define TELE_MAX 12 #define ADDR_MAX 30 #define MAX 100 typedef struct PeoInfo { char name[FILENAME_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 QingContact(Contact* pc); //排序联系人 void PaiContact(Contact* pc);
总结
本篇文章详细的,有体系的介绍了通讯录管理系统的结构,方便我们小白的更加理解C语言的自定义结构体。