1. 前言
通讯录是在动态顺序表的基础上实现的,其实就是顺序表的每个元素存储的不再是数字,而是存储一个联系人的结构体,所以如果有些小伙伴看不懂的话,可以移步参考一下动态顺序表的实现:顺序表(C语言详细版)-CSDN博客。
1.1 通讯录的功能
1)至少能够存储每个用户的通讯信息;
2)能够保存用户信息:名字、性别、年龄、电话、地址等;
3)增加联系人信息;
4)删除指定联系人;
5)查找制定联系人;
6)修改指定联系人;
7)显示联系人信息。
2. 定义联系人的结构体
#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100
// 定义联系人数据结构
// 姓名 性别 年龄 电话 地址
typedef struct personInfo
{char name[NAME_MAX]; // 姓名char gender[GENDER_MAX];// 性别int age; // 年龄char tel[TEL_MAX]; // 电话char addr[ADDR_MAX]; // 地址
}peoInfo;
3. 通讯录的初始化
如果我们要对通讯录初始化,我们可以通过对顺序表初始化,来实现对通讯录的初始化。要使用顺序表方法,所以我们必须前置声明 struct SeqList,然后将它重新命名为 Contact (通讯录英文)。
typedef struct SeqList Contact; // 前置声明
通讯录初始化声明:
/* 要用到顺序表相关的方法,对通讯录的操作,实际上就是对顺序表进行操作 * 给顺序表改个名字,叫做通讯录 */
//typedef SL Contact;
typedef struct SeqList Contact; // 必须要这样前置声明
// 通讯录相关的方法// 通讯录的初始化
//void ContactInit(SL* sl);
void ContactInit(Contact* con);
通讯录初始化定义:
// 通讯录的初始化
void ContactInit(Contact* con)//sl
{// 实际上要进行的是顺序表的初始化// 顺序表的初始化已经实现好了SLInit(con);
}
测试代码:
// 通讯录的测试方法
void ContactTest01()
{Contact con; // 创建的通讯录对象 实际上就是顺序表对象 等价于 SL sl// 通讯录初始化ContactInit(&con);
}int main()
{ContactTest01();return 0;
}
调试结果:有效联系人的人数为0,容纳联系人的总数也为0
4. 通讯录的销毁
对通讯录的销毁就是对顺序表的销毁,所以通讯录的销毁函数可以调用顺序表的销毁函数接口。
// 通讯录的销毁
void ContactDesTroy(Contact* con)
{SLDestroy(con);
}
测试程序:
// 通讯录的测试方法
void ContactTest01()
{Contact con; // 创建的通讯录对象 实际上就是顺序表对象 等价于 SL sl// 通讯录初始化ContactInit(&con);// 通讯录销毁ContactDesTroy(&con);
}int main()
{ContactTest01();return 0;
}
调试结果:其实跟初始化效果是一样的,因为我们通讯录里面没有数据嘛
5. 展示通讯录数据
为了更好地测试我们程序,我们可以先写一个打印程序,这样就不用一个个调试观察了。
// 展示通讯录数据
void ContactShow(Contact* con)
{// 表头:姓名 性别 年龄 电话 地址printf("%-5s %-5s %-5s %-5s %-5s\n", "姓名", "性别", "年龄", "电话", "地址");// 遍历通讯录,按照格式打印每个联系人数据for (int i = 0; i < con->size; i++){// 调整一下格式printf("%3s %3s %3d %3s %3s\n", \con->arr[i].name, \con->arr[i].gender, \con->arr[i].age, \con->arr[i].tel, \con->arr[i].addr);}
}
6. 通讯录添加联系人
往通讯录添加联系人,就是往顺序表插入数据,所以我们这里可以调用顺序表的尾插、头插、指定位置插入,我们这里就用尾插接口来实现吧!(其他插入接口函数也是能实现的,等会可以试试)
// 通讯录添加数据
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);//SLPushFront(con, info); // 头插//SLInsert(con, 0, info); // 指定位置插入
}
测试尾插联系人程序:
// 通讯录的测试方法
void ContactTest01()
{Contact con; // 创建的通讯录对象 实际上就是顺序表对象 等价于 SL sl// 通讯录初始化ContactInit(&con);// 添加数据ContactAdd(&con);ContactAdd(&con);ContactShow(&con);// 通讯录销毁ContactDesTroy(&con);
}int main()
{ContactTest01();return 0;
}
运行结果:
测试头插联系人结果:
测试指定位置插入联系人:
7. 通讯录删除联系人
通讯录删除联系人,我们可以调用顺序表的指定位置删除删除函数接口。在删除联系人之前,我们还必须找到该联系人,然后再把该联系人删除。我们查找联系人是根据联系人的姓名来查找(我们也可以根据其它信息来查找,这里就不实现了),找到联系人的下标,然后将下标返回。
// 根据用户的姓名来查找
int FindByName(Contact* con, char name[])
{for (int i = 0; i < con->size; i++){if (0 == strcmp(con->arr[i].name, name)){// 找到了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 ContactTest01()
{Contact con; // 创建的通讯录对象 实际上就是顺序表对象 等价于 SL sl// 通讯录初始化ContactInit(&con);// 添加数据ContactAdd(&con);ContactAdd(&con);ContactShow(&con);// 测试删除数据ContactDel(&con);ContactShow(&con);// 通讯录销毁ContactDesTroy(&con);
}int main()
{ContactTest01();return 0;
}
运行结果:
8. 通讯录的修改
先找要修改的联系人的下标,返回该下标,然后再进行修改。
// 通讯录的修改
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 ContactTest01()
{Contact con; // 创建的通讯录对象 实际上就是顺序表对象 等价于 SL sl// 通讯录初始化ContactInit(&con);// 添加数据ContactAdd(&con);ContactAdd(&con);ContactShow(&con);// 测试修改信息ContactModify(&con);ContactShow(&con);// 通讯录销毁ContactDesTroy(&con);
}int main()
{ContactTest01();return 0;
}
运行结果:
9. 通讯录查找
通讯录的查找,我们也是通过姓名来查找,找到了联系人的下标,然后返回下标,最后把找到的联系人打印出来。
// 通讯录查找
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("%3s %3s %3d %3s %3s\n", \con->arr[find].name, \con->arr[find].gender, \con->arr[find].age, \con->arr[find].tel, \con->arr[find].addr);
}
测试程序:
// 通讯录的测试方法
void ContactTest01()
{Contact con; // 创建的通讯录对象 实际上就是顺序表对象 等价于 SL sl// 通讯录初始化ContactInit(&con);// 添加数据ContactAdd(&con);ContactAdd(&con);ContactShow(&con);// 测试查找ContactFind(&con);// 通讯录销毁ContactDesTroy(&con);
}int main()
{ContactTest01();return 0;
}
运行结果: