目录
一、通讯录代码的实现
1.定义联系人的数据结构
关于联系人我们将从姓名、 性别 、年龄、 电话 、地址五个方面进行相对应的查找
代码如下:
cpp
//定义联系人数据结构
//姓名 性别 年龄 电话 地址
typedef struct personInfo // personInfo 是联系人的意思
{
char name[NAME_MAX];
char gender[GENDER_MAX];
int age;
char tel[TEL_MAX];
char addr[ADDR_MAX];
}peoInfo;
通讯录实现的方法:对顺序表进行操作就行了
此时我们给顺序表改一个名字,叫通讯录 ,方便我们更好的去理解
代码如下:
cpp
typedef struct Seqlist Contact;
2.通讯录的初始化
实际上要进行的是顺序表的初始化,由于顺序表的初始化已经实现好了,于是我们直接调用函就行了
Contact.c原文件代码如下:
cpp
//通讯录的初始化
void ContactInit(Contact* con)
{
//实际上要进行的是顺序表的初始化
//但是,顺序表的初始化已经实现好了
//于是我们直接调用函就行了
SLInit(con);
}
Contact.h头文件的代码如下:
这里我们进行了通讯录初始化的声明
cpp
void ContactInit(Contact* con); //这里的 con 就是顺序表
3.通讯录的销毁
这里的销毁和上面的初始化一样,直接调用函数(基于顺序表的代码内容)就行了
代码如下:
Contact.c原文件代码如下:
cpp
//通讯录的销毁
void ContactDesTroy(Contact* con)
{
SLDestroy(con); //这里的销毁和上面的初始化一样,直接调用函数就行了
}
Contact.h头文件的代码如下:
这里我们进行了通讯录初始化的声明
cpp
//通讯录的销毁
void ContactDesTroy(Contact* con);
4.通讯录增添数据
Contact.c原文件代码如下:
cpp
//通讯录的增添
void ContactAdd(Contact* con)
{
//获取用户输入的内容 :姓名 性别 年龄 电话 地址
peoInfo info; //直接引入之前已经声明好的内容
printf("请输入要添加的联系人的姓名");
scanf("%s", info.name);
printf("请输入要添加的联系人的性别");
scanf("%s", info.gender);
printf("请输入要添加的联系人的年龄");
scanf("%d", &info.age); //唯一一个不是数组名的变量,因为使用scanf必须要取地址
printf("请输入要添加的联系人的电话");
scanf("%s", info.tel);
printf("请输入要添加的联系人的地址");
scanf("%s", info.addr);
//此时往通讯录中添加联系人的数据
//头插尾插......都可以
//这里我们选择尾插
SLPushBack(con, info); //con是通讯录 info是我们要插入的数据
}
这里我们来解析一下上面的代码内容
cpp
void ContactAdd(Contact* con)
-
函数名 :
ContactAdd- 添加联系人 -
返回值 :
void- 无返回值 -
参数 :
Contact* con- 指向通讯录的指针 -
功能:向通讯录中添加一个新的联系人
创建联系人信息变量
cpp
peoInfo info; // 直接引入之前已经声明好的内容
-
peoInfo是联系人信息结构体类型(应该是typedef定义过的) -
info是结构体变量,用于临时存储用户输入的联系人信息 -
注释说明这个结构体在前面已经定义好了
获取姓名
cpp
printf("请输入要添加的联系人的姓名");
scanf("%s", info.name);
-
info.name是字符数组,数组名本身就是地址,所以不需要& -
使用
%s格式符读取字符串
后面的性别和年龄地址是一样的意思,这里我们就不解析了
添加到通讯录
cpp
// 头插尾插......都可以
// 这里我们选择尾插
SLPushBack(con, info); // con是通讯录,info是我们要插入的数据
-
SLPushBack是顺序表的尾插函数 -
将填写好的
info插入到通讯录con的末尾 -
注释说明有多种插入方式,这里选择最简单的尾插
Contact.h头文件的代码如下:
这里我们进行了通讯录初始化的声明
cpp
//通讯录增添数据
void ContactAdd(Contact* con);
5.通讯录删除数据
Contact.c原文件代码如下:
cpp
//通讯录删除数据
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");
}
注意:这里我们在进行删除联系人数据的时候,我们必须得知道此时的联系人是否存在这个数据,否则没有了怎么删除,所以在进行删除之前,我们必须进行判断
判断联系人数据是否存在的代码如下:
cpp
int FindByName(Contact* con, char name[])
{
for (int i = 0; i < con->size; i++)
{
if (0 == strcmp(con->arr[i].name, name)) //进行比较,如果相等则返回为0
{
//找到了
return 1;
}
}
//此时没有找到
return -1; //返回假值,退出程序
}
这里我们来解释一下上面的整个删除联系人数据的代码意思
函数分析
| 项目 | 说明 |
|---|---|
| 函数名 | ContactDel - 删除联系人 |
| 返回值 | void - 无返回值 |
| 参数 | Contact* con - 指向通讯录的指针 |
| 核心逻辑 | 查找 → 判断 → 删除 |
定义姓名数组
cpp
char name[NAME_MAX];
NAME_MAX是宏定义,表示姓名的最大长度
获取要删除的姓名
cpp
printf("请输入要删除的联系人姓名:\n");
scanf("%s", name);
-
提示用户输入
-
name是数组名,本身就是地址,不需要&
查找联系人
cpp
int find = FindByName(con, name);
-
调用查找函数,返回结果存入
find -
这里存在逻辑错误(后面会详细分析)
判断是否存在
cpp
if (find < 0)
{
printf("输入的联系人数据不存在\n");
return;
}
-
如果返回值小于0,说明没找到
-
直接返回,不执行删除
执行删除
cpp
SLErase(con, find);
printf("删除成功\n");
-
SLErase是顺序表的删除函数 -
传入通讯录指针和要删除的位置
find
查找功能代码解析
cpp
// 查找数据
int FindByName(Contact* con, char name[])
{
for (int i = 0; i < con->size; i++)
{
if (0 == strcmp(con->arr[i].name, name)) // 进行比较,如果相等则返回为0
{
// 找到了
return 1;
}
}
}
// 此时没有找到
return -1; // 返回值,退出程序
函数分析
| 项目 | 说明 |
|---|---|
| 函数名 | FindByName - 按姓名查找 |
| 返回值 | int - 返回位置或状态码 |
| 参数1 | Contact* con - 通讯录指针 |
| 参数2 | char name[] - 要查找的姓名 |
| 核心逻辑 | 遍历比较 → 返回结果 |
Contact.h头文件的代码如下:
这里我们进行了通讯录初始化的声明
cpp
//通讯录删除数据
void ContactDel(Contact* con);
6.通讯录的修改
Contact.c原文件代码如下:
cpp
//通讯录的修改
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");
}
我们来一一解释上面的代码意思
cpp
//通讯录的修改
void ContactModify(Contact* con)
| 项目 | 说明 |
|---|---|
| 函数名 | ContactModify - 修改联系人 |
| 返回值 | void - 无返回值 |
| 参数 | Contact* con - 指向通讯录的指针 |
| 功能 | 修改指定联系人的信息 |
查找要修改的联系人
cpp
//要修改的联系人数据必须存在
char name[NAME_MAX];
printf("请输入要修改的用户姓名: \n");
scanf("%s", name);
int find = FindByName(con, name); //判断联系人是否存在
if (find < 0)
{
printf("要修改的联系人数据不存在\n");
return;
}
执行流程:
-
定义字符数组存储要查找的姓名
-
提示用户输入姓名
-
调用
FindByName查找联系人 -
判断返回值:如果小于0表示不存在,直接返回
注意 :这里的FindByName函数存在之前分析过的问题,应该返回位置下标,而不是简单的1或-1
Contact.h头文件的代码如下:
这里我们进行了通讯录初始化的声明
cpp
//通讯录的修改
void ContactModify(Contact* con);
7.通讯录的查找
Contact.c原文件代码如下:
cpp
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);
}
这里的内容之前解释过,差不多是一个意思,这里我们就不仔细讲解了
Contact.h头文件的代码如下:
这里我们进行了通讯录初始化的声明
cpp
通讯录的查找
void ContactFind(Contact* con);
8.展示通讯录数据
Contact.c原文件代码如下:
cpp
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);
}
}
这里的内容也是很简单的,所以我们就不解析了
Contact.h头文件的代码如下:
这里我们进行了通讯录初始化的声明
cpp
/展示通讯录数据
void ContactShow(Contact* con);
以上8点就是关于通讯录所有代码的书写与意思的解释
二、通讯录总结
关于代码本身
这个通讯录项目,就像一面镜子,照出了C语言学习中的点点滴滴
添加功能 → 教会我们如何获取输入
删除功能 → 教会我们如何查找定位
修改功能 → 教会我们如何更新数据
查找功能 → 教会我们如何展示信息
每一个功能都不是孤立的,它们通过数据紧密相连,共同构成了一个完整的系统。
关于数据结构的理解
通过这个项目,我们真正理解了顺序表:
| 操作 | 我们做了什么 | 时间复杂度 |
|---|---|---|
| 添加 | 放到末尾 | O(1) |
| 删除 | 找到后移动元素 | O(n) |
| 修改 | 找到后直接改 | O(1) |
| 查找 | 遍历比较 | O(n) |
纸上得来终觉浅,绝知此事要躬行------亲手实现一遍,比看十遍理论都管用。
感谢这个小小的通讯录项目,它让我们真正走进了编程的世界! 🚀