🍀实现一个通讯录:
通讯录中保存人的信息:
名字
年龄
性别
电话
住址
🍀通讯录的功能:
1.通讯录可以存放100个人的信息
2.显示所有联系人的信息
3.排序功能
4.增:增加联系人
5.删:删除指定联系人
6.查:查找指定联系人
7.改:修改指定联系人
🍀多文件实现
test.c 测试通讯录
contact.h 函数和类型的声明
contact.c 函数的实现
💮设计结构体——保存人的信息
初级:
struct PeoInfo { char name[20]; int age; char sex[5];//一个汉字占两个字符 char tele[12]; char addr[30]; };
结构体的引用:
struct PeoInfo num1 ; struct PeoInfo num2; struct PeoInfo data[50];
改进:
考虑到每次使用结构体都需要写 struct PeoInfo
比较繁琐,能不能直接把struct
自己省略掉呢?
这时候就需要对改结构体进行重命名typedef
:
typedef struct PeoInfo { char name[20]; int age; char sex[5]; char tele[12]; char addr[30]; }PeoInfo;
这样,当我们使用结构体时,就不用用 struct PeoInfo
了,直接使用PeoInfo
就可以了。
💮初始通讯录
因为我们刚刚定义了结构体用来存储人的信息,但一个通讯录中有很多人,我们上面设置了该通讯录可以存放100个人的信息,所以我们需要用结构体数组
将每一个类型都是结构体的元素存储起来。
C语言定义结构体数组
一般形式:
结构体类型 数组名[数组长度];
所以我们定义 通讯录:
PeoInfo data[100];
同时,我们需要一个变量,来判断通讯录里已经存放数据的个数。(以防止在增添联系人时,超过了定义的通讯录的最大容量)
int sz=0;
💮封装通讯录
在上面考虑到通讯录PeoInfo data[100]
和变量 sz
是一种封锁的关系。即,sz
等于几,PeoInfo data
里面就有几个数据元素。sz
加1,则PeoInfo data
数组里会再存放一个元素。
所以,我们考虑将通讯录进行进一步的封装
,构建一个结构体
:
typedef struct Contact { PeoInfo data[100]; int sz; }Contact;
这时,我们的通讯录就为 con
Contact con;
💮define宏定义修改通讯录的最大容量
同样我们也可以对 我们刚开始定义的 姓名、地址、联系方式等 以同样的宏定义进行转变。
初始化通讯录
将通讯录初始化为0。可以定义一个函数,用来初始化通讯录。
void InitContact(Contact* pc) { memset(pc->data, 0, sizeof(pc->data); pc->sz = 0; }
因为我们要改变通讯录的内部,所以函数参数是一个地址值,类型是我们定义的通讯录结构体 Contact
类型。
利用memset
函数,将结构体中数组所有元素全部赋值为0.同时将pc所指向的sz
也初始化为0.
void InitContact(Contact* pc) { memset(pc->data, 0, sizeof(pc->data); pc->sz = 0; }
💐💐大致框架
接下来,我们在void test ()
函数中写一下大概的框架:
(因为要尽可能避免在主函数中太过冗长,所以我们把通讯录的具体实现——增删查找等等都放在test函数中,之后我们就只需要在主函数中进行调用
即可。)
首先,我们可以用do...while
循环 打印一个菜单。
定义一个函数 void menu()
完成打印。在()函数中调用即可。
之后我们利用switch,对输入的input
进行判断,进行相应的操作。对于下面的七种情况,我们可以写七个函数
分别实现其相应的功能。
我们进行的所有操作都是对于通讯录
而言的,所以在test函数中必须有通讯录。所以我们将我们已经初始化的通讯录放在函数中。
不要忘了包含头文件contact.h
(在contact.h头文件中,包含着本身已经封装好的常见的头文件 比如 、等,还有我们自己对于结构体或者函数的一些声明和定义,比如定义人的信息的结构体 PeoInfo
、定义通讯录的 Contact
,以及我们函数的声明
,完成Contact初始化的函数InitContact
等,还有之后,我们要对通讯录进行操作的一系列增删查找函数等函数的声明
都会放在都文件中。)
(要注意,函数的定义不是放在头文件中的,而是在contat.c
中)
💐改进–枚举 提高代码的可读性
🌼🌼定义函数实现功能
🌼AddContact
//增加联系人的信息 void AddContact(Contact* pc) { //判断数组是否可以增添? if (pc->sz == 100) { printf("通讯录已满,无法添加\n"); return; } //通讯录没满 else { printf("请输入名字:>"); scanf("%s", pc->data[pc->sz].name);//pc->data 指向的是结构体数组 数组名本身就是地址,不用用取地址符号 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("增加联系人成功!"); } }