前言
本篇博客将接着上次顺序表的内容进行拓展应用,这次来为大家介绍通讯录的实现,它就是基于顺序表的结构完成的;如果你对此感兴趣,请看下面的内容;
1.顺序表的应用
我们前面学过,顺序表可以存放任意类型的元素,前面我们在顺序表中存放整型元素,浮点型元素等内置类型;今天,我们将在顺序表中存放结构体这种自定义类型的变量;生活中,大家都使用过手机的通讯录,通讯录中有联系人的各种信息,那么如果我们想创建一个通讯录,那么我们就需要把每个联系人的不同信息放到一个结构体中,并且将其存放起来,那么就需要用到顺序表这个数据结构了;
OK,上面说了通讯录的基本逻辑,下面开始进行代码实现;
首先,基于顺序表专题的代码,我们需要新创建一个通讯录的头文件和一个通讯录的实现文件;
这里我们就创建好了;下面我们需要在头文件中定义联系人数据结构,在这里,我们需要定义联系人的姓名、性别、年龄、电话、地址这五个信息,大家请看下面的代码;
#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100
typedef struct personInfo
{char name[NAME_MAX];int age;char gender[GENDER_MAX];char tel[TEL_MAX];char addr[ADDR_MAX];
}peoInfo;
这里大家可以看到,我们定义了我们需要的数据,并且规定了它们的大小;
下面,我们还需要在顺序表的头文件中。将数据类型进行替换;
typedef peoInfo SLDataType;
下面。我们要对通讯录实行初始化、销毁,增删查改等一系列操作;那么我们需要知道,对通讯录的操作实际上就是对顺序表进行操作;
那么这里我们就需要进行以下操作;
首先,我们要给顺序表改个名字,让它叫作通讯录;
typedef SL Contact;
这里我们就改好了,但是这里大家需要注意一个点,我们必须要在通讯录的头文件中进行前置声明,否则将找不到SL这个结构体;
1.1 通讯录的初始化
首先,我们需要在通讯录头文件中进行方法声明;
void ContactInit(Contact* con);
下面,我们要在通讯录的实现文件中去实现初始化的方法;这里大家注意,上面说了对通讯录的操作就是对顺序表的操作,那么我们只需要引用顺序表初始化的方法就可以实现对通讯录的初始化;这里大家就需要在通讯录的实现文件中包含两个头文件:"Contact.h" "SeqList.h";然后我们就可以引用顺序表的初始化方法来对通讯录进行初始化了;
void ContactInit(Contact* con)
{SLInit(con);
}
初始化的代码很简单,直接引用顺序表中写好的初始化方法即可。
初始化完成后,我们需要进行测试,这个时候我们需要进行测试;
这里大家在测试的过程中打开调试窗口,监视一下con,你会发现,con实际上就是顺序表,这与我们前面所述一致,我们对通讯录操作实际上就是对顺序表进行操作。
1.2 通讯录的销毁
上面说完了初始化,下面来看通讯录的销毁,操作方法与上面类似;
首先还是要在通讯录的头文件中进行声明;
void ContactDestroy(Contact* con);
声明完后,我们要在“Contact.c”文件中进行方法实现;
void ContactDestroy(Contact* con)
{SLDestroy(con);
}
这里因为我们前面已经写过顺序表的销毁方法了,所以这里直接可以拿来用,代码比较简单。
实现完成后,我们要进行测试,继续在test.c文件中进行测试;
测试的结果大家可以自行进行调试,这里不做赘述。
1.3 通讯录添加数据
首先还是先在头文件中声明;
void ContactAdd(Contact* con);
其次我们来进行方法实现;
void ContactAdd(Contact* con)
{peoInfo info;printf("请输入要添加的联系人姓名:\n");scanf("%s", info.name);printf("请输入要添加的联系人性别:\n");scanf("%s", info.gender);printf("请输入要添加的联系人年龄:\n");scanf("%d", &info.age);printf("请输入要添加的联系人电话:\n");scanf("%d", info.tel);printf("请输入要添加的联系人地址:\n");scanf("%d", info.addr);SLPushBack(con, info);
}
这里大家来看代码,我们要将用户输入的信息保存到通讯录中,所以我们需要先用通讯录来创建一个结构体变量,然后进行存储。这里要提醒大家一点,在输入年龄时,我们需要加上&操作符,儿其他的变量都是不需要的,因为大家可以看一开始我们对通讯录的定义,只有年龄是整型变量,其他的都是字符数组,我们知道数组名表示的就是首元素的地址,所以在这里我们输入的格式中不需要加&操作符,这一点希望大家注意一下;最后这里我以尾插为例来进行数据的插入。
下面来进行测试;
大家在测试的时候。可以进行调试,监视通讯录中的数据,如上图所示,我们可以发现已经将我们输入的联系人数据存入通讯录。
1.4 通讯录删除数据
上来我们还是先在“Contact.h”中声明方法;
void ContactDel(Contact* con);
下面来实现删除的方法,这里大家思考一下,我们想要删除数据,是不是先要有数据存在,我们才能进行删除,那么我们想要删除指定的信息,就必须得先进行查找;所以这里我们需要引进一个查找的函数,我们以查找姓名为例;
int FindByName(Contact* con, char name[])
{for (int i = 0; i< con->size; i++){if (strcmp(con->arr[i].name, name) == 0){return i;}return -1;}
}
这里大家来看这个查找函数,我们用到了strcmp函数来判断两个字符串是否相等,如果返回值为0,那么证明我们找到了对应的姓名信息。
我们继续来实现删除的方法,大家看下面的代码;
void ContactDel(Contact* con)
{char name[NAME_MAX];scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要删除的联系人数据不存在\n");return;}SLErase(con, find);printf("删除成功\n");
}
这里我们要根据姓名来查找,所以直接创建一个字符数组即可,然后我们需要调用我们上面刚写的查找函数,如果返回值为负数,证明没有找到(返回的下标,下标不能为负数);如果找到了,这里我们要删除它,那么就需要用在顺序表中定义的方法“在指定位置删除数据”,这样我们就可以成功删除我们想删除的数据。
下面我们在test.c文件中测试一下通讯录的删除;
大家发现,size变成了0,证明我们删除成功了。
1.5 通讯录的展示
这里为大家介绍展示通讯录的方法;首先还是声明;
void ContactShow(Contact* con);
然后来进行方法的实现;
void ContactShow(Contact* con)
{printf("%s %s %s %s %s", "姓名", "性别", "年龄", "电话", "地址");for (int i = 0; i < con->size; i++){printf("%s %s %d %s %s\n", con->arr[i].name,con->arr[i].gender,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}
这里我们要遍历通讯录,将通讯录中的信息打印出来;
下面我们来测试一下;
大家可以看到,通讯录中的数据发生了变化,这里比调试看的更直观。
1.6 通讯录的修改
继续来看通讯录的修改,一上来还是先进行声明;
void ContactModify(Contact* con);
下面再来实现修改的方法,这里大家要注意,要修改数据,前提要保证数据的存在性,所以这里的代码和上面的删除代码就有几分相似了;
这里大家会发现上半部分和删除的代码是一样的,下半部分我们只需要依次输入新的联系人数据即可。
void ContactModify(Contact* con)
{char name[NAME_MAX];printf("请输入要删除的联系人姓名\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要删除的联系人数据不存在\n");return;}printf("请输入新的姓名 \n");scanf("%s", con->arr[find].name);printf("请输入新的性别 \n");scanf("%s", con->arr[find].gender);printf("请输入新的年龄 \n");scanf("%s", &con->arr[find].age);printf("请输入新的电话 \n");scanf("%s", con->arr[find].tel);printf("请输入新的地址 \n");scanf("%s", con->arr[find].addr);printf("修改成功\n");
}
下面来测试一下修改的代码;
大家可以看到。这里我们完成了修改。
1.7 通讯录的查找
还是在头文件中进行声明;
void ContactFind(Contact* con);
然后我们来实现查找方法;
void ContactFind(Contact* con)
{char name[NAME_MAX];printf("请输入要删除的联系人姓名\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要查找的联系人数据不存在\n");return;}printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");printf("%s %s %d %s %s\n", con->arr[find].name,con->arr[find].gender,con->arr[find].age,con->arr[find].tel,con->arr[find].addr);
}
接下来,我们来测试一下;
大家可以看到,在我们输入完信息后,我们可以查找到我们对应联系人的所有信息,这里我们的查找功能就成功实现了。
2. 通讯录的整体实现
上面已经为大家介绍完通讯录的所有操作了,下面我们要将其加工成一个像样的项目;
void meau()
{printf("************通讯录************\n");printf("**1.增加联系人 2.删除联系人**\n");printf("**3.修改联系人 4.查找联系人**\n");printf("**5.展示联系人 6.退出通讯录**\n");printf("******************************\n");
}
int main()
{int op = -1;Contact con;ContactInit(&con);do{meau();printf("请选择操作: \n");scanf("%d", &op);switch (op){case 1:ContactAdd(&con);break;case 2:ContactDel(&con);break;case 3:ContactModify(&con);break;case 4:ContactFind(&con);break;case 5:ContactShow(&con);break;case 0:printf("通讯录退出\n");break;default :printf("输入错误,请选择正确的选项!\n");break;}} while (op != 0);ContactDestroy(&con);return 0;
}
这里我们增加了一个菜单来供用户选择,下面我们使用了do-while语句来实现循环的效果,还用到了switch语句来实现分支结构,经过这一系列操作,我们完善了通讯录项目。
下面为大家展示完整的代码;
首先,来展示头文件Contact.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100
typedef struct SeqList Contact;
typedef struct personInfo
{char name[NAME_MAX];int age;char gender[GENDER_MAX];char tel[TEL_MAX];char addr[ADDR_MAX];
}peoInfo;void ContactInit(Contact* con);
void ContactDestroy(Contact* con);
void ContactAdd(Contact* con);
void ContactDel(Contact* con);
void ContactModify(Contact* con);
void ContactFind(Contact* con);
void ContactShow(Contact* con);
下面是通讯录的实现文件Contact.c
#include"Contact.h"
#include"Seqlist.h"
void ContactInit(Contact* con)
{SLInit(con);
}
void ContactDestroy(Contact* con)
{SLDestroy(con);
}
void ContactAdd(Contact* con)
{peoInfo info;printf("请输入要添加的联系人姓名:\n");scanf("%s", info.name);printf("请输入要添加的联系人性别:\n");scanf("%s", info.gender);printf("请输入要添加的联系人年龄:\n");scanf("%d", &info.age);printf("请输入要添加的联系人电话:\n");scanf("%s", info.tel);printf("请输入要添加的联系人地址:\n");scanf("%s", info.addr);SLPushBack(con, info);
}
int FindByName(Contact* con, char name[])
{for (int i = 0; i< con->size; i++){if (strcmp(con->arr[i].name, name) == 0){return i;}}return -1;
}
void ContactDel(Contact* con)
{char name[NAME_MAX];printf("请输入要删除的联系人姓名\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要删除的联系人数据不存在\n");return;}SLErase(con, find);printf("删除成功! \n");
}
void ContactShow(Contact* con)
{printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");for (int i = 0; i < con->size; i++){printf("%s %s %d %s %s\n", con->arr[i].name,con->arr[i].gender,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}
void ContactModify(Contact* con)
{char name[NAME_MAX];printf("请输入要删除的联系人姓名\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要修改的联系人数据不存在\n");return;}printf("请输入新的姓名 \n");scanf("%s", con->arr[find].name);printf("请输入新的性别 \n");scanf("%s", con->arr[find].gender);printf("请输入新的年龄 \n");scanf("%d", &con->arr[find].age);printf("请输入新的电话 \n");scanf("%s", con->arr[find].tel);printf("请输入新的地址 \n");scanf("%s", con->arr[find].addr);printf("修改成功\n");
}
void ContactFind(Contact* con)
{char name[NAME_MAX];printf("请输入要查找的联系人姓名\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要查找的联系人数据不存在\n");return;}printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");printf("%s %s %d %s %s\n", con->arr[find].name,con->arr[find].gender,con->arr[find].age,con->arr[find].tel,con->arr[find].addr);
}
最后来看测试文件test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
void ContactTest01()
{Contact con;ContactInit(&con);ContactAdd(&con);ContactAdd(&con);ContactShow(&con);//ContactModify(&con);//ContactDel(&con);//ContactShow(&con);ContactFind(&con);ContactDestroy(&con);
}
int main()
{ContactTest01();return 0;
}
这里说明一下,通讯录是顺序表的应用,关于顺序表的相关方法,大家可以在我的另一篇博客《顺序表专题》中看到,这里就不再重复展示。
3. 总结
本篇博客主要为大家介绍了顺序表这个数据结构的经典运用——通讯录,顺序表是数据结构的基础内容,希望大家理解并掌握顺序表的写法,同时通过通讯录来进一步加深对顺序表的理解。通讯录的本质就是顺序表,只不过套了一个的外壳,叫做了顺序表;最后,希望本篇博客可以为大家带来帮助,谢谢阅读!